Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

+1359 -180
+194
Documentation/connector/cn_test.c
··· 1 + /* 2 + * cn_test.c 3 + * 4 + * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> 5 + * All rights reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/kernel.h> 23 + #include <linux/module.h> 24 + #include <linux/moduleparam.h> 25 + #include <linux/skbuff.h> 26 + #include <linux/timer.h> 27 + 28 + #include "connector.h" 29 + 30 + static struct cb_id cn_test_id = { 0x123, 0x456 }; 31 + static char cn_test_name[] = "cn_test"; 32 + static struct sock *nls; 33 + static struct timer_list cn_test_timer; 34 + 35 + void cn_test_callback(void *data) 36 + { 37 + struct cn_msg *msg = (struct cn_msg *)data; 38 + 39 + printk("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n", 40 + __func__, jiffies, msg->id.idx, msg->id.val, 41 + msg->seq, msg->ack, msg->len, (char *)msg->data); 42 + } 43 + 44 + static int cn_test_want_notify(void) 45 + { 46 + struct cn_ctl_msg *ctl; 47 + struct cn_notify_req *req; 48 + struct cn_msg *msg = NULL; 49 + int size, size0; 50 + struct sk_buff *skb; 51 + struct nlmsghdr *nlh; 52 + u32 group = 1; 53 + 54 + size0 = sizeof(*msg) + sizeof(*ctl) + 3 * sizeof(*req); 55 + 56 + size = NLMSG_SPACE(size0); 57 + 58 + skb = alloc_skb(size, GFP_ATOMIC); 59 + if (!skb) { 60 + printk(KERN_ERR "Failed to allocate new skb with size=%u.\n", 61 + size); 62 + 63 + return -ENOMEM; 64 + } 65 + 66 + nlh = NLMSG_PUT(skb, 0, 0x123, NLMSG_DONE, size - sizeof(*nlh)); 67 + 68 + msg = (struct cn_msg *)NLMSG_DATA(nlh); 69 + 70 + memset(msg, 0, size0); 71 + 72 + msg->id.idx = -1; 73 + msg->id.val = -1; 74 + msg->seq = 0x123; 75 + msg->ack = 0x345; 76 + msg->len = size0 - sizeof(*msg); 77 + 78 + ctl = (struct cn_ctl_msg *)(msg + 1); 79 + 80 + ctl->idx_notify_num = 1; 81 + ctl->val_notify_num = 2; 82 + ctl->group = group; 83 + ctl->len = msg->len - sizeof(*ctl); 84 + 85 + req = (struct cn_notify_req *)(ctl + 1); 86 + 87 + /* 88 + * Idx. 89 + */ 90 + req->first = cn_test_id.idx; 91 + req->range = 10; 92 + 93 + /* 94 + * Val 0. 95 + */ 96 + req++; 97 + req->first = cn_test_id.val; 98 + req->range = 10; 99 + 100 + /* 101 + * Val 1. 102 + */ 103 + req++; 104 + req->first = cn_test_id.val + 20; 105 + req->range = 10; 106 + 107 + NETLINK_CB(skb).dst_groups = ctl->group; 108 + //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC); 109 + netlink_unicast(nls, skb, 0, 0); 110 + 111 + printk(KERN_INFO "Request was sent. Group=0x%x.\n", ctl->group); 112 + 113 + return 0; 114 + 115 + nlmsg_failure: 116 + printk(KERN_ERR "Failed to send %u.%u\n", msg->seq, msg->ack); 117 + kfree_skb(skb); 118 + return -EINVAL; 119 + } 120 + 121 + static u32 cn_test_timer_counter; 122 + static void cn_test_timer_func(unsigned long __data) 123 + { 124 + struct cn_msg *m; 125 + char data[32]; 126 + 127 + m = kmalloc(sizeof(*m) + sizeof(data), GFP_ATOMIC); 128 + if (m) { 129 + memset(m, 0, sizeof(*m) + sizeof(data)); 130 + 131 + memcpy(&m->id, &cn_test_id, sizeof(m->id)); 132 + m->seq = cn_test_timer_counter; 133 + m->len = sizeof(data); 134 + 135 + m->len = 136 + scnprintf(data, sizeof(data), "counter = %u", 137 + cn_test_timer_counter) + 1; 138 + 139 + memcpy(m + 1, data, m->len); 140 + 141 + cn_netlink_send(m, 0, gfp_any()); 142 + kfree(m); 143 + } 144 + 145 + cn_test_timer_counter++; 146 + 147 + mod_timer(&cn_test_timer, jiffies + HZ); 148 + } 149 + 150 + static int cn_test_init(void) 151 + { 152 + int err; 153 + 154 + err = cn_add_callback(&cn_test_id, cn_test_name, cn_test_callback); 155 + if (err) 156 + goto err_out; 157 + cn_test_id.val++; 158 + err = cn_add_callback(&cn_test_id, cn_test_name, cn_test_callback); 159 + if (err) { 160 + cn_del_callback(&cn_test_id); 161 + goto err_out; 162 + } 163 + 164 + init_timer(&cn_test_timer); 165 + cn_test_timer.function = cn_test_timer_func; 166 + cn_test_timer.expires = jiffies + HZ; 167 + cn_test_timer.data = 0; 168 + add_timer(&cn_test_timer); 169 + 170 + return 0; 171 + 172 + err_out: 173 + if (nls && nls->sk_socket) 174 + sock_release(nls->sk_socket); 175 + 176 + return err; 177 + } 178 + 179 + static void cn_test_fini(void) 180 + { 181 + del_timer_sync(&cn_test_timer); 182 + cn_del_callback(&cn_test_id); 183 + cn_test_id.val--; 184 + cn_del_callback(&cn_test_id); 185 + if (nls && nls->sk_socket) 186 + sock_release(nls->sk_socket); 187 + } 188 + 189 + module_init(cn_test_init); 190 + module_exit(cn_test_fini); 191 + 192 + MODULE_LICENSE("GPL"); 193 + MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); 194 + MODULE_DESCRIPTION("Connector's test module");
+133
Documentation/connector/connector.txt
··· 1 + /*****************************************/ 2 + Kernel Connector. 3 + /*****************************************/ 4 + 5 + Kernel connector - new netlink based userspace <-> kernel space easy 6 + to use communication module. 7 + 8 + Connector driver adds possibility to connect various agents using 9 + netlink based network. One must register callback and 10 + identifier. When driver receives special netlink message with 11 + appropriate identifier, appropriate callback will be called. 12 + 13 + From the userspace point of view it's quite straightforward: 14 + 15 + socket(); 16 + bind(); 17 + send(); 18 + recv(); 19 + 20 + But if kernelspace want to use full power of such connections, driver 21 + writer must create special sockets, must know about struct sk_buff 22 + handling... Connector allows any kernelspace agents to use netlink 23 + based networking for inter-process communication in a significantly 24 + easier way: 25 + 26 + int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *)); 27 + void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask); 28 + 29 + struct cb_id 30 + { 31 + __u32 idx; 32 + __u32 val; 33 + }; 34 + 35 + idx and val are unique identifiers which must be registered in 36 + connector.h for in-kernel usage. void (*callback) (void *) - is a 37 + callback function which will be called when message with above idx.val 38 + will be received by connector core. Argument for that function must 39 + be dereferenced to struct cn_msg *. 40 + 41 + struct cn_msg 42 + { 43 + struct cb_id id; 44 + 45 + __u32 seq; 46 + __u32 ack; 47 + 48 + __u32 len; /* Length of the following data */ 49 + __u8 data[0]; 50 + }; 51 + 52 + /*****************************************/ 53 + Connector interfaces. 54 + /*****************************************/ 55 + 56 + int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *)); 57 + 58 + Registers new callback with connector core. 59 + 60 + struct cb_id *id - unique connector's user identifier. 61 + It must be registered in connector.h for legal in-kernel users. 62 + char *name - connector's callback symbolic name. 63 + void (*callback) (void *) - connector's callback. 64 + Argument must be dereferenced to struct cn_msg *. 65 + 66 + void cn_del_callback(struct cb_id *id); 67 + 68 + Unregisters new callback with connector core. 69 + 70 + struct cb_id *id - unique connector's user identifier. 71 + 72 + void cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask); 73 + 74 + Sends message to the specified groups. It can be safely called from 75 + any context, but may silently fail under strong memory pressure. 76 + 77 + struct cn_msg * - message header(with attached data). 78 + u32 __group - destination group. 79 + If __group is zero, then appropriate group will 80 + be searched through all registered connector users, 81 + and message will be delivered to the group which was 82 + created for user with the same ID as in msg. 83 + If __group is not zero, then message will be delivered 84 + to the specified group. 85 + int gfp_mask - GFP mask. 86 + 87 + Note: When registering new callback user, connector core assigns 88 + netlink group to the user which is equal to it's id.idx. 89 + 90 + /*****************************************/ 91 + Protocol description. 92 + /*****************************************/ 93 + 94 + Current offers transport layer with fixed header. Recommended 95 + protocol which uses such header is following: 96 + 97 + msg->seq and msg->ack are used to determine message genealogy. When 98 + someone sends message it puts there locally unique sequence and random 99 + acknowledge numbers. Sequence number may be copied into 100 + nlmsghdr->nlmsg_seq too. 101 + 102 + Sequence number is incremented with each message to be sent. 103 + 104 + If we expect reply to our message, then sequence number in received 105 + message MUST be the same as in original message, and acknowledge 106 + number MUST be the same + 1. 107 + 108 + If we receive message and it's sequence number is not equal to one we 109 + are expecting, then it is new message. If we receive message and it's 110 + sequence number is the same as one we are expecting, but it's 111 + acknowledge is not equal acknowledge number in original message + 1, 112 + then it is new message. 113 + 114 + Obviously, protocol header contains above id. 115 + 116 + connector allows event notification in the following form: kernel 117 + driver or userspace process can ask connector to notify it when 118 + selected id's will be turned on or off(registered or unregistered it's 119 + callback). It is done by sending special command to connector 120 + driver(it also registers itself with id={-1, -1}). 121 + 122 + As example of usage Documentation/connector now contains cn_test.c - 123 + testing module which uses connector to request notification and to 124 + send messages. 125 + 126 + /*****************************************/ 127 + Reliability. 128 + /*****************************************/ 129 + 130 + Netlink itself is not reliable protocol, that means that messages can 131 + be lost due to memory pressure or process' receiving queue overflowed, 132 + so caller is warned must be prepared. That is why struct cn_msg [main 133 + connector's message header] contains u32 seq and u32 ack fields.
+2
drivers/Kconfig
··· 4 4 5 5 source "drivers/base/Kconfig" 6 6 7 + source "drivers/connector/Kconfig" 8 + 7 9 source "drivers/mtd/Kconfig" 8 10 9 11 source "drivers/parport/Kconfig"
+2
drivers/Makefile
··· 17 17 # default. 18 18 obj-y += char/ 19 19 20 + obj-$(CONFIG_CONNECTOR) += connector/ 21 + 20 22 # i810fb and intelfb depend on char/agp/ 21 23 obj-$(CONFIG_FB_I810) += video/i810/ 22 24 obj-$(CONFIG_FB_INTEL) += video/intelfb/
+13
drivers/connector/Kconfig
··· 1 + menu "Connector - unified userspace <-> kernelspace linker" 2 + 3 + config CONNECTOR 4 + tristate "Connector - unified userspace <-> kernelspace linker" 5 + depends on NET 6 + ---help--- 7 + This is unified userspace <-> kernelspace connector working on top 8 + of the netlink socket protocol. 9 + 10 + Connector support can also be built as a module. If so, the module 11 + will be called cn.ko. 12 + 13 + endmenu
+3
drivers/connector/Makefile
··· 1 + obj-$(CONFIG_CONNECTOR) += cn.o 2 + 3 + cn-y += cn_queue.o connector.o
+173
drivers/connector/cn_queue.c
··· 1 + /* 2 + * cn_queue.c 3 + * 4 + * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> 5 + * All rights reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + * 21 + */ 22 + 23 + #include <linux/kernel.h> 24 + #include <linux/module.h> 25 + #include <linux/list.h> 26 + #include <linux/workqueue.h> 27 + #include <linux/spinlock.h> 28 + #include <linux/slab.h> 29 + #include <linux/skbuff.h> 30 + #include <linux/suspend.h> 31 + #include <linux/connector.h> 32 + #include <linux/delay.h> 33 + 34 + static void cn_queue_wrapper(void *data) 35 + { 36 + struct cn_callback_entry *cbq = data; 37 + 38 + cbq->cb->callback(cbq->cb->priv); 39 + cbq->destruct_data(cbq->ddata); 40 + cbq->ddata = NULL; 41 + } 42 + 43 + static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callback *cb) 44 + { 45 + struct cn_callback_entry *cbq; 46 + 47 + cbq = kzalloc(sizeof(*cbq), GFP_KERNEL); 48 + if (!cbq) { 49 + printk(KERN_ERR "Failed to create new callback queue.\n"); 50 + return NULL; 51 + } 52 + 53 + cbq->cb = cb; 54 + INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq); 55 + return cbq; 56 + } 57 + 58 + static void cn_queue_free_callback(struct cn_callback_entry *cbq) 59 + { 60 + cancel_delayed_work(&cbq->work); 61 + flush_workqueue(cbq->pdev->cn_queue); 62 + 63 + kfree(cbq); 64 + } 65 + 66 + int cn_cb_equal(struct cb_id *i1, struct cb_id *i2) 67 + { 68 + return ((i1->idx == i2->idx) && (i1->val == i2->val)); 69 + } 70 + 71 + int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb) 72 + { 73 + struct cn_callback_entry *cbq, *__cbq; 74 + int found = 0; 75 + 76 + cbq = cn_queue_alloc_callback_entry(cb); 77 + if (!cbq) 78 + return -ENOMEM; 79 + 80 + atomic_inc(&dev->refcnt); 81 + cbq->pdev = dev; 82 + 83 + spin_lock_bh(&dev->queue_lock); 84 + list_for_each_entry(__cbq, &dev->queue_list, callback_entry) { 85 + if (cn_cb_equal(&__cbq->cb->id, &cb->id)) { 86 + found = 1; 87 + break; 88 + } 89 + } 90 + if (!found) 91 + list_add_tail(&cbq->callback_entry, &dev->queue_list); 92 + spin_unlock_bh(&dev->queue_lock); 93 + 94 + if (found) { 95 + atomic_dec(&dev->refcnt); 96 + cn_queue_free_callback(cbq); 97 + return -EINVAL; 98 + } 99 + 100 + cbq->nls = dev->nls; 101 + cbq->seq = 0; 102 + cbq->group = cbq->cb->id.idx; 103 + 104 + return 0; 105 + } 106 + 107 + void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) 108 + { 109 + struct cn_callback_entry *cbq, *n; 110 + int found = 0; 111 + 112 + spin_lock_bh(&dev->queue_lock); 113 + list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) { 114 + if (cn_cb_equal(&cbq->cb->id, id)) { 115 + list_del(&cbq->callback_entry); 116 + found = 1; 117 + break; 118 + } 119 + } 120 + spin_unlock_bh(&dev->queue_lock); 121 + 122 + if (found) { 123 + cn_queue_free_callback(cbq); 124 + atomic_dec_and_test(&dev->refcnt); 125 + } 126 + } 127 + 128 + struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls) 129 + { 130 + struct cn_queue_dev *dev; 131 + 132 + dev = kzalloc(sizeof(*dev), GFP_KERNEL); 133 + if (!dev) 134 + return NULL; 135 + 136 + snprintf(dev->name, sizeof(dev->name), "%s", name); 137 + atomic_set(&dev->refcnt, 0); 138 + INIT_LIST_HEAD(&dev->queue_list); 139 + spin_lock_init(&dev->queue_lock); 140 + 141 + dev->nls = nls; 142 + dev->netlink_groups = 0; 143 + 144 + dev->cn_queue = create_workqueue(dev->name); 145 + if (!dev->cn_queue) { 146 + kfree(dev); 147 + return NULL; 148 + } 149 + 150 + return dev; 151 + } 152 + 153 + void cn_queue_free_dev(struct cn_queue_dev *dev) 154 + { 155 + struct cn_callback_entry *cbq, *n; 156 + 157 + flush_workqueue(dev->cn_queue); 158 + destroy_workqueue(dev->cn_queue); 159 + 160 + spin_lock_bh(&dev->queue_lock); 161 + list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) 162 + list_del(&cbq->callback_entry); 163 + spin_unlock_bh(&dev->queue_lock); 164 + 165 + while (atomic_read(&dev->refcnt)) { 166 + printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n", 167 + dev->name, atomic_read(&dev->refcnt)); 168 + msleep(1000); 169 + } 170 + 171 + kfree(dev); 172 + dev = NULL; 173 + }
+486
drivers/connector/connector.c
··· 1 + /* 2 + * connector.c 3 + * 4 + * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> 5 + * All rights reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/kernel.h> 23 + #include <linux/module.h> 24 + #include <linux/list.h> 25 + #include <linux/skbuff.h> 26 + #include <linux/netlink.h> 27 + #include <linux/moduleparam.h> 28 + #include <linux/connector.h> 29 + 30 + #include <net/sock.h> 31 + 32 + MODULE_LICENSE("GPL"); 33 + MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); 34 + MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); 35 + 36 + static u32 cn_idx = CN_IDX_CONNECTOR; 37 + static u32 cn_val = CN_VAL_CONNECTOR; 38 + 39 + module_param(cn_idx, uint, 0); 40 + module_param(cn_val, uint, 0); 41 + MODULE_PARM_DESC(cn_idx, "Connector's main device idx."); 42 + MODULE_PARM_DESC(cn_val, "Connector's main device val."); 43 + 44 + static DECLARE_MUTEX(notify_lock); 45 + static LIST_HEAD(notify_list); 46 + 47 + static struct cn_dev cdev; 48 + 49 + int cn_already_initialized = 0; 50 + 51 + /* 52 + * msg->seq and msg->ack are used to determine message genealogy. 53 + * When someone sends message it puts there locally unique sequence 54 + * and random acknowledge numbers. Sequence number may be copied into 55 + * nlmsghdr->nlmsg_seq too. 56 + * 57 + * Sequence number is incremented with each message to be sent. 58 + * 59 + * If we expect reply to our message then the sequence number in 60 + * received message MUST be the same as in original message, and 61 + * acknowledge number MUST be the same + 1. 62 + * 63 + * If we receive a message and its sequence number is not equal to the 64 + * one we are expecting then it is a new message. 65 + * 66 + * If we receive a message and its sequence number is the same as one 67 + * we are expecting but it's acknowledgement number is not equal to 68 + * the acknowledgement number in the original message + 1, then it is 69 + * a new message. 70 + * 71 + */ 72 + int cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask) 73 + { 74 + struct cn_callback_entry *__cbq; 75 + unsigned int size; 76 + struct sk_buff *skb; 77 + struct nlmsghdr *nlh; 78 + struct cn_msg *data; 79 + struct cn_dev *dev = &cdev; 80 + u32 group = 0; 81 + int found = 0; 82 + 83 + if (!__group) { 84 + spin_lock_bh(&dev->cbdev->queue_lock); 85 + list_for_each_entry(__cbq, &dev->cbdev->queue_list, 86 + callback_entry) { 87 + if (cn_cb_equal(&__cbq->cb->id, &msg->id)) { 88 + found = 1; 89 + group = __cbq->group; 90 + } 91 + } 92 + spin_unlock_bh(&dev->cbdev->queue_lock); 93 + 94 + if (!found) 95 + return -ENODEV; 96 + } else { 97 + group = __group; 98 + } 99 + 100 + size = NLMSG_SPACE(sizeof(*msg) + msg->len); 101 + 102 + skb = alloc_skb(size, gfp_mask); 103 + if (!skb) 104 + return -ENOMEM; 105 + 106 + nlh = NLMSG_PUT(skb, 0, msg->seq, NLMSG_DONE, size - sizeof(*nlh)); 107 + 108 + data = NLMSG_DATA(nlh); 109 + 110 + memcpy(data, msg, sizeof(*data) + msg->len); 111 + 112 + NETLINK_CB(skb).dst_group = group; 113 + 114 + netlink_broadcast(dev->nls, skb, 0, group, gfp_mask); 115 + 116 + return 0; 117 + 118 + nlmsg_failure: 119 + kfree_skb(skb); 120 + return -EINVAL; 121 + } 122 + 123 + /* 124 + * Callback helper - queues work and setup destructor for given data. 125 + */ 126 + static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data) 127 + { 128 + struct cn_callback_entry *__cbq; 129 + struct cn_dev *dev = &cdev; 130 + int found = 0; 131 + 132 + spin_lock_bh(&dev->cbdev->queue_lock); 133 + list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { 134 + if (cn_cb_equal(&__cbq->cb->id, &msg->id)) { 135 + /* 136 + * Let's scream if there is some magic and the 137 + * data will arrive asynchronously here. 138 + * [i.e. netlink messages will be queued]. 139 + * After the first warning I will fix it 140 + * quickly, but now I think it is 141 + * impossible. --zbr (2004_04_27). 142 + */ 143 + if (likely(!test_bit(0, &__cbq->work.pending) && 144 + __cbq->ddata == NULL)) { 145 + __cbq->cb->priv = msg; 146 + 147 + __cbq->ddata = data; 148 + __cbq->destruct_data = destruct_data; 149 + 150 + if (queue_work(dev->cbdev->cn_queue, 151 + &__cbq->work)) 152 + found = 1; 153 + } else { 154 + printk("%s: cbq->data=%p, " 155 + "work->pending=%08lx.\n", 156 + __func__, __cbq->ddata, 157 + __cbq->work.pending); 158 + WARN_ON(1); 159 + } 160 + break; 161 + } 162 + } 163 + spin_unlock_bh(&dev->cbdev->queue_lock); 164 + 165 + return found ? 0 : -ENODEV; 166 + } 167 + 168 + /* 169 + * Skb receive helper - checks skb and msg size and calls callback 170 + * helper. 171 + */ 172 + static int __cn_rx_skb(struct sk_buff *skb, struct nlmsghdr *nlh) 173 + { 174 + u32 pid, uid, seq, group; 175 + struct cn_msg *msg; 176 + 177 + pid = NETLINK_CREDS(skb)->pid; 178 + uid = NETLINK_CREDS(skb)->uid; 179 + seq = nlh->nlmsg_seq; 180 + group = NETLINK_CB((skb)).dst_group; 181 + msg = NLMSG_DATA(nlh); 182 + 183 + return cn_call_callback(msg, (void (*)(void *))kfree_skb, skb); 184 + } 185 + 186 + /* 187 + * Main netlink receiving function. 188 + * 189 + * It checks skb and netlink header sizes and calls the skb receive 190 + * helper with a shared skb. 191 + */ 192 + static void cn_rx_skb(struct sk_buff *__skb) 193 + { 194 + struct nlmsghdr *nlh; 195 + u32 len; 196 + int err; 197 + struct sk_buff *skb; 198 + 199 + skb = skb_get(__skb); 200 + 201 + if (skb->len >= NLMSG_SPACE(0)) { 202 + nlh = (struct nlmsghdr *)skb->data; 203 + 204 + if (nlh->nlmsg_len < sizeof(struct cn_msg) || 205 + skb->len < nlh->nlmsg_len || 206 + nlh->nlmsg_len > CONNECTOR_MAX_MSG_SIZE) { 207 + kfree_skb(skb); 208 + goto out; 209 + } 210 + 211 + len = NLMSG_ALIGN(nlh->nlmsg_len); 212 + if (len > skb->len) 213 + len = skb->len; 214 + 215 + err = __cn_rx_skb(skb, nlh); 216 + if (err < 0) 217 + kfree_skb(skb); 218 + } 219 + 220 + out: 221 + kfree_skb(__skb); 222 + } 223 + 224 + /* 225 + * Netlink socket input callback - dequeues the skbs and calls the 226 + * main netlink receiving function. 227 + */ 228 + static void cn_input(struct sock *sk, int len) 229 + { 230 + struct sk_buff *skb; 231 + 232 + while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) 233 + cn_rx_skb(skb); 234 + } 235 + 236 + /* 237 + * Notification routing. 238 + * 239 + * Gets id and checks if there are notification request for it's idx 240 + * and val. If there are such requests notify the listeners with the 241 + * given notify event. 242 + * 243 + */ 244 + static void cn_notify(struct cb_id *id, u32 notify_event) 245 + { 246 + struct cn_ctl_entry *ent; 247 + 248 + down(&notify_lock); 249 + list_for_each_entry(ent, &notify_list, notify_entry) { 250 + int i; 251 + struct cn_notify_req *req; 252 + struct cn_ctl_msg *ctl = ent->msg; 253 + int idx_found, val_found; 254 + 255 + idx_found = val_found = 0; 256 + 257 + req = (struct cn_notify_req *)ctl->data; 258 + for (i = 0; i < ctl->idx_notify_num; ++i, ++req) { 259 + if (id->idx >= req->first && 260 + id->idx < req->first + req->range) { 261 + idx_found = 1; 262 + break; 263 + } 264 + } 265 + 266 + for (i = 0; i < ctl->val_notify_num; ++i, ++req) { 267 + if (id->val >= req->first && 268 + id->val < req->first + req->range) { 269 + val_found = 1; 270 + break; 271 + } 272 + } 273 + 274 + if (idx_found && val_found) { 275 + struct cn_msg m = { .ack = notify_event, }; 276 + 277 + memcpy(&m.id, id, sizeof(m.id)); 278 + cn_netlink_send(&m, ctl->group, GFP_KERNEL); 279 + } 280 + } 281 + up(&notify_lock); 282 + } 283 + 284 + /* 285 + * Callback add routing - adds callback with given ID and name. 286 + * If there is registered callback with the same ID it will not be added. 287 + * 288 + * May sleep. 289 + */ 290 + int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *)) 291 + { 292 + int err; 293 + struct cn_dev *dev = &cdev; 294 + struct cn_callback *cb; 295 + 296 + cb = kzalloc(sizeof(*cb), GFP_KERNEL); 297 + if (!cb) 298 + return -ENOMEM; 299 + 300 + scnprintf(cb->name, sizeof(cb->name), "%s", name); 301 + 302 + memcpy(&cb->id, id, sizeof(cb->id)); 303 + cb->callback = callback; 304 + 305 + err = cn_queue_add_callback(dev->cbdev, cb); 306 + if (err) { 307 + kfree(cb); 308 + return err; 309 + } 310 + 311 + cn_notify(id, 0); 312 + 313 + return 0; 314 + } 315 + 316 + /* 317 + * Callback remove routing - removes callback 318 + * with given ID. 319 + * If there is no registered callback with given 320 + * ID nothing happens. 321 + * 322 + * May sleep while waiting for reference counter to become zero. 323 + */ 324 + void cn_del_callback(struct cb_id *id) 325 + { 326 + struct cn_dev *dev = &cdev; 327 + 328 + cn_queue_del_callback(dev->cbdev, id); 329 + cn_notify(id, 1); 330 + } 331 + 332 + /* 333 + * Checks two connector's control messages to be the same. 334 + * Returns 1 if they are the same or if the first one is corrupted. 335 + */ 336 + static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2) 337 + { 338 + int i; 339 + struct cn_notify_req *req1, *req2; 340 + 341 + if (m1->idx_notify_num != m2->idx_notify_num) 342 + return 0; 343 + 344 + if (m1->val_notify_num != m2->val_notify_num) 345 + return 0; 346 + 347 + if (m1->len != m2->len) 348 + return 0; 349 + 350 + if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) != 351 + m1->len) 352 + return 1; 353 + 354 + req1 = (struct cn_notify_req *)m1->data; 355 + req2 = (struct cn_notify_req *)m2->data; 356 + 357 + for (i = 0; i < m1->idx_notify_num; ++i) { 358 + if (req1->first != req2->first || req1->range != req2->range) 359 + return 0; 360 + req1++; 361 + req2++; 362 + } 363 + 364 + for (i = 0; i < m1->val_notify_num; ++i) { 365 + if (req1->first != req2->first || req1->range != req2->range) 366 + return 0; 367 + req1++; 368 + req2++; 369 + } 370 + 371 + return 1; 372 + } 373 + 374 + /* 375 + * Main connector device's callback. 376 + * 377 + * Used for notification of a request's processing. 378 + */ 379 + static void cn_callback(void *data) 380 + { 381 + struct cn_msg *msg = data; 382 + struct cn_ctl_msg *ctl; 383 + struct cn_ctl_entry *ent; 384 + u32 size; 385 + 386 + if (msg->len < sizeof(*ctl)) 387 + return; 388 + 389 + ctl = (struct cn_ctl_msg *)msg->data; 390 + 391 + size = (sizeof(*ctl) + ((ctl->idx_notify_num + 392 + ctl->val_notify_num) * 393 + sizeof(struct cn_notify_req))); 394 + 395 + if (msg->len != size) 396 + return; 397 + 398 + if (ctl->len + sizeof(*ctl) != msg->len) 399 + return; 400 + 401 + /* 402 + * Remove notification. 403 + */ 404 + if (ctl->group == 0) { 405 + struct cn_ctl_entry *n; 406 + 407 + down(&notify_lock); 408 + list_for_each_entry_safe(ent, n, &notify_list, notify_entry) { 409 + if (cn_ctl_msg_equals(ent->msg, ctl)) { 410 + list_del(&ent->notify_entry); 411 + kfree(ent); 412 + } 413 + } 414 + up(&notify_lock); 415 + 416 + return; 417 + } 418 + 419 + size += sizeof(*ent); 420 + 421 + ent = kzalloc(size, GFP_KERNEL); 422 + if (!ent) 423 + return; 424 + 425 + ent->msg = (struct cn_ctl_msg *)(ent + 1); 426 + 427 + memcpy(ent->msg, ctl, size - sizeof(*ent)); 428 + 429 + down(&notify_lock); 430 + list_add(&ent->notify_entry, &notify_list); 431 + up(&notify_lock); 432 + } 433 + 434 + static int __init cn_init(void) 435 + { 436 + struct cn_dev *dev = &cdev; 437 + int err; 438 + 439 + dev->input = cn_input; 440 + dev->id.idx = cn_idx; 441 + dev->id.val = cn_val; 442 + 443 + dev->nls = netlink_kernel_create(NETLINK_CONNECTOR, 444 + CN_NETLINK_USERS + 0xf, 445 + dev->input, THIS_MODULE); 446 + if (!dev->nls) 447 + return -EIO; 448 + 449 + dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls); 450 + if (!dev->cbdev) { 451 + if (dev->nls->sk_socket) 452 + sock_release(dev->nls->sk_socket); 453 + return -EINVAL; 454 + } 455 + 456 + err = cn_add_callback(&dev->id, "connector", &cn_callback); 457 + if (err) { 458 + cn_queue_free_dev(dev->cbdev); 459 + if (dev->nls->sk_socket) 460 + sock_release(dev->nls->sk_socket); 461 + return -EINVAL; 462 + } 463 + 464 + cn_already_initialized = 1; 465 + 466 + return 0; 467 + } 468 + 469 + static void __exit cn_fini(void) 470 + { 471 + struct cn_dev *dev = &cdev; 472 + 473 + cn_already_initialized = 0; 474 + 475 + cn_del_callback(&dev->id); 476 + cn_queue_free_dev(dev->cbdev); 477 + if (dev->nls->sk_socket) 478 + sock_release(dev->nls->sk_socket); 479 + } 480 + 481 + module_init(cn_init); 482 + module_exit(cn_fini); 483 + 484 + EXPORT_SYMBOL_GPL(cn_add_callback); 485 + EXPORT_SYMBOL_GPL(cn_del_callback); 486 + EXPORT_SYMBOL_GPL(cn_netlink_send);
+2
drivers/net/bnx2.c
··· 5015 5015 .phys_id = bnx2_phys_id, 5016 5016 .get_stats_count = bnx2_get_stats_count, 5017 5017 .get_ethtool_stats = bnx2_get_ethtool_stats, 5018 + .get_perm_addr = ethtool_op_get_perm_addr, 5018 5019 }; 5019 5020 5020 5021 /* Called with rtnl_lock */ ··· 5443 5442 pci_set_drvdata(pdev, dev); 5444 5443 5445 5444 memcpy(dev->dev_addr, bp->mac_addr, 6); 5445 + memcpy(dev->perm_addr, bp->mac_addr, 6); 5446 5446 bp->name = board_info[ent->driver_data].name, 5447 5447 printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz found at mem %lx, " 5448 5448 "IRQ %d, ",
+1 -1
drivers/net/hamradio/6pack.c
··· 293 293 { 294 294 #ifdef CONFIG_INET 295 295 if (type != htons(ETH_P_AX25)) 296 - return ax25_encapsulate(skb, dev, type, daddr, saddr, len); 296 + return ax25_hard_header(skb, dev, type, daddr, saddr, len); 297 297 #endif 298 298 return 0; 299 299 }
+3 -14
drivers/net/hamradio/baycom_epp.c
··· 40 40 41 41 /*****************************************************************************/ 42 42 43 - #include <linux/config.h> 43 + #include <linux/crc-ccitt.h> 44 44 #include <linux/module.h> 45 45 #include <linux/kernel.h> 46 46 #include <linux/init.h> ··· 48 48 #include <linux/workqueue.h> 49 49 #include <linux/fs.h> 50 50 #include <linux/parport.h> 51 - #include <linux/smp_lock.h> 52 - #include <asm/uaccess.h> 53 51 #include <linux/if_arp.h> 54 - #include <linux/kmod.h> 55 52 #include <linux/hdlcdrv.h> 56 53 #include <linux/baycom.h> 57 54 #include <linux/jiffies.h> 58 - #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 59 - /* prototypes for ax25_encapsulate and ax25_rebuild_header */ 60 55 #include <net/ax25.h> 61 - #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 62 - #include <linux/crc-ccitt.h> 56 + #include <asm/uaccess.h> 63 57 64 58 /* --------------------------------------------------------------------- */ 65 59 ··· 1171 1177 /* Fill in the fields of the device structure */ 1172 1178 bc->skb = NULL; 1173 1179 1174 - #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 1175 - dev->hard_header = ax25_encapsulate; 1180 + dev->hard_header = ax25_hard_header; 1176 1181 dev->rebuild_header = ax25_rebuild_header; 1177 - #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 1178 - dev->hard_header = NULL; 1179 - dev->rebuild_header = NULL; 1180 - #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 1181 1182 dev->set_mac_address = baycom_set_mac_address; 1182 1183 1183 1184 dev->type = ARPHRD_AX25; /* AF_AX25 device */
+1 -1
drivers/net/hamradio/bpqether.c
··· 488 488 dev->flags = 0; 489 489 490 490 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 491 - dev->hard_header = ax25_encapsulate; 491 + dev->hard_header = ax25_hard_header; 492 492 dev->rebuild_header = ax25_rebuild_header; 493 493 #endif 494 494
+5 -5
drivers/net/hamradio/dmascc.c
··· 449 449 static void dev_setup(struct net_device *dev) 450 450 { 451 451 dev->type = ARPHRD_AX25; 452 - dev->hard_header_len = 73; 452 + dev->hard_header_len = AX25_MAX_HEADER_LEN; 453 453 dev->mtu = 1500; 454 - dev->addr_len = 7; 454 + dev->addr_len = AX25_ADDR_LEN; 455 455 dev->tx_queue_len = 64; 456 - memcpy(dev->broadcast, ax25_broadcast, 7); 457 - memcpy(dev->dev_addr, ax25_test, 7); 456 + memcpy(dev->broadcast, ax25_broadcast, AX25_ADDR_LEN); 457 + memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); 458 458 } 459 459 460 460 static int __init setup_adapter(int card_base, int type, int n) ··· 600 600 dev->do_ioctl = scc_ioctl; 601 601 dev->hard_start_xmit = scc_send_packet; 602 602 dev->get_stats = scc_get_stats; 603 - dev->hard_header = ax25_encapsulate; 603 + dev->hard_header = ax25_hard_header; 604 604 dev->rebuild_header = ax25_rebuild_header; 605 605 dev->set_mac_address = scc_set_mac_address; 606 606 }
+2 -14
drivers/net/hamradio/hdlcdrv.c
··· 42 42 43 43 /*****************************************************************************/ 44 44 45 - #include <linux/config.h> 46 45 #include <linux/module.h> 47 46 #include <linux/types.h> 48 47 #include <linux/net.h> ··· 51 52 #include <linux/errno.h> 52 53 #include <linux/init.h> 53 54 #include <linux/bitops.h> 54 - #include <asm/uaccess.h> 55 55 56 56 #include <linux/netdevice.h> 57 57 #include <linux/if_arp.h> 58 - #include <linux/etherdevice.h> 59 58 #include <linux/skbuff.h> 60 59 #include <linux/hdlcdrv.h> 61 - /* prototypes for ax25_encapsulate and ax25_rebuild_header */ 62 60 #include <net/ax25.h> 61 + #include <asm/uaccess.h> 63 62 64 - /* make genksyms happy */ 65 - #include <linux/ip.h> 66 - #include <linux/udp.h> 67 - #include <linux/tcp.h> 68 63 #include <linux/crc-ccitt.h> 69 64 70 65 /* --------------------------------------------------------------------- */ ··· 701 708 702 709 s->skb = NULL; 703 710 704 - #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 705 - dev->hard_header = ax25_encapsulate; 711 + dev->hard_header = ax25_hard_header; 706 712 dev->rebuild_header = ax25_rebuild_header; 707 - #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 708 - dev->hard_header = NULL; 709 - dev->rebuild_header = NULL; 710 - #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 711 713 dev->set_mac_address = hdlcdrv_set_mac_address; 712 714 713 715 dev->type = ARPHRD_AX25; /* AF_AX25 device */
+1 -1
drivers/net/hamradio/mkiss.c
··· 500 500 { 501 501 #ifdef CONFIG_INET 502 502 if (type != htons(ETH_P_AX25)) 503 - return ax25_encapsulate(skb, dev, type, daddr, saddr, len); 503 + return ax25_hard_header(skb, dev, type, daddr, saddr, len); 504 504 #endif 505 505 return 0; 506 506 }
+1 -1
drivers/net/hamradio/scc.c
··· 1557 1557 dev->stop = scc_net_close; 1558 1558 1559 1559 dev->hard_start_xmit = scc_net_tx; 1560 - dev->hard_header = ax25_encapsulate; 1560 + dev->hard_header = ax25_hard_header; 1561 1561 dev->rebuild_header = ax25_rebuild_header; 1562 1562 dev->set_mac_address = scc_net_set_mac_address; 1563 1563 dev->get_stats = scc_net_get_stats;
+7 -21
drivers/net/hamradio/yam.c
··· 60 60 #include <linux/if_arp.h> 61 61 #include <linux/etherdevice.h> 62 62 #include <linux/skbuff.h> 63 - #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 64 - /* prototypes for ax25_encapsulate and ax25_rebuild_header */ 65 63 #include <net/ax25.h> 66 - #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 67 - 68 - /* make genksyms happy */ 69 - #include <linux/ip.h> 70 - #include <linux/udp.h> 71 - #include <linux/tcp.h> 72 64 73 65 #include <linux/kernel.h> 74 66 #include <linux/proc_fs.h> ··· 1108 1116 1109 1117 skb_queue_head_init(&yp->send_queue); 1110 1118 1111 - #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) 1112 - dev->hard_header = ax25_encapsulate; 1119 + dev->hard_header = ax25_hard_header; 1113 1120 dev->rebuild_header = ax25_rebuild_header; 1114 - #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 1115 - dev->hard_header = NULL; 1116 - dev->rebuild_header = NULL; 1117 - #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */ 1118 1121 1119 1122 dev->set_mac_address = yam_set_mac_address; 1120 1123 1121 - dev->type = ARPHRD_AX25; /* AF_AX25 device */ 1122 - dev->hard_header_len = 73; /* We do digipeaters now */ 1123 - dev->mtu = 256; /* AX25 is the default */ 1124 - dev->addr_len = 7; /* sizeof an ax.25 address */ 1125 - memcpy(dev->broadcast, ax25_bcast, 7); 1126 - memcpy(dev->dev_addr, ax25_test, 7); 1127 - 1124 + dev->type = ARPHRD_AX25; 1125 + dev->hard_header_len = AX25_MAX_HEADER_LEN; 1126 + dev->mtu = AX25_MTU; 1127 + dev->addr_len = AX25_ADDR_LEN; 1128 + memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); 1129 + memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); 1128 1130 } 1129 1131 1130 1132 static int __init yam_init_driver(void)
+8 -2
drivers/net/tg3.c
··· 6893 6893 get_stat64(&hw_stats->tx_octets); 6894 6894 6895 6895 stats->rx_errors = old_stats->rx_errors + 6896 - get_stat64(&hw_stats->rx_errors) + 6897 - get_stat64(&hw_stats->rx_discards); 6896 + get_stat64(&hw_stats->rx_errors); 6898 6897 stats->tx_errors = old_stats->tx_errors + 6899 6898 get_stat64(&hw_stats->tx_errors) + 6900 6899 get_stat64(&hw_stats->tx_mac_errors) + ··· 6920 6921 6921 6922 stats->rx_crc_errors = old_stats->rx_crc_errors + 6922 6923 calc_crc_errors(tp); 6924 + 6925 + stats->rx_missed_errors = old_stats->rx_missed_errors + 6926 + get_stat64(&hw_stats->rx_discards); 6923 6927 6924 6928 return stats; 6925 6929 } ··· 8305 8303 .get_ethtool_stats = tg3_get_ethtool_stats, 8306 8304 .get_coalesce = tg3_get_coalesce, 8307 8305 .set_coalesce = tg3_set_coalesce, 8306 + .get_perm_addr = ethtool_op_get_perm_addr, 8308 8307 }; 8309 8308 8310 8309 static void __devinit tg3_get_eeprom_size(struct tg3 *tp) ··· 9784 9781 if (prom_getproplen(node, "local-mac-address") == 6) { 9785 9782 prom_getproperty(node, "local-mac-address", 9786 9783 dev->dev_addr, 6); 9784 + memcpy(dev->perm_addr, dev->dev_addr, 6); 9787 9785 return 0; 9788 9786 } 9789 9787 } ··· 9796 9792 struct net_device *dev = tp->dev; 9797 9793 9798 9794 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 9795 + memcpy(dev->perm_addr, idprom->id_ethaddr, 6); 9799 9796 return 0; 9800 9797 } 9801 9798 #endif ··· 9866 9861 #endif 9867 9862 return -EINVAL; 9868 9863 } 9864 + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); 9869 9865 return 0; 9870 9866 } 9871 9867
+158
include/linux/connector.h
··· 1 + /* 2 + * connector.h 3 + * 4 + * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> 5 + * All rights reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #ifndef __CONNECTOR_H 23 + #define __CONNECTOR_H 24 + 25 + #include <asm/types.h> 26 + 27 + #define CN_IDX_CONNECTOR 0xffffffff 28 + #define CN_VAL_CONNECTOR 0xffffffff 29 + 30 + #define CN_NETLINK_USERS 1 31 + 32 + /* 33 + * Maximum connector's message size. 34 + */ 35 + #define CONNECTOR_MAX_MSG_SIZE 1024 36 + 37 + /* 38 + * idx and val are unique identifiers which 39 + * are used for message routing and 40 + * must be registered in connector.h for in-kernel usage. 41 + */ 42 + 43 + struct cb_id { 44 + __u32 idx; 45 + __u32 val; 46 + }; 47 + 48 + struct cn_msg { 49 + struct cb_id id; 50 + 51 + __u32 seq; 52 + __u32 ack; 53 + 54 + __u16 len; /* Length of the following data */ 55 + __u16 flags; 56 + __u8 data[0]; 57 + }; 58 + 59 + /* 60 + * Notify structure - requests notification about 61 + * registering/unregistering idx/val in range [first, first+range]. 62 + */ 63 + struct cn_notify_req { 64 + __u32 first; 65 + __u32 range; 66 + }; 67 + 68 + /* 69 + * Main notification control message 70 + * *_notify_num - number of appropriate cn_notify_req structures after 71 + * this struct. 72 + * group - notification receiver's idx. 73 + * len - total length of the attached data. 74 + */ 75 + struct cn_ctl_msg { 76 + __u32 idx_notify_num; 77 + __u32 val_notify_num; 78 + __u32 group; 79 + __u32 len; 80 + __u8 data[0]; 81 + }; 82 + 83 + #ifdef __KERNEL__ 84 + 85 + #include <asm/atomic.h> 86 + 87 + #include <linux/list.h> 88 + #include <linux/workqueue.h> 89 + 90 + #include <net/sock.h> 91 + 92 + #define CN_CBQ_NAMELEN 32 93 + 94 + struct cn_queue_dev { 95 + atomic_t refcnt; 96 + unsigned char name[CN_CBQ_NAMELEN]; 97 + 98 + struct workqueue_struct *cn_queue; 99 + 100 + struct list_head queue_list; 101 + spinlock_t queue_lock; 102 + 103 + int netlink_groups; 104 + struct sock *nls; 105 + }; 106 + 107 + struct cn_callback { 108 + unsigned char name[CN_CBQ_NAMELEN]; 109 + 110 + struct cb_id id; 111 + void (*callback) (void *); 112 + void *priv; 113 + }; 114 + 115 + struct cn_callback_entry { 116 + struct list_head callback_entry; 117 + struct cn_callback *cb; 118 + struct work_struct work; 119 + struct cn_queue_dev *pdev; 120 + 121 + void (*destruct_data) (void *); 122 + void *ddata; 123 + 124 + int seq, group; 125 + struct sock *nls; 126 + }; 127 + 128 + struct cn_ctl_entry { 129 + struct list_head notify_entry; 130 + struct cn_ctl_msg *msg; 131 + }; 132 + 133 + struct cn_dev { 134 + struct cb_id id; 135 + 136 + u32 seq, groups; 137 + struct sock *nls; 138 + void (*input) (struct sock * sk, int len); 139 + 140 + struct cn_queue_dev *cbdev; 141 + }; 142 + 143 + int cn_add_callback(struct cb_id *, char *, void (*callback) (void *)); 144 + void cn_del_callback(struct cb_id *); 145 + int cn_netlink_send(struct cn_msg *, u32, int); 146 + 147 + int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb); 148 + void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); 149 + 150 + struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *); 151 + void cn_queue_free_dev(struct cn_queue_dev *dev); 152 + 153 + int cn_cb_equal(struct cb_id *, struct cb_id *); 154 + 155 + extern int cn_already_initialized; 156 + 157 + #endif /* __KERNEL__ */ 158 + #endif /* __CONNECTOR_H */
+1
include/linux/netlink.h
··· 15 15 #define NETLINK_ISCSI 8 /* Open-iSCSI */ 16 16 #define NETLINK_AUDIT 9 /* auditing */ 17 17 #define NETLINK_FIB_LOOKUP 10 18 + #define NETLINK_CONNECTOR 11 18 19 #define NETLINK_NETFILTER 12 /* netfilter subsystem */ 19 20 #define NETLINK_IP6_FW 13 20 21 #define NETLINK_DNRTMSG 14 /* DECnet routing messages */
+2 -1
include/linux/sysctl.h
··· 544 544 NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8, 545 545 NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9, 546 546 NET_NETROM_ROUTING_CONTROL=10, 547 - NET_NETROM_LINK_FAILS_COUNT=11 547 + NET_NETROM_LINK_FAILS_COUNT=11, 548 + NET_NETROM_RESET=12 548 549 }; 549 550 550 551 /* /proc/sys/net/ax25 */
+20 -11
include/net/ax25.h
··· 26 26 27 27 /* AX.25 Protocol IDs */ 28 28 #define AX25_P_ROSE 0x01 29 - #define AX25_P_IP 0xCC 30 - #define AX25_P_ARP 0xCD 31 - #define AX25_P_TEXT 0xF0 32 - #define AX25_P_NETROM 0xCF 33 - #define AX25_P_SEGMENT 0x08 29 + #define AX25_P_VJCOMP 0x06 /* Compressed TCP/IP packet */ 30 + /* Van Jacobsen (RFC 1144) */ 31 + #define AX25_P_VJUNCOMP 0x07 /* Uncompressed TCP/IP packet */ 32 + /* Van Jacobsen (RFC 1144) */ 33 + #define AX25_P_SEGMENT 0x08 /* Segmentation fragment */ 34 + #define AX25_P_TEXNET 0xc3 /* TEXTNET datagram protocol */ 35 + #define AX25_P_LQ 0xc4 /* Link Quality Protocol */ 36 + #define AX25_P_ATALK 0xca /* Appletalk */ 37 + #define AX25_P_ATALK_ARP 0xcb /* Appletalk ARP */ 38 + #define AX25_P_IP 0xcc /* ARPA Internet Protocol */ 39 + #define AX25_P_ARP 0xcd /* ARPA Adress Resolution */ 40 + #define AX25_P_FLEXNET 0xce /* FlexNet */ 41 + #define AX25_P_NETROM 0xcf /* NET/ROM */ 42 + #define AX25_P_TEXT 0xF0 /* No layer 3 protocol impl. */ 34 43 35 44 /* AX.25 Segment control values */ 36 45 #define AX25_SEG_REM 0x7F ··· 97 88 /* Define Link State constants. */ 98 89 99 90 enum { 100 - AX25_STATE_0, 101 - AX25_STATE_1, 102 - AX25_STATE_2, 103 - AX25_STATE_3, 104 - AX25_STATE_4 91 + AX25_STATE_0, /* Listening */ 92 + AX25_STATE_1, /* SABM sent */ 93 + AX25_STATE_2, /* DISC sent */ 94 + AX25_STATE_3, /* Established */ 95 + AX25_STATE_4 /* Recovery */ 105 96 }; 106 97 107 98 #define AX25_MODULUS 8 /* Standard AX.25 modulus */ ··· 328 319 extern int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); 329 320 330 321 /* ax25_ip.c */ 331 - extern int ax25_encapsulate(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int); 322 + extern int ax25_hard_header(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int); 332 323 extern int ax25_rebuild_header(struct sk_buff *); 333 324 334 325 /* ax25_out.c */
+31 -1
include/net/netrom.h
··· 6 6 7 7 #ifndef _NETROM_H 8 8 #define _NETROM_H 9 + 9 10 #include <linux/netrom.h> 10 11 #include <linux/list.h> 11 12 #include <net/sock.h> ··· 23 22 #define NR_DISCACK 0x04 24 23 #define NR_INFO 0x05 25 24 #define NR_INFOACK 0x06 25 + #define NR_RESET 0x07 26 26 27 27 #define NR_CHOKE_FLAG 0x80 28 28 #define NR_NAK_FLAG 0x40 ··· 53 51 #define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */ 54 52 #define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */ 55 53 #define NR_DEFAULT_FAILS 2 /* Link fails until route fails */ 54 + #define NR_DEFAULT_RESET 0 /* Sent / accept reset cmds? */ 56 55 57 56 #define NR_MODULUS 256 58 57 #define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */ 59 58 #define NR_MAX_PACKET_SIZE 236 /* Maximum Packet Length - 236 */ 59 + 60 + struct nr_private { 61 + struct net_device_stats stats; 62 + }; 60 63 61 64 struct nr_sock { 62 65 struct sock sock; ··· 183 176 extern int sysctl_netrom_transport_no_activity_timeout; 184 177 extern int sysctl_netrom_routing_control; 185 178 extern int sysctl_netrom_link_fails_count; 179 + extern int sysctl_netrom_reset_circuit; 180 + 186 181 extern int nr_rx_frame(struct sk_buff *, struct net_device *); 187 182 extern void nr_destroy_socket(struct sock *); 188 183 ··· 227 218 extern int nr_validate_nr(struct sock *, unsigned short); 228 219 extern int nr_in_rx_window(struct sock *, unsigned short); 229 220 extern void nr_write_internal(struct sock *, int); 230 - extern void nr_transmit_refusal(struct sk_buff *, int); 221 + 222 + extern void __nr_transmit_reply(struct sk_buff *skb, int mine, 223 + unsigned char cmdflags); 224 + 225 + /* 226 + * This routine is called when a Connect Acknowledge with the Choke Flag 227 + * set is needed to refuse a connection. 228 + */ 229 + #define nr_transmit_refusal(skb, mine) \ 230 + do { \ 231 + __nr_transmit_reply((skb), (mine), NR_CONNACK | NR_CHOKE_FLAG); \ 232 + } while (0) 233 + 234 + /* 235 + * This routine is called when we don't have a circuit matching an incoming 236 + * NET/ROM packet. This is an G8PZT Xrouter extension. 237 + */ 238 + #define nr_transmit_reset(skb, mine) \ 239 + do { \ 240 + __nr_transmit_reply((skb), (mine), NR_RESET); \ 241 + } while (0) 242 + 231 243 extern void nr_disconnect(struct sock *, int); 232 244 233 245 /* nr_timer.c */
+21 -25
net/ax25/af_ax25.c
··· 1695 1695 /* These two are safe on a single CPU system as only user tasks fiddle here */ 1696 1696 if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) 1697 1697 amount = skb->len; 1698 - res = put_user(amount, (int __user *)argp); 1698 + res = put_user(amount, (int __user *) argp); 1699 1699 break; 1700 1700 } 1701 1701 1702 1702 case SIOCGSTAMP: 1703 - if (sk != NULL) { 1704 - res = sock_get_timestamp(sk, argp); 1705 - break; 1706 - } 1707 - res = -EINVAL; 1703 + res = sock_get_timestamp(sk, argp); 1708 1704 break; 1709 1705 1710 1706 case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */ ··· 1947 1951 }; 1948 1952 1949 1953 static struct proto_ops ax25_proto_ops = { 1950 - .family = PF_AX25, 1951 - .owner = THIS_MODULE, 1952 - .release = ax25_release, 1953 - .bind = ax25_bind, 1954 - .connect = ax25_connect, 1955 - .socketpair = sock_no_socketpair, 1956 - .accept = ax25_accept, 1957 - .getname = ax25_getname, 1958 - .poll = datagram_poll, 1959 - .ioctl = ax25_ioctl, 1960 - .listen = ax25_listen, 1961 - .shutdown = ax25_shutdown, 1962 - .setsockopt = ax25_setsockopt, 1963 - .getsockopt = ax25_getsockopt, 1964 - .sendmsg = ax25_sendmsg, 1965 - .recvmsg = ax25_recvmsg, 1966 - .mmap = sock_no_mmap, 1967 - .sendpage = sock_no_sendpage, 1954 + .family = PF_AX25, 1955 + .owner = THIS_MODULE, 1956 + .release = ax25_release, 1957 + .bind = ax25_bind, 1958 + .connect = ax25_connect, 1959 + .socketpair = sock_no_socketpair, 1960 + .accept = ax25_accept, 1961 + .getname = ax25_getname, 1962 + .poll = datagram_poll, 1963 + .ioctl = ax25_ioctl, 1964 + .listen = ax25_listen, 1965 + .shutdown = ax25_shutdown, 1966 + .setsockopt = ax25_setsockopt, 1967 + .getsockopt = ax25_getsockopt, 1968 + .sendmsg = ax25_sendmsg, 1969 + .recvmsg = ax25_recvmsg, 1970 + .mmap = sock_no_mmap, 1971 + .sendpage = sock_no_sendpage, 1968 1972 }; 1969 1973 1970 1974 /* ··· 1980 1984 .notifier_call =ax25_device_event, 1981 1985 }; 1982 1986 1983 - EXPORT_SYMBOL(ax25_encapsulate); 1987 + EXPORT_SYMBOL(ax25_hard_header); 1984 1988 EXPORT_SYMBOL(ax25_rebuild_header); 1985 1989 EXPORT_SYMBOL(ax25_findbyuid); 1986 1990 EXPORT_SYMBOL(ax25_find_cb);
+3 -3
net/ax25/ax25_ip.c
··· 47 47 48 48 #ifdef CONFIG_INET 49 49 50 - int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) 50 + int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) 51 51 { 52 52 unsigned char *buff; 53 53 ··· 88 88 *buff++ = AX25_P_ARP; 89 89 break; 90 90 default: 91 - printk(KERN_ERR "AX.25: ax25_encapsulate - wrong protocol type 0x%2.2x\n", type); 91 + printk(KERN_ERR "AX.25: ax25_hard_header - wrong protocol type 0x%2.2x\n", type); 92 92 *buff++ = 0; 93 93 break; 94 94 } ··· 209 209 210 210 #else /* INET */ 211 211 212 - int ax25_encapsulate(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) 212 + int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) 213 213 { 214 214 return -AX25_HEADER_LEN; 215 215 }
+5 -8
net/core/pktgen.c
··· 1452 1452 thread_lock(); 1453 1453 t->control |= T_REMDEV; 1454 1454 thread_unlock(); 1455 - current->state = TASK_INTERRUPTIBLE; 1456 - schedule_timeout(HZ/8); /* Propagate thread->control */ 1455 + schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ 1457 1456 ret = count; 1458 1457 sprintf(pg_result, "OK: rem_device_all"); 1459 1458 goto out; ··· 1715 1716 printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now)); 1716 1717 while (now < spin_until_us) { 1717 1718 /* TODO: optimise sleeping behavior */ 1718 - if (spin_until_us - now > (1000000/HZ)+1) { 1719 - current->state = TASK_INTERRUPTIBLE; 1720 - schedule_timeout(1); 1721 - } else if (spin_until_us - now > 100) { 1719 + if (spin_until_us - now > jiffies_to_usecs(1)+1) 1720 + schedule_timeout_interruptible(1); 1721 + else if (spin_until_us - now > 100) { 1722 1722 do_softirq(); 1723 1723 if (!pkt_dev->running) 1724 1724 return; ··· 2447 2449 } 2448 2450 thread_unlock(); 2449 2451 2450 - current->state = TASK_INTERRUPTIBLE; 2451 - schedule_timeout(HZ/8); /* Propagate thread->control */ 2452 + schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ 2452 2453 2453 2454 pktgen_wait_all_threads_run(); 2454 2455 }
+8
net/dccp/ccids/ccid3.c
··· 1095 1095 { 1096 1096 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 1097 1097 1098 + /* Listen socks doesn't have a private CCID block */ 1099 + if (sk->sk_state == DCCP_LISTEN) 1100 + return; 1101 + 1098 1102 BUG_ON(hcrx == NULL); 1099 1103 1100 1104 info->tcpi_ca_state = hcrx->ccid3hcrx_state; ··· 1109 1105 static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) 1110 1106 { 1111 1107 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 1108 + 1109 + /* Listen socks doesn't have a private CCID block */ 1110 + if (sk->sk_state == DCCP_LISTEN) 1111 + return; 1112 1112 1113 1113 BUG_ON(hctx == NULL); 1114 1114
+2 -4
net/ipv4/ipconfig.c
··· 1103 1103 #endif 1104 1104 1105 1105 jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout); 1106 - while (time_before(jiffies, jiff) && !ic_got_reply) { 1107 - set_current_state(TASK_UNINTERRUPTIBLE); 1108 - schedule_timeout(1); 1109 - } 1106 + while (time_before(jiffies, jiff) && !ic_got_reply) 1107 + schedule_timeout_uninterruptible(1); 1110 1108 #ifdef IPCONFIG_DHCP 1111 1109 /* DHCP isn't done until we get a DHCPACK. */ 1112 1110 if ((ic_got_reply & IC_BOOTP)
+3 -6
net/irda/ircomm/ircomm_tty.c
··· 567 567 self->tty = NULL; 568 568 569 569 if (self->blocked_open) { 570 - if (self->close_delay) { 571 - current->state = TASK_INTERRUPTIBLE; 572 - schedule_timeout(self->close_delay); 573 - } 570 + if (self->close_delay) 571 + schedule_timeout_interruptible(self->close_delay); 574 572 wake_up_interruptible(&self->open_wait); 575 573 } 576 574 ··· 861 863 spin_lock_irqsave(&self->spinlock, flags); 862 864 while (self->tx_skb && self->tx_skb->len) { 863 865 spin_unlock_irqrestore(&self->spinlock, flags); 864 - current->state = TASK_INTERRUPTIBLE; 865 - schedule_timeout(poll_time); 866 + schedule_timeout_interruptible(poll_time); 866 867 spin_lock_irqsave(&self->spinlock, flags); 867 868 if (signal_pending(current)) 868 869 break;
+13 -15
net/netrom/af_netrom.c
··· 56 56 int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE; 57 57 int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING; 58 58 int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS; 59 + int sysctl_netrom_reset_circuit = NR_DEFAULT_RESET; 59 60 60 61 static unsigned short circuit = 0x101; 61 62 ··· 909 908 if (frametype != NR_CONNREQ) { 910 909 /* 911 910 * Here it would be nice to be able to send a reset but 912 - * NET/ROM doesn't have one. The following hack would 913 - * have been a way to extend the protocol but apparently 914 - * it kills BPQ boxes... :-( 911 + * NET/ROM doesn't have one. We've tried to extend the protocol 912 + * by sending NR_CONNACK | NR_CHOKE_FLAGS replies but that 913 + * apparently kills BPQ boxes... :-( 914 + * So now we try to follow the established behaviour of 915 + * G8PZT's Xrouter which is sending packets with command type 7 916 + * as an extension of the protocol. 915 917 */ 916 - #if 0 917 - /* 918 - * Never reply to a CONNACK/CHOKE. 919 - */ 920 - if (frametype != NR_CONNACK || flags != NR_CHOKE_FLAG) 921 - nr_transmit_refusal(skb, 1); 922 - #endif 918 + if (sysctl_netrom_reset_circuit && 919 + (frametype != NR_RESET || flags != 0)) 920 + nr_transmit_reset(skb, 1); 921 + 923 922 return 0; 924 923 } 925 924 ··· 1188 1187 } 1189 1188 1190 1189 case SIOCGSTAMP: 1191 - ret = -EINVAL; 1192 - if (sk != NULL) 1193 - ret = sock_get_timestamp(sk, argp); 1190 + ret = sock_get_timestamp(sk, argp); 1194 1191 release_sock(sk); 1195 1192 return ret; 1196 1193 ··· 1392 1393 struct net_device *dev; 1393 1394 1394 1395 sprintf(name, "nr%d", i); 1395 - dev = alloc_netdev(sizeof(struct net_device_stats), name, 1396 - nr_setup); 1396 + dev = alloc_netdev(sizeof(struct nr_private), name, nr_setup); 1397 1397 if (!dev) { 1398 1398 printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); 1399 1399 goto fail;
+20 -34
net/netrom/nr_dev.c
··· 47 47 struct net_device_stats *stats = netdev_priv(dev); 48 48 49 49 if (!netif_running(dev)) { 50 - stats->rx_errors++; 50 + stats->rx_dropped++; 51 51 return 0; 52 52 } 53 53 ··· 71 71 72 72 static int nr_rebuild_header(struct sk_buff *skb) 73 73 { 74 - struct net_device *dev = skb->dev; 75 - struct net_device_stats *stats = netdev_priv(dev); 76 - struct sk_buff *skbn; 77 74 unsigned char *bp = skb->data; 78 - int len; 79 75 80 - if (arp_find(bp + 7, skb)) { 76 + if (arp_find(bp + 7, skb)) 81 77 return 1; 82 - } 83 78 84 79 bp[6] &= ~AX25_CBIT; 85 80 bp[6] &= ~AX25_EBIT; ··· 85 90 bp[6] |= AX25_EBIT; 86 91 bp[6] |= AX25_SSSID_SPARE; 87 92 88 - if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { 89 - kfree_skb(skb); 90 - return 1; 91 - } 92 - 93 - if (skb->sk != NULL) 94 - skb_set_owner_w(skbn, skb->sk); 95 - 96 - kfree_skb(skb); 97 - 98 - len = skbn->len; 99 - 100 - if (!nr_route_frame(skbn, NULL)) { 101 - kfree_skb(skbn); 102 - stats->tx_errors++; 103 - } 104 - 105 - stats->tx_packets++; 106 - stats->tx_bytes += len; 107 - 108 - return 1; 93 + return 0; 109 94 } 110 95 111 96 #else ··· 160 185 161 186 static int nr_xmit(struct sk_buff *skb, struct net_device *dev) 162 187 { 163 - struct net_device_stats *stats = netdev_priv(dev); 164 - dev_kfree_skb(skb); 165 - stats->tx_errors++; 188 + struct nr_private *nr = netdev_priv(dev); 189 + struct net_device_stats *stats = &nr->stats; 190 + unsigned int len = skb->len; 191 + 192 + if (!nr_route_frame(skb, NULL)) { 193 + kfree_skb(skb); 194 + stats->tx_errors++; 195 + return 0; 196 + } 197 + 198 + stats->tx_packets++; 199 + stats->tx_bytes += len; 200 + 166 201 return 0; 167 202 } 168 203 169 204 static struct net_device_stats *nr_get_stats(struct net_device *dev) 170 205 { 171 - return netdev_priv(dev); 206 + struct nr_private *nr = netdev_priv(dev); 207 + 208 + return &nr->stats; 172 209 } 173 210 174 211 void nr_setup(struct net_device *dev) ··· 195 208 dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; 196 209 dev->addr_len = AX25_ADDR_LEN; 197 210 dev->type = ARPHRD_NETROM; 198 - dev->tx_queue_len = 40; 199 211 dev->rebuild_header = nr_rebuild_header; 200 212 dev->set_mac_address = nr_set_mac_address; 201 213 202 214 /* New-style flags. */ 203 - dev->flags = 0; 215 + dev->flags = IFF_NOARP; 204 216 205 217 dev->get_stats = nr_get_stats; 206 218 }
+15
net/netrom/nr_in.c
··· 98 98 nr_disconnect(sk, ECONNREFUSED); 99 99 break; 100 100 101 + case NR_RESET: 102 + if (sysctl_netrom_reset_circuit); 103 + nr_disconnect(sk, ECONNRESET); 104 + break; 105 + 101 106 default: 102 107 break; 103 108 } ··· 127 122 128 123 case NR_DISCACK: 129 124 nr_disconnect(sk, 0); 125 + break; 126 + 127 + case NR_RESET: 128 + if (sysctl_netrom_reset_circuit); 129 + nr_disconnect(sk, ECONNRESET); 130 130 break; 131 131 132 132 default: ··· 262 252 nr_start_t2timer(sk); 263 253 } 264 254 } 255 + break; 256 + 257 + case NR_RESET: 258 + if (sysctl_netrom_reset_circuit); 259 + nr_disconnect(sk, ECONNRESET); 265 260 break; 266 261 267 262 default:
+3 -4
net/netrom/nr_subr.c
··· 210 210 } 211 211 212 212 /* 213 - * This routine is called when a Connect Acknowledge with the Choke Flag 214 - * set is needed to refuse a connection. 213 + * This routine is called to send an error reply. 215 214 */ 216 - void nr_transmit_refusal(struct sk_buff *skb, int mine) 215 + void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags) 217 216 { 218 217 struct sk_buff *skbn; 219 218 unsigned char *dptr; ··· 253 254 *dptr++ = 0; 254 255 } 255 256 256 - *dptr++ = NR_CONNACK | NR_CHOKE_FLAG; 257 + *dptr++ = cmdflags; 257 258 *dptr++ = 0; 258 259 259 260 if (!nr_route_frame(skbn, NULL))
+12
net/netrom/sysctl_net_netrom.c
··· 30 30 static int max_idle[] = {65535 * HZ}; 31 31 static int min_route[] = {0}, max_route[] = {1}; 32 32 static int min_fails[] = {1}, max_fails[] = {10}; 33 + static int min_reset[] = {0}, max_reset[] = {1}; 33 34 34 35 static struct ctl_table_header *nr_table_header; 35 36 ··· 155 154 .strategy = &sysctl_intvec, 156 155 .extra1 = &min_fails, 157 156 .extra2 = &max_fails 157 + }, 158 + { 159 + .ctl_name = NET_NETROM_RESET, 160 + .procname = "reset", 161 + .data = &sysctl_netrom_reset_circuit, 162 + .maxlen = sizeof(int), 163 + .mode = 0644, 164 + .proc_handler = &proc_dointvec_minmax, 165 + .strategy = &sysctl_intvec, 166 + .extra1 = &min_reset, 167 + .extra2 = &max_reset 158 168 }, 159 169 { .ctl_name = 0 } 160 170 };
+3 -5
net/rose/af_rose.c
··· 1243 1243 amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); 1244 1244 if (amount < 0) 1245 1245 amount = 0; 1246 - return put_user(amount, (unsigned int __user *)argp); 1246 + return put_user(amount, (unsigned int __user *) argp); 1247 1247 } 1248 1248 1249 1249 case TIOCINQ: { ··· 1252 1252 /* These two are safe on a single CPU system as only user tasks fiddle here */ 1253 1253 if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) 1254 1254 amount = skb->len; 1255 - return put_user(amount, (unsigned int __user *)argp); 1255 + return put_user(amount, (unsigned int __user *) argp); 1256 1256 } 1257 1257 1258 1258 case SIOCGSTAMP: 1259 - if (sk != NULL) 1260 - return sock_get_timestamp(sk, (struct timeval __user *)argp); 1261 - return -EINVAL; 1259 + return sock_get_timestamp(sk, (struct timeval __user *) argp); 1262 1260 1263 1261 case SIOCGIFADDR: 1264 1262 case SIOCSIFADDR:
+1 -1
net/rose/rose_dev.c
··· 149 149 dev->set_mac_address = rose_set_mac_address; 150 150 151 151 /* New-style flags. */ 152 - dev->flags = 0; 152 + dev->flags = IFF_NOARP; 153 153 dev->get_stats = rose_get_stats; 154 154 }
+1 -2
net/sunrpc/svcsock.c
··· 1170 1170 while (rqstp->rq_arghi < pages) { 1171 1171 struct page *p = alloc_page(GFP_KERNEL); 1172 1172 if (!p) { 1173 - set_current_state(TASK_UNINTERRUPTIBLE); 1174 - schedule_timeout(HZ/2); 1173 + schedule_timeout_uninterruptible(msecs_to_jiffies(500)); 1175 1174 continue; 1176 1175 } 1177 1176 rqstp->rq_argpages[rqstp->rq_arghi++] = p;