diff options
Diffstat (limited to 'net/can')
-rw-r--r-- | net/can/af_can.c | 124 | ||||
-rw-r--r-- | net/can/af_can.h | 4 | ||||
-rw-r--r-- | net/can/bcm.c | 6 | ||||
-rw-r--r-- | net/can/proc.c | 93 | ||||
-rw-r--r-- | net/can/raw.c | 3 |
5 files changed, 108 insertions, 122 deletions
diff --git a/net/can/af_can.c b/net/can/af_can.c index 51adc4c2b860..702be5a2c956 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -77,8 +77,8 @@ static int stats_timer __read_mostly = 1; | |||
77 | module_param(stats_timer, int, S_IRUGO); | 77 | module_param(stats_timer, int, S_IRUGO); |
78 | MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)"); | 78 | MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)"); |
79 | 79 | ||
80 | HLIST_HEAD(can_rx_dev_list); | 80 | /* receive filters subscribed for 'all' CAN devices */ |
81 | static struct dev_rcv_lists can_rx_alldev_list; | 81 | struct dev_rcv_lists can_rx_alldev_list; |
82 | static DEFINE_SPINLOCK(can_rcvlists_lock); | 82 | static DEFINE_SPINLOCK(can_rcvlists_lock); |
83 | 83 | ||
84 | static struct kmem_cache *rcv_cache __read_mostly; | 84 | static struct kmem_cache *rcv_cache __read_mostly; |
@@ -292,28 +292,10 @@ EXPORT_SYMBOL(can_send); | |||
292 | 292 | ||
293 | static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev) | 293 | static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev) |
294 | { | 294 | { |
295 | struct dev_rcv_lists *d = NULL; | 295 | if (!dev) |
296 | struct hlist_node *n; | 296 | return &can_rx_alldev_list; |
297 | 297 | else | |
298 | /* | 298 | return (struct dev_rcv_lists *)dev->ml_priv; |
299 | * find receive list for this device | ||
300 | * | ||
301 | * The hlist_for_each_entry*() macros curse through the list | ||
302 | * using the pointer variable n and set d to the containing | ||
303 | * struct in each list iteration. Therefore, after list | ||
304 | * iteration, d is unmodified when the list is empty, and it | ||
305 | * points to last list element, when the list is non-empty | ||
306 | * but no match in the loop body is found. I.e. d is *not* | ||
307 | * NULL when no match is found. We can, however, use the | ||
308 | * cursor variable n to decide if a match was found. | ||
309 | */ | ||
310 | |||
311 | hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) { | ||
312 | if (d->dev == dev) | ||
313 | break; | ||
314 | } | ||
315 | |||
316 | return n ? d : NULL; | ||
317 | } | 299 | } |
318 | 300 | ||
319 | /** | 301 | /** |
@@ -433,6 +415,9 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | |||
433 | 415 | ||
434 | /* insert new receiver (dev,canid,mask) -> (func,data) */ | 416 | /* insert new receiver (dev,canid,mask) -> (func,data) */ |
435 | 417 | ||
418 | if (dev && dev->type != ARPHRD_CAN) | ||
419 | return -ENODEV; | ||
420 | |||
436 | r = kmem_cache_alloc(rcv_cache, GFP_KERNEL); | 421 | r = kmem_cache_alloc(rcv_cache, GFP_KERNEL); |
437 | if (!r) | 422 | if (!r) |
438 | return -ENOMEM; | 423 | return -ENOMEM; |
@@ -468,16 +453,6 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | |||
468 | EXPORT_SYMBOL(can_rx_register); | 453 | EXPORT_SYMBOL(can_rx_register); |
469 | 454 | ||
470 | /* | 455 | /* |
471 | * can_rx_delete_device - rcu callback for dev_rcv_lists structure removal | ||
472 | */ | ||
473 | static void can_rx_delete_device(struct rcu_head *rp) | ||
474 | { | ||
475 | struct dev_rcv_lists *d = container_of(rp, struct dev_rcv_lists, rcu); | ||
476 | |||
477 | kfree(d); | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * can_rx_delete_receiver - rcu callback for single receiver entry removal | 456 | * can_rx_delete_receiver - rcu callback for single receiver entry removal |
482 | */ | 457 | */ |
483 | static void can_rx_delete_receiver(struct rcu_head *rp) | 458 | static void can_rx_delete_receiver(struct rcu_head *rp) |
@@ -506,6 +481,9 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
506 | struct hlist_node *next; | 481 | struct hlist_node *next; |
507 | struct dev_rcv_lists *d; | 482 | struct dev_rcv_lists *d; |
508 | 483 | ||
484 | if (dev && dev->type != ARPHRD_CAN) | ||
485 | return; | ||
486 | |||
509 | spin_lock(&can_rcvlists_lock); | 487 | spin_lock(&can_rcvlists_lock); |
510 | 488 | ||
511 | d = find_dev_rcv_lists(dev); | 489 | d = find_dev_rcv_lists(dev); |
@@ -541,7 +519,6 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
541 | "dev %s, id %03X, mask %03X\n", | 519 | "dev %s, id %03X, mask %03X\n", |
542 | DNAME(dev), can_id, mask); | 520 | DNAME(dev), can_id, mask); |
543 | r = NULL; | 521 | r = NULL; |
544 | d = NULL; | ||
545 | goto out; | 522 | goto out; |
546 | } | 523 | } |
547 | 524 | ||
@@ -552,10 +529,10 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
552 | can_pstats.rcv_entries--; | 529 | can_pstats.rcv_entries--; |
553 | 530 | ||
554 | /* remove device structure requested by NETDEV_UNREGISTER */ | 531 | /* remove device structure requested by NETDEV_UNREGISTER */ |
555 | if (d->remove_on_zero_entries && !d->entries) | 532 | if (d->remove_on_zero_entries && !d->entries) { |
556 | hlist_del_rcu(&d->list); | 533 | kfree(d); |
557 | else | 534 | dev->ml_priv = NULL; |
558 | d = NULL; | 535 | } |
559 | 536 | ||
560 | out: | 537 | out: |
561 | spin_unlock(&can_rcvlists_lock); | 538 | spin_unlock(&can_rcvlists_lock); |
@@ -563,10 +540,6 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
563 | /* schedule the receiver item for deletion */ | 540 | /* schedule the receiver item for deletion */ |
564 | if (r) | 541 | if (r) |
565 | call_rcu(&r->rcu, can_rx_delete_receiver); | 542 | call_rcu(&r->rcu, can_rx_delete_receiver); |
566 | |||
567 | /* schedule the device structure for deletion */ | ||
568 | if (d) | ||
569 | call_rcu(&d->rcu, can_rx_delete_device); | ||
570 | } | 543 | } |
571 | EXPORT_SYMBOL(can_rx_unregister); | 544 | EXPORT_SYMBOL(can_rx_unregister); |
572 | 545 | ||
@@ -780,48 +753,35 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, | |||
780 | 753 | ||
781 | case NETDEV_REGISTER: | 754 | case NETDEV_REGISTER: |
782 | 755 | ||
783 | /* | 756 | /* create new dev_rcv_lists for this device */ |
784 | * create new dev_rcv_lists for this device | ||
785 | * | ||
786 | * N.B. zeroing the struct is the correct initialization | ||
787 | * for the embedded hlist_head structs. | ||
788 | * Another list type, e.g. list_head, would require | ||
789 | * explicit initialization. | ||
790 | */ | ||
791 | |||
792 | d = kzalloc(sizeof(*d), GFP_KERNEL); | 757 | d = kzalloc(sizeof(*d), GFP_KERNEL); |
793 | if (!d) { | 758 | if (!d) { |
794 | printk(KERN_ERR | 759 | printk(KERN_ERR |
795 | "can: allocation of receive list failed\n"); | 760 | "can: allocation of receive list failed\n"); |
796 | return NOTIFY_DONE; | 761 | return NOTIFY_DONE; |
797 | } | 762 | } |
798 | d->dev = dev; | 763 | BUG_ON(dev->ml_priv); |
799 | 764 | dev->ml_priv = d; | |
800 | spin_lock(&can_rcvlists_lock); | ||
801 | hlist_add_head_rcu(&d->list, &can_rx_dev_list); | ||
802 | spin_unlock(&can_rcvlists_lock); | ||
803 | 765 | ||
804 | break; | 766 | break; |
805 | 767 | ||
806 | case NETDEV_UNREGISTER: | 768 | case NETDEV_UNREGISTER: |
807 | spin_lock(&can_rcvlists_lock); | 769 | spin_lock(&can_rcvlists_lock); |
808 | 770 | ||
809 | d = find_dev_rcv_lists(dev); | 771 | d = dev->ml_priv; |
810 | if (d) { | 772 | if (d) { |
811 | if (d->entries) { | 773 | if (d->entries) |
812 | d->remove_on_zero_entries = 1; | 774 | d->remove_on_zero_entries = 1; |
813 | d = NULL; | 775 | else { |
814 | } else | 776 | kfree(d); |
815 | hlist_del_rcu(&d->list); | 777 | dev->ml_priv = NULL; |
778 | } | ||
816 | } else | 779 | } else |
817 | printk(KERN_ERR "can: notifier: receive list not " | 780 | printk(KERN_ERR "can: notifier: receive list not " |
818 | "found for dev %s\n", dev->name); | 781 | "found for dev %s\n", dev->name); |
819 | 782 | ||
820 | spin_unlock(&can_rcvlists_lock); | 783 | spin_unlock(&can_rcvlists_lock); |
821 | 784 | ||
822 | if (d) | ||
823 | call_rcu(&d->rcu, can_rx_delete_device); | ||
824 | |||
825 | break; | 785 | break; |
826 | } | 786 | } |
827 | 787 | ||
@@ -853,21 +813,13 @@ static __init int can_init(void) | |||
853 | { | 813 | { |
854 | printk(banner); | 814 | printk(banner); |
855 | 815 | ||
816 | memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list)); | ||
817 | |||
856 | rcv_cache = kmem_cache_create("can_receiver", sizeof(struct receiver), | 818 | rcv_cache = kmem_cache_create("can_receiver", sizeof(struct receiver), |
857 | 0, 0, NULL); | 819 | 0, 0, NULL); |
858 | if (!rcv_cache) | 820 | if (!rcv_cache) |
859 | return -ENOMEM; | 821 | return -ENOMEM; |
860 | 822 | ||
861 | /* | ||
862 | * Insert can_rx_alldev_list for reception on all devices. | ||
863 | * This struct is zero initialized which is correct for the | ||
864 | * embedded hlist heads, the dev pointer, and the entries counter. | ||
865 | */ | ||
866 | |||
867 | spin_lock(&can_rcvlists_lock); | ||
868 | hlist_add_head_rcu(&can_rx_alldev_list.list, &can_rx_dev_list); | ||
869 | spin_unlock(&can_rcvlists_lock); | ||
870 | |||
871 | if (stats_timer) { | 823 | if (stats_timer) { |
872 | /* the statistics are updated every second (timer triggered) */ | 824 | /* the statistics are updated every second (timer triggered) */ |
873 | setup_timer(&can_stattimer, can_stat_update, 0); | 825 | setup_timer(&can_stattimer, can_stat_update, 0); |
@@ -887,8 +839,7 @@ static __init int can_init(void) | |||
887 | 839 | ||
888 | static __exit void can_exit(void) | 840 | static __exit void can_exit(void) |
889 | { | 841 | { |
890 | struct dev_rcv_lists *d; | 842 | struct net_device *dev; |
891 | struct hlist_node *n, *next; | ||
892 | 843 | ||
893 | if (stats_timer) | 844 | if (stats_timer) |
894 | del_timer(&can_stattimer); | 845 | del_timer(&can_stattimer); |
@@ -900,14 +851,19 @@ static __exit void can_exit(void) | |||
900 | unregister_netdevice_notifier(&can_netdev_notifier); | 851 | unregister_netdevice_notifier(&can_netdev_notifier); |
901 | sock_unregister(PF_CAN); | 852 | sock_unregister(PF_CAN); |
902 | 853 | ||
903 | /* remove can_rx_dev_list */ | 854 | /* remove created dev_rcv_lists from still registered CAN devices */ |
904 | spin_lock(&can_rcvlists_lock); | 855 | rcu_read_lock(); |
905 | hlist_del(&can_rx_alldev_list.list); | 856 | for_each_netdev_rcu(&init_net, dev) { |
906 | hlist_for_each_entry_safe(d, n, next, &can_rx_dev_list, list) { | 857 | if (dev->type == ARPHRD_CAN && dev->ml_priv){ |
907 | hlist_del(&d->list); | 858 | |
908 | kfree(d); | 859 | struct dev_rcv_lists *d = dev->ml_priv; |
860 | |||
861 | BUG_ON(d->entries); | ||
862 | kfree(d); | ||
863 | dev->ml_priv = NULL; | ||
864 | } | ||
909 | } | 865 | } |
910 | spin_unlock(&can_rcvlists_lock); | 866 | rcu_read_unlock(); |
911 | 867 | ||
912 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | 868 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
913 | 869 | ||
diff --git a/net/can/af_can.h b/net/can/af_can.h index 18f91e37cc30..34253b84e30f 100644 --- a/net/can/af_can.h +++ b/net/can/af_can.h | |||
@@ -63,10 +63,8 @@ struct receiver { | |||
63 | 63 | ||
64 | enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_EFF, RX_MAX }; | 64 | enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_EFF, RX_MAX }; |
65 | 65 | ||
66 | /* per device receive filters linked at dev->ml_priv */ | ||
66 | struct dev_rcv_lists { | 67 | struct dev_rcv_lists { |
67 | struct hlist_node list; | ||
68 | struct rcu_head rcu; | ||
69 | struct net_device *dev; | ||
70 | struct hlist_head rx[RX_MAX]; | 68 | struct hlist_head rx[RX_MAX]; |
71 | struct hlist_head rx_sff[0x800]; | 69 | struct hlist_head rx_sff[0x800]; |
72 | int remove_on_zero_entries; | 70 | int remove_on_zero_entries; |
diff --git a/net/can/bcm.c b/net/can/bcm.c index e32af52238a2..9c65e9deb9c3 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/can.h> | 56 | #include <linux/can.h> |
57 | #include <linux/can/core.h> | 57 | #include <linux/can/core.h> |
58 | #include <linux/can/bcm.h> | 58 | #include <linux/can/bcm.h> |
59 | #include <linux/slab.h> | ||
59 | #include <net/sock.h> | 60 | #include <net/sock.h> |
60 | #include <net/net_namespace.h> | 61 | #include <net/net_namespace.h> |
61 | 62 | ||
@@ -712,8 +713,6 @@ static void bcm_remove_op(struct bcm_op *op) | |||
712 | kfree(op->last_frames); | 713 | kfree(op->last_frames); |
713 | 714 | ||
714 | kfree(op); | 715 | kfree(op); |
715 | |||
716 | return; | ||
717 | } | 716 | } |
718 | 717 | ||
719 | static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) | 718 | static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) |
@@ -1478,6 +1477,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, | |||
1478 | struct sock *sk = sock->sk; | 1477 | struct sock *sk = sock->sk; |
1479 | struct bcm_sock *bo = bcm_sk(sk); | 1478 | struct bcm_sock *bo = bcm_sk(sk); |
1480 | 1479 | ||
1480 | if (len < sizeof(*addr)) | ||
1481 | return -EINVAL; | ||
1482 | |||
1481 | if (bo->bound) | 1483 | if (bo->bound) |
1482 | return -EISCONN; | 1484 | return -EISCONN; |
1483 | 1485 | ||
diff --git a/net/can/proc.c b/net/can/proc.c index 9b9ad29be567..f4265cc9c3fb 100644 --- a/net/can/proc.c +++ b/net/can/proc.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/proc_fs.h> | 45 | #include <linux/proc_fs.h> |
46 | #include <linux/list.h> | 46 | #include <linux/list.h> |
47 | #include <linux/rcupdate.h> | 47 | #include <linux/rcupdate.h> |
48 | #include <linux/if_arp.h> | ||
48 | #include <linux/can/core.h> | 49 | #include <linux/can/core.h> |
49 | 50 | ||
50 | #include "af_can.h" | 51 | #include "af_can.h" |
@@ -84,6 +85,9 @@ static const char rx_list_name[][8] = { | |||
84 | [RX_EFF] = "rx_eff", | 85 | [RX_EFF] = "rx_eff", |
85 | }; | 86 | }; |
86 | 87 | ||
88 | /* receive filters subscribed for 'all' CAN devices */ | ||
89 | extern struct dev_rcv_lists can_rx_alldev_list; | ||
90 | |||
87 | /* | 91 | /* |
88 | * af_can statistics stuff | 92 | * af_can statistics stuff |
89 | */ | 93 | */ |
@@ -190,10 +194,6 @@ void can_stat_update(unsigned long data) | |||
190 | 194 | ||
191 | /* | 195 | /* |
192 | * proc read functions | 196 | * proc read functions |
193 | * | ||
194 | * From known use-cases we expect about 10 entries in a receive list to be | ||
195 | * printed in the proc_fs. So PAGE_SIZE is definitely enough space here. | ||
196 | * | ||
197 | */ | 197 | */ |
198 | 198 | ||
199 | static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list, | 199 | static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list, |
@@ -202,7 +202,6 @@ static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list, | |||
202 | struct receiver *r; | 202 | struct receiver *r; |
203 | struct hlist_node *n; | 203 | struct hlist_node *n; |
204 | 204 | ||
205 | rcu_read_lock(); | ||
206 | hlist_for_each_entry_rcu(r, n, rx_list, list) { | 205 | hlist_for_each_entry_rcu(r, n, rx_list, list) { |
207 | char *fmt = (r->can_id & CAN_EFF_FLAG)? | 206 | char *fmt = (r->can_id & CAN_EFF_FLAG)? |
208 | " %-5s %08X %08x %08x %08x %8ld %s\n" : | 207 | " %-5s %08X %08x %08x %08x %8ld %s\n" : |
@@ -212,7 +211,6 @@ static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list, | |||
212 | (unsigned long)r->func, (unsigned long)r->data, | 211 | (unsigned long)r->func, (unsigned long)r->data, |
213 | r->matches, r->ident); | 212 | r->matches, r->ident); |
214 | } | 213 | } |
215 | rcu_read_unlock(); | ||
216 | } | 214 | } |
217 | 215 | ||
218 | static void can_print_recv_banner(struct seq_file *m) | 216 | static void can_print_recv_banner(struct seq_file *m) |
@@ -346,24 +344,39 @@ static const struct file_operations can_version_proc_fops = { | |||
346 | .release = single_release, | 344 | .release = single_release, |
347 | }; | 345 | }; |
348 | 346 | ||
347 | static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx, | ||
348 | struct net_device *dev, | ||
349 | struct dev_rcv_lists *d) | ||
350 | { | ||
351 | if (!hlist_empty(&d->rx[idx])) { | ||
352 | can_print_recv_banner(m); | ||
353 | can_print_rcvlist(m, &d->rx[idx], dev); | ||
354 | } else | ||
355 | seq_printf(m, " (%s: no entry)\n", DNAME(dev)); | ||
356 | |||
357 | } | ||
358 | |||
349 | static int can_rcvlist_proc_show(struct seq_file *m, void *v) | 359 | static int can_rcvlist_proc_show(struct seq_file *m, void *v) |
350 | { | 360 | { |
351 | /* double cast to prevent GCC warning */ | 361 | /* double cast to prevent GCC warning */ |
352 | int idx = (int)(long)m->private; | 362 | int idx = (int)(long)m->private; |
363 | struct net_device *dev; | ||
353 | struct dev_rcv_lists *d; | 364 | struct dev_rcv_lists *d; |
354 | struct hlist_node *n; | ||
355 | 365 | ||
356 | seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]); | 366 | seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]); |
357 | 367 | ||
358 | rcu_read_lock(); | 368 | rcu_read_lock(); |
359 | hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) { | ||
360 | 369 | ||
361 | if (!hlist_empty(&d->rx[idx])) { | 370 | /* receive list for 'all' CAN devices (dev == NULL) */ |
362 | can_print_recv_banner(m); | 371 | d = &can_rx_alldev_list; |
363 | can_print_rcvlist(m, &d->rx[idx], d->dev); | 372 | can_rcvlist_proc_show_one(m, idx, NULL, d); |
364 | } else | 373 | |
365 | seq_printf(m, " (%s: no entry)\n", DNAME(d->dev)); | 374 | /* receive list for registered CAN devices */ |
375 | for_each_netdev_rcu(&init_net, dev) { | ||
376 | if (dev->type == ARPHRD_CAN && dev->ml_priv) | ||
377 | can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv); | ||
366 | } | 378 | } |
379 | |||
367 | rcu_read_unlock(); | 380 | rcu_read_unlock(); |
368 | 381 | ||
369 | seq_putc(m, '\n'); | 382 | seq_putc(m, '\n'); |
@@ -383,34 +396,50 @@ static const struct file_operations can_rcvlist_proc_fops = { | |||
383 | .release = single_release, | 396 | .release = single_release, |
384 | }; | 397 | }; |
385 | 398 | ||
399 | static inline void can_rcvlist_sff_proc_show_one(struct seq_file *m, | ||
400 | struct net_device *dev, | ||
401 | struct dev_rcv_lists *d) | ||
402 | { | ||
403 | int i; | ||
404 | int all_empty = 1; | ||
405 | |||
406 | /* check wether at least one list is non-empty */ | ||
407 | for (i = 0; i < 0x800; i++) | ||
408 | if (!hlist_empty(&d->rx_sff[i])) { | ||
409 | all_empty = 0; | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | if (!all_empty) { | ||
414 | can_print_recv_banner(m); | ||
415 | for (i = 0; i < 0x800; i++) { | ||
416 | if (!hlist_empty(&d->rx_sff[i])) | ||
417 | can_print_rcvlist(m, &d->rx_sff[i], dev); | ||
418 | } | ||
419 | } else | ||
420 | seq_printf(m, " (%s: no entry)\n", DNAME(dev)); | ||
421 | } | ||
422 | |||
386 | static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) | 423 | static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) |
387 | { | 424 | { |
425 | struct net_device *dev; | ||
388 | struct dev_rcv_lists *d; | 426 | struct dev_rcv_lists *d; |
389 | struct hlist_node *n; | ||
390 | 427 | ||
391 | /* RX_SFF */ | 428 | /* RX_SFF */ |
392 | seq_puts(m, "\nreceive list 'rx_sff':\n"); | 429 | seq_puts(m, "\nreceive list 'rx_sff':\n"); |
393 | 430 | ||
394 | rcu_read_lock(); | 431 | rcu_read_lock(); |
395 | hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) { | 432 | |
396 | int i, all_empty = 1; | 433 | /* sff receive list for 'all' CAN devices (dev == NULL) */ |
397 | /* check wether at least one list is non-empty */ | 434 | d = &can_rx_alldev_list; |
398 | for (i = 0; i < 0x800; i++) | 435 | can_rcvlist_sff_proc_show_one(m, NULL, d); |
399 | if (!hlist_empty(&d->rx_sff[i])) { | 436 | |
400 | all_empty = 0; | 437 | /* sff receive list for registered CAN devices */ |
401 | break; | 438 | for_each_netdev_rcu(&init_net, dev) { |
402 | } | 439 | if (dev->type == ARPHRD_CAN && dev->ml_priv) |
403 | 440 | can_rcvlist_sff_proc_show_one(m, dev, dev->ml_priv); | |
404 | if (!all_empty) { | ||
405 | can_print_recv_banner(m); | ||
406 | for (i = 0; i < 0x800; i++) { | ||
407 | if (!hlist_empty(&d->rx_sff[i])) | ||
408 | can_print_rcvlist(m, &d->rx_sff[i], | ||
409 | d->dev); | ||
410 | } | ||
411 | } else | ||
412 | seq_printf(m, " (%s: no entry)\n", DNAME(d->dev)); | ||
413 | } | 441 | } |
442 | |||
414 | rcu_read_unlock(); | 443 | rcu_read_unlock(); |
415 | 444 | ||
416 | seq_putc(m, '\n'); | 445 | seq_putc(m, '\n'); |
diff --git a/net/can/raw.c b/net/can/raw.c index abca920440b5..da99cf153b33 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
46 | #include <linux/uio.h> | 46 | #include <linux/uio.h> |
47 | #include <linux/net.h> | 47 | #include <linux/net.h> |
48 | #include <linux/slab.h> | ||
48 | #include <linux/netdevice.h> | 49 | #include <linux/netdevice.h> |
49 | #include <linux/socket.h> | 50 | #include <linux/socket.h> |
50 | #include <linux/if_arp.h> | 51 | #include <linux/if_arp.h> |
@@ -444,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
444 | return -EFAULT; | 445 | return -EFAULT; |
445 | } | 446 | } |
446 | } else if (count == 1) { | 447 | } else if (count == 1) { |
447 | if (copy_from_user(&sfilter, optval, optlen)) | 448 | if (copy_from_user(&sfilter, optval, sizeof(sfilter))) |
448 | return -EFAULT; | 449 | return -EFAULT; |
449 | } | 450 | } |
450 | 451 | ||