forked from Minki/linux
Merge branch 'netconf-delnetconf'
David Ahern says: ==================== netconf: Add support for RTM_DELNETCONF netconf notifications are sent as devices register but not when they are deleted leaving userspace caches out of sync. Add support for RTM_DELNETCONF to ipv4, ipv6 and mpls. MPLS is missing RTM_NEWNETCONF as devices are created, so add it as well. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
0e42c72195
@ -153,8 +153,8 @@ struct in_ifaddr {
|
||||
int register_inetaddr_notifier(struct notifier_block *nb);
|
||||
int unregister_inetaddr_notifier(struct notifier_block *nb);
|
||||
|
||||
void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||
struct ipv4_devconf *devconf);
|
||||
void inet_netconf_notify_devconf(struct net *net, int event, int type,
|
||||
int ifindex, struct ipv4_devconf *devconf);
|
||||
|
||||
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)
|
||||
|
@ -262,8 +262,8 @@ int register_inet6addr_notifier(struct notifier_block *nb);
|
||||
int unregister_inet6addr_notifier(struct notifier_block *nb);
|
||||
int inet6addr_notifier_call_chain(unsigned long val, void *v);
|
||||
|
||||
void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||
struct ipv6_devconf *devconf);
|
||||
void inet6_netconf_notify_devconf(struct net *net, int event, int type,
|
||||
int ifindex, struct ipv6_devconf *devconf);
|
||||
|
||||
/**
|
||||
* __in6_dev_get - get inet6_dev pointer from netdevice
|
||||
|
@ -122,6 +122,8 @@ enum {
|
||||
|
||||
RTM_NEWNETCONF = 80,
|
||||
#define RTM_NEWNETCONF RTM_NEWNETCONF
|
||||
RTM_DELNETCONF,
|
||||
#define RTM_DELNETCONF RTM_DELNETCONF
|
||||
RTM_GETNETCONF = 82,
|
||||
#define RTM_GETNETCONF RTM_GETNETCONF
|
||||
|
||||
|
@ -1802,6 +1802,9 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
||||
if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (!devconf)
|
||||
goto out;
|
||||
|
||||
if ((all || type == NETCONFA_FORWARDING) &&
|
||||
nla_put_s32(skb, NETCONFA_FORWARDING,
|
||||
IPV4_DEVCONF(*devconf, FORWARDING)) < 0)
|
||||
@ -1823,6 +1826,7 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
||||
IPV4_DEVCONF(*devconf, IGNORE_ROUTES_WITH_LINKDOWN)) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
out:
|
||||
nlmsg_end(skb, nlh);
|
||||
return 0;
|
||||
|
||||
@ -1831,8 +1835,8 @@ nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||
struct ipv4_devconf *devconf)
|
||||
void inet_netconf_notify_devconf(struct net *net, int event, int type,
|
||||
int ifindex, struct ipv4_devconf *devconf)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err = -ENOBUFS;
|
||||
@ -1842,7 +1846,7 @@ void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||
goto errout;
|
||||
|
||||
err = inet_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
|
||||
RTM_NEWNETCONF, 0, type);
|
||||
event, 0, type);
|
||||
if (err < 0) {
|
||||
/* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */
|
||||
WARN_ON(err == -EMSGSIZE);
|
||||
@ -2021,10 +2025,12 @@ static void inet_forward_change(struct net *net)
|
||||
|
||||
IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
|
||||
IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
|
||||
inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv4.devconf_all);
|
||||
inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv4.devconf_dflt);
|
||||
|
||||
@ -2037,7 +2043,8 @@ static void inet_forward_change(struct net *net)
|
||||
in_dev = __in_dev_get_rtnl(dev);
|
||||
if (in_dev) {
|
||||
IN_DEV_CONF_SET(in_dev, FORWARDING, on);
|
||||
inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
dev->ifindex, &in_dev->cnf);
|
||||
}
|
||||
}
|
||||
@ -2082,19 +2089,22 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
|
||||
if (i == IPV4_DEVCONF_RP_FILTER - 1 &&
|
||||
new_value != old_value) {
|
||||
ifindex = devinet_conf_ifindex(net, cnf);
|
||||
inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_RP_FILTER,
|
||||
ifindex, cnf);
|
||||
}
|
||||
if (i == IPV4_DEVCONF_PROXY_ARP - 1 &&
|
||||
new_value != old_value) {
|
||||
ifindex = devinet_conf_ifindex(net, cnf);
|
||||
inet_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_PROXY_NEIGH,
|
||||
ifindex, cnf);
|
||||
}
|
||||
if (i == IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN - 1 &&
|
||||
new_value != old_value) {
|
||||
ifindex = devinet_conf_ifindex(net, cnf);
|
||||
inet_netconf_notify_devconf(net, NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
ifindex, cnf);
|
||||
}
|
||||
}
|
||||
@ -2129,7 +2139,7 @@ static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
|
||||
container_of(cnf, struct in_device, cnf);
|
||||
if (*valp)
|
||||
dev_disable_lro(idev->dev);
|
||||
inet_netconf_notify_devconf(net,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
idev->dev->ifindex,
|
||||
cnf);
|
||||
@ -2137,7 +2147,8 @@ static int devinet_sysctl_forward(struct ctl_table *ctl, int write,
|
||||
rtnl_unlock();
|
||||
rt_cache_flush(net);
|
||||
} else
|
||||
inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv4.devconf_dflt);
|
||||
}
|
||||
@ -2259,7 +2270,8 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
|
||||
|
||||
p->sysctl = t;
|
||||
|
||||
inet_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p);
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL,
|
||||
ifindex, p);
|
||||
return 0;
|
||||
|
||||
free:
|
||||
@ -2268,16 +2280,18 @@ out:
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
|
||||
static void __devinet_sysctl_unregister(struct net *net,
|
||||
struct ipv4_devconf *cnf, int ifindex)
|
||||
{
|
||||
struct devinet_sysctl_table *t = cnf->sysctl;
|
||||
|
||||
if (!t)
|
||||
return;
|
||||
if (t) {
|
||||
cnf->sysctl = NULL;
|
||||
unregister_net_sysctl_table(t->sysctl_header);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
cnf->sysctl = NULL;
|
||||
unregister_net_sysctl_table(t->sysctl_header);
|
||||
kfree(t);
|
||||
inet_netconf_notify_devconf(net, RTM_DELNETCONF, 0, ifindex, NULL);
|
||||
}
|
||||
|
||||
static int devinet_sysctl_register(struct in_device *idev)
|
||||
@ -2299,7 +2313,9 @@ static int devinet_sysctl_register(struct in_device *idev)
|
||||
|
||||
static void devinet_sysctl_unregister(struct in_device *idev)
|
||||
{
|
||||
__devinet_sysctl_unregister(&idev->cnf);
|
||||
struct net *net = dev_net(idev->dev);
|
||||
|
||||
__devinet_sysctl_unregister(net, &idev->cnf, idev->dev->ifindex);
|
||||
neigh_sysctl_unregister(idev->arp_parms);
|
||||
}
|
||||
|
||||
@ -2374,9 +2390,9 @@ static __net_init int devinet_init_net(struct net *net)
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
err_reg_ctl:
|
||||
__devinet_sysctl_unregister(dflt);
|
||||
__devinet_sysctl_unregister(net, dflt, NETCONFA_IFINDEX_DEFAULT);
|
||||
err_reg_dflt:
|
||||
__devinet_sysctl_unregister(all);
|
||||
__devinet_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
|
||||
err_reg_all:
|
||||
if (tbl != ctl_forward_entry)
|
||||
kfree(tbl);
|
||||
@ -2398,8 +2414,10 @@ static __net_exit void devinet_exit_net(struct net *net)
|
||||
|
||||
tbl = net->ipv4.forw_hdr->ctl_table_arg;
|
||||
unregister_net_sysctl_table(net->ipv4.forw_hdr);
|
||||
__devinet_sysctl_unregister(net->ipv4.devconf_dflt);
|
||||
__devinet_sysctl_unregister(net->ipv4.devconf_all);
|
||||
__devinet_sysctl_unregister(net, net->ipv4.devconf_dflt,
|
||||
NETCONFA_IFINDEX_DEFAULT);
|
||||
__devinet_sysctl_unregister(net, net->ipv4.devconf_all,
|
||||
NETCONFA_IFINDEX_ALL);
|
||||
kfree(tbl);
|
||||
#endif
|
||||
kfree(net->ipv4.devconf_dflt);
|
||||
|
@ -631,7 +631,7 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
|
||||
in_dev = __in_dev_get_rtnl(dev);
|
||||
if (in_dev) {
|
||||
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--;
|
||||
inet_netconf_notify_devconf(dev_net(dev),
|
||||
inet_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
dev->ifindex, &in_dev->cnf);
|
||||
ip_rt_multicast_event(in_dev);
|
||||
@ -820,8 +820,8 @@ static int vif_add(struct net *net, struct mr_table *mrt,
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
|
||||
inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING, dev->ifindex,
|
||||
&in_dev->cnf);
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_MC_FORWARDING,
|
||||
dev->ifindex, &in_dev->cnf);
|
||||
ip_rt_multicast_event(in_dev);
|
||||
|
||||
/* Fill in the VIF structures */
|
||||
@ -1282,7 +1282,8 @@ static void mrtsock_destruct(struct sock *sk)
|
||||
ipmr_for_each_table(mrt, net) {
|
||||
if (sk == rtnl_dereference(mrt->mroute_sk)) {
|
||||
IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
|
||||
inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv4.devconf_all);
|
||||
RCU_INIT_POINTER(mrt->mroute_sk, NULL);
|
||||
@ -1344,7 +1345,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval,
|
||||
if (ret == 0) {
|
||||
rcu_assign_pointer(mrt->mroute_sk, sk);
|
||||
IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
|
||||
inet_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv4.devconf_all);
|
||||
}
|
||||
|
@ -549,6 +549,9 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
||||
if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (!devconf)
|
||||
goto out;
|
||||
|
||||
if ((all || type == NETCONFA_FORWARDING) &&
|
||||
nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
|
||||
goto nla_put_failure;
|
||||
@ -567,6 +570,7 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
||||
devconf->ignore_routes_with_linkdown) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
out:
|
||||
nlmsg_end(skb, nlh);
|
||||
return 0;
|
||||
|
||||
@ -575,8 +579,8 @@ nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||
struct ipv6_devconf *devconf)
|
||||
void inet6_netconf_notify_devconf(struct net *net, int event, int type,
|
||||
int ifindex, struct ipv6_devconf *devconf)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err = -ENOBUFS;
|
||||
@ -586,7 +590,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
|
||||
goto errout;
|
||||
|
||||
err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0,
|
||||
RTM_NEWNETCONF, 0, type);
|
||||
event, 0, type);
|
||||
if (err < 0) {
|
||||
/* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */
|
||||
WARN_ON(err == -EMSGSIZE);
|
||||
@ -769,7 +773,8 @@ static void dev_forward_change(struct inet6_dev *idev)
|
||||
else
|
||||
addrconf_leave_anycast(ifa);
|
||||
}
|
||||
inet6_netconf_notify_devconf(dev_net(dev), NETCONFA_FORWARDING,
|
||||
inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
dev->ifindex, &idev->cnf);
|
||||
}
|
||||
|
||||
@ -804,7 +809,8 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
|
||||
|
||||
if (p == &net->ipv6.devconf_dflt->forwarding) {
|
||||
if ((!newf) ^ (!old))
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv6.devconf_dflt);
|
||||
rtnl_unlock();
|
||||
@ -816,13 +822,15 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf)
|
||||
|
||||
net->ipv6.devconf_dflt->forwarding = newf;
|
||||
if ((!newf) ^ (!old_dflt))
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv6.devconf_dflt);
|
||||
|
||||
addrconf_forward_change(net, newf);
|
||||
if ((!newf) ^ (!old))
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv6.devconf_all);
|
||||
} else if ((!newf) ^ (!old))
|
||||
@ -847,6 +855,7 @@ static void addrconf_linkdown_change(struct net *net, __s32 newf)
|
||||
idev->cnf.ignore_routes_with_linkdown = newf;
|
||||
if (changed)
|
||||
inet6_netconf_notify_devconf(dev_net(dev),
|
||||
RTM_NEWNETCONF,
|
||||
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
dev->ifindex,
|
||||
&idev->cnf);
|
||||
@ -869,6 +878,7 @@ static int addrconf_fixup_linkdown(struct ctl_table *table, int *p, int newf)
|
||||
if (p == &net->ipv6.devconf_dflt->ignore_routes_with_linkdown) {
|
||||
if ((!newf) ^ (!old))
|
||||
inet6_netconf_notify_devconf(net,
|
||||
RTM_NEWNETCONF,
|
||||
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv6.devconf_dflt);
|
||||
@ -881,6 +891,7 @@ static int addrconf_fixup_linkdown(struct ctl_table *table, int *p, int newf)
|
||||
addrconf_linkdown_change(net, newf);
|
||||
if ((!newf) ^ (!old))
|
||||
inet6_netconf_notify_devconf(net,
|
||||
RTM_NEWNETCONF,
|
||||
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv6.devconf_all);
|
||||
@ -5675,17 +5686,20 @@ int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
|
||||
return restart_syscall();
|
||||
|
||||
if (valp == &net->ipv6.devconf_dflt->proxy_ndp)
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_PROXY_NEIGH,
|
||||
NETCONFA_IFINDEX_DEFAULT,
|
||||
net->ipv6.devconf_dflt);
|
||||
else if (valp == &net->ipv6.devconf_all->proxy_ndp)
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_PROXY_NEIGH,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv6.devconf_all);
|
||||
else {
|
||||
struct inet6_dev *idev = ctl->extra1;
|
||||
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_PROXY_NEIGH,
|
||||
idev->dev->ifindex,
|
||||
&idev->cnf);
|
||||
}
|
||||
@ -6348,7 +6362,8 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
|
||||
ifindex = NETCONFA_IFINDEX_DEFAULT;
|
||||
else
|
||||
ifindex = idev->dev->ifindex;
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_ALL, ifindex, p);
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL,
|
||||
ifindex, p);
|
||||
return 0;
|
||||
|
||||
free:
|
||||
@ -6357,7 +6372,8 @@ out:
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
|
||||
static void __addrconf_sysctl_unregister(struct net *net,
|
||||
struct ipv6_devconf *p, int ifindex)
|
||||
{
|
||||
struct ctl_table *table;
|
||||
|
||||
@ -6368,6 +6384,8 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
|
||||
unregister_net_sysctl_table(p->sysctl_header);
|
||||
p->sysctl_header = NULL;
|
||||
kfree(table);
|
||||
|
||||
inet6_netconf_notify_devconf(net, RTM_DELNETCONF, 0, ifindex, NULL);
|
||||
}
|
||||
|
||||
static int addrconf_sysctl_register(struct inet6_dev *idev)
|
||||
@ -6391,7 +6409,8 @@ static int addrconf_sysctl_register(struct inet6_dev *idev)
|
||||
|
||||
static void addrconf_sysctl_unregister(struct inet6_dev *idev)
|
||||
{
|
||||
__addrconf_sysctl_unregister(&idev->cnf);
|
||||
__addrconf_sysctl_unregister(dev_net(idev->dev), &idev->cnf,
|
||||
idev->dev->ifindex);
|
||||
neigh_sysctl_unregister(idev->nd_parms);
|
||||
}
|
||||
|
||||
@ -6434,7 +6453,7 @@ static int __net_init addrconf_init_net(struct net *net)
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
err_reg_dflt:
|
||||
__addrconf_sysctl_unregister(all);
|
||||
__addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
|
||||
err_reg_all:
|
||||
kfree(dflt);
|
||||
#endif
|
||||
@ -6447,8 +6466,10 @@ err_alloc_all:
|
||||
static void __net_exit addrconf_exit_net(struct net *net)
|
||||
{
|
||||
#ifdef CONFIG_SYSCTL
|
||||
__addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
|
||||
__addrconf_sysctl_unregister(net->ipv6.devconf_all);
|
||||
__addrconf_sysctl_unregister(net, net->ipv6.devconf_dflt,
|
||||
NETCONFA_IFINDEX_DEFAULT);
|
||||
__addrconf_sysctl_unregister(net, net->ipv6.devconf_all,
|
||||
NETCONFA_IFINDEX_ALL);
|
||||
#endif
|
||||
kfree(net->ipv6.devconf_dflt);
|
||||
kfree(net->ipv6.devconf_all);
|
||||
|
@ -815,7 +815,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
|
||||
in6_dev = __in6_dev_get(dev);
|
||||
if (in6_dev) {
|
||||
in6_dev->cnf.mc_forwarding--;
|
||||
inet6_netconf_notify_devconf(dev_net(dev),
|
||||
inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
dev->ifindex, &in6_dev->cnf);
|
||||
}
|
||||
@ -974,7 +974,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
|
||||
in6_dev = __in6_dev_get(dev);
|
||||
if (in6_dev) {
|
||||
in6_dev->cnf.mc_forwarding++;
|
||||
inet6_netconf_notify_devconf(dev_net(dev),
|
||||
inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
dev->ifindex, &in6_dev->cnf);
|
||||
}
|
||||
@ -1599,7 +1599,8 @@ static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
|
||||
write_unlock_bh(&mrt_lock);
|
||||
|
||||
if (!err)
|
||||
inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv6.devconf_all);
|
||||
rtnl_unlock();
|
||||
@ -1620,7 +1621,7 @@ int ip6mr_sk_done(struct sock *sk)
|
||||
mrt->mroute6_sk = NULL;
|
||||
net->ipv6.devconf_all->mc_forwarding--;
|
||||
write_unlock_bh(&mrt_lock);
|
||||
inet6_netconf_notify_devconf(net,
|
||||
inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_MC_FORWARDING,
|
||||
NETCONFA_IFINDEX_ALL,
|
||||
net->ipv6.devconf_all);
|
||||
|
@ -1040,8 +1040,8 @@ static int mpls_netconf_msgsize_devconf(int type)
|
||||
return size;
|
||||
}
|
||||
|
||||
static void mpls_netconf_notify_devconf(struct net *net, int type,
|
||||
struct mpls_dev *mdev)
|
||||
static void mpls_netconf_notify_devconf(struct net *net, int event,
|
||||
int type, struct mpls_dev *mdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err = -ENOBUFS;
|
||||
@ -1050,8 +1050,7 @@ static void mpls_netconf_notify_devconf(struct net *net, int type,
|
||||
if (!skb)
|
||||
goto errout;
|
||||
|
||||
err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, RTM_NEWNETCONF,
|
||||
0, type);
|
||||
err = mpls_netconf_fill_devconf(skb, mdev, 0, 0, event, 0, type);
|
||||
if (err < 0) {
|
||||
/* -EMSGSIZE implies BUG in mpls_netconf_msgsize_devconf() */
|
||||
WARN_ON(err == -EMSGSIZE);
|
||||
@ -1184,9 +1183,8 @@ static int mpls_conf_proc(struct ctl_table *ctl, int write,
|
||||
|
||||
if (i == offsetof(struct mpls_dev, input_enabled) &&
|
||||
val != oval) {
|
||||
mpls_netconf_notify_devconf(net,
|
||||
NETCONFA_INPUT,
|
||||
mdev);
|
||||
mpls_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_INPUT, mdev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1227,10 +1225,11 @@ static int mpls_dev_sysctl_register(struct net_device *dev,
|
||||
|
||||
snprintf(path, sizeof(path), "net/mpls/conf/%s", dev->name);
|
||||
|
||||
mdev->sysctl = register_net_sysctl(dev_net(dev), path, table);
|
||||
mdev->sysctl = register_net_sysctl(net, path, table);
|
||||
if (!mdev->sysctl)
|
||||
goto free;
|
||||
|
||||
mpls_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_ALL, mdev);
|
||||
return 0;
|
||||
|
||||
free:
|
||||
@ -1239,13 +1238,17 @@ out:
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
static void mpls_dev_sysctl_unregister(struct mpls_dev *mdev)
|
||||
static void mpls_dev_sysctl_unregister(struct net_device *dev,
|
||||
struct mpls_dev *mdev)
|
||||
{
|
||||
struct net *net = dev_net(dev);
|
||||
struct ctl_table *table;
|
||||
|
||||
table = mdev->sysctl->ctl_table_arg;
|
||||
unregister_net_sysctl_table(mdev->sysctl);
|
||||
kfree(table);
|
||||
|
||||
mpls_netconf_notify_devconf(net, RTM_DELNETCONF, 0, mdev);
|
||||
}
|
||||
|
||||
static struct mpls_dev *mpls_add_dev(struct net_device *dev)
|
||||
@ -1271,11 +1274,12 @@ static struct mpls_dev *mpls_add_dev(struct net_device *dev)
|
||||
u64_stats_init(&mpls_stats->syncp);
|
||||
}
|
||||
|
||||
mdev->dev = dev;
|
||||
|
||||
err = mpls_dev_sysctl_register(dev, mdev);
|
||||
if (err)
|
||||
goto free;
|
||||
|
||||
mdev->dev = dev;
|
||||
rcu_assign_pointer(dev->mpls_ptr, mdev);
|
||||
|
||||
return mdev;
|
||||
@ -1421,7 +1425,7 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
|
||||
mpls_ifdown(dev, event);
|
||||
mdev = mpls_dev_get(dev);
|
||||
if (mdev) {
|
||||
mpls_dev_sysctl_unregister(mdev);
|
||||
mpls_dev_sysctl_unregister(dev, mdev);
|
||||
RCU_INIT_POINTER(dev->mpls_ptr, NULL);
|
||||
call_rcu(&mdev->rcu, mpls_dev_destroy_rcu);
|
||||
}
|
||||
@ -1431,7 +1435,7 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
|
||||
if (mdev) {
|
||||
int err;
|
||||
|
||||
mpls_dev_sysctl_unregister(mdev);
|
||||
mpls_dev_sysctl_unregister(dev, mdev);
|
||||
err = mpls_dev_sysctl_register(dev, mdev);
|
||||
if (err)
|
||||
return notifier_from_errno(err);
|
||||
|
@ -69,6 +69,7 @@ static struct nlmsg_perm nlmsg_route_perms[] =
|
||||
{ RTM_GETDCB, NETLINK_ROUTE_SOCKET__NLMSG_READ },
|
||||
{ RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
|
||||
{ RTM_NEWNETCONF, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
|
||||
{ RTM_DELNETCONF, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
|
||||
{ RTM_GETNETCONF, NETLINK_ROUTE_SOCKET__NLMSG_READ },
|
||||
{ RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
|
||||
{ RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
|
||||
|
Loading…
Reference in New Issue
Block a user