Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F158007695
D51227.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D51227.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D51227: bridge: make 802.1ad (Q-in-Q) configurable
Attached
Detach File
Event Timeline
Log In to Comment