aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorBenjamin Thery <benjamin.thery@bull.net>2008-12-10 19:07:08 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-10 19:07:08 -0500
commitbd91b8bf372911c1e4d66d6bb44fe409349a6791 (patch)
tree18a79fc3c86ad833523562d7b73a9a557207b51b /net/ipv6
parent5eaa65b240c5eb7bf2235eb9dd177c83e6e3832c (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>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_output.c3
-rw-r--r--net/ipv6/ip6mr.c22
2 files changed, 12 insertions, 13 deletions
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
52struct 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