diff options
author | Tom Goff <thomas.goff@boeing.com> | 2009-06-14 06:16:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-14 06:16:13 -0400 |
commit | 403dbb97f654cd59b87999fe1b64d29bf90b3a2a (patch) | |
tree | c8d4ea1152288792f5e6bde54e79497dcfd44a9e /net | |
parent | e61a4b634a15c11725eac8e66b457ba411168c7f (diff) |
PIM-SM: namespace changes
IPv4:
- make PIM register vifs netns local
- set the netns when a PIM register vif is created
- make PIM available in all network namespaces (if CONFIG_IP_PIMSM_V2)
by adding the protocol handler when multicast routing is initialized
IPv6:
- make PIM register vifs netns local
- make PIM available in all network namespaces (if CONFIG_IPV6_PIMSM_V2)
by adding the protocol handler when multicast routing is initialized
Signed-off-by: Tom Goff <thomas.goff@boeing.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ipmr.c | 29 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 20 |
2 files changed, 29 insertions, 20 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index ffd986104468..9a8da5ed92b7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -226,9 +226,10 @@ static void reg_vif_setup(struct net_device *dev) | |||
226 | dev->flags = IFF_NOARP; | 226 | dev->flags = IFF_NOARP; |
227 | dev->netdev_ops = ®_vif_netdev_ops, | 227 | dev->netdev_ops = ®_vif_netdev_ops, |
228 | dev->destructor = free_netdev; | 228 | dev->destructor = free_netdev; |
229 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static struct net_device *ipmr_reg_vif(void) | 232 | static struct net_device *ipmr_reg_vif(struct net *net) |
232 | { | 233 | { |
233 | struct net_device *dev; | 234 | struct net_device *dev; |
234 | struct in_device *in_dev; | 235 | struct in_device *in_dev; |
@@ -238,6 +239,8 @@ static struct net_device *ipmr_reg_vif(void) | |||
238 | if (dev == NULL) | 239 | if (dev == NULL) |
239 | return NULL; | 240 | return NULL; |
240 | 241 | ||
242 | dev_net_set(dev, net); | ||
243 | |||
241 | if (register_netdevice(dev)) { | 244 | if (register_netdevice(dev)) { |
242 | free_netdev(dev); | 245 | free_netdev(dev); |
243 | return NULL; | 246 | return NULL; |
@@ -448,7 +451,7 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
448 | */ | 451 | */ |
449 | if (net->ipv4.mroute_reg_vif_num >= 0) | 452 | if (net->ipv4.mroute_reg_vif_num >= 0) |
450 | return -EADDRINUSE; | 453 | return -EADDRINUSE; |
451 | dev = ipmr_reg_vif(); | 454 | dev = ipmr_reg_vif(net); |
452 | if (!dev) | 455 | if (!dev) |
453 | return -ENOBUFS; | 456 | return -ENOBUFS; |
454 | err = dev_set_allmulti(dev, 1); | 457 | err = dev_set_allmulti(dev, 1); |
@@ -1031,16 +1034,6 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1031 | if (v != net->ipv4.mroute_do_pim) { | 1034 | if (v != net->ipv4.mroute_do_pim) { |
1032 | net->ipv4.mroute_do_pim = v; | 1035 | net->ipv4.mroute_do_pim = v; |
1033 | net->ipv4.mroute_do_assert = v; | 1036 | net->ipv4.mroute_do_assert = v; |
1034 | #ifdef CONFIG_IP_PIMSM_V2 | ||
1035 | if (net->ipv4.mroute_do_pim) | ||
1036 | ret = inet_add_protocol(&pim_protocol, | ||
1037 | IPPROTO_PIM); | ||
1038 | else | ||
1039 | ret = inet_del_protocol(&pim_protocol, | ||
1040 | IPPROTO_PIM); | ||
1041 | if (ret < 0) | ||
1042 | ret = -EAGAIN; | ||
1043 | #endif | ||
1044 | } | 1037 | } |
1045 | rtnl_unlock(); | 1038 | rtnl_unlock(); |
1046 | return ret; | 1039 | return ret; |
@@ -1954,6 +1947,7 @@ static const struct file_operations ipmr_mfc_fops = { | |||
1954 | #ifdef CONFIG_IP_PIMSM_V2 | 1947 | #ifdef CONFIG_IP_PIMSM_V2 |
1955 | static struct net_protocol pim_protocol = { | 1948 | static struct net_protocol pim_protocol = { |
1956 | .handler = pim_rcv, | 1949 | .handler = pim_rcv, |
1950 | .netns_ok = 1, | ||
1957 | }; | 1951 | }; |
1958 | #endif | 1952 | #endif |
1959 | 1953 | ||
@@ -2040,8 +2034,19 @@ int __init ip_mr_init(void) | |||
2040 | err = register_netdevice_notifier(&ip_mr_notifier); | 2034 | err = register_netdevice_notifier(&ip_mr_notifier); |
2041 | if (err) | 2035 | if (err) |
2042 | goto reg_notif_fail; | 2036 | goto reg_notif_fail; |
2037 | #ifdef CONFIG_IP_PIMSM_V2 | ||
2038 | if (inet_add_protocol(&pim_protocol, IPPROTO_PIM) < 0) { | ||
2039 | printk(KERN_ERR "ip_mr_init: can't add PIM protocol\n"); | ||
2040 | err = -EAGAIN; | ||
2041 | goto add_proto_fail; | ||
2042 | } | ||
2043 | #endif | ||
2043 | return 0; | 2044 | return 0; |
2044 | 2045 | ||
2046 | #ifdef CONFIG_IP_PIMSM_V2 | ||
2047 | add_proto_fail: | ||
2048 | unregister_netdevice_notifier(&ip_mr_notifier); | ||
2049 | #endif | ||
2045 | reg_notif_fail: | 2050 | reg_notif_fail: |
2046 | del_timer(&ipmr_expire_timer); | 2051 | del_timer(&ipmr_expire_timer); |
2047 | unregister_pernet_subsys(&ipmr_net_ops); | 2052 | unregister_pernet_subsys(&ipmr_net_ops); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index a35d8fc55b04..c769f155c698 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -441,6 +441,7 @@ static void reg_vif_setup(struct net_device *dev) | |||
441 | dev->flags = IFF_NOARP; | 441 | dev->flags = IFF_NOARP; |
442 | dev->netdev_ops = ®_vif_netdev_ops; | 442 | dev->netdev_ops = ®_vif_netdev_ops; |
443 | dev->destructor = free_netdev; | 443 | dev->destructor = free_netdev; |
444 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
444 | } | 445 | } |
445 | 446 | ||
446 | static struct net_device *ip6mr_reg_vif(struct net *net) | 447 | static struct net_device *ip6mr_reg_vif(struct net *net) |
@@ -1077,7 +1078,18 @@ int __init ip6_mr_init(void) | |||
1077 | err = register_netdevice_notifier(&ip6_mr_notifier); | 1078 | err = register_netdevice_notifier(&ip6_mr_notifier); |
1078 | if (err) | 1079 | if (err) |
1079 | goto reg_notif_fail; | 1080 | goto reg_notif_fail; |
1081 | #ifdef CONFIG_IPV6_PIMSM_V2 | ||
1082 | if (inet6_add_protocol(&pim6_protocol, IPPROTO_PIM) < 0) { | ||
1083 | printk(KERN_ERR "ip6_mr_init: can't add PIM protocol\n"); | ||
1084 | err = -EAGAIN; | ||
1085 | goto add_proto_fail; | ||
1086 | } | ||
1087 | #endif | ||
1080 | return 0; | 1088 | return 0; |
1089 | #ifdef CONFIG_IPV6_PIMSM_V2 | ||
1090 | add_proto_fail: | ||
1091 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
1092 | #endif | ||
1081 | reg_notif_fail: | 1093 | reg_notif_fail: |
1082 | del_timer(&ipmr_expire_timer); | 1094 | del_timer(&ipmr_expire_timer); |
1083 | unregister_pernet_subsys(&ip6mr_net_ops); | 1095 | unregister_pernet_subsys(&ip6mr_net_ops); |
@@ -1363,14 +1375,6 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1363 | if (v != net->ipv6.mroute_do_pim) { | 1375 | if (v != net->ipv6.mroute_do_pim) { |
1364 | net->ipv6.mroute_do_pim = v; | 1376 | net->ipv6.mroute_do_pim = v; |
1365 | net->ipv6.mroute_do_assert = v; | 1377 | net->ipv6.mroute_do_assert = v; |
1366 | if (net->ipv6.mroute_do_pim) | ||
1367 | ret = inet6_add_protocol(&pim6_protocol, | ||
1368 | IPPROTO_PIM); | ||
1369 | else | ||
1370 | ret = inet6_del_protocol(&pim6_protocol, | ||
1371 | IPPROTO_PIM); | ||
1372 | if (ret < 0) | ||
1373 | ret = -EAGAIN; | ||
1374 | } | 1378 | } |
1375 | rtnl_unlock(); | 1379 | rtnl_unlock(); |
1376 | return ret; | 1380 | return ret; |