git: b82b8055ad44 - main - ifconfig: fix vlan/vlanproto reconfiguration

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

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

commit b82b8055ad44cac6ee1e1201cf1ea4dbdd20cacd
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-07-18 22:25:56 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-07-21 16:36:01 +0000

    ifconfig: fix vlan/vlanproto reconfiguration
    
    The setvlantag() and setvlanproto() functions are used in two scenarios:
    when we create a new vlan interface and when we update an existing
    interface.
    These are distinguished by the getvlan() at the end of the functions. If
    this fails we assume that is because the interface doesn't exist (so
    we're creating a new one). We only update the 'params' struct, and
    expect the settings to be applied when we vlan_create().
    
    However, if we're updating an existing interface we do not retrieve the
    current settings, and can end up invalidating settings.
    
    Fix this by using the settings we retrieved while checking which
    scenario we're in.
    
    Note that we do not address this for setvlandev(), because if_vlan does
    not allow the vlan parent device to be changed without disassociating it
    first (with ifconfig vlanX -vlandev).
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D35848
---
 sbin/ifconfig/ifvlan.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c
index 8b7b6e9daf9a..74d683ebb55a 100644
--- a/sbin/ifconfig/ifvlan.c
+++ b/sbin/ifconfig/ifvlan.c
@@ -204,8 +204,11 @@ DECL_CMD_FUNC(setvlantag, val, d)
 	if (params.vlr_tag != ul)
 		errx(1, "value for vlan out of range");
 
-	if (getvlan(s, &ifr, &vreq) != -1)
+	if (getvlan(s, &ifr, &vreq) != -1) {
+		vreq.vlr_tag = params.vlr_tag;
+		memcpy(&params, &vreq, sizeof(params));
 		vlan_set(s, &ifr);
+	}
 }
 
 static
@@ -233,8 +236,11 @@ DECL_CMD_FUNC(setvlanproto, val, d)
 	} else
 		errx(1, "invalid value for vlanproto");
 
-	if (getvlan(s, &ifr, &vreq) != -1)
+	if (getvlan(s, &ifr, &vreq) != -1) {
+		vreq.vlr_proto = params.vlr_proto;
+		memcpy(&params, &vreq, sizeof(params));
 		vlan_set(s, &ifr);
+	}
 }
 
 static