The branch main has been updated by ivy:

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

commit ce06c1921e0c8f1e7999acdf371c756e80a3c709
Author:     Lexi Winter <i...@freebsd.org>
AuthorDate: 2025-08-03 22:54:59 +0000
Commit:     Lexi Winter <i...@freebsd.org>
CommitDate: 2025-08-03 22:55:10 +0000

    bridge: Add a vlanfilter bridge option
    
    vlanfilter was originally a per-interface flag to allow more flexible
    configurations where some interfaces had VLAN filtering enabled and
    some didn't.  In practice, this just makes the configuration more
    confusing without any real benefit, so remove it, and make vlanfilter
    a bridge flag instead.
    
    Add a new bridge option "defuntagged", which sets the automatically
    assigned PVID for new members.  If set to 0 (the default) then no
    PVID is assigned, which matches the current behaviour.
    
    While here, add some more atf_checks to the bridge VLAN tests to
    make debugging easier.
    
    Differential Revision:  https://reviews.freebsd.org/D51600
---
 lib/libifconfig/libifconfig.h        |   2 +
 lib/libifconfig/libifconfig_bridge.c |  12 +++
 sbin/ifconfig/ifbridge.c             |  80 +++++++++++++----
 sbin/ifconfig/ifconfig.8             |  33 +++----
 share/man/man4/bridge.4              |   4 +-
 sys/net/if_bridge.c                  |  84 +++++++++++++++---
 sys/net/if_bridgevar.h               |  21 ++++-
 tests/sys/net/if_bridge_test.sh      | 161 +++++++++++++++++++++++++----------
 8 files changed, 299 insertions(+), 98 deletions(-)

diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h
index fc835485a51e..b2f0cf9744ea 100644
--- a/lib/libifconfig/libifconfig.h
+++ b/lib/libifconfig/libifconfig.h
@@ -69,6 +69,8 @@ struct ifconfig_bridge_status {
        size_t members_count;           /**< how many member interfaces */
        uint32_t cache_size;            /**< size of address cache */
        uint32_t cache_lifetime;        /**< address cache entry lifetime */
+       ifbr_flags_t flags;             /**< bridge flags */
+       ether_vlanid_t defpvid;         /**< default pvid */
 };
 
 struct ifconfig_capabilities {
diff --git a/lib/libifconfig/libifconfig_bridge.c 
b/lib/libifconfig/libifconfig_bridge.c
index b4a920f488c5..675bf5dd2ff5 100644
--- a/lib/libifconfig/libifconfig_bridge.c
+++ b/lib/libifconfig/libifconfig_bridge.c
@@ -92,6 +92,18 @@ ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h,
        }
        bridge->inner.cache_lifetime = cache_param.ifbrp_ctime;
 
+       if (ifconfig_bridge_ioctlwrap(h, name, BRDGGFLAGS,
+           &cache_param, sizeof(cache_param), false) != 0) {
+               goto err;
+       }
+       bridge->inner.flags = cache_param.ifbrp_flags;
+
+       if (ifconfig_bridge_ioctlwrap(h, name, BRDGGDEFPVID,
+           &cache_param, sizeof(cache_param), false) != 0) {
+               goto err;
+       }
+       bridge->inner.defpvid = cache_param.ifbrp_defpvid;
+
        if (ifconfig_bridge_ioctlwrap(h, name, BRDGPARAM,
            &bridge->params, sizeof(bridge->params), false) != 0) {
                goto err;
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
index 1a8c4c6e9c3e..335ed9bf513f 100644
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -223,6 +223,11 @@ bridge_status(if_ctx *ctx)
            params->ifbop_root_path_cost,
            params->ifbop_root_port & 0xfff);
 
+       printb("\tbridge flags", bridge->flags, IFBRFBITS);
+       if (bridge->defpvid)
+               printf(" defuntagged=%u", (unsigned) bridge->defpvid);
+       printf("\n");
+
        prefix = "\tmember: ";
        pad    = "\t        ";
        for (size_t i = 0; i < bridge->members_count; ++i) {
@@ -514,7 +519,6 @@ setbridge_deladdr(if_ctx *ctx, int argc, const char *const 
*argv)
 static void
 setbridge_addr(if_ctx *ctx, const char *val __unused, int dummy __unused)
 {
-
        bridge_addresses(ctx, "");
 }
 
@@ -735,18 +739,6 @@ unsetbridge_private(if_ctx *ctx, const char *val, int 
dummy __unused)
        do_bridgeflag(ctx, val, IFBIF_PRIVATE, 0);
 }
 
-static void
-setbridge_vlanfilter(if_ctx *ctx, const char *val, int dummy __unused)
-{
-       do_bridgeflag(ctx, val, IFBIF_VLANFILTER, 1);
-}
-
-static void
-unsetbridge_vlanfilter(if_ctx *ctx, const char *val, int dummy __unused)
-{
-       do_bridgeflag(ctx, val, IFBIF_VLANFILTER, 0);
-}
-
 static int
 parse_vlans(ifbvlan_set_t *set, const char *str)
 {
@@ -838,6 +830,59 @@ delbridge_tagged(if_ctx *ctx, const char *ifn, const char 
*vlans)
        set_bridge_vlanset(ctx, ifn, vlans, BRDG_VLAN_OP_DEL);
 }
 
+static void
+setbridge_flags(if_ctx *ctx, const char *val __unused, int newflags)
+{
+       struct ifbrparam req;
+
+       if (do_cmd(ctx, BRDGGFLAGS, &req, sizeof(req), 0) < 0)
+               err(1, "BRDGGFLAGS");
+
+       req.ifbrp_flags |= (uint32_t)newflags;
+
+       if (do_cmd(ctx, BRDGSFLAGS, &req, sizeof(req), 1) < 0)
+               err(1, "BRDGSFLAGS");
+}
+
+static void
+unsetbridge_flags(if_ctx *ctx, const char *val __unused, int newflags)
+{
+       struct ifbrparam req;
+
+       if (do_cmd(ctx, BRDGGFLAGS, &req, sizeof(req), 0) < 0)
+               err(1, "BRDGGFLAGS");
+
+       req.ifbrp_flags &= ~(uint32_t)newflags;
+
+       if (do_cmd(ctx, BRDGSFLAGS, &req, sizeof(req), 1) < 0)
+               err(1, "BRDGSFLAGS");
+}
+
+static void
+setbridge_defuntagged(if_ctx *ctx, const char *arg, int dummy __unused)
+{
+       struct ifbrparam req;
+
+       memset(&req, 0, sizeof(req));
+       if (get_vlan_id(arg, &req.ifbrp_defpvid) < 0)
+               errx(1, "invalid vlan id: %s", arg);
+
+       if (do_cmd(ctx, BRDGSDEFPVID, &req, sizeof(req), 1) < 0)
+               err(1, "BRDGSDEFPVID");
+}
+
+static void
+unsetbridge_defuntagged(if_ctx *ctx, const char *val __unused, int dummy 
__unused)
+{
+       struct ifbrparam req;
+
+       memset(&req, 0, sizeof(req));
+       req.ifbrp_defpvid = 0;
+
+       if (do_cmd(ctx, BRDGSDEFPVID, &req, sizeof(req), 1) < 0)
+               err(1, "BRDGSDEFPVID");
+}
+
 static struct cmd bridge_cmds[] = {
        DEF_CMD_ARG("addm",             setbridge_add),
        DEF_CMD_ARG("deletem",          setbridge_delete),
@@ -874,8 +919,6 @@ static struct cmd bridge_cmds[] = {
        DEF_CMD_ARG2("ifpriority",      setbridge_ifpriority),
        DEF_CMD_ARG2("ifpathcost",      setbridge_ifpathcost),
        DEF_CMD_ARG2("ifmaxaddr",       setbridge_ifmaxaddr),
-       DEF_CMD_ARG("vlanfilter",       setbridge_vlanfilter),
-       DEF_CMD_ARG("-vlanfilter",      unsetbridge_vlanfilter),
        DEF_CMD_ARG2("untagged",        setbridge_untagged),
        DEF_CMD_ARG("-untagged",        unsetbridge_untagged),
        DEF_CMD_ARG2("tagged",          setbridge_tagged),
@@ -884,7 +927,14 @@ static struct cmd bridge_cmds[] = {
        DEF_CMD_ARG("timeout",          setbridge_timeout),
        DEF_CMD_ARG("private",          setbridge_private),
        DEF_CMD_ARG("-private",         unsetbridge_private),
+       DEF_CMD("vlanfilter", (int32_t)IFBRF_VLANFILTER,
+                                       setbridge_flags),
+       DEF_CMD("-vlanfilter", (int32_t)IFBRF_VLANFILTER,
+                                       unsetbridge_flags),
+       DEF_CMD_ARG("defuntagged",      setbridge_defuntagged),
+       DEF_CMD("-defuntagged", 0,      unsetbridge_defuntagged),
 };
+
 static struct afswtch af_bridge = {
        .af_name        = "af_bridge",
        .af_af          = AF_UNSPEC,
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 6a50a91880ef..06ec62197fba 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -2710,18 +2710,23 @@ The behaviour of these options is described in the
 section of
 .Xr bridge 4 .
 .Bl -tag -width indent
-.It Cm vlanfilter Ar interface
-Enable VLAN filtering on an interface.
-.It Cm -vlanfilter Ar interface
-Disable VLAN filtering on an interface.
+.It Cm vlanfilter
+Enable VLAN filtering on the bridge.
+.It Cm -vlanfilter
+Disable VLAN filtering on the bridge.
+This is the default.
 .It Cm untagged Ar interface Ar vlan-id
 Set the untagged VLAN identifier for an interface.
-.Pp
-Setting
-.Cm untagged
-will automatically enable VLAN filtering on the interface.
 .It Cm -untagged Ar interface Ar vlan-id
 Clear the untagged VLAN identifier for an interface.
+.It Cm defuntagged Ar vlan-id
+Enable the
+.Cm untagged
+option by default on newly added members.
+.It Cm -defuntagged
+Do not enable the
+.Cm untagged
+option by default on newly added members.
 .It Cm tagged Ar interface Ar vlan-list
 Set the interface's VLAN access list to the provided list of VLANs.
 The list should be a comma-separated list of one or more VLAN IDs
@@ -2733,27 +2738,15 @@ meaning the empty set,
 or the value
 .Dq all
 meaning all VLANs (1-4094).
-.Pp
-Setting
-.Cm tagged
-will automatically enable VLAN filtering on the interface.
 .It Cm +tagged Ar interface Ar vlan-list
 Add the provided list of VLAN IDs to the interface's VLAN access list.
 The list should be formatted as described for
 .Cm tagged .
-.Pp
-Setting
-.Cm +tagged
-will automatically enable VLAN filtering on the interface.
 .It Cm -tagged Ar interface Ar vlan-list
 Remove the provided list of VLAN IDs from the interface's VLAN access
 list.
 The list should be formatted as described for
 .Cm tagged .
-.Pp
-Setting
-.Cm -tagged
-will automatically enable VLAN filtering on the interface.
 .El
 .Ss Link Aggregation and Link Failover Parameters
 The following parameters are specific to lagg interfaces:
diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4
index 2dff393ebc29..7048df4593bf 100644
--- a/share/man/man4/bridge.4
+++ b/share/man/man4/bridge.4
@@ -36,7 +36,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 5, 2025
+.Dd July 28, 2025
 .Dt IF_BRIDGE 4
 .Os
 .Sh NAME
@@ -289,7 +289,7 @@ interface on the bridge and (if necessary) assign IP 
addresses there.
 By default no access control is enabled, so any interface may
 participate in any VLAN.
 .Pp
-VLAN filtering may be enabled on an interface using the
+VLAN filtering may be enabled on a bridge using the
 .Xr ifconfig 8
 .Cm vlanfilter
 option.
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 0a35fb4095fb..46e54339a171 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -300,6 +300,8 @@ struct bridge_softc {
        struct ether_addr       sc_defaddr;     /* Default MAC address */
        if_input_fn_t           sc_if_input;    /* Saved copy of if_input */
        struct epoch_context    sc_epoch_ctx;
+       ifbr_flags_t            sc_flags;       /* bridge flags */
+       ether_vlanid_t          sc_defpvid;     /* default PVID */
 };
 
 VNET_DEFINE_STATIC(struct sx, bridge_list_sx);
@@ -417,6 +419,10 @@ static int bridge_ioctl_grte(struct bridge_softc *, void 
*);
 static int     bridge_ioctl_gifsstp(struct bridge_softc *, void *);
 static int     bridge_ioctl_sproto(struct bridge_softc *, void *);
 static int     bridge_ioctl_stxhc(struct bridge_softc *, void *);
+static int     bridge_ioctl_gflags(struct bridge_softc *, void *);
+static int     bridge_ioctl_sflags(struct bridge_softc *, void *);
+static int     bridge_ioctl_gdefpvid(struct bridge_softc *, void *);
+static int     bridge_ioctl_sdefpvid(struct bridge_softc *, void *);
 static int     bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
                    int);
 #ifdef INET
@@ -636,6 +642,18 @@ static const struct bridge_control bridge_control_table[] 
= {
 
        { bridge_ioctl_gifvlanset,      sizeof(struct ifbif_vlan_req),
          BC_F_COPYIN|BC_F_COPYOUT },
+
+       { bridge_ioctl_gflags,          sizeof(struct ifbrparam),
+         BC_F_COPYOUT },
+
+       { bridge_ioctl_sflags,          sizeof(struct ifbrparam),
+         BC_F_COPYIN|BC_F_SUSER },
+
+       { bridge_ioctl_gdefpvid,        sizeof(struct ifbrparam),
+         BC_F_COPYOUT },
+
+       { bridge_ioctl_sdefpvid,        sizeof(struct ifbrparam),
+         BC_F_COPYIN|BC_F_SUSER },
 };
 static const int bridge_control_table_size = nitems(bridge_control_table);
 
@@ -1476,6 +1494,8 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
        bif->bif_ifp = ifs;
        bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
        bif->bif_savedcaps = ifs->if_capenable;
+       if (sc->sc_flags & IFBRF_VLANFILTER)
+               bif->bif_pvid = sc->sc_defpvid;
 
        /*
         * Assign the interface's MAC address to the bridge if it's the first
@@ -1941,6 +1961,9 @@ bridge_ioctl_sifpvid(struct bridge_softc *sc, void *arg)
        struct ifbreq *req = arg;
        struct bridge_iflist *bif;
 
+       if ((sc->sc_flags & IFBRF_VLANFILTER) == 0)
+               return (EXTERROR(EINVAL, "VLAN filtering not enabled"));
+
        bif = bridge_lookup_member(sc, req->ifbr_ifsname);
        if (bif == NULL)
                return (EXTERROR(ENOENT, "Interface is not a bridge member"));
@@ -1948,8 +1971,6 @@ bridge_ioctl_sifpvid(struct bridge_softc *sc, void *arg)
        if (req->ifbr_pvid > DOT1Q_VID_MAX)
                return (EXTERROR(EINVAL, "Invalid VLAN ID"));
 
-       if (req->ifbr_pvid != DOT1Q_VID_NULL)
-               bif->bif_flags |= IFBIF_VLANFILTER;
        bif->bif_pvid = req->ifbr_pvid;
        return (0);
 }
@@ -1960,6 +1981,9 @@ bridge_ioctl_sifvlanset(struct bridge_softc *sc, void 
*arg)
        struct ifbif_vlan_req *req = arg;
        struct bridge_iflist *bif;
 
+       if ((sc->sc_flags & IFBRF_VLANFILTER) == 0)
+               return (EXTERROR(EINVAL, "VLAN filtering not enabled"));
+
        bif = bridge_lookup_member(sc, req->bv_ifname);
        if (bif == NULL)
                return (EXTERROR(ENOENT, "Interface is not a bridge member"));
@@ -1991,12 +2015,6 @@ bridge_ioctl_sifvlanset(struct bridge_softc *sc, void 
*arg)
                    "Unsupported BRDGSIFVLANSET operation"));
        }
 
-       /*
-        * The only reason to modify the VLAN access list is to use VLAN
-        * filtering on this interface, so enable it automatically.
-        */
-       bif->bif_flags |= IFBIF_VLANFILTER;
-
        return (0);
 }
 
@@ -2190,6 +2208,50 @@ bridge_ioctl_stxhc(struct bridge_softc *sc, void *arg)
        return (bstp_set_holdcount(&sc->sc_stp, param->ifbrp_txhc));
 }
 
+static int
+bridge_ioctl_gflags(struct bridge_softc *sc, void *arg)
+{
+       struct ifbrparam *param = arg;
+
+       param->ifbrp_flags = sc->sc_flags;
+
+       return (0);
+}
+
+static int
+bridge_ioctl_sflags(struct bridge_softc *sc, void *arg)
+{
+       struct ifbrparam *param = arg;
+
+       sc->sc_flags = param->ifbrp_flags;
+
+       return (0);
+}
+
+static int
+bridge_ioctl_gdefpvid(struct bridge_softc *sc, void *arg)
+{
+       struct ifbrparam *param = arg;
+
+       param->ifbrp_defpvid = sc->sc_defpvid;
+
+       return (0);
+}
+
+static int
+bridge_ioctl_sdefpvid(struct bridge_softc *sc, void *arg)
+{
+       struct ifbrparam *param = arg;
+
+       /* Reject invalid VIDs, but allow 0 to mean 'none'. */
+       if (param->ifbrp_defpvid > DOT1Q_VID_MAX)
+               return (EINVAL);
+
+       sc->sc_defpvid = param->ifbrp_defpvid;
+
+       return (0);
+}
+
 /*
  * bridge_ifdetach:
  *
@@ -2325,7 +2387,7 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet 
*dst_ifp, struct mbuf *m,
                 * outgoing interface matches the VLAN ID of the frame, remove
                 * the VLAN header.
                 */
-               if ((bif->bif_flags & IFBIF_VLANFILTER) &&
+               if ((sc->sc_flags & IFBRF_VLANFILTER) &&
                    bif->bif_pvid != DOT1Q_VID_NULL &&
                    VLANTAGOF(m) == bif->bif_pvid) {
                        m->m_flags &= ~M_VLANTAG;
@@ -3185,7 +3247,7 @@ bridge_vfilter_in(const struct bridge_iflist *sbif, 
struct mbuf *m)
                return (false);
 
        /* If VLAN filtering isn't enabled, pass everything. */
-       if ((sbif->bif_flags & IFBIF_VLANFILTER) == 0)
+       if ((sbif->bif_sc->sc_flags & IFBRF_VLANFILTER) == 0)
                return (true);
 
        if (vlan == DOT1Q_VID_NULL) {
@@ -3231,7 +3293,7 @@ bridge_vfilter_out(const struct bridge_iflist *dbif, 
const struct mbuf *m)
        NET_EPOCH_ASSERT();
 
        /* If VLAN filtering isn't enabled, pass everything. */
-       if ((dbif->bif_flags & IFBIF_VLANFILTER) == 0)
+       if ((dbif->bif_sc->sc_flags & IFBRF_VLANFILTER) == 0)
                return (true);
 
        vlan = VLANTAGOF(m);
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
index c458dcc152a0..6718c5ebcc34 100644
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -127,6 +127,17 @@
 #define        BRDGSIFPVID             31      /* set if PVID */
 #define        BRDGSIFVLANSET          32      /* set if vlan set */
 #define        BRDGGIFVLANSET          33      /* get if vlan set */
+#define        BRDGGFLAGS              34      /* get bridge flags (ifbrparam) 
*/
+#define        BRDGSFLAGS              35      /* set bridge flags (ifbrparam) 
*/
+#define        BRDGGDEFPVID            36      /* get default pvid (ifbrparam) 
*/
+#define        BRDGSDEFPVID            37      /* set default pvid (ifbrparam) 
*/
+
+/* BRDGSFLAGS, Bridge flags (non-interface-specific) */
+typedef uint32_t ifbr_flags_t;
+
+#define        IFBRF_VLANFILTER        (1U<<0) /* VLAN filtering enabled */
+
+#define        IFBRFBITS       "\020\01VLANFILTER"
 
 /*
  * Generic bridge control request.
@@ -161,11 +172,12 @@ struct ifbreq {
 #define        IFBIF_BSTP_ADMEDGE      0x0200  /* member stp admin edge 
enabled */
 #define        IFBIF_BSTP_ADMCOST      0x0400  /* member stp admin path cost */
 #define        IFBIF_PRIVATE           0x0800  /* if is a private segment */
-#define        IFBIF_VLANFILTER        0x1000  /* if does vlan filtering */
+/* was IFBIF_VLANFILTER        0x1000 */
+#define        IFBIF_QINQ              0x2000  /* if allows 802.1ad Q-in-Q */
 
 #define        IFBIFBITS       "\020\001LEARNING\002DISCOVER\003STP\004SPAN" \
                        "\005STICKY\014PRIVATE\006EDGE\007AUTOEDGE\010PTP" \
-                       "\011AUTOPTP\015VLANFILTER"
+                       "\011AUTOPTP"
 #define        IFBIFMASK       
~(IFBIF_BSTP_EDGE|IFBIF_BSTP_AUTOEDGE|IFBIF_BSTP_PTP| \
                        IFBIF_BSTP_AUTOPTP|IFBIF_BSTP_ADMEDGE| \
                        IFBIF_BSTP_ADMCOST)     /* not saved */
@@ -237,7 +249,10 @@ struct ifbrparam {
 #define        ifbrp_fwddelay  ifbrp_ifbrpu.ifbrpu_int8        /* fwd time 
(sec) */
 #define        ifbrp_maxage    ifbrp_ifbrpu.ifbrpu_int8        /* max age 
(sec) */
 #define        ifbrp_cexceeded ifbrp_ifbrpu.ifbrpu_int32       /* # of cache 
dropped
-                                                        * adresses */
+                                                        * addresses */
+#define        ifbrp_flags     ifbrp_ifbrpu.ifbrpu_int32       /* bridge flags 
*/
+#define        ifbrp_defpvid   ifbrp_ifbrpu.ifbrpu_int16       /* default pvid 
*/
+
 /*
  * Bridge current operational parameters structure.
  */
diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh
index 31299c562510..534144f46632 100755
--- a/tests/sys/net/if_bridge_test.sh
+++ b/tests/sys/net/if_bridge_test.sh
@@ -919,7 +919,7 @@ vlan_pvid_body()
 
        bridge=$(vnet_mkbridge)
 
-       ifconfig ${bridge} up
+       ifconfig ${bridge} vlanfilter up
        ifconfig ${epone}a up
        ifconfig ${eptwo}a up
        ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20
@@ -958,16 +958,18 @@ vlan_pvid_filtered_body()
        vnet_mkjail one ${epone}b
        vnet_mkjail two ${eptwo}b
 
-       jexec one ifconfig ${epone}b 192.0.2.1/24 up
-       jexec two ifconfig ${eptwo}b 192.0.2.2/24 up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b 192.0.2.1/24 up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b 192.0.2.2/24 up
 
        bridge=$(vnet_mkbridge)
 
-       ifconfig ${bridge} up
-       ifconfig ${epone}a up
-       ifconfig ${eptwo}a up
-       ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20
-       ifconfig ${bridge} addm ${eptwo}a untagged ${eptwo}a 30
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter up
+       atf_check -s exit:0 ifconfig ${epone}a up
+       atf_check -s exit:0 ifconfig ${eptwo}a up
+       atf_check -s exit:0 ifconfig ${bridge} \
+           addm ${epone}a untagged ${epone}a 20
+       atf_check -s exit:0 ifconfig ${bridge} \
+           addm ${eptwo}a untagged ${eptwo}a 30
 
        atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2
        atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1
@@ -997,18 +999,22 @@ vlan_pvid_tagged_body()
        vnet_mkjail two ${eptwo}b
 
        # Create two tagged interfaces on the appropriate VLANs
-       jexec one ifconfig ${epone}b up
-       jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up
-       jexec two ifconfig ${eptwo}b up
-       jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b.20 \
+           create 192.0.2.1/24 up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b.20 \
+           create 192.0.2.2/24 up
 
        bridge=$(vnet_mkbridge)
 
-       ifconfig ${bridge} up
-       ifconfig ${epone}a up
-       ifconfig ${eptwo}a up
-       ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20
-       ifconfig ${bridge} addm ${eptwo}a untagged ${eptwo}a 20
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter up
+       atf_check -s exit:0 ifconfig ${epone}a up
+       atf_check -s exit:0 ifconfig ${eptwo}a up
+       atf_check -s exit:0 ifconfig ${bridge} \
+           addm ${epone}a untagged ${epone}a 20
+       atf_check -s exit:0 ifconfig ${bridge} \
+           addm ${eptwo}a untagged ${eptwo}a 20
 
        # Tagged frames should not be passed.
        atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2
@@ -1042,18 +1048,20 @@ vlan_pvid_1q_body()
        # This forces the bridge to add and remove .1q tags to bridge the
        # traffic.
 
-       jexec one ifconfig ${epone}b 192.0.2.1/24 up
-       jexec two ifconfig ${eptwo}b up
-       jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b 192.0.2.1/24 up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 
up
 
        bridge=$(vnet_mkbridge)
 
-       ifconfig ${bridge} addm ${epone}a untagged ${epone}a 20
-       ifconfig ${bridge} addm ${eptwo}a
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter up
+       atf_check -s exit:0 ifconfig ${bridge} \
+           addm ${epone}a untagged ${epone}a 20
+       atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a \
+           tagged ${eptwo}a 20
 
-       ifconfig ${bridge} up
-       ifconfig ${epone}a up
-       ifconfig ${eptwo}a up
+       atf_check -s exit:0 ifconfig ${epone}a up
+       atf_check -s exit:0 ifconfig ${eptwo}a up
 
        atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2
        atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1
@@ -1085,18 +1093,20 @@ vlan_filtering_body()
        vnet_mkjail one ${epone}b
        vnet_mkjail two ${eptwo}b
 
-       jexec one ifconfig ${epone}b up
-       jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up
-       jexec two ifconfig ${eptwo}b up
-       jexec two ifconfig ${eptwo}b.20 create 192.0.2.2/24 up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b.20 \
+           create 192.0.2.1/24 up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b up
+       atf_check -s exit:0 jexec two ifconfig ${eptwo}b.20 \
+           create 192.0.2.2/24 up
 
        bridge=$(vnet_mkbridge)
 
-       ifconfig ${bridge} up
-       ifconfig ${epone}a up
-       ifconfig ${eptwo}a up
-       ifconfig ${bridge} addm ${epone}a vlanfilter ${epone}a
-       ifconfig ${bridge} addm ${eptwo}a vlanfilter ${eptwo}a
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter up
+       atf_check -s exit:0 ifconfig ${epone}a up
+       atf_check -s exit:0 ifconfig ${eptwo}a up
+       atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a
+       atf_check -s exit:0 ifconfig ${bridge} addm ${eptwo}a
 
        # Right now there are no VLANs on the access list, so everything
        # should be blocked.
@@ -1116,15 +1126,15 @@ vlan_filtering_body()
        atf_check -s exit:0 ifconfig ${bridge} -untagged ${eptwo}a
 
        # Add VLANs 10-30 to the access list; now access should be allowed.
-       ifconfig ${bridge} +tagged ${epone}a 10-30
-       ifconfig ${bridge} +tagged ${eptwo}a 10-30
+       atf_check -s exit:0 ifconfig ${bridge} +tagged ${epone}a 10-30
+       atf_check -s exit:0 ifconfig ${bridge} +tagged ${eptwo}a 10-30
        atf_check -s exit:0 -o ignore jexec one ping -c 3 -t 1 192.0.2.2
        atf_check -s exit:0 -o ignore jexec two ping -c 3 -t 1 192.0.2.1
 
        # Remove vlan 20 from the access list, now access should be blocked
        # again.
-       ifconfig ${bridge} -tagged ${epone}a 20
-       ifconfig ${bridge} -tagged ${eptwo}a 20
+       atf_check -s exit:0 ifconfig ${bridge} -tagged ${epone}a 20
+       atf_check -s exit:0 ifconfig ${bridge} -tagged ${eptwo}a 20
        atf_check -s exit:2 -o ignore jexec one ping -c 3 -t 1 192.0.2.2
        atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1
 }
@@ -1151,9 +1161,10 @@ vlan_ifconfig_tagged_body()
 
        ep=$(vnet_mkepair)
        bridge=$(vnet_mkbridge)
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter up
 
-       ifconfig ${bridge} addm ${ep}a vlanfilter ${ep}a up
-       ifconfig ${ep}a up
+       atf_check -s exit:0 ifconfig ${bridge} addm ${ep}a
+       atf_check -s exit:0 ifconfig ${ep}a up
 
        # To start with, no vlans should be configured.
        atf_check -s exit:0 -o not-match:"tagged" ifconfig ${bridge}
@@ -1210,18 +1221,20 @@ vlan_svi_body()
 
        vnet_mkjail one ${epone}b
 
-       jexec one ifconfig ${epone}b up
-       jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b up
+       atf_check -s exit:0 jexec one ifconfig ${epone}b.20 \
+           create 192.0.2.1/24 up
 
        bridge=$(vnet_mkbridge)
 
-       ifconfig ${bridge} up
-       ifconfig ${epone}a up
-       ifconfig ${bridge} addm ${epone}a tagged ${epone}a 20
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter up
+       atf_check -s exit:0 ifconfig ${epone}a up
+       atf_check -s exit:0 ifconfig ${bridge} addm ${epone}a \
+           tagged ${epone}a 20
 
        svi=$(vnet_mkvlan)
-       ifconfig ${svi} vlan 20 vlandev ${bridge}
-       ifconfig ${svi} inet 192.0.2.2/24 up
+       atf_check -s exit:0 ifconfig ${svi} vlan 20 vlandev ${bridge}
+       atf_check -s exit:0 ifconfig ${svi} inet 192.0.2.2/24 up
 
        atf_check -s exit:0 -o ignore ping -c 3 -t 1 192.0.2.1
 }
@@ -1311,6 +1324,59 @@ bridge_svi_in_bridge_cleanup()
        vnet_cleanup
 }
 
+atf_test_case "vlan_defuntagged" "cleanup"
+vlan_defuntagged_head()
+{
+       atf_set descr 'defuntagged (defpvid) bridge option'
+       atf_set require.user root
+}
+
+vlan_defuntagged_body()
+{
+       vnet_init
+       vnet_init_bridge
+
+       bridge=$(vnet_mkbridge)
+       atf_check -s exit:0 ifconfig ${bridge} vlanfilter
+
+       # Invalid VLAN IDs
+       atf_check -s exit:1 -ematch:"invalid vlan id: 0" \
+               ifconfig ${bridge} defuntagged 0
+       atf_check -s exit:1 -ematch:"invalid vlan id: 4095" \
+               ifconfig ${bridge} defuntagged 4095
+       atf_check -s exit:1 -ematch:"invalid vlan id: 5000" \
+               ifconfig ${bridge} defuntagged 5000
+
+       # Check the bridge option is set and cleared correctly
+       atf_check -s exit:0 -onot-match:"defuntagged=" \
+               ifconfig ${bridge}
+
+       atf_check -s exit:0 ifconfig ${bridge} defuntagged 10
+       atf_check -s exit:0 -omatch:"defuntagged=10$" \
+               ifconfig ${bridge}
+
+       atf_check -s exit:0 ifconfig ${bridge} -defuntagged
+       atf_check -s exit:0 -onot-match:"defuntagged=" \
+               ifconfig ${bridge}
+
+       # Check the untagged option is correctly set on a member
+       atf_check -s exit:0 ifconfig ${bridge} defuntagged 10
+
+       epair=$(vnet_mkepair)
+       atf_check -s exit:0 ifconfig ${bridge} addm ${epair}a
+
+       tag=$(ifconfig ${bridge} | sed -Ene \
+               "/member: ${epair}a/ { N;s/.*untagged ([0-9]+).*/\\1/p;q; }")
+       if [ "$tag" != "10" ]; then
+               atf_fail "wrong untagged vlan: ${tag}"
+       fi
+}
+
+vlan_defuntagged_cleanup()
+{
+       vnet_cleanup
+}
+
 atf_init_test_cases()
 {
        atf_add_test_case "bridge_transmit_ipv4_unicast"
@@ -1338,5 +1404,6 @@ atf_init_test_cases()
        atf_add_test_case "vlan_ifconfig_tagged"
        atf_add_test_case "vlan_svi"
        atf_add_test_case "vlan_qinq"
+       atf_add_test_case "vlan_defuntagged"
        atf_add_test_case "bridge_svi_in_bridge"
 }

Reply via email to