|
@@ -442,6 +442,8 @@ static int inet6_netconf_msgsize_devconf(int type)
|
|
if (type == -1 || type == NETCONFA_MC_FORWARDING)
|
|
if (type == -1 || type == NETCONFA_MC_FORWARDING)
|
|
size += nla_total_size(4);
|
|
size += nla_total_size(4);
|
|
#endif
|
|
#endif
|
|
|
|
+ if (type == -1 || type == NETCONFA_PROXY_NEIGH)
|
|
|
|
+ size += nla_total_size(4);
|
|
|
|
|
|
return size;
|
|
return size;
|
|
}
|
|
}
|
|
@@ -475,6 +477,10 @@ static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
|
|
devconf->mc_forwarding) < 0)
|
|
devconf->mc_forwarding) < 0)
|
|
goto nla_put_failure;
|
|
goto nla_put_failure;
|
|
#endif
|
|
#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);
|
|
return nlmsg_end(skb, nlh);
|
|
|
|
|
|
nla_put_failure:
|
|
nla_put_failure:
|
|
@@ -509,6 +515,7 @@ errout:
|
|
static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
|
|
static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = {
|
|
[NETCONFA_IFINDEX] = { .len = sizeof(int) },
|
|
[NETCONFA_IFINDEX] = { .len = sizeof(int) },
|
|
[NETCONFA_FORWARDING] = { .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,
|
|
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;
|
|
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
|
|
static struct addrconf_sysctl_table
|
|
{
|
|
{
|
|
struct ctl_table_header *sysctl_header;
|
|
struct ctl_table_header *sysctl_header;
|
|
@@ -4914,7 +4961,7 @@ static struct addrconf_sysctl_table
|
|
.data = &ipv6_devconf.proxy_ndp,
|
|
.data = &ipv6_devconf.proxy_ndp,
|
|
.maxlen = sizeof(int),
|
|
.maxlen = sizeof(int),
|
|
.mode = 0644,
|
|
.mode = 0644,
|
|
- .proc_handler = proc_dointvec,
|
|
|
|
|
|
+ .proc_handler = addrconf_sysctl_proxy_ndp,
|
|
},
|
|
},
|
|
{
|
|
{
|
|
.procname = "accept_source_route",
|
|
.procname = "accept_source_route",
|