Page MenuHomeFreeBSD

D51227.diff
No OneTemporary

D51227.diff

diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -883,6 +883,18 @@
err(1, "BRDGSDEFPVID");
}
+static void
+setbridge_qinq(if_ctx *ctx, const char *val, int dummy __unused)
+{
+ do_bridgeflag(ctx, val, IFBIF_QINQ, 1);
+}
+
+static void
+unsetbridge_qinq(if_ctx *ctx, const char *val, int dummy __unused)
+{
+ do_bridgeflag(ctx, val, IFBIF_QINQ, 0);
+}
+
static struct cmd bridge_cmds[] = {
DEF_CMD_ARG("addm", setbridge_add),
DEF_CMD_ARG("deletem", setbridge_delete),
@@ -933,6 +945,12 @@
unsetbridge_flags),
DEF_CMD_ARG("defuntagged", setbridge_defuntagged),
DEF_CMD("-defuntagged", 0, unsetbridge_defuntagged),
+ DEF_CMD("defqinq", (int32_t)IFBRF_DEFQINQ,
+ setbridge_flags),
+ DEF_CMD("-defqinq", (int32_t)IFBRF_DEFQINQ,
+ unsetbridge_flags),
+ DEF_CMD_ARG("qinq", setbridge_qinq),
+ DEF_CMD_ARG("-qinq", unsetbridge_qinq),
};
static struct afswtch af_bridge = {
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 30, 2025
+.Dd August 5, 2025
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -2747,6 +2747,24 @@
list.
The list should be formatted as described for
.Cm tagged .
+.It Cm qinq Ar interface
+Allow this interface to send 802.1ad
+.Dq Q-in-Q
+frames.
+.It Cm -qinq Ar interface
+Do not allow this interface to send 802.1ad
+.Dq Q-in-Q
+frames.
+This is the default behavior.
+.It Cm defqinq
+Enable the
+.Cm qinq
+option by default on newly added members.
+.It Cm -defqinq
+Do not enable the
+.Cm qinq
+option by default on newly added members.
+This is the default behavior.
.El
.Ss Link Aggregation and Link Failover Parameters
The following parameters are specific to lagg interfaces:
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1496,6 +1496,8 @@
bif->bif_savedcaps = ifs->if_capenable;
if (sc->sc_flags & IFBRF_VLANFILTER)
bif->bif_pvid = sc->sc_defpvid;
+ if (sc->sc_flags & IFBRF_DEFQINQ)
+ bif->bif_flags |= IFBIF_QINQ;
/*
* Assign the interface's MAC address to the bridge if it's the first
@@ -2828,6 +2830,16 @@
NET_EPOCH_ASSERT();
+ /* We need the Ethernet header later, so make sure we have it now. */
+ if (m->m_len < ETHER_HDR_LEN) {
+ m = m_pullup(m, ETHER_HDR_LEN);
+ if (m == NULL) {
+ if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1);
+ m_freem(m);
+ return (NULL);
+ }
+ }
+
eh = mtod(m, struct ether_header *);
vlan = VLANTAGOF(m);
@@ -3250,6 +3262,18 @@
if ((sbif->bif_sc->sc_flags & IFBRF_VLANFILTER) == 0)
return (true);
+ /* If Q-in-Q is disabled, check for stacked tags. */
+ if ((sbif->bif_flags & IFBIF_QINQ) == 0) {
+ struct ether_header *eh;
+ uint16_t proto;
+
+ eh = mtod(m, struct ether_header *);
+ proto = ntohs(eh->ether_type);
+
+ if (proto == ETHERTYPE_VLAN || proto == ETHERTYPE_QINQ)
+ return (false);
+ }
+
if (vlan == DOT1Q_VID_NULL) {
/*
* The frame doesn't have a tag. If the interface does not
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -136,8 +136,9 @@
typedef uint32_t ifbr_flags_t;
#define IFBRF_VLANFILTER (1U<<0) /* VLAN filtering enabled */
+#define IFBRF_DEFQINQ (1U<<1) /* 802.1ad Q-in-Q allowed by default */
-#define IFBRFBITS "\020\01VLANFILTER"
+#define IFBRFBITS "\020\01VLANFILTER\02DEFQINQ"
/*
* Generic bridge control request.
@@ -172,12 +173,11 @@
#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 */
-/* was IFBIF_VLANFILTER 0x1000 */
-#define IFBIF_QINQ 0x2000 /* if allows 802.1ad Q-in-Q */
+#define IFBIF_QINQ 0x1000 /* if allows 802.1ad Q-in-Q */
#define IFBIFBITS "\020\001LEARNING\002DISCOVER\003STP\004SPAN" \
"\005STICKY\014PRIVATE\006EDGE\007AUTOEDGE\010PTP" \
- "\011AUTOPTP"
+ "\011AUTOPTP\015QINQ"
#define IFBIFMASK ~(IFBIF_BSTP_EDGE|IFBIF_BSTP_AUTOEDGE|IFBIF_BSTP_PTP| \
IFBIF_BSTP_AUTOPTP|IFBIF_BSTP_ADMEDGE| \
IFBIF_BSTP_ADMCOST) /* not saved */
diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh
--- a/tests/sys/net/if_bridge_test.sh
+++ b/tests/sys/net/if_bridge_test.sh
@@ -1268,21 +1268,25 @@
# Create a QinQ trunk between the two jails. The outer (provider) tag
# is 5, and the inner tag is 10.
- jexec one ifconfig ${epone}b up
- jexec one ifconfig ${epone}b.5 create vlanproto 802.1ad up
- jexec one ifconfig ${epone}b.5.10 create inet 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.5 create vlanproto 802.1ad up
+ atf_check -s exit:0 jexec one \
+ ifconfig ${epone}b.5.10 create inet 192.0.2.1/24 up
- jexec two ifconfig ${eptwo}b up
- jexec two ifconfig ${eptwo}b.5 create vlanproto 802.1ad up
- jexec two ifconfig ${eptwo}b.5.10 create inet 192.0.2.2/24 up
+ atf_check -s exit:0 jexec two ifconfig ${eptwo}b up
+ atf_check -s exit:0 jexec two ifconfig \
+ ${eptwo}b.5 create vlanproto 802.1ad up
+ atf_check -s exit:0 jexec two ifconfig \
+ ${eptwo}b.5.10 create inet 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 defqinq 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.
@@ -1290,10 +1294,16 @@
atf_check -s exit:2 -o ignore jexec two ping -c 3 -t 1 192.0.2.1
# Add the provider tag to the access list; now traffic should be passed.
- ifconfig ${bridge} +tagged ${epone}a 5
- ifconfig ${bridge} +tagged ${eptwo}a 5
+ atf_check -s exit:0 ifconfig ${bridge} +tagged ${epone}a 5
+ atf_check -s exit:0 ifconfig ${bridge} +tagged ${eptwo}a 5
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 the qinq flag from one of the interfaces; traffic should
+ # be blocked again.
+ atf_check -s exit:0 ifconfig ${bridge} -qinq ${epone}a
+ 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
}
vlan_qinq_cleanup()

File Metadata

Mime Type
text/plain
Expires
Thu, May 28, 10:39 AM (9 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33583881
Default Alt Text
D51227.diff (6 KB)

Event Timeline