netconf: add support for IPv6 proxy_ndp

Need to be able to see changes to proxy NDP status on a per
interface basis via netlink (analog to proxy_arp).

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
stephen hemminger 2013-12-17 22:37:14 -08:00 committed by David S. Miller
parent 09aea5df7f
commit c92d5491a6
1 changed files with 48 additions and 1 deletions

View File

@ -442,6 +442,8 @@ static int inet6_netconf_msgsize_devconf(int type)
if (type == -1 || type == NETCONFA_MC_FORWARDING)
size += nla_total_size(4);
#endif
if (type == -1 || type == NETCONFA_PROXY_NEIGH)
size += nla_total_size(4);
return size;
}
@ -475,6 +477,10 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
devconf->mc_forwarding) < 0)
goto nla_put_failure;
#endif
if ((type == -1 || type == NETCONFA_PROXY_NEIGH) &&
nla_put_s32(skb, NETCONFA_PROXY_NEIGH, devconf->proxy_ndp) < 0)
goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
@ -509,6 +515,7 @@ void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex,
static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
[NETCONFA_IFINDEX] = { .len = sizeof(int) },
[NETCONFA_FORWARDING] = { .len = sizeof(int) },
[NETCONFA_PROXY_NEIGH] = { .len = sizeof(int) },
};
static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
@ -4728,6 +4735,46 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
return ret;
}
static
int addrconf_sysctl_proxy_ndp(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int ret;
int old, new;
old = *valp;
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
new = *valp;
if (write && old != new) {
struct net *net = ctl->extra2;
if (!rtnl_trylock())
return restart_syscall();
if (valp == &net->ipv6.devconf_dflt->proxy_ndp)
inet6_netconf_notify_devconf(net, 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,
NETCONFA_IFINDEX_ALL,
net->ipv6.devconf_all);
else {
struct inet6_dev *idev = ctl->extra1;
inet6_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
idev->dev->ifindex,
&idev->cnf);
}
rtnl_unlock();
}
return ret;
}
static struct addrconf_sysctl_table
{
struct ctl_table_header *sysctl_header;
@ -4914,7 +4961,7 @@ static struct addrconf_sysctl_table
.data = &ipv6_devconf.proxy_ndp,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
.proc_handler = addrconf_sysctl_proxy_ndp,
},
{
.procname = "accept_source_route",