diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2012-11-06 11:46:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-13 14:27:45 -0500 |
commit | 5cb04436eef62aa8f5c482f8ec8deba391dea465 (patch) | |
tree | 068d69d9f28c14ae515c1a6a02bcfdc04093d248 /net | |
parent | 24a372cd0b87c15f8d98275d045326249155af55 (diff) |
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: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/addrconf.c | 8 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 7 |
2 files changed, 15 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index fab23db8ee73..cb803b7bb0d8 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4037,6 +4037,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
4037 | array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; | 4037 | array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; |
4038 | array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; | 4038 | array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; |
4039 | array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; | 4039 | array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; |
4040 | array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; | ||
4040 | } | 4041 | } |
4041 | 4042 | ||
4042 | static inline size_t inet6_ifla6_size(void) | 4043 | static inline size_t inet6_ifla6_size(void) |
@@ -4705,6 +4706,13 @@ static struct addrconf_sysctl_table | |||
4705 | .proc_handler = proc_dointvec | 4706 | .proc_handler = proc_dointvec |
4706 | }, | 4707 | }, |
4707 | { | 4708 | { |
4709 | .procname = "ndisc_notify", | ||
4710 | .data = &ipv6_devconf.ndisc_notify, | ||
4711 | .maxlen = sizeof(int), | ||
4712 | .mode = 0644, | ||
4713 | .proc_handler = proc_dointvec | ||
4714 | }, | ||
4715 | { | ||
4708 | /* sentinel */ | 4716 | /* sentinel */ |
4709 | } | 4717 | } |
4710 | }, | 4718 | }, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 6ba4b54a550a..f41853bca428 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1572,11 +1572,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, | |||
1572 | { | 1572 | { |
1573 | struct net_device *dev = ptr; | 1573 | struct net_device *dev = ptr; |
1574 | struct net *net = dev_net(dev); | 1574 | struct net *net = dev_net(dev); |
1575 | struct inet6_dev *idev; | ||
1575 | 1576 | ||
1576 | switch (event) { | 1577 | switch (event) { |
1577 | case NETDEV_CHANGEADDR: | 1578 | case NETDEV_CHANGEADDR: |
1578 | neigh_changeaddr(&nd_tbl, dev); | 1579 | neigh_changeaddr(&nd_tbl, dev); |
1579 | fib6_run_gc(~0UL, net); | 1580 | fib6_run_gc(~0UL, net); |
1581 | idev = in6_dev_get(dev); | ||
1582 | if (!idev) | ||
1583 | break; | ||
1584 | if (idev->cnf.ndisc_notify) | ||
1585 | ndisc_send_unsol_na(dev); | ||
1586 | in6_dev_put(idev); | ||
1580 | break; | 1587 | break; |
1581 | case NETDEV_DOWN: | 1588 | case NETDEV_DOWN: |
1582 | neigh_ifdown(&nd_tbl, dev); | 1589 | neigh_ifdown(&nd_tbl, dev); |