git: 663f556b03a8 - main - if_vlan: allow vlan and vlanproto to be changed

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 21 Jul 2022 16:36:47 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=663f556b03a86b66ce6a9af1edf229ef74775676

commit 663f556b03a86b66ce6a9af1edf229ef74775676
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-07-18 22:23:50 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-07-21 16:36:01 +0000

    if_vlan: allow vlan and vlanproto to be changed
    
    It's currently not possible to change the vlan ID or vlan protocol (i.e.
    802.1q vs. 802.1ad) without de-configuring the interface (i.e. ifconfig
    vlanX -vlandev).
    Add a specific flow for this, allowing both the protocol and id (but not
    parent interface) to be changed without going through the '-vlandev'
    step.
    
    Reviewed by:    glebius
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D35846
---
 sys/net/if_vlan.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index f8af0fd3d915..03a06f09c541 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1538,8 +1538,24 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid,
 	 */
 	if (vid == 0 || vid == 0xFFF || (vid & ~EVL_VLID_MASK))
 		return (EINVAL);
-	if (ifv->ifv_trunk)
-		return (EBUSY);
+	if (ifv->ifv_trunk) {
+		trunk = ifv->ifv_trunk;
+		if (trunk->parent != p)
+			return (EBUSY);
+
+		VLAN_XLOCK();
+
+		ifv->ifv_proto = proto;
+
+		if (ifv->ifv_vid != vid) {
+			/* Re-hash */
+			vlan_remhash(trunk, ifv);
+			ifv->ifv_vid = vid;
+			error = vlan_inshash(trunk, ifv);
+		}
+		/* Will unlock */
+		goto done;
+	}
 
 	VLAN_XLOCK();
 	if (p->if_vlantrunk == NULL) {