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
This commit is contained in:
ae 2019-11-07 15:00:37 +00:00
parent 750beadc87
commit c2745f25b2

View File

@ -1459,11 +1459,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid)
* Set up our interface address to reflect the underlying * Set up our interface address to reflect the underlying
* physical interface's. * 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 = ((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen =
p->if_addrlen; 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. */ /* We are ready for operation now. */
ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags |= IFF_DRV_RUNNING;