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>
This commit is contained in:
parent
e8ad1a8fab
commit
d67b8c616b
@ -171,6 +171,9 @@ struct in_ifaddr {
|
|||||||
extern int register_inetaddr_notifier(struct notifier_block *nb);
|
extern int register_inetaddr_notifier(struct notifier_block *nb);
|
||||||
extern int unregister_inetaddr_notifier(struct notifier_block *nb);
|
extern int unregister_inetaddr_notifier(struct notifier_block *nb);
|
||||||
|
|
||||||
|
extern void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||||
|
struct ipv4_devconf *devconf);
|
||||||
|
|
||||||
extern struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref);
|
extern struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref);
|
||||||
static inline struct net_device *ip_dev_find(struct net *net, __be32 addr)
|
static inline struct net_device *ip_dev_find(struct net *net, __be32 addr)
|
||||||
{
|
{
|
||||||
|
@ -172,6 +172,9 @@ extern bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
|
|||||||
extern int register_inet6addr_notifier(struct notifier_block *nb);
|
extern int register_inet6addr_notifier(struct notifier_block *nb);
|
||||||
extern int unregister_inet6addr_notifier(struct notifier_block *nb);
|
extern int unregister_inet6addr_notifier(struct notifier_block *nb);
|
||||||
|
|
||||||
|
extern void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||||
|
struct ipv6_devconf *devconf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __in6_dev_get - get inet6_dev pointer from netdevice
|
* __in6_dev_get - get inet6_dev pointer from netdevice
|
||||||
* @dev: network device
|
* @dev: network device
|
||||||
|
@ -13,6 +13,7 @@ enum {
|
|||||||
NETCONFA_IFINDEX,
|
NETCONFA_IFINDEX,
|
||||||
NETCONFA_FORWARDING,
|
NETCONFA_FORWARDING,
|
||||||
NETCONFA_RP_FILTER,
|
NETCONFA_RP_FILTER,
|
||||||
|
NETCONFA_MC_FORWARDING,
|
||||||
__NETCONFA_MAX
|
__NETCONFA_MAX
|
||||||
};
|
};
|
||||||
#define NETCONFA_MAX (__NETCONFA_MAX - 1)
|
#define NETCONFA_MAX (__NETCONFA_MAX - 1)
|
||||||
|
@ -1453,6 +1453,8 @@ static int inet_netconf_msgsize_devconf(int type)
|
|||||||
size += nla_total_size(4);
|
size += nla_total_size(4);
|
||||||
if (type == -1 || type == NETCONFA_RP_FILTER)
|
if (type == -1 || type == NETCONFA_RP_FILTER)
|
||||||
size += nla_total_size(4);
|
size += nla_total_size(4);
|
||||||
|
if (type == -1 || type == NETCONFA_MC_FORWARDING)
|
||||||
|
size += nla_total_size(4);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -1485,6 +1487,10 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
|||||||
nla_put_s32(skb, NETCONFA_RP_FILTER,
|
nla_put_s32(skb, NETCONFA_RP_FILTER,
|
||||||
IPV4_DEVCONF(*devconf, RP_FILTER)) < 0)
|
IPV4_DEVCONF(*devconf, RP_FILTER)) < 0)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
if ((type == -1 || type == NETCONFA_MC_FORWARDING) &&
|
||||||
|
nla_put_s32(skb, NETCONFA_MC_FORWARDING,
|
||||||
|
IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0)
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
return nlmsg_end(skb, nlh);
|
return nlmsg_end(skb, nlh);
|
||||||
|
|
||||||
@ -1493,8 +1499,8 @@ nla_put_failure:
|
|||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||||
struct ipv4_devconf *devconf)
|
struct ipv4_devconf *devconf)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int err = -ENOBUFS;
|
int err = -ENOBUFS;
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
#include <net/fib_rules.h>
|
#include <net/fib_rules.h>
|
||||||
|
#include <linux/netconf.h>
|
||||||
|
|
||||||
#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
|
#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
|
||||||
#define CONFIG_IP_PIMSM 1
|
#define CONFIG_IP_PIMSM 1
|
||||||
@ -582,6 +583,9 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
|
|||||||
in_dev = __in_dev_get_rtnl(dev);
|
in_dev = __in_dev_get_rtnl(dev);
|
||||||
if (in_dev) {
|
if (in_dev) {
|
||||||
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
|
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
|
||||||
|
inet_netconf_notify_devconf(dev_net(dev),
|
||||||
|
NETCONFA_MC_FORWARDING,
|
||||||
|
dev->ifindex, &in_dev->cnf);
|
||||||
ip_rt_multicast_event(in_dev);
|
ip_rt_multicast_event(in_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,6 +776,8 @@ static int vif_add(struct net *net, struct mr_table *mrt,
|
|||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
}
|
}
|
||||||
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
|
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
|
||||||
|
inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, dev->ifindex,
|
||||||
|
&in_dev->cnf);
|
||||||
ip_rt_multicast_event(in_dev);
|
ip_rt_multicast_event(in_dev);
|
||||||
|
|
||||||
/* Fill in the VIF structures */
|
/* Fill in the VIF structures */
|
||||||
@ -1185,6 +1191,9 @@ static void mrtsock_destruct(struct sock *sk)
|
|||||||
ipmr_for_each_table(mrt, net) {
|
ipmr_for_each_table(mrt, net) {
|
||||||
if (sk == rtnl_dereference(mrt->mroute_sk)) {
|
if (sk == rtnl_dereference(mrt->mroute_sk)) {
|
||||||
IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
|
IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
|
||||||
|
inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||||
|
NETCONFA_IFINDEX_ALL,
|
||||||
|
net->ipv4.devconf_all);
|
||||||
RCU_INIT_POINTER(mrt->mroute_sk, NULL);
|
RCU_INIT_POINTER(mrt->mroute_sk, NULL);
|
||||||
mroute_clean_tables(mrt);
|
mroute_clean_tables(mrt);
|
||||||
}
|
}
|
||||||
@ -1236,6 +1245,9 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
rcu_assign_pointer(mrt->mroute_sk, sk);
|
rcu_assign_pointer(mrt->mroute_sk, sk);
|
||||||
IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
|
IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
|
||||||
|
inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||||
|
NETCONFA_IFINDEX_ALL,
|
||||||
|
net->ipv4.devconf_all);
|
||||||
}
|
}
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -469,6 +469,8 @@ static int inet6_netconf_msgsize_devconf(int type)
|
|||||||
/* type -1 is used for ALL */
|
/* type -1 is used for ALL */
|
||||||
if (type == -1 || type == NETCONFA_FORWARDING)
|
if (type == -1 || type == NETCONFA_FORWARDING)
|
||||||
size += nla_total_size(4);
|
size += nla_total_size(4);
|
||||||
|
if (type == -1 || type == NETCONFA_MC_FORWARDING)
|
||||||
|
size += nla_total_size(4);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -496,6 +498,10 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
|||||||
if ((type == -1 || type == NETCONFA_FORWARDING) &&
|
if ((type == -1 || type == NETCONFA_FORWARDING) &&
|
||||||
nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
|
nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
if ((type == -1 || type == NETCONFA_MC_FORWARDING) &&
|
||||||
|
nla_put_s32(skb, NETCONFA_MC_FORWARDING,
|
||||||
|
devconf->mc_forwarding) < 0)
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
return nlmsg_end(skb, nlh);
|
return nlmsg_end(skb, nlh);
|
||||||
|
|
||||||
@ -504,8 +510,8 @@ nla_put_failure:
|
|||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||||
struct ipv6_devconf *devconf)
|
struct ipv6_devconf *devconf)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int err = -ENOBUFS;
|
int err = -ENOBUFS;
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <linux/netfilter_ipv6.h>
|
#include <linux/netfilter_ipv6.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <net/ip6_checksum.h>
|
#include <net/ip6_checksum.h>
|
||||||
|
#include <linux/netconf.h>
|
||||||
|
|
||||||
struct mr6_table {
|
struct mr6_table {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@ -805,8 +806,12 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
|
|||||||
dev_set_allmulti(dev, -1);
|
dev_set_allmulti(dev, -1);
|
||||||
|
|
||||||
in6_dev = __in6_dev_get(dev);
|
in6_dev = __in6_dev_get(dev);
|
||||||
if (in6_dev)
|
if (in6_dev) {
|
||||||
in6_dev->cnf.mc_forwarding--;
|
in6_dev->cnf.mc_forwarding--;
|
||||||
|
inet6_netconf_notify_devconf(dev_net(dev),
|
||||||
|
NETCONFA_MC_FORWARDING,
|
||||||
|
dev->ifindex, &in6_dev->cnf);
|
||||||
|
}
|
||||||
|
|
||||||
if (v->flags & MIFF_REGISTER)
|
if (v->flags & MIFF_REGISTER)
|
||||||
unregister_netdevice_queue(dev, head);
|
unregister_netdevice_queue(dev, head);
|
||||||
@ -958,8 +963,12 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
in6_dev = __in6_dev_get(dev);
|
in6_dev = __in6_dev_get(dev);
|
||||||
if (in6_dev)
|
if (in6_dev) {
|
||||||
in6_dev->cnf.mc_forwarding++;
|
in6_dev->cnf.mc_forwarding++;
|
||||||
|
inet6_netconf_notify_devconf(dev_net(dev),
|
||||||
|
NETCONFA_MC_FORWARDING,
|
||||||
|
dev->ifindex, &in6_dev->cnf);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill in the VIF structures
|
* Fill in the VIF structures
|
||||||
@ -1513,6 +1522,9 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
|
|||||||
if (likely(mrt->mroute6_sk == NULL)) {
|
if (likely(mrt->mroute6_sk == NULL)) {
|
||||||
mrt->mroute6_sk = sk;
|
mrt->mroute6_sk = sk;
|
||||||
net->ipv6.devconf_all->mc_forwarding++;
|
net->ipv6.devconf_all->mc_forwarding++;
|
||||||
|
inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||||
|
NETCONFA_IFINDEX_ALL,
|
||||||
|
net->ipv6.devconf_all);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err = -EADDRINUSE;
|
err = -EADDRINUSE;
|
||||||
@ -1535,6 +1547,10 @@ int ip6mr_sk_done(struct sock *sk)
|
|||||||
write_lock_bh(&mrt_lock);
|
write_lock_bh(&mrt_lock);
|
||||||
mrt->mroute6_sk = NULL;
|
mrt->mroute6_sk = NULL;
|
||||||
net->ipv6.devconf_all->mc_forwarding--;
|
net->ipv6.devconf_all->mc_forwarding--;
|
||||||
|
inet6_netconf_notify_devconf(net,
|
||||||
|
NETCONFA_MC_FORWARDING,
|
||||||
|
NETCONFA_IFINDEX_ALL,
|
||||||
|
net->ipv6.devconf_all);
|
||||||
write_unlock_bh(&mrt_lock);
|
write_unlock_bh(&mrt_lock);
|
||||||
|
|
||||||
mroute_clean_tables(mrt);
|
mroute_clean_tables(mrt);
|
||||||
|
Loading…
Reference in New Issue
Block a user