History

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.

Hannes Frederic Sowa committed 14 years ago

Commit 5cb04431 parent 24a372c4 files · +17 −0Browse files

Unified · Split

4 files
  1. include/linux/ipv6.h +1 −0
  2. include/uapi/linux/ipv6.h +1 −0
  3. net/ipv6/addrconf.c +8 −0
  4. net/ipv6/ndisc.c +7 −0
include/linux/ipv6.h+1−0
@@ -47,6 +47,7 @@ struct ipv6_devconf { · 46 unmodified lines
4747 __s32 disable_ipv6;
4848 __s32 accept_dad;
4949 __s32 force_tllao;
50+ __s32 ndisc_notify;
5051 void *sysctl;
5152 };
5253
include/uapi/linux/ipv6.h+1−0
@@ -157,6 +157,7 @@ enum { · 156 unmodified lines
157157 DEVCONF_DISABLE_IPV6,
158158 DEVCONF_ACCEPT_DAD,
159159 DEVCONF_FORCE_TLLAO,
160+ DEVCONF_NDISC_NOTIFY,
160161 DEVCONF_MAX
161162 };
162163
net/ipv6/addrconf.c+8−0
@@ -4037,6 +4037,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, · 4036 unmodified lines
40374037 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
40384038 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
40394039 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
4040+ array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
40404041 }
40414042
40424043 static inline size_t inet6_ifla6_size(void)
@@ -4704,6 +4705,13 @@ static struct addrconf_sysctl_table · 661 unmodified lines
47044705 .mode = 0644,
47054706 .proc_handler = proc_dointvec
47064707 },
4708+ {
4709+ .procname = "ndisc_notify",
4710+ .data = &ipv6_devconf.ndisc_notify,
4711+ .maxlen = sizeof(int),
4712+ .mode = 0644,
4713+ .proc_handler = proc_dointvec
4714+ },
47074715 {
47084716 /* sentinel */
47094717 }
net/ipv6/ndisc.c+7−0
@@ -1572,11 +1572,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, · 1571 unmodified lines
15721572 {
15731573 struct net_device *dev = ptr;
15741574 struct net *net = dev_net(dev);
1575+ struct inet6_dev *idev;
15751576
15761577 switch (event) {
15771578 case NETDEV_CHANGEADDR:
15781579 neigh_changeaddr(&nd_tbl, dev);
15791580 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);
15801587 break;
15811588 case NETDEV_DOWN:
15821589 neigh_ifdown(&nd_tbl, dev);