Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Nov 2019 15:00:38 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354443 - head/sys/net
Message-ID:  <201911071500.xA7F0cFa045626@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Thu Nov  7 15:00:37 2019
New Revision: 354443
URL: https://svnweb.freebsd.org/changeset/base/354443

Log:
  Enqueue lladdr_task to update link level address of vlan, when its parent
  interface has changed.
  
  During vlan reconfiguration without destroying interface, it is possible,
  that parent interface will be changed. This usually means, that link
  layer address of vlan will be different. Therefore we need to update all
  associated with vlan's addresses permanent llentries - NDP for IPv6
  addresses, and ARP for IPv4 addresses. This is done via lladdr_task
  execution. To avoid extra work, before execution do the check, that L2
  address is different.
  
  No objection from:	#network
  Obtained from:	Yandex LLC
  MFC after:	1 week
  Sponsored by:	Yandex LLC
  Differential Revision:	https://reviews.freebsd.org/D22243

Modified:
  head/sys/net/if_vlan.c

Modified: head/sys/net/if_vlan.c
==============================================================================
--- head/sys/net/if_vlan.c	Thu Nov  7 14:16:55 2019	(r354442)
+++ head/sys/net/if_vlan.c	Thu Nov  7 15:00:37 2019	(r354443)
@@ -1459,11 +1459,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint1
 	 * Set up our interface address to reflect the underlying
 	 * physical interface's.
 	 */
-	bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen);
+	TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv);
 	((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen =
 	    p->if_addrlen;
 
-	TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv);
+	/*
+	 * Do not schedule link address update if it was the same
+	 * as previous parent's. This helps avoid updating for each
+	 * associated llentry.
+	 */
+	if (memcmp(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen) != 0) {
+		bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen);
+		taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task);
+	}
 
 	/* We are ready for operation now. */
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911071500.xA7F0cFa045626>