Commit 5cb04436 authored by Hannes Frederic Sowa's avatar Hannes Frederic Sowa Committed by David S. Miller

ipv6: add knob to send unsolicited ND on link-layer address change

This patch introduces a new knob ndisc_notify. If enabled, the kernel
will transmit an unsolicited neighbour advertisement on link-layer address
change to update the neighbour tables of the corresponding hosts more quickly.

This is the equivalent to arp_notify in ipv4 world.
Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 24a372cd
...@@ -47,6 +47,7 @@ struct ipv6_devconf { ...@@ -47,6 +47,7 @@ struct ipv6_devconf {
__s32 disable_ipv6; __s32 disable_ipv6;
__s32 accept_dad; __s32 accept_dad;
__s32 force_tllao; __s32 force_tllao;
__s32 ndisc_notify;
void *sysctl; void *sysctl;
}; };
......
...@@ -157,6 +157,7 @@ enum { ...@@ -157,6 +157,7 @@ enum {
DEVCONF_DISABLE_IPV6, DEVCONF_DISABLE_IPV6,
DEVCONF_ACCEPT_DAD, DEVCONF_ACCEPT_DAD,
DEVCONF_FORCE_TLLAO, DEVCONF_FORCE_TLLAO,
DEVCONF_NDISC_NOTIFY,
DEVCONF_MAX DEVCONF_MAX
}; };
......
...@@ -4037,6 +4037,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, ...@@ -4037,6 +4037,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
} }
static inline size_t inet6_ifla6_size(void) static inline size_t inet6_ifla6_size(void)
...@@ -4704,6 +4705,13 @@ static struct addrconf_sysctl_table ...@@ -4704,6 +4705,13 @@ static struct addrconf_sysctl_table
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec .proc_handler = proc_dointvec
}, },
{
.procname = "ndisc_notify",
.data = &ipv6_devconf.ndisc_notify,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{ {
/* sentinel */ /* sentinel */
} }
......
...@@ -1572,11 +1572,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, ...@@ -1572,11 +1572,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
{ {
struct net_device *dev = ptr; struct net_device *dev = ptr;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
struct inet6_dev *idev;
switch (event) { switch (event) {
case NETDEV_CHANGEADDR: case NETDEV_CHANGEADDR:
neigh_changeaddr(&nd_tbl, dev); neigh_changeaddr(&nd_tbl, dev);
fib6_run_gc(~0UL, net); fib6_run_gc(~0UL, net);
idev = in6_dev_get(dev);
if (!idev)
break;
if (idev->cnf.ndisc_notify)
ndisc_send_unsol_na(dev);
in6_dev_put(idev);
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
neigh_ifdown(&nd_tbl, dev); neigh_ifdown(&nd_tbl, dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment