From: hartkopp Date: Wed, 6 Dec 2006 10:42:02 +0000 (+0000) Subject: Made the device receive list for sockets that are bound to 'any' interfaces an X-Git-Url: http://rtime.felk.cvut.cz/gitweb/socketcan-devel.git/commitdiff_plain/0b8f51d1022bbbe4ab36d80db5765c8e163362fe Made the device receive list for sockets that are bound to 'any' interfaces an element of the rx_dev_list due to a discussion with Urs. This has the effects: 1. The 'any' entries are shown in the procfs 2. remove of obsolete code 3. fix of debugging output (NULL pointer dereferencing) 4. preparation for removing the device receive lists in can_exit() TODO: see point 4: The unloading of can.ko does not remove device receive lists for devices that are currently registered. git-svn-id: svn://svn.berlios.de//socketcan/trunk@112 030b6a49-0b11-0410-94ab-b0dab22257f2 --- diff --git a/kernel/2.6/net/can/af_can.c b/kernel/2.6/net/can/af_can.c index 0739963..5a82cc7 100644 --- a/kernel/2.6/net/can/af_can.c +++ b/kernel/2.6/net/can/af_can.c @@ -126,7 +126,7 @@ static LIST_HEAD(notifier_list); static rwlock_t notifier_lock = RW_LOCK_UNLOCKED; HLIST_HEAD(rx_dev_list); -struct dev_rcv_lists rx_alldev_list; +struct dev_rcv_lists *rx_alldev_list; /* shortcut to persistent entry */ static spinlock_t rcv_lists_lock = SPIN_LOCK_UNLOCKED; static kmem_cache_t *rcv_cache; @@ -171,6 +171,17 @@ static __init int can_init(void) if (!rcv_cache) return -ENOMEM; + /* create a dev_rcv_list for unbound receiption */ + if (!(rx_alldev_list = kmalloc(sizeof(*rx_alldev_list), GFP_KERNEL))) { + printk(KERN_ERR "CAN: allocation of rx_alldev_list failed\n"); + return -ENOMEM; + } + memset(rx_alldev_list, 0, sizeof(*rx_alldev_list)); /* dev = NULL */ + + spin_lock(&rcv_lists_lock); + hlist_add_head_rcu(&rx_alldev_list->list, &rx_dev_list); + spin_unlock(&rcv_lists_lock); + if (stats_timer) { /* statistics init */ init_timer(&stattimer); @@ -202,6 +213,8 @@ static __exit void can_exit(void) unregister_netdevice_notifier(&can_netdev_notifier); sock_unregister(PF_CAN); + /* TODO: remove rx_dev_list */ + kmem_cache_destroy(rcv_cache); } @@ -525,7 +538,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, if (!(d = find_dev_rcv_lists(dev))) { DBG("receive list not found for dev %s, id %03X, mask %03X\n", - dev->name, can_id, mask); + DNAME(dev), can_id, mask); kmem_cache_free(rcv_cache, r); ret = -ENODEV; goto out_unlock; @@ -594,7 +607,7 @@ int can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, if (!(d = find_dev_rcv_lists(dev))) { DBG("receive list not found for dev %s, id %03X, mask %03X\n", - dev->name, can_id, mask); + DNAME(dev), can_id, mask); ret = -ENODEV; goto out; } @@ -619,7 +632,7 @@ int can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, if (!next) { DBG("receive list entry not found for " - "dev %s, id %03X, mask %03X\n", dev->name, can_id, mask); + "dev %s, id %03X, mask %03X\n", DNAME(dev), can_id, mask); ret = -EINVAL; r = NULL; goto out; @@ -665,7 +678,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev, rcu_read_lock(); /* deliver the packet to sockets listening on all devices */ - matches = can_rcv_filter(&rx_alldev_list, skb); + matches = can_rcv_filter(rx_alldev_list, skb); /* find receive list for this device */ if ((d = find_dev_rcv_lists(dev))) @@ -773,9 +786,6 @@ static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev) /* find receive list for this device */ - if (!dev) - return &rx_alldev_list; - /* The hlist_for_each_entry*() macros curse through the list * using the pointer variable n and set d to the containing * struct in each list iteration. Therefore, after list diff --git a/kernel/2.6/net/can/af_can.h b/kernel/2.6/net/can/af_can.h index 1afe485..5eee8d8 100644 --- a/kernel/2.6/net/can/af_can.h +++ b/kernel/2.6/net/can/af_can.h @@ -52,6 +52,8 @@ #include +#define DNAME(dev) (dev)?dev->name:"any" + void can_debug_skb(struct sk_buff *skb); void can_debug_cframe(const char *msg, struct can_frame *cframe, ...); diff --git a/kernel/2.6/net/can/proc.c b/kernel/2.6/net/can/proc.c index be1874c..7182bae 100644 --- a/kernel/2.6/net/can/proc.c +++ b/kernel/2.6/net/can/proc.c @@ -213,7 +213,7 @@ static int can_print_recv_list(char *page, int len, struct hlist_head *rx_list, " %-5s %03X %08x %08x %08x %8ld %s\n"; len += snprintf(page + len, PAGE_SIZE - len, fmt, - dev->name, r->can_id, r->mask, + DNAME(dev), r->can_id, r->mask, (unsigned int)r->func, (unsigned int)r->data, r->matches, r->ident); @@ -359,9 +359,9 @@ static int can_proc_read_rcvlist_all(char *page, char **start, off_t off, if (!hlist_empty(&d->rx_all)) { len = can_print_recv_banner(page, len); len = can_print_recv_list(page, len, &d->rx_all, d->dev); - } else if (d->dev) + } else len += snprintf(page + len, PAGE_SIZE - len, - " (%s: no entry)\n", d->dev->name); + " (%s: no entry)\n", DNAME(d->dev)); } rcu_read_unlock(); @@ -389,9 +389,9 @@ static int can_proc_read_rcvlist_fil(char *page, char **start, off_t off, if (!hlist_empty(&d->rx_fil)) { len = can_print_recv_banner(page, len); len = can_print_recv_list(page, len, &d->rx_fil, d->dev); - } else if (d->dev) + } else len += snprintf(page + len, PAGE_SIZE - len, - " (%s: no entry)\n", d->dev->name); + " (%s: no entry)\n", DNAME(d->dev)); } rcu_read_unlock(); @@ -419,9 +419,9 @@ static int can_proc_read_rcvlist_inv(char *page, char **start, off_t off, if (!hlist_empty(&d->rx_inv)) { len = can_print_recv_banner(page, len); len = can_print_recv_list(page, len, &d->rx_inv, d->dev); - } else if (d->dev) + } else len += snprintf(page + len, PAGE_SIZE - len, - " (%s: no entry)\n", d->dev->name); + " (%s: no entry)\n", DNAME(d->dev)); } rcu_read_unlock(); @@ -459,9 +459,9 @@ static int can_proc_read_rcvlist_sff(char *page, char **start, off_t off, if (!hlist_empty(&d->rx_sff[i]) && len < PAGE_SIZE - 100) len = can_print_recv_list(page, len, &d->rx_sff[i], d->dev); } - } else if (d->dev) + } else len += snprintf(page + len, PAGE_SIZE - len, - " (%s: no entry)\n", d->dev->name); + " (%s: no entry)\n", DNAME(d->dev)); } rcu_read_unlock(); @@ -489,9 +489,9 @@ static int can_proc_read_rcvlist_eff(char *page, char **start, off_t off, if (!hlist_empty(&d->rx_eff)) { len = can_print_recv_banner(page, len); len = can_print_recv_list(page, len, &d->rx_eff, d->dev); - } else if (d->dev) + } else len += snprintf(page + len, PAGE_SIZE - len, - " (%s: no entry)\n", d->dev->name); + " (%s: no entry)\n", DNAME(d->dev)); } rcu_read_unlock(); @@ -519,9 +519,9 @@ static int can_proc_read_rcvlist_err(char *page, char **start, off_t off, if (!hlist_empty(&d->rx_err)) { len = can_print_recv_banner(page, len); len = can_print_recv_list(page, len, &d->rx_err, d->dev); - } else if (d->dev) + } else len += snprintf(page + len, PAGE_SIZE - len, - " (%s: no entry)\n", d->dev->name); + " (%s: no entry)\n", DNAME(d->dev)); } rcu_read_unlock();