Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct ipv6_devconf {
	__s32		disable_ipv6;
	__s32		accept_dad;
	__s32		force_tllao;
	__s32           ndisc_notify;
	void		*sysctl;
};

+1 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ enum {
	DEVCONF_DISABLE_IPV6,
	DEVCONF_ACCEPT_DAD,
	DEVCONF_FORCE_TLLAO,
	DEVCONF_NDISC_NOTIFY,
	DEVCONF_MAX
};

+8 −0
Original line number Diff line number Diff line
@@ -4037,6 +4037,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
	array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
	array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
	array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
	array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
}

static inline size_t inet6_ifla6_size(void)
@@ -4704,6 +4705,13 @@ static struct addrconf_sysctl_table
			.mode           = 0644,
			.proc_handler   = proc_dointvec
		},
		{
			.procname       = "ndisc_notify",
			.data           = &ipv6_devconf.ndisc_notify,
			.maxlen         = sizeof(int),
			.mode           = 0644,
			.proc_handler   = proc_dointvec
		},
		{
			/* sentinel */
		}
+7 −0
Original line number Diff line number Diff line
@@ -1572,11 +1572,18 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
{
	struct net_device *dev = ptr;
	struct net *net = dev_net(dev);
	struct inet6_dev *idev;

	switch (event) {
	case NETDEV_CHANGEADDR:
		neigh_changeaddr(&nd_tbl, dev);
		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;
	case NETDEV_DOWN:
		neigh_ifdown(&nd_tbl, dev);