diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2012-12-03 20:13:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-04 13:08:10 -0500 |
commit | d67b8c616b48df30e2836d797795f2420d109bc9 (patch) | |
tree | e06b3f77e905e789def714958fcd455c8b3c037b /net | |
parent | e8ad1a8fab6f550aba1f1fe7ba26749ff5460751 (diff) |
netconf: advertise mc_forwarding status
This patch advertise the MC_FORWARDING status for IPv4 and IPv6.
This field is readonly, only multicast engine in the kernel updates it.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/devinet.c | 10 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 12 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 10 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 20 |
4 files changed, 46 insertions, 6 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index e13183abd7f6..cc06a47f1216 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1453,6 +1453,8 @@ static int inet_netconf_msgsize_devconf(int type) | |||
1453 | size += nla_total_size(4); | 1453 | size += nla_total_size(4); |
1454 | if (type == -1 || type == NETCONFA_RP_FILTER) | 1454 | if (type == -1 || type == NETCONFA_RP_FILTER) |
1455 | size += nla_total_size(4); | 1455 | size += nla_total_size(4); |
1456 | if (type == -1 || type == NETCONFA_MC_FORWARDING) | ||
1457 | size += nla_total_size(4); | ||
1456 | 1458 | ||
1457 | return size; | 1459 | return size; |
1458 | } | 1460 | } |
@@ -1485,6 +1487,10 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex, | |||
1485 | nla_put_s32(skb, NETCONFA_RP_FILTER, | 1487 | nla_put_s32(skb, NETCONFA_RP_FILTER, |
1486 | IPV4_DEVCONF(*devconf, RP_FILTER)) < 0) | 1488 | IPV4_DEVCONF(*devconf, RP_FILTER)) < 0) |
1487 | goto nla_put_failure; | 1489 | goto nla_put_failure; |
1490 | if ((type == -1 || type == NETCONFA_MC_FORWARDING) && | ||
1491 | nla_put_s32(skb, NETCONFA_MC_FORWARDING, | ||
1492 | IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0) | ||
1493 | goto nla_put_failure; | ||
1488 | 1494 | ||
1489 | return nlmsg_end(skb, nlh); | 1495 | return nlmsg_end(skb, nlh); |
1490 | 1496 | ||
@@ -1493,8 +1499,8 @@ nla_put_failure: | |||
1493 | return -EMSGSIZE; | 1499 | return -EMSGSIZE; |
1494 | } | 1500 | } |
1495 | 1501 | ||
1496 | static void inet_netconf_notify_devconf(struct net *net, int type, int ifindex, | 1502 | void inet_netconf_notify_devconf(struct net *net, int type, int ifindex, |
1497 | struct ipv4_devconf *devconf) | 1503 | struct ipv4_devconf *devconf) |
1498 | { | 1504 | { |
1499 | struct sk_buff *skb; | 1505 | struct sk_buff *skb; |
1500 | int err = -ENOBUFS; | 1506 | int err = -ENOBUFS; |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 58e4160fdcee..0c452e3fdc1b 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include <net/checksum.h> | 65 | #include <net/checksum.h> |
66 | #include <net/netlink.h> | 66 | #include <net/netlink.h> |
67 | #include <net/fib_rules.h> | 67 | #include <net/fib_rules.h> |
68 | #include <linux/netconf.h> | ||
68 | 69 | ||
69 | #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) | 70 | #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) |
70 | #define CONFIG_IP_PIMSM 1 | 71 | #define CONFIG_IP_PIMSM 1 |
@@ -582,6 +583,9 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify, | |||
582 | in_dev = __in_dev_get_rtnl(dev); | 583 | in_dev = __in_dev_get_rtnl(dev); |
583 | if (in_dev) { | 584 | if (in_dev) { |
584 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; | 585 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; |
586 | inet_netconf_notify_devconf(dev_net(dev), | ||
587 | NETCONFA_MC_FORWARDING, | ||
588 | dev->ifindex, &in_dev->cnf); | ||
585 | ip_rt_multicast_event(in_dev); | 589 | ip_rt_multicast_event(in_dev); |
586 | } | 590 | } |
587 | 591 | ||
@@ -772,6 +776,8 @@ static int vif_add(struct net *net, struct mr_table *mrt, | |||
772 | return -EADDRNOTAVAIL; | 776 | return -EADDRNOTAVAIL; |
773 | } | 777 | } |
774 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; | 778 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
779 | inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, dev->ifindex, | ||
780 | &in_dev->cnf); | ||
775 | ip_rt_multicast_event(in_dev); | 781 | ip_rt_multicast_event(in_dev); |
776 | 782 | ||
777 | /* Fill in the VIF structures */ | 783 | /* Fill in the VIF structures */ |
@@ -1185,6 +1191,9 @@ static void mrtsock_destruct(struct sock *sk) | |||
1185 | ipmr_for_each_table(mrt, net) { | 1191 | ipmr_for_each_table(mrt, net) { |
1186 | if (sk == rtnl_dereference(mrt->mroute_sk)) { | 1192 | if (sk == rtnl_dereference(mrt->mroute_sk)) { |
1187 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; | 1193 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; |
1194 | inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, | ||
1195 | NETCONFA_IFINDEX_ALL, | ||
1196 | net->ipv4.devconf_all); | ||
1188 | RCU_INIT_POINTER(mrt->mroute_sk, NULL); | 1197 | RCU_INIT_POINTER(mrt->mroute_sk, NULL); |
1189 | mroute_clean_tables(mrt); | 1198 | mroute_clean_tables(mrt); |
1190 | } | 1199 | } |
@@ -1236,6 +1245,9 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi | |||
1236 | if (ret == 0) { | 1245 | if (ret == 0) { |
1237 | rcu_assign_pointer(mrt->mroute_sk, sk); | 1246 | rcu_assign_pointer(mrt->mroute_sk, sk); |
1238 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)++; | 1247 | IPV4_DEVCONF_ALL(net, MC_FORWARDING)++; |
1248 | inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, | ||
1249 | NETCONFA_IFINDEX_ALL, | ||
1250 | net->ipv4.devconf_all); | ||
1239 | } | 1251 | } |
1240 | rtnl_unlock(); | 1252 | rtnl_unlock(); |
1241 | return ret; | 1253 | return ret; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 22ae75d54017..28e0e627229c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -469,6 +469,8 @@ static int inet6_netconf_msgsize_devconf(int type) | |||
469 | /* type -1 is used for ALL */ | 469 | /* type -1 is used for ALL */ |
470 | if (type == -1 || type == NETCONFA_FORWARDING) | 470 | if (type == -1 || type == NETCONFA_FORWARDING) |
471 | size += nla_total_size(4); | 471 | size += nla_total_size(4); |
472 | if (type == -1 || type == NETCONFA_MC_FORWARDING) | ||
473 | size += nla_total_size(4); | ||
472 | 474 | ||
473 | return size; | 475 | return size; |
474 | } | 476 | } |
@@ -496,6 +498,10 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex, | |||
496 | if ((type == -1 || type == NETCONFA_FORWARDING) && | 498 | if ((type == -1 || type == NETCONFA_FORWARDING) && |
497 | nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0) | 499 | nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0) |
498 | goto nla_put_failure; | 500 | goto nla_put_failure; |
501 | if ((type == -1 || type == NETCONFA_MC_FORWARDING) && | ||
502 | nla_put_s32(skb, NETCONFA_MC_FORWARDING, | ||
503 | devconf->mc_forwarding) < 0) | ||
504 | goto nla_put_failure; | ||
499 | 505 | ||
500 | return nlmsg_end(skb, nlh); | 506 | return nlmsg_end(skb, nlh); |
501 | 507 | ||
@@ -504,8 +510,8 @@ nla_put_failure: | |||
504 | return -EMSGSIZE; | 510 | return -EMSGSIZE; |
505 | } | 511 | } |
506 | 512 | ||
507 | static void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex, | 513 | void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex, |
508 | struct ipv6_devconf *devconf) | 514 | struct ipv6_devconf *devconf) |
509 | { | 515 | { |
510 | struct sk_buff *skb; | 516 | struct sk_buff *skb; |
511 | int err = -ENOBUFS; | 517 | int err = -ENOBUFS; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 926ea544f499..1c05fe604d37 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/netfilter_ipv6.h> | 52 | #include <linux/netfilter_ipv6.h> |
53 | #include <linux/export.h> | 53 | #include <linux/export.h> |
54 | #include <net/ip6_checksum.h> | 54 | #include <net/ip6_checksum.h> |
55 | #include <linux/netconf.h> | ||
55 | 56 | ||
56 | struct mr6_table { | 57 | struct mr6_table { |
57 | struct list_head list; | 58 | struct list_head list; |
@@ -805,8 +806,12 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) | |||
805 | dev_set_allmulti(dev, -1); | 806 | dev_set_allmulti(dev, -1); |
806 | 807 | ||
807 | in6_dev = __in6_dev_get(dev); | 808 | in6_dev = __in6_dev_get(dev); |
808 | if (in6_dev) | 809 | if (in6_dev) { |
809 | in6_dev->cnf.mc_forwarding--; | 810 | in6_dev->cnf.mc_forwarding--; |
811 | inet6_netconf_notify_devconf(dev_net(dev), | ||
812 | NETCONFA_MC_FORWARDING, | ||
813 | dev->ifindex, &in6_dev->cnf); | ||
814 | } | ||
810 | 815 | ||
811 | if (v->flags & MIFF_REGISTER) | 816 | if (v->flags & MIFF_REGISTER) |
812 | unregister_netdevice_queue(dev, head); | 817 | unregister_netdevice_queue(dev, head); |
@@ -958,8 +963,12 @@ static int mif6_add(struct net *net, struct mr6_table *mrt, | |||
958 | } | 963 | } |
959 | 964 | ||
960 | in6_dev = __in6_dev_get(dev); | 965 | in6_dev = __in6_dev_get(dev); |
961 | if (in6_dev) | 966 | if (in6_dev) { |
962 | in6_dev->cnf.mc_forwarding++; | 967 | in6_dev->cnf.mc_forwarding++; |
968 | inet6_netconf_notify_devconf(dev_net(dev), | ||
969 | NETCONFA_MC_FORWARDING, | ||
970 | dev->ifindex, &in6_dev->cnf); | ||
971 | } | ||
963 | 972 | ||
964 | /* | 973 | /* |
965 | * Fill in the VIF structures | 974 | * Fill in the VIF structures |
@@ -1513,6 +1522,9 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk) | |||
1513 | if (likely(mrt->mroute6_sk == NULL)) { | 1522 | if (likely(mrt->mroute6_sk == NULL)) { |
1514 | mrt->mroute6_sk = sk; | 1523 | mrt->mroute6_sk = sk; |
1515 | net->ipv6.devconf_all->mc_forwarding++; | 1524 | net->ipv6.devconf_all->mc_forwarding++; |
1525 | inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, | ||
1526 | NETCONFA_IFINDEX_ALL, | ||
1527 | net->ipv6.devconf_all); | ||
1516 | } | 1528 | } |
1517 | else | 1529 | else |
1518 | err = -EADDRINUSE; | 1530 | err = -EADDRINUSE; |
@@ -1535,6 +1547,10 @@ int ip6mr_sk_done(struct sock *sk) | |||
1535 | write_lock_bh(&mrt_lock); | 1547 | write_lock_bh(&mrt_lock); |
1536 | mrt->mroute6_sk = NULL; | 1548 | mrt->mroute6_sk = NULL; |
1537 | net->ipv6.devconf_all->mc_forwarding--; | 1549 | net->ipv6.devconf_all->mc_forwarding--; |
1550 | inet6_netconf_notify_devconf(net, | ||
1551 | NETCONFA_MC_FORWARDING, | ||
1552 | NETCONFA_IFINDEX_ALL, | ||
1553 | net->ipv6.devconf_all); | ||
1538 | write_unlock_bh(&mrt_lock); | 1554 | write_unlock_bh(&mrt_lock); |
1539 | 1555 | ||
1540 | mroute_clean_tables(mrt); | 1556 | mroute_clean_tables(mrt); |