diff options
author | Benjamin Thery <benjamin.thery@bull.net> | 2008-12-10 19:07:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-10 19:07:08 -0500 |
commit | bd91b8bf372911c1e4d66d6bb44fe409349a6791 (patch) | |
tree | 18a79fc3c86ad833523562d7b73a9a557207b51b | |
parent | 5eaa65b240c5eb7bf2235eb9dd177c83e6e3832c (diff) |
netns: ip6mr: allocate mroute6_socket per-namespace.
Preliminary work to make IPv6 multicast forwarding netns-aware.
Make IPv6 multicast forwarding mroute6_socket per-namespace,
moves it into struct netns_ipv6.
At the moment, mroute6_socket is only referenced in init_net.
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/mroute6.h | 8 | ||||
-rw-r--r-- | include/net/netns/ipv6.h | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 22 |
4 files changed, 21 insertions, 15 deletions
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index 6f4c180179e2..2cd9901ee5c7 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h | |||
@@ -117,6 +117,7 @@ struct sioc_mif_req6 | |||
117 | 117 | ||
118 | #include <linux/pim.h> | 118 | #include <linux/pim.h> |
119 | #include <linux/skbuff.h> /* for struct sk_buff_head */ | 119 | #include <linux/skbuff.h> /* for struct sk_buff_head */ |
120 | #include <net/net_namespace.h> | ||
120 | 121 | ||
121 | #ifdef CONFIG_IPV6_MROUTE | 122 | #ifdef CONFIG_IPV6_MROUTE |
122 | static inline int ip6_mroute_opt(int opt) | 123 | static inline int ip6_mroute_opt(int opt) |
@@ -232,10 +233,13 @@ struct rtmsg; | |||
232 | extern int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait); | 233 | extern int ip6mr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait); |
233 | 234 | ||
234 | #ifdef CONFIG_IPV6_MROUTE | 235 | #ifdef CONFIG_IPV6_MROUTE |
235 | extern struct sock *mroute6_socket; | 236 | static inline struct sock *mroute6_socket(struct net *net) |
237 | { | ||
238 | return net->ipv6.mroute6_sk; | ||
239 | } | ||
236 | extern int ip6mr_sk_done(struct sock *sk); | 240 | extern int ip6mr_sk_done(struct sock *sk); |
237 | #else | 241 | #else |
238 | #define mroute6_socket NULL | 242 | static inline struct sock *mroute6_socket(struct net *net) { return NULL; } |
239 | static inline int ip6mr_sk_done(struct sock *sk) { return 0; } | 243 | static inline int ip6mr_sk_done(struct sock *sk) { return 0; } |
240 | #endif | 244 | #endif |
241 | #endif | 245 | #endif |
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 2932721180c0..8a0a67d073b3 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h | |||
@@ -55,5 +55,8 @@ struct netns_ipv6 { | |||
55 | struct sock *ndisc_sk; | 55 | struct sock *ndisc_sk; |
56 | struct sock *tcp_sk; | 56 | struct sock *tcp_sk; |
57 | struct sock *igmp_sk; | 57 | struct sock *igmp_sk; |
58 | #ifdef CONFIG_IPV6_MROUTE | ||
59 | struct sock *mroute6_sk; | ||
60 | #endif | ||
58 | }; | 61 | }; |
59 | #endif | 62 | #endif |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7d92fd97cfb9..4b15938bef4d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -137,7 +137,8 @@ static int ip6_output2(struct sk_buff *skb) | |||
137 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | 137 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); |
138 | 138 | ||
139 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && | 139 | if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && |
140 | ((mroute6_socket && !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || | 140 | ((mroute6_socket(dev_net(dev)) && |
141 | !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || | ||
141 | ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, | 142 | ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, |
142 | &ipv6_hdr(skb)->saddr))) { | 143 | &ipv6_hdr(skb)->saddr))) { |
143 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); | 144 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index d1008e6891e7..02163dbf84c3 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -49,9 +49,6 @@ | |||
49 | #include <net/addrconf.h> | 49 | #include <net/addrconf.h> |
50 | #include <linux/netfilter_ipv6.h> | 50 | #include <linux/netfilter_ipv6.h> |
51 | 51 | ||
52 | struct sock *mroute6_socket; | ||
53 | |||
54 | |||
55 | /* Big lock, protecting vif table, mrt cache and mroute socket state. | 52 | /* Big lock, protecting vif table, mrt cache and mroute socket state. |
56 | Note that the changes are semaphored via rtnl_lock. | 53 | Note that the changes are semaphored via rtnl_lock. |
57 | */ | 54 | */ |
@@ -820,7 +817,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
820 | skb_pull(skb, sizeof(struct ipv6hdr)); | 817 | skb_pull(skb, sizeof(struct ipv6hdr)); |
821 | } | 818 | } |
822 | 819 | ||
823 | if (mroute6_socket == NULL) { | 820 | if (init_net.ipv6.mroute6_sk == NULL) { |
824 | kfree_skb(skb); | 821 | kfree_skb(skb); |
825 | return -EINVAL; | 822 | return -EINVAL; |
826 | } | 823 | } |
@@ -828,7 +825,8 @@ static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert) | |||
828 | /* | 825 | /* |
829 | * Deliver to user space multicast routing algorithms | 826 | * Deliver to user space multicast routing algorithms |
830 | */ | 827 | */ |
831 | if ((ret = sock_queue_rcv_skb(mroute6_socket, skb)) < 0) { | 828 | ret = sock_queue_rcv_skb(init_net.ipv6.mroute6_sk, skb); |
829 | if (ret < 0) { | ||
832 | if (net_ratelimit()) | 830 | if (net_ratelimit()) |
833 | printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); | 831 | printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); |
834 | kfree_skb(skb); | 832 | kfree_skb(skb); |
@@ -1145,8 +1143,8 @@ static int ip6mr_sk_init(struct sock *sk) | |||
1145 | 1143 | ||
1146 | rtnl_lock(); | 1144 | rtnl_lock(); |
1147 | write_lock_bh(&mrt_lock); | 1145 | write_lock_bh(&mrt_lock); |
1148 | if (likely(mroute6_socket == NULL)) | 1146 | if (likely(init_net.ipv6.mroute6_sk == NULL)) |
1149 | mroute6_socket = sk; | 1147 | init_net.ipv6.mroute6_sk = sk; |
1150 | else | 1148 | else |
1151 | err = -EADDRINUSE; | 1149 | err = -EADDRINUSE; |
1152 | write_unlock_bh(&mrt_lock); | 1150 | write_unlock_bh(&mrt_lock); |
@@ -1161,9 +1159,9 @@ int ip6mr_sk_done(struct sock *sk) | |||
1161 | int err = 0; | 1159 | int err = 0; |
1162 | 1160 | ||
1163 | rtnl_lock(); | 1161 | rtnl_lock(); |
1164 | if (sk == mroute6_socket) { | 1162 | if (sk == init_net.ipv6.mroute6_sk) { |
1165 | write_lock_bh(&mrt_lock); | 1163 | write_lock_bh(&mrt_lock); |
1166 | mroute6_socket = NULL; | 1164 | init_net.ipv6.mroute6_sk = NULL; |
1167 | write_unlock_bh(&mrt_lock); | 1165 | write_unlock_bh(&mrt_lock); |
1168 | 1166 | ||
1169 | mroute_clean_tables(sk); | 1167 | mroute_clean_tables(sk); |
@@ -1189,7 +1187,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1189 | mifi_t mifi; | 1187 | mifi_t mifi; |
1190 | 1188 | ||
1191 | if (optname != MRT6_INIT) { | 1189 | if (optname != MRT6_INIT) { |
1192 | if (sk != mroute6_socket && !capable(CAP_NET_ADMIN)) | 1190 | if (sk != init_net.ipv6.mroute6_sk && !capable(CAP_NET_ADMIN)) |
1193 | return -EACCES; | 1191 | return -EACCES; |
1194 | } | 1192 | } |
1195 | 1193 | ||
@@ -1214,7 +1212,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1214 | if (vif.mif6c_mifi >= MAXMIFS) | 1212 | if (vif.mif6c_mifi >= MAXMIFS) |
1215 | return -ENFILE; | 1213 | return -ENFILE; |
1216 | rtnl_lock(); | 1214 | rtnl_lock(); |
1217 | ret = mif6_add(&vif, sk == mroute6_socket); | 1215 | ret = mif6_add(&vif, sk == init_net.ipv6.mroute6_sk); |
1218 | rtnl_unlock(); | 1216 | rtnl_unlock(); |
1219 | return ret; | 1217 | return ret; |
1220 | 1218 | ||
@@ -1242,7 +1240,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1242 | if (optname == MRT6_DEL_MFC) | 1240 | if (optname == MRT6_DEL_MFC) |
1243 | ret = ip6mr_mfc_delete(&mfc); | 1241 | ret = ip6mr_mfc_delete(&mfc); |
1244 | else | 1242 | else |
1245 | ret = ip6mr_mfc_add(&mfc, sk == mroute6_socket); | 1243 | ret = ip6mr_mfc_add(&mfc, sk == init_net.ipv6.mroute6_sk); |
1246 | rtnl_unlock(); | 1244 | rtnl_unlock(); |
1247 | return ret; | 1245 | return ret; |
1248 | 1246 | ||