diff options
-rw-r--r-- | include/linux/can/core.h | 7 | ||||
-rw-r--r-- | include/net/net_namespace.h | 4 | ||||
-rw-r--r-- | include/net/netns/can.h | 31 | ||||
-rw-r--r-- | net/can/af_can.c | 122 | ||||
-rw-r--r-- | net/can/af_can.h | 4 | ||||
-rw-r--r-- | net/can/bcm.c | 13 | ||||
-rw-r--r-- | net/can/gw.c | 4 | ||||
-rw-r--r-- | net/can/proc.c | 144 | ||||
-rw-r--r-- | net/can/raw.c | 92 |
9 files changed, 242 insertions, 179 deletions
diff --git a/include/linux/can/core.h b/include/linux/can/core.h index df08a41d5be5..319a0da827b8 100644 --- a/include/linux/can/core.h +++ b/include/linux/can/core.h | |||
@@ -45,12 +45,13 @@ struct can_proto { | |||
45 | extern int can_proto_register(const struct can_proto *cp); | 45 | extern int can_proto_register(const struct can_proto *cp); |
46 | extern void can_proto_unregister(const struct can_proto *cp); | 46 | extern void can_proto_unregister(const struct can_proto *cp); |
47 | 47 | ||
48 | int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | 48 | int can_rx_register(struct net *net, struct net_device *dev, |
49 | canid_t can_id, canid_t mask, | ||
49 | void (*func)(struct sk_buff *, void *), | 50 | void (*func)(struct sk_buff *, void *), |
50 | void *data, char *ident, struct sock *sk); | 51 | void *data, char *ident, struct sock *sk); |
51 | 52 | ||
52 | extern void can_rx_unregister(struct net_device *dev, canid_t can_id, | 53 | extern void can_rx_unregister(struct net *net, struct net_device *dev, |
53 | canid_t mask, | 54 | canid_t can_id, canid_t mask, |
54 | void (*func)(struct sk_buff *, void *), | 55 | void (*func)(struct sk_buff *, void *), |
55 | void *data); | 56 | void *data); |
56 | 57 | ||
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index af8fe8a909dc..fe80bb48ab1f 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <net/netns/nftables.h> | 27 | #include <net/netns/nftables.h> |
28 | #include <net/netns/xfrm.h> | 28 | #include <net/netns/xfrm.h> |
29 | #include <net/netns/mpls.h> | 29 | #include <net/netns/mpls.h> |
30 | #include <net/netns/can.h> | ||
30 | #include <linux/ns_common.h> | 31 | #include <linux/ns_common.h> |
31 | #include <linux/idr.h> | 32 | #include <linux/idr.h> |
32 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
@@ -141,6 +142,9 @@ struct net { | |||
141 | #if IS_ENABLED(CONFIG_MPLS) | 142 | #if IS_ENABLED(CONFIG_MPLS) |
142 | struct netns_mpls mpls; | 143 | struct netns_mpls mpls; |
143 | #endif | 144 | #endif |
145 | #if IS_ENABLED(CONFIG_CAN) | ||
146 | struct netns_can can; | ||
147 | #endif | ||
144 | struct sock *diag_nlsk; | 148 | struct sock *diag_nlsk; |
145 | atomic_t fnhe_genid; | 149 | atomic_t fnhe_genid; |
146 | }; | 150 | }; |
diff --git a/include/net/netns/can.h b/include/net/netns/can.h new file mode 100644 index 000000000000..e8beba772f1a --- /dev/null +++ b/include/net/netns/can.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * can in net namespaces | ||
3 | */ | ||
4 | |||
5 | #ifndef __NETNS_CAN_H__ | ||
6 | #define __NETNS_CAN_H__ | ||
7 | |||
8 | #include <linux/spinlock.h> | ||
9 | |||
10 | struct dev_rcv_lists; | ||
11 | |||
12 | struct netns_can { | ||
13 | #if IS_ENABLED(CONFIG_PROC_FS) | ||
14 | struct proc_dir_entry *proc_dir; | ||
15 | struct proc_dir_entry *pde_version; | ||
16 | struct proc_dir_entry *pde_stats; | ||
17 | struct proc_dir_entry *pde_reset_stats; | ||
18 | struct proc_dir_entry *pde_rcvlist_all; | ||
19 | struct proc_dir_entry *pde_rcvlist_fil; | ||
20 | struct proc_dir_entry *pde_rcvlist_inv; | ||
21 | struct proc_dir_entry *pde_rcvlist_sff; | ||
22 | struct proc_dir_entry *pde_rcvlist_eff; | ||
23 | struct proc_dir_entry *pde_rcvlist_err; | ||
24 | #endif | ||
25 | |||
26 | /* receive filters subscribed for 'all' CAN devices */ | ||
27 | struct dev_rcv_lists *can_rx_alldev_list; | ||
28 | spinlock_t can_rcvlists_lock; | ||
29 | }; | ||
30 | |||
31 | #endif /* __NETNS_CAN_H__ */ | ||
diff --git a/net/can/af_can.c b/net/can/af_can.c index 5488e4a6ccd0..abf7d854a94d 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -75,9 +75,7 @@ static int stats_timer __read_mostly = 1; | |||
75 | module_param(stats_timer, int, S_IRUGO); | 75 | module_param(stats_timer, int, S_IRUGO); |
76 | MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)"); | 76 | MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)"); |
77 | 77 | ||
78 | /* receive filters subscribed for 'all' CAN devices */ | 78 | static int can_net_id; |
79 | struct dev_rcv_lists can_rx_alldev_list; | ||
80 | static DEFINE_SPINLOCK(can_rcvlists_lock); | ||
81 | 79 | ||
82 | static struct kmem_cache *rcv_cache __read_mostly; | 80 | static struct kmem_cache *rcv_cache __read_mostly; |
83 | 81 | ||
@@ -145,9 +143,6 @@ static int can_create(struct net *net, struct socket *sock, int protocol, | |||
145 | if (protocol < 0 || protocol >= CAN_NPROTO) | 143 | if (protocol < 0 || protocol >= CAN_NPROTO) |
146 | return -EINVAL; | 144 | return -EINVAL; |
147 | 145 | ||
148 | if (!net_eq(net, &init_net)) | ||
149 | return -EAFNOSUPPORT; | ||
150 | |||
151 | cp = can_get_proto(protocol); | 146 | cp = can_get_proto(protocol); |
152 | 147 | ||
153 | #ifdef CONFIG_MODULES | 148 | #ifdef CONFIG_MODULES |
@@ -331,10 +326,11 @@ EXPORT_SYMBOL(can_send); | |||
331 | * af_can rx path | 326 | * af_can rx path |
332 | */ | 327 | */ |
333 | 328 | ||
334 | static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev) | 329 | static struct dev_rcv_lists *find_dev_rcv_lists(struct net *net, |
330 | struct net_device *dev) | ||
335 | { | 331 | { |
336 | if (!dev) | 332 | if (!dev) |
337 | return &can_rx_alldev_list; | 333 | return net->can.can_rx_alldev_list; |
338 | else | 334 | else |
339 | return (struct dev_rcv_lists *)dev->ml_priv; | 335 | return (struct dev_rcv_lists *)dev->ml_priv; |
340 | } | 336 | } |
@@ -467,9 +463,9 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, | |||
467 | * -ENOMEM on missing cache mem to create subscription entry | 463 | * -ENOMEM on missing cache mem to create subscription entry |
468 | * -ENODEV unknown device | 464 | * -ENODEV unknown device |
469 | */ | 465 | */ |
470 | int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | 466 | int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id, |
471 | void (*func)(struct sk_buff *, void *), void *data, | 467 | canid_t mask, void (*func)(struct sk_buff *, void *), |
472 | char *ident, struct sock *sk) | 468 | void *data, char *ident, struct sock *sk) |
473 | { | 469 | { |
474 | struct receiver *r; | 470 | struct receiver *r; |
475 | struct hlist_head *rl; | 471 | struct hlist_head *rl; |
@@ -481,13 +477,16 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | |||
481 | if (dev && dev->type != ARPHRD_CAN) | 477 | if (dev && dev->type != ARPHRD_CAN) |
482 | return -ENODEV; | 478 | return -ENODEV; |
483 | 479 | ||
480 | if (dev && !net_eq(net, dev_net(dev))) | ||
481 | return -ENODEV; | ||
482 | |||
484 | r = kmem_cache_alloc(rcv_cache, GFP_KERNEL); | 483 | r = kmem_cache_alloc(rcv_cache, GFP_KERNEL); |
485 | if (!r) | 484 | if (!r) |
486 | return -ENOMEM; | 485 | return -ENOMEM; |
487 | 486 | ||
488 | spin_lock(&can_rcvlists_lock); | 487 | spin_lock(&net->can.can_rcvlists_lock); |
489 | 488 | ||
490 | d = find_dev_rcv_lists(dev); | 489 | d = find_dev_rcv_lists(net, dev); |
491 | if (d) { | 490 | if (d) { |
492 | rl = find_rcv_list(&can_id, &mask, d); | 491 | rl = find_rcv_list(&can_id, &mask, d); |
493 | 492 | ||
@@ -510,7 +509,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | |||
510 | err = -ENODEV; | 509 | err = -ENODEV; |
511 | } | 510 | } |
512 | 511 | ||
513 | spin_unlock(&can_rcvlists_lock); | 512 | spin_unlock(&net->can.can_rcvlists_lock); |
514 | 513 | ||
515 | return err; | 514 | return err; |
516 | } | 515 | } |
@@ -540,8 +539,9 @@ static void can_rx_delete_receiver(struct rcu_head *rp) | |||
540 | * Description: | 539 | * Description: |
541 | * Removes subscription entry depending on given (subscription) values. | 540 | * Removes subscription entry depending on given (subscription) values. |
542 | */ | 541 | */ |
543 | void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | 542 | void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, |
544 | void (*func)(struct sk_buff *, void *), void *data) | 543 | canid_t mask, void (*func)(struct sk_buff *, void *), |
544 | void *data) | ||
545 | { | 545 | { |
546 | struct receiver *r = NULL; | 546 | struct receiver *r = NULL; |
547 | struct hlist_head *rl; | 547 | struct hlist_head *rl; |
@@ -550,9 +550,12 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
550 | if (dev && dev->type != ARPHRD_CAN) | 550 | if (dev && dev->type != ARPHRD_CAN) |
551 | return; | 551 | return; |
552 | 552 | ||
553 | spin_lock(&can_rcvlists_lock); | 553 | if (dev && !net_eq(net, dev_net(dev))) |
554 | return; | ||
554 | 555 | ||
555 | d = find_dev_rcv_lists(dev); | 556 | spin_lock(&net->can.can_rcvlists_lock); |
557 | |||
558 | d = find_dev_rcv_lists(net, dev); | ||
556 | if (!d) { | 559 | if (!d) { |
557 | pr_err("BUG: receive list not found for " | 560 | pr_err("BUG: receive list not found for " |
558 | "dev %s, id %03X, mask %03X\n", | 561 | "dev %s, id %03X, mask %03X\n", |
@@ -598,7 +601,7 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
598 | } | 601 | } |
599 | 602 | ||
600 | out: | 603 | out: |
601 | spin_unlock(&can_rcvlists_lock); | 604 | spin_unlock(&net->can.can_rcvlists_lock); |
602 | 605 | ||
603 | /* schedule the receiver item for deletion */ | 606 | /* schedule the receiver item for deletion */ |
604 | if (r) { | 607 | if (r) { |
@@ -696,10 +699,10 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev) | |||
696 | rcu_read_lock(); | 699 | rcu_read_lock(); |
697 | 700 | ||
698 | /* deliver the packet to sockets listening on all devices */ | 701 | /* deliver the packet to sockets listening on all devices */ |
699 | matches = can_rcv_filter(&can_rx_alldev_list, skb); | 702 | matches = can_rcv_filter(dev_net(dev)->can.can_rx_alldev_list, skb); |
700 | 703 | ||
701 | /* find receive list for this device */ | 704 | /* find receive list for this device */ |
702 | d = find_dev_rcv_lists(dev); | 705 | d = find_dev_rcv_lists(dev_net(dev), dev); |
703 | if (d) | 706 | if (d) |
704 | matches += can_rcv_filter(d, skb); | 707 | matches += can_rcv_filter(d, skb); |
705 | 708 | ||
@@ -719,9 +722,6 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev, | |||
719 | { | 722 | { |
720 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; | 723 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; |
721 | 724 | ||
722 | if (unlikely(!net_eq(dev_net(dev), &init_net))) | ||
723 | goto drop; | ||
724 | |||
725 | if (WARN_ONCE(dev->type != ARPHRD_CAN || | 725 | if (WARN_ONCE(dev->type != ARPHRD_CAN || |
726 | skb->len != CAN_MTU || | 726 | skb->len != CAN_MTU || |
727 | cfd->len > CAN_MAX_DLEN, | 727 | cfd->len > CAN_MAX_DLEN, |
@@ -743,9 +743,6 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev, | |||
743 | { | 743 | { |
744 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; | 744 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; |
745 | 745 | ||
746 | if (unlikely(!net_eq(dev_net(dev), &init_net))) | ||
747 | goto drop; | ||
748 | |||
749 | if (WARN_ONCE(dev->type != ARPHRD_CAN || | 746 | if (WARN_ONCE(dev->type != ARPHRD_CAN || |
750 | skb->len != CANFD_MTU || | 747 | skb->len != CANFD_MTU || |
751 | cfd->len > CANFD_MAX_DLEN, | 748 | cfd->len > CANFD_MAX_DLEN, |
@@ -835,9 +832,6 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, | |||
835 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | 832 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
836 | struct dev_rcv_lists *d; | 833 | struct dev_rcv_lists *d; |
837 | 834 | ||
838 | if (!net_eq(dev_net(dev), &init_net)) | ||
839 | return NOTIFY_DONE; | ||
840 | |||
841 | if (dev->type != ARPHRD_CAN) | 835 | if (dev->type != ARPHRD_CAN) |
842 | return NOTIFY_DONE; | 836 | return NOTIFY_DONE; |
843 | 837 | ||
@@ -855,7 +849,7 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, | |||
855 | break; | 849 | break; |
856 | 850 | ||
857 | case NETDEV_UNREGISTER: | 851 | case NETDEV_UNREGISTER: |
858 | spin_lock(&can_rcvlists_lock); | 852 | spin_lock(&dev_net(dev)->can.can_rcvlists_lock); |
859 | 853 | ||
860 | d = dev->ml_priv; | 854 | d = dev->ml_priv; |
861 | if (d) { | 855 | if (d) { |
@@ -869,7 +863,7 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, | |||
869 | pr_err("can: notifier: receive list not found for dev " | 863 | pr_err("can: notifier: receive list not found for dev " |
870 | "%s\n", dev->name); | 864 | "%s\n", dev->name); |
871 | 865 | ||
872 | spin_unlock(&can_rcvlists_lock); | 866 | spin_unlock(&dev_net(dev)->can.can_rcvlists_lock); |
873 | 867 | ||
874 | break; | 868 | break; |
875 | } | 869 | } |
@@ -877,6 +871,40 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, | |||
877 | return NOTIFY_DONE; | 871 | return NOTIFY_DONE; |
878 | } | 872 | } |
879 | 873 | ||
874 | static int can_pernet_init(struct net *net) | ||
875 | { | ||
876 | net->can.can_rcvlists_lock = | ||
877 | __SPIN_LOCK_UNLOCKED(net->can.can_rcvlists_lock); | ||
878 | net->can.can_rx_alldev_list = | ||
879 | kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); | ||
880 | |||
881 | if (IS_ENABLED(CONFIG_PROC_FS)) | ||
882 | can_init_proc(net); | ||
883 | |||
884 | return 0; | ||
885 | } | ||
886 | |||
887 | static void can_pernet_exit(struct net *net) | ||
888 | { | ||
889 | struct net_device *dev; | ||
890 | |||
891 | if (IS_ENABLED(CONFIG_PROC_FS)) | ||
892 | can_remove_proc(net); | ||
893 | |||
894 | /* remove created dev_rcv_lists from still registered CAN devices */ | ||
895 | rcu_read_lock(); | ||
896 | for_each_netdev_rcu(net, dev) { | ||
897 | if (dev->type == ARPHRD_CAN && dev->ml_priv) { | ||
898 | struct dev_rcv_lists *d = dev->ml_priv; | ||
899 | |||
900 | BUG_ON(d->entries); | ||
901 | kfree(d); | ||
902 | dev->ml_priv = NULL; | ||
903 | } | ||
904 | } | ||
905 | rcu_read_unlock(); | ||
906 | } | ||
907 | |||
880 | /* | 908 | /* |
881 | * af_can module init/exit functions | 909 | * af_can module init/exit functions |
882 | */ | 910 | */ |
@@ -902,6 +930,13 @@ static struct notifier_block can_netdev_notifier __read_mostly = { | |||
902 | .notifier_call = can_notifier, | 930 | .notifier_call = can_notifier, |
903 | }; | 931 | }; |
904 | 932 | ||
933 | static struct pernet_operations can_pernet_ops __read_mostly = { | ||
934 | .init = can_pernet_init, | ||
935 | .exit = can_pernet_exit, | ||
936 | .id = &can_net_id, | ||
937 | .size = 0, | ||
938 | }; | ||
939 | |||
905 | static __init int can_init(void) | 940 | static __init int can_init(void) |
906 | { | 941 | { |
907 | /* check for correct padding to be able to use the structs similarly */ | 942 | /* check for correct padding to be able to use the structs similarly */ |
@@ -912,8 +947,6 @@ static __init int can_init(void) | |||
912 | 947 | ||
913 | pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n"); | 948 | pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n"); |
914 | 949 | ||
915 | memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list)); | ||
916 | |||
917 | rcv_cache = kmem_cache_create("can_receiver", sizeof(struct receiver), | 950 | rcv_cache = kmem_cache_create("can_receiver", sizeof(struct receiver), |
918 | 0, 0, NULL); | 951 | 0, 0, NULL); |
919 | if (!rcv_cache) | 952 | if (!rcv_cache) |
@@ -925,9 +958,10 @@ static __init int can_init(void) | |||
925 | setup_timer(&can_stattimer, can_stat_update, 0); | 958 | setup_timer(&can_stattimer, can_stat_update, 0); |
926 | mod_timer(&can_stattimer, round_jiffies(jiffies + HZ)); | 959 | mod_timer(&can_stattimer, round_jiffies(jiffies + HZ)); |
927 | } | 960 | } |
928 | can_init_proc(); | ||
929 | } | 961 | } |
930 | 962 | ||
963 | register_pernet_subsys(&can_pernet_ops); | ||
964 | |||
931 | /* protocol register */ | 965 | /* protocol register */ |
932 | sock_register(&can_family_ops); | 966 | sock_register(&can_family_ops); |
933 | register_netdevice_notifier(&can_netdev_notifier); | 967 | register_netdevice_notifier(&can_netdev_notifier); |
@@ -939,13 +973,9 @@ static __init int can_init(void) | |||
939 | 973 | ||
940 | static __exit void can_exit(void) | 974 | static __exit void can_exit(void) |
941 | { | 975 | { |
942 | struct net_device *dev; | ||
943 | |||
944 | if (IS_ENABLED(CONFIG_PROC_FS)) { | 976 | if (IS_ENABLED(CONFIG_PROC_FS)) { |
945 | if (stats_timer) | 977 | if (stats_timer) |
946 | del_timer_sync(&can_stattimer); | 978 | del_timer_sync(&can_stattimer); |
947 | |||
948 | can_remove_proc(); | ||
949 | } | 979 | } |
950 | 980 | ||
951 | /* protocol unregister */ | 981 | /* protocol unregister */ |
@@ -954,19 +984,7 @@ static __exit void can_exit(void) | |||
954 | unregister_netdevice_notifier(&can_netdev_notifier); | 984 | unregister_netdevice_notifier(&can_netdev_notifier); |
955 | sock_unregister(PF_CAN); | 985 | sock_unregister(PF_CAN); |
956 | 986 | ||
957 | /* remove created dev_rcv_lists from still registered CAN devices */ | 987 | unregister_pernet_subsys(&can_pernet_ops); |
958 | rcu_read_lock(); | ||
959 | for_each_netdev_rcu(&init_net, dev) { | ||
960 | if (dev->type == ARPHRD_CAN && dev->ml_priv) { | ||
961 | |||
962 | struct dev_rcv_lists *d = dev->ml_priv; | ||
963 | |||
964 | BUG_ON(d->entries); | ||
965 | kfree(d); | ||
966 | dev->ml_priv = NULL; | ||
967 | } | ||
968 | } | ||
969 | rcu_read_unlock(); | ||
970 | 988 | ||
971 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | 989 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
972 | 990 | ||
diff --git a/net/can/af_can.h b/net/can/af_can.h index b86f5129e838..f273c9d9b129 100644 --- a/net/can/af_can.h +++ b/net/can/af_can.h | |||
@@ -114,8 +114,8 @@ struct s_pstats { | |||
114 | extern struct dev_rcv_lists can_rx_alldev_list; | 114 | extern struct dev_rcv_lists can_rx_alldev_list; |
115 | 115 | ||
116 | /* function prototypes for the CAN networklayer procfs (proc.c) */ | 116 | /* function prototypes for the CAN networklayer procfs (proc.c) */ |
117 | void can_init_proc(void); | 117 | void can_init_proc(struct net *net); |
118 | void can_remove_proc(void); | 118 | void can_remove_proc(struct net *net); |
119 | void can_stat_update(unsigned long data); | 119 | void can_stat_update(unsigned long data); |
120 | 120 | ||
121 | /* structures and variables from af_can.c needed in proc.c for reading */ | 121 | /* structures and variables from af_can.c needed in proc.c for reading */ |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 95d13b233c65..1976629a8463 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -764,8 +764,8 @@ static void bcm_remove_op(struct bcm_op *op) | |||
764 | static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) | 764 | static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) |
765 | { | 765 | { |
766 | if (op->rx_reg_dev == dev) { | 766 | if (op->rx_reg_dev == dev) { |
767 | can_rx_unregister(dev, op->can_id, REGMASK(op->can_id), | 767 | can_rx_unregister(&init_net, dev, op->can_id, |
768 | bcm_rx_handler, op); | 768 | REGMASK(op->can_id), bcm_rx_handler, op); |
769 | 769 | ||
770 | /* mark as removed subscription */ | 770 | /* mark as removed subscription */ |
771 | op->rx_reg_dev = NULL; | 771 | op->rx_reg_dev = NULL; |
@@ -808,7 +808,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, | |||
808 | } | 808 | } |
809 | } | 809 | } |
810 | } else | 810 | } else |
811 | can_rx_unregister(NULL, op->can_id, | 811 | can_rx_unregister(&init_net, NULL, op->can_id, |
812 | REGMASK(op->can_id), | 812 | REGMASK(op->can_id), |
813 | bcm_rx_handler, op); | 813 | bcm_rx_handler, op); |
814 | 814 | ||
@@ -1222,7 +1222,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
1222 | 1222 | ||
1223 | dev = dev_get_by_index(&init_net, ifindex); | 1223 | dev = dev_get_by_index(&init_net, ifindex); |
1224 | if (dev) { | 1224 | if (dev) { |
1225 | err = can_rx_register(dev, op->can_id, | 1225 | err = can_rx_register(&init_net, dev, |
1226 | op->can_id, | ||
1226 | REGMASK(op->can_id), | 1227 | REGMASK(op->can_id), |
1227 | bcm_rx_handler, op, | 1228 | bcm_rx_handler, op, |
1228 | "bcm", sk); | 1229 | "bcm", sk); |
@@ -1232,7 +1233,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
1232 | } | 1233 | } |
1233 | 1234 | ||
1234 | } else | 1235 | } else |
1235 | err = can_rx_register(NULL, op->can_id, | 1236 | err = can_rx_register(&init_net, NULL, op->can_id, |
1236 | REGMASK(op->can_id), | 1237 | REGMASK(op->can_id), |
1237 | bcm_rx_handler, op, "bcm", sk); | 1238 | bcm_rx_handler, op, "bcm", sk); |
1238 | if (err) { | 1239 | if (err) { |
@@ -1528,7 +1529,7 @@ static int bcm_release(struct socket *sock) | |||
1528 | } | 1529 | } |
1529 | } | 1530 | } |
1530 | } else | 1531 | } else |
1531 | can_rx_unregister(NULL, op->can_id, | 1532 | can_rx_unregister(&init_net, NULL, op->can_id, |
1532 | REGMASK(op->can_id), | 1533 | REGMASK(op->can_id), |
1533 | bcm_rx_handler, op); | 1534 | bcm_rx_handler, op); |
1534 | 1535 | ||
diff --git a/net/can/gw.c b/net/can/gw.c index 7056a1a2bb70..3c117a33e15f 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -440,14 +440,14 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) | |||
440 | 440 | ||
441 | static inline int cgw_register_filter(struct cgw_job *gwj) | 441 | static inline int cgw_register_filter(struct cgw_job *gwj) |
442 | { | 442 | { |
443 | return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id, | 443 | return can_rx_register(&init_net, gwj->src.dev, gwj->ccgw.filter.can_id, |
444 | gwj->ccgw.filter.can_mask, can_can_gw_rcv, | 444 | gwj->ccgw.filter.can_mask, can_can_gw_rcv, |
445 | gwj, "gw", NULL); | 445 | gwj, "gw", NULL); |
446 | } | 446 | } |
447 | 447 | ||
448 | static inline void cgw_unregister_filter(struct cgw_job *gwj) | 448 | static inline void cgw_unregister_filter(struct cgw_job *gwj) |
449 | { | 449 | { |
450 | can_rx_unregister(gwj->src.dev, gwj->ccgw.filter.can_id, | 450 | can_rx_unregister(&init_net, gwj->src.dev, gwj->ccgw.filter.can_id, |
451 | gwj->ccgw.filter.can_mask, can_can_gw_rcv, gwj); | 451 | gwj->ccgw.filter.can_mask, can_can_gw_rcv, gwj); |
452 | } | 452 | } |
453 | 453 | ||
diff --git a/net/can/proc.c b/net/can/proc.c index 85ef7bb0f176..9a8d54d57b22 100644 --- a/net/can/proc.c +++ b/net/can/proc.c | |||
@@ -62,17 +62,6 @@ | |||
62 | #define CAN_PROC_RCVLIST_EFF "rcvlist_eff" | 62 | #define CAN_PROC_RCVLIST_EFF "rcvlist_eff" |
63 | #define CAN_PROC_RCVLIST_ERR "rcvlist_err" | 63 | #define CAN_PROC_RCVLIST_ERR "rcvlist_err" |
64 | 64 | ||
65 | static struct proc_dir_entry *can_dir; | ||
66 | static struct proc_dir_entry *pde_version; | ||
67 | static struct proc_dir_entry *pde_stats; | ||
68 | static struct proc_dir_entry *pde_reset_stats; | ||
69 | static struct proc_dir_entry *pde_rcvlist_all; | ||
70 | static struct proc_dir_entry *pde_rcvlist_fil; | ||
71 | static struct proc_dir_entry *pde_rcvlist_inv; | ||
72 | static struct proc_dir_entry *pde_rcvlist_sff; | ||
73 | static struct proc_dir_entry *pde_rcvlist_eff; | ||
74 | static struct proc_dir_entry *pde_rcvlist_err; | ||
75 | |||
76 | static int user_reset; | 65 | static int user_reset; |
77 | 66 | ||
78 | static const char rx_list_name[][8] = { | 67 | static const char rx_list_name[][8] = { |
@@ -351,20 +340,21 @@ static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx, | |||
351 | static int can_rcvlist_proc_show(struct seq_file *m, void *v) | 340 | static int can_rcvlist_proc_show(struct seq_file *m, void *v) |
352 | { | 341 | { |
353 | /* double cast to prevent GCC warning */ | 342 | /* double cast to prevent GCC warning */ |
354 | int idx = (int)(long)m->private; | 343 | int idx = (int)(long)PDE_DATA(m->file->f_inode); |
355 | struct net_device *dev; | 344 | struct net_device *dev; |
356 | struct dev_rcv_lists *d; | 345 | struct dev_rcv_lists *d; |
346 | struct net *net = m->private; | ||
357 | 347 | ||
358 | seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]); | 348 | seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]); |
359 | 349 | ||
360 | rcu_read_lock(); | 350 | rcu_read_lock(); |
361 | 351 | ||
362 | /* receive list for 'all' CAN devices (dev == NULL) */ | 352 | /* receive list for 'all' CAN devices (dev == NULL) */ |
363 | d = &can_rx_alldev_list; | 353 | d = net->can.can_rx_alldev_list; |
364 | can_rcvlist_proc_show_one(m, idx, NULL, d); | 354 | can_rcvlist_proc_show_one(m, idx, NULL, d); |
365 | 355 | ||
366 | /* receive list for registered CAN devices */ | 356 | /* receive list for registered CAN devices */ |
367 | for_each_netdev_rcu(&init_net, dev) { | 357 | for_each_netdev_rcu(net, dev) { |
368 | if (dev->type == ARPHRD_CAN && dev->ml_priv) | 358 | if (dev->type == ARPHRD_CAN && dev->ml_priv) |
369 | can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv); | 359 | can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv); |
370 | } | 360 | } |
@@ -377,7 +367,7 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v) | |||
377 | 367 | ||
378 | static int can_rcvlist_proc_open(struct inode *inode, struct file *file) | 368 | static int can_rcvlist_proc_open(struct inode *inode, struct file *file) |
379 | { | 369 | { |
380 | return single_open(file, can_rcvlist_proc_show, PDE_DATA(inode)); | 370 | return single_open_net(inode, file, can_rcvlist_proc_show); |
381 | } | 371 | } |
382 | 372 | ||
383 | static const struct file_operations can_rcvlist_proc_fops = { | 373 | static const struct file_operations can_rcvlist_proc_fops = { |
@@ -417,6 +407,7 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) | |||
417 | { | 407 | { |
418 | struct net_device *dev; | 408 | struct net_device *dev; |
419 | struct dev_rcv_lists *d; | 409 | struct dev_rcv_lists *d; |
410 | struct net *net = m->private; | ||
420 | 411 | ||
421 | /* RX_SFF */ | 412 | /* RX_SFF */ |
422 | seq_puts(m, "\nreceive list 'rx_sff':\n"); | 413 | seq_puts(m, "\nreceive list 'rx_sff':\n"); |
@@ -424,11 +415,11 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) | |||
424 | rcu_read_lock(); | 415 | rcu_read_lock(); |
425 | 416 | ||
426 | /* sff receive list for 'all' CAN devices (dev == NULL) */ | 417 | /* sff receive list for 'all' CAN devices (dev == NULL) */ |
427 | d = &can_rx_alldev_list; | 418 | d = net->can.can_rx_alldev_list; |
428 | can_rcvlist_proc_show_array(m, NULL, d->rx_sff, ARRAY_SIZE(d->rx_sff)); | 419 | can_rcvlist_proc_show_array(m, NULL, d->rx_sff, ARRAY_SIZE(d->rx_sff)); |
429 | 420 | ||
430 | /* sff receive list for registered CAN devices */ | 421 | /* sff receive list for registered CAN devices */ |
431 | for_each_netdev_rcu(&init_net, dev) { | 422 | for_each_netdev_rcu(net, dev) { |
432 | if (dev->type == ARPHRD_CAN && dev->ml_priv) { | 423 | if (dev->type == ARPHRD_CAN && dev->ml_priv) { |
433 | d = dev->ml_priv; | 424 | d = dev->ml_priv; |
434 | can_rcvlist_proc_show_array(m, dev, d->rx_sff, | 425 | can_rcvlist_proc_show_array(m, dev, d->rx_sff, |
@@ -444,7 +435,7 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) | |||
444 | 435 | ||
445 | static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file) | 436 | static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file) |
446 | { | 437 | { |
447 | return single_open(file, can_rcvlist_sff_proc_show, NULL); | 438 | return single_open_net(inode, file, can_rcvlist_sff_proc_show); |
448 | } | 439 | } |
449 | 440 | ||
450 | static const struct file_operations can_rcvlist_sff_proc_fops = { | 441 | static const struct file_operations can_rcvlist_sff_proc_fops = { |
@@ -460,6 +451,7 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v) | |||
460 | { | 451 | { |
461 | struct net_device *dev; | 452 | struct net_device *dev; |
462 | struct dev_rcv_lists *d; | 453 | struct dev_rcv_lists *d; |
454 | struct net *net = m->private; | ||
463 | 455 | ||
464 | /* RX_EFF */ | 456 | /* RX_EFF */ |
465 | seq_puts(m, "\nreceive list 'rx_eff':\n"); | 457 | seq_puts(m, "\nreceive list 'rx_eff':\n"); |
@@ -467,11 +459,11 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v) | |||
467 | rcu_read_lock(); | 459 | rcu_read_lock(); |
468 | 460 | ||
469 | /* eff receive list for 'all' CAN devices (dev == NULL) */ | 461 | /* eff receive list for 'all' CAN devices (dev == NULL) */ |
470 | d = &can_rx_alldev_list; | 462 | d = net->can.can_rx_alldev_list; |
471 | can_rcvlist_proc_show_array(m, NULL, d->rx_eff, ARRAY_SIZE(d->rx_eff)); | 463 | can_rcvlist_proc_show_array(m, NULL, d->rx_eff, ARRAY_SIZE(d->rx_eff)); |
472 | 464 | ||
473 | /* eff receive list for registered CAN devices */ | 465 | /* eff receive list for registered CAN devices */ |
474 | for_each_netdev_rcu(&init_net, dev) { | 466 | for_each_netdev_rcu(net, dev) { |
475 | if (dev->type == ARPHRD_CAN && dev->ml_priv) { | 467 | if (dev->type == ARPHRD_CAN && dev->ml_priv) { |
476 | d = dev->ml_priv; | 468 | d = dev->ml_priv; |
477 | can_rcvlist_proc_show_array(m, dev, d->rx_eff, | 469 | can_rcvlist_proc_show_array(m, dev, d->rx_eff, |
@@ -487,7 +479,7 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v) | |||
487 | 479 | ||
488 | static int can_rcvlist_eff_proc_open(struct inode *inode, struct file *file) | 480 | static int can_rcvlist_eff_proc_open(struct inode *inode, struct file *file) |
489 | { | 481 | { |
490 | return single_open(file, can_rcvlist_eff_proc_show, NULL); | 482 | return single_open_net(inode, file, can_rcvlist_eff_proc_show); |
491 | } | 483 | } |
492 | 484 | ||
493 | static const struct file_operations can_rcvlist_eff_proc_fops = { | 485 | static const struct file_operations can_rcvlist_eff_proc_fops = { |
@@ -499,81 +491,85 @@ static const struct file_operations can_rcvlist_eff_proc_fops = { | |||
499 | }; | 491 | }; |
500 | 492 | ||
501 | /* | 493 | /* |
502 | * proc utility functions | ||
503 | */ | ||
504 | |||
505 | static void can_remove_proc_readentry(const char *name) | ||
506 | { | ||
507 | if (can_dir) | ||
508 | remove_proc_entry(name, can_dir); | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * can_init_proc - create main CAN proc directory and procfs entries | 494 | * can_init_proc - create main CAN proc directory and procfs entries |
513 | */ | 495 | */ |
514 | void can_init_proc(void) | 496 | void can_init_proc(struct net *net) |
515 | { | 497 | { |
516 | /* create /proc/net/can directory */ | 498 | /* create /proc/net/can directory */ |
517 | can_dir = proc_mkdir("can", init_net.proc_net); | 499 | net->can.proc_dir = proc_net_mkdir(net, "can", net->proc_net); |
518 | 500 | ||
519 | if (!can_dir) { | 501 | if (!net->can.proc_dir) { |
520 | pr_info("can: failed to create /proc/net/can.\n"); | 502 | printk(KERN_INFO "can: failed to create /proc/net/can . " |
503 | "CONFIG_PROC_FS missing?\n"); | ||
521 | return; | 504 | return; |
522 | } | 505 | } |
523 | 506 | ||
524 | /* own procfs entries from the AF_CAN core */ | 507 | /* own procfs entries from the AF_CAN core */ |
525 | pde_version = proc_create(CAN_PROC_VERSION, 0644, can_dir, | 508 | net->can.pde_version = proc_create(CAN_PROC_VERSION, 0644, |
526 | &can_version_proc_fops); | 509 | net->can.proc_dir, |
527 | pde_stats = proc_create(CAN_PROC_STATS, 0644, can_dir, | 510 | &can_version_proc_fops); |
528 | &can_stats_proc_fops); | 511 | net->can.pde_stats = proc_create(CAN_PROC_STATS, 0644, |
529 | pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, can_dir, | 512 | net->can.proc_dir, |
530 | &can_reset_stats_proc_fops); | 513 | &can_stats_proc_fops); |
531 | pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, can_dir, | 514 | net->can.pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, |
532 | &can_rcvlist_proc_fops, (void *)RX_ERR); | 515 | net->can.proc_dir, |
533 | pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, can_dir, | 516 | &can_reset_stats_proc_fops); |
534 | &can_rcvlist_proc_fops, (void *)RX_ALL); | 517 | net->can.pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, |
535 | pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, can_dir, | 518 | net->can.proc_dir, |
536 | &can_rcvlist_proc_fops, (void *)RX_FIL); | 519 | &can_rcvlist_proc_fops, |
537 | pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, can_dir, | 520 | (void *)RX_ERR); |
538 | &can_rcvlist_proc_fops, (void *)RX_INV); | 521 | net->can.pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, |
539 | pde_rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644, can_dir, | 522 | net->can.proc_dir, |
540 | &can_rcvlist_eff_proc_fops); | 523 | &can_rcvlist_proc_fops, |
541 | pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, can_dir, | 524 | (void *)RX_ALL); |
542 | &can_rcvlist_sff_proc_fops); | 525 | net->can.pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, |
526 | net->can.proc_dir, | ||
527 | &can_rcvlist_proc_fops, | ||
528 | (void *)RX_FIL); | ||
529 | net->can.pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, | ||
530 | net->can.proc_dir, | ||
531 | &can_rcvlist_proc_fops, | ||
532 | (void *)RX_INV); | ||
533 | net->can.pde_rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644, | ||
534 | net->can.proc_dir, | ||
535 | &can_rcvlist_eff_proc_fops); | ||
536 | net->can.pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, | ||
537 | net->can.proc_dir, | ||
538 | &can_rcvlist_sff_proc_fops); | ||
543 | } | 539 | } |
544 | 540 | ||
545 | /* | 541 | /* |
546 | * can_remove_proc - remove procfs entries and main CAN proc directory | 542 | * can_remove_proc - remove procfs entries and main CAN proc directory |
547 | */ | 543 | */ |
548 | void can_remove_proc(void) | 544 | void can_remove_proc(struct net *net) |
549 | { | 545 | { |
550 | if (pde_version) | 546 | if (net->can.pde_version) |
551 | can_remove_proc_readentry(CAN_PROC_VERSION); | 547 | remove_proc_entry(CAN_PROC_VERSION, net->can.proc_dir); |
552 | 548 | ||
553 | if (pde_stats) | 549 | if (net->can.pde_stats) |
554 | can_remove_proc_readentry(CAN_PROC_STATS); | 550 | remove_proc_entry(CAN_PROC_STATS, net->can.proc_dir); |
555 | 551 | ||
556 | if (pde_reset_stats) | 552 | if (net->can.pde_reset_stats) |
557 | can_remove_proc_readentry(CAN_PROC_RESET_STATS); | 553 | remove_proc_entry(CAN_PROC_RESET_STATS, net->can.proc_dir); |
558 | 554 | ||
559 | if (pde_rcvlist_err) | 555 | if (net->can.pde_rcvlist_err) |
560 | can_remove_proc_readentry(CAN_PROC_RCVLIST_ERR); | 556 | remove_proc_entry(CAN_PROC_RCVLIST_ERR, net->can.proc_dir); |
561 | 557 | ||
562 | if (pde_rcvlist_all) | 558 | if (net->can.pde_rcvlist_all) |
563 | can_remove_proc_readentry(CAN_PROC_RCVLIST_ALL); | 559 | remove_proc_entry(CAN_PROC_RCVLIST_ALL, net->can.proc_dir); |
564 | 560 | ||
565 | if (pde_rcvlist_fil) | 561 | if (net->can.pde_rcvlist_fil) |
566 | can_remove_proc_readentry(CAN_PROC_RCVLIST_FIL); | 562 | remove_proc_entry(CAN_PROC_RCVLIST_FIL, net->can.proc_dir); |
567 | 563 | ||
568 | if (pde_rcvlist_inv) | 564 | if (net->can.pde_rcvlist_inv) |
569 | can_remove_proc_readentry(CAN_PROC_RCVLIST_INV); | 565 | remove_proc_entry(CAN_PROC_RCVLIST_INV, net->can.proc_dir); |
570 | 566 | ||
571 | if (pde_rcvlist_eff) | 567 | if (net->can.pde_rcvlist_eff) |
572 | can_remove_proc_readentry(CAN_PROC_RCVLIST_EFF); | 568 | remove_proc_entry(CAN_PROC_RCVLIST_EFF, net->can.proc_dir); |
573 | 569 | ||
574 | if (pde_rcvlist_sff) | 570 | if (net->can.pde_rcvlist_sff) |
575 | can_remove_proc_readentry(CAN_PROC_RCVLIST_SFF); | 571 | remove_proc_entry(CAN_PROC_RCVLIST_SFF, net->can.proc_dir); |
576 | 572 | ||
577 | if (can_dir) | 573 | if (net->can.proc_dir) |
578 | remove_proc_entry("can", init_net.proc_net); | 574 | remove_proc_entry("can", net->proc_net); |
579 | } | 575 | } |
diff --git a/net/can/raw.c b/net/can/raw.c index 6dc546a06673..864c80dbdb72 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -181,20 +181,21 @@ static void raw_rcv(struct sk_buff *oskb, void *data) | |||
181 | kfree_skb(skb); | 181 | kfree_skb(skb); |
182 | } | 182 | } |
183 | 183 | ||
184 | static int raw_enable_filters(struct net_device *dev, struct sock *sk, | 184 | static int raw_enable_filters(struct net *net, struct net_device *dev, |
185 | struct can_filter *filter, int count) | 185 | struct sock *sk, struct can_filter *filter, |
186 | int count) | ||
186 | { | 187 | { |
187 | int err = 0; | 188 | int err = 0; |
188 | int i; | 189 | int i; |
189 | 190 | ||
190 | for (i = 0; i < count; i++) { | 191 | for (i = 0; i < count; i++) { |
191 | err = can_rx_register(dev, filter[i].can_id, | 192 | err = can_rx_register(net, dev, filter[i].can_id, |
192 | filter[i].can_mask, | 193 | filter[i].can_mask, |
193 | raw_rcv, sk, "raw", sk); | 194 | raw_rcv, sk, "raw", sk); |
194 | if (err) { | 195 | if (err) { |
195 | /* clean up successfully registered filters */ | 196 | /* clean up successfully registered filters */ |
196 | while (--i >= 0) | 197 | while (--i >= 0) |
197 | can_rx_unregister(dev, filter[i].can_id, | 198 | can_rx_unregister(net, dev, filter[i].can_id, |
198 | filter[i].can_mask, | 199 | filter[i].can_mask, |
199 | raw_rcv, sk); | 200 | raw_rcv, sk); |
200 | break; | 201 | break; |
@@ -204,57 +205,62 @@ static int raw_enable_filters(struct net_device *dev, struct sock *sk, | |||
204 | return err; | 205 | return err; |
205 | } | 206 | } |
206 | 207 | ||
207 | static int raw_enable_errfilter(struct net_device *dev, struct sock *sk, | 208 | static int raw_enable_errfilter(struct net *net, struct net_device *dev, |
208 | can_err_mask_t err_mask) | 209 | struct sock *sk, can_err_mask_t err_mask) |
209 | { | 210 | { |
210 | int err = 0; | 211 | int err = 0; |
211 | 212 | ||
212 | if (err_mask) | 213 | if (err_mask) |
213 | err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG, | 214 | err = can_rx_register(net, dev, 0, err_mask | CAN_ERR_FLAG, |
214 | raw_rcv, sk, "raw", sk); | 215 | raw_rcv, sk, "raw", sk); |
215 | 216 | ||
216 | return err; | 217 | return err; |
217 | } | 218 | } |
218 | 219 | ||
219 | static void raw_disable_filters(struct net_device *dev, struct sock *sk, | 220 | static void raw_disable_filters(struct net *net, struct net_device *dev, |
220 | struct can_filter *filter, int count) | 221 | struct sock *sk, struct can_filter *filter, |
222 | int count) | ||
221 | { | 223 | { |
222 | int i; | 224 | int i; |
223 | 225 | ||
224 | for (i = 0; i < count; i++) | 226 | for (i = 0; i < count; i++) |
225 | can_rx_unregister(dev, filter[i].can_id, filter[i].can_mask, | 227 | can_rx_unregister(net, dev, filter[i].can_id, |
226 | raw_rcv, sk); | 228 | filter[i].can_mask, raw_rcv, sk); |
227 | } | 229 | } |
228 | 230 | ||
229 | static inline void raw_disable_errfilter(struct net_device *dev, | 231 | static inline void raw_disable_errfilter(struct net *net, |
232 | struct net_device *dev, | ||
230 | struct sock *sk, | 233 | struct sock *sk, |
231 | can_err_mask_t err_mask) | 234 | can_err_mask_t err_mask) |
232 | 235 | ||
233 | { | 236 | { |
234 | if (err_mask) | 237 | if (err_mask) |
235 | can_rx_unregister(dev, 0, err_mask | CAN_ERR_FLAG, | 238 | can_rx_unregister(net, dev, 0, err_mask | CAN_ERR_FLAG, |
236 | raw_rcv, sk); | 239 | raw_rcv, sk); |
237 | } | 240 | } |
238 | 241 | ||
239 | static inline void raw_disable_allfilters(struct net_device *dev, | 242 | static inline void raw_disable_allfilters(struct net *net, |
243 | struct net_device *dev, | ||
240 | struct sock *sk) | 244 | struct sock *sk) |
241 | { | 245 | { |
242 | struct raw_sock *ro = raw_sk(sk); | 246 | struct raw_sock *ro = raw_sk(sk); |
243 | 247 | ||
244 | raw_disable_filters(dev, sk, ro->filter, ro->count); | 248 | raw_disable_filters(net, dev, sk, ro->filter, ro->count); |
245 | raw_disable_errfilter(dev, sk, ro->err_mask); | 249 | raw_disable_errfilter(net, dev, sk, ro->err_mask); |
246 | } | 250 | } |
247 | 251 | ||
248 | static int raw_enable_allfilters(struct net_device *dev, struct sock *sk) | 252 | static int raw_enable_allfilters(struct net *net, struct net_device *dev, |
253 | struct sock *sk) | ||
249 | { | 254 | { |
250 | struct raw_sock *ro = raw_sk(sk); | 255 | struct raw_sock *ro = raw_sk(sk); |
251 | int err; | 256 | int err; |
252 | 257 | ||
253 | err = raw_enable_filters(dev, sk, ro->filter, ro->count); | 258 | err = raw_enable_filters(net, dev, sk, ro->filter, ro->count); |
254 | if (!err) { | 259 | if (!err) { |
255 | err = raw_enable_errfilter(dev, sk, ro->err_mask); | 260 | err = raw_enable_errfilter(net, dev, sk, ro->err_mask); |
256 | if (err) | 261 | if (err) |
257 | raw_disable_filters(dev, sk, ro->filter, ro->count); | 262 | raw_disable_filters(net, dev, sk, ro->filter, |
263 | ro->count); | ||
258 | } | 264 | } |
259 | 265 | ||
260 | return err; | 266 | return err; |
@@ -267,7 +273,7 @@ static int raw_notifier(struct notifier_block *nb, | |||
267 | struct raw_sock *ro = container_of(nb, struct raw_sock, notifier); | 273 | struct raw_sock *ro = container_of(nb, struct raw_sock, notifier); |
268 | struct sock *sk = &ro->sk; | 274 | struct sock *sk = &ro->sk; |
269 | 275 | ||
270 | if (!net_eq(dev_net(dev), &init_net)) | 276 | if (!net_eq(dev_net(dev), sock_net(sk))) |
271 | return NOTIFY_DONE; | 277 | return NOTIFY_DONE; |
272 | 278 | ||
273 | if (dev->type != ARPHRD_CAN) | 279 | if (dev->type != ARPHRD_CAN) |
@@ -282,7 +288,7 @@ static int raw_notifier(struct notifier_block *nb, | |||
282 | lock_sock(sk); | 288 | lock_sock(sk); |
283 | /* remove current filters & unregister */ | 289 | /* remove current filters & unregister */ |
284 | if (ro->bound) | 290 | if (ro->bound) |
285 | raw_disable_allfilters(dev, sk); | 291 | raw_disable_allfilters(dev_net(dev), dev, sk); |
286 | 292 | ||
287 | if (ro->count > 1) | 293 | if (ro->count > 1) |
288 | kfree(ro->filter); | 294 | kfree(ro->filter); |
@@ -358,13 +364,13 @@ static int raw_release(struct socket *sock) | |||
358 | if (ro->ifindex) { | 364 | if (ro->ifindex) { |
359 | struct net_device *dev; | 365 | struct net_device *dev; |
360 | 366 | ||
361 | dev = dev_get_by_index(&init_net, ro->ifindex); | 367 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); |
362 | if (dev) { | 368 | if (dev) { |
363 | raw_disable_allfilters(dev, sk); | 369 | raw_disable_allfilters(dev_net(dev), dev, sk); |
364 | dev_put(dev); | 370 | dev_put(dev); |
365 | } | 371 | } |
366 | } else | 372 | } else |
367 | raw_disable_allfilters(NULL, sk); | 373 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
368 | } | 374 | } |
369 | 375 | ||
370 | if (ro->count > 1) | 376 | if (ro->count > 1) |
@@ -404,7 +410,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) | |||
404 | if (addr->can_ifindex) { | 410 | if (addr->can_ifindex) { |
405 | struct net_device *dev; | 411 | struct net_device *dev; |
406 | 412 | ||
407 | dev = dev_get_by_index(&init_net, addr->can_ifindex); | 413 | dev = dev_get_by_index(sock_net(sk), addr->can_ifindex); |
408 | if (!dev) { | 414 | if (!dev) { |
409 | err = -ENODEV; | 415 | err = -ENODEV; |
410 | goto out; | 416 | goto out; |
@@ -420,13 +426,13 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) | |||
420 | ifindex = dev->ifindex; | 426 | ifindex = dev->ifindex; |
421 | 427 | ||
422 | /* filters set by default/setsockopt */ | 428 | /* filters set by default/setsockopt */ |
423 | err = raw_enable_allfilters(dev, sk); | 429 | err = raw_enable_allfilters(sock_net(sk), dev, sk); |
424 | dev_put(dev); | 430 | dev_put(dev); |
425 | } else { | 431 | } else { |
426 | ifindex = 0; | 432 | ifindex = 0; |
427 | 433 | ||
428 | /* filters set by default/setsockopt */ | 434 | /* filters set by default/setsockopt */ |
429 | err = raw_enable_allfilters(NULL, sk); | 435 | err = raw_enable_allfilters(sock_net(sk), NULL, sk); |
430 | } | 436 | } |
431 | 437 | ||
432 | if (!err) { | 438 | if (!err) { |
@@ -435,13 +441,15 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) | |||
435 | if (ro->ifindex) { | 441 | if (ro->ifindex) { |
436 | struct net_device *dev; | 442 | struct net_device *dev; |
437 | 443 | ||
438 | dev = dev_get_by_index(&init_net, ro->ifindex); | 444 | dev = dev_get_by_index(sock_net(sk), |
445 | ro->ifindex); | ||
439 | if (dev) { | 446 | if (dev) { |
440 | raw_disable_allfilters(dev, sk); | 447 | raw_disable_allfilters(dev_net(dev), |
448 | dev, sk); | ||
441 | dev_put(dev); | 449 | dev_put(dev); |
442 | } | 450 | } |
443 | } else | 451 | } else |
444 | raw_disable_allfilters(NULL, sk); | 452 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
445 | } | 453 | } |
446 | ro->ifindex = ifindex; | 454 | ro->ifindex = ifindex; |
447 | ro->bound = 1; | 455 | ro->bound = 1; |
@@ -517,15 +525,16 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
517 | lock_sock(sk); | 525 | lock_sock(sk); |
518 | 526 | ||
519 | if (ro->bound && ro->ifindex) | 527 | if (ro->bound && ro->ifindex) |
520 | dev = dev_get_by_index(&init_net, ro->ifindex); | 528 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); |
521 | 529 | ||
522 | if (ro->bound) { | 530 | if (ro->bound) { |
523 | /* (try to) register the new filters */ | 531 | /* (try to) register the new filters */ |
524 | if (count == 1) | 532 | if (count == 1) |
525 | err = raw_enable_filters(dev, sk, &sfilter, 1); | 533 | err = raw_enable_filters(sock_net(sk), dev, sk, |
534 | &sfilter, 1); | ||
526 | else | 535 | else |
527 | err = raw_enable_filters(dev, sk, filter, | 536 | err = raw_enable_filters(sock_net(sk), dev, sk, |
528 | count); | 537 | filter, count); |
529 | if (err) { | 538 | if (err) { |
530 | if (count > 1) | 539 | if (count > 1) |
531 | kfree(filter); | 540 | kfree(filter); |
@@ -533,7 +542,8 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
533 | } | 542 | } |
534 | 543 | ||
535 | /* remove old filter registrations */ | 544 | /* remove old filter registrations */ |
536 | raw_disable_filters(dev, sk, ro->filter, ro->count); | 545 | raw_disable_filters(sock_net(sk), dev, sk, ro->filter, |
546 | ro->count); | ||
537 | } | 547 | } |
538 | 548 | ||
539 | /* remove old filter space */ | 549 | /* remove old filter space */ |
@@ -569,18 +579,20 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
569 | lock_sock(sk); | 579 | lock_sock(sk); |
570 | 580 | ||
571 | if (ro->bound && ro->ifindex) | 581 | if (ro->bound && ro->ifindex) |
572 | dev = dev_get_by_index(&init_net, ro->ifindex); | 582 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); |
573 | 583 | ||
574 | /* remove current error mask */ | 584 | /* remove current error mask */ |
575 | if (ro->bound) { | 585 | if (ro->bound) { |
576 | /* (try to) register the new err_mask */ | 586 | /* (try to) register the new err_mask */ |
577 | err = raw_enable_errfilter(dev, sk, err_mask); | 587 | err = raw_enable_errfilter(sock_net(sk), dev, sk, |
588 | err_mask); | ||
578 | 589 | ||
579 | if (err) | 590 | if (err) |
580 | goto out_err; | 591 | goto out_err; |
581 | 592 | ||
582 | /* remove old err_mask registration */ | 593 | /* remove old err_mask registration */ |
583 | raw_disable_errfilter(dev, sk, ro->err_mask); | 594 | raw_disable_errfilter(sock_net(sk), dev, sk, |
595 | ro->err_mask); | ||
584 | } | 596 | } |
585 | 597 | ||
586 | /* link new err_mask to the socket */ | 598 | /* link new err_mask to the socket */ |
@@ -741,7 +753,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
741 | return -EINVAL; | 753 | return -EINVAL; |
742 | } | 754 | } |
743 | 755 | ||
744 | dev = dev_get_by_index(&init_net, ifindex); | 756 | dev = dev_get_by_index(sock_net(sk), ifindex); |
745 | if (!dev) | 757 | if (!dev) |
746 | return -ENXIO; | 758 | return -ENXIO; |
747 | 759 | ||