aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2019-11-07 15:00:37 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2019-11-07 15:00:37 +0000
commita961401ee0c528553ccc2bf45c855f727994f827 (patch)
treeec8fbc99c6cf50c2f4fd7ba2c15dcae299ba359b
parent78c12e766daa1fa59e1e65a8adfa4a641d7838a9 (diff)
downloadsrc-a961401ee0c528553ccc2bf45c855f727994f827.tar.gz
src-a961401ee0c528553ccc2bf45c855f727994f827.zip
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
Notes
Notes: svn path=/head/; revision=354443
-rw-r--r--sys/net/if_vlan.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index e48613f7ad5f..e7e32fb2a38d 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1459,11 +1459,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid)
* 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;