Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151202184
D51231.id.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
D51231.id.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
@@ -190,6 +190,21 @@
}
}
+static char const *
+vlan_proto_name(uint16_t proto)
+{
+ switch (proto) {
+ case 0:
+ return "none";
+ case ETHERTYPE_VLAN:
+ return "802.1q";
+ case ETHERTYPE_QINQ:
+ return "802.1ad";
+ default:
+ return "unknown";
+ }
+}
+
static void
bridge_status(if_ctx *ctx)
{
@@ -261,6 +276,9 @@
else
printf(" <unknown state %d>", state);
}
+ if (member->ifbr_vlanproto != 0)
+ printf(" vlan protocol %s",
+ vlan_proto_name(member->ifbr_vlanproto));
if (member->ifbr_pvid != 0)
printf(" untagged %u", (unsigned)member->ifbr_pvid);
print_vlans(&bridge->member_vlans[i]);
@@ -895,6 +913,25 @@
do_bridgeflag(ctx, val, IFBIF_QINQ, 0);
}
+static void
+setbridge_ifvlanproto(if_ctx *ctx, const char *ifname, const char *proto)
+{
+ struct ifbreq req;
+
+ memset(&req, 0, sizeof(req));
+ strlcpy(req.ifbr_ifsname, ifname, sizeof(req.ifbr_ifsname));
+
+ if (strcmp(proto, "802.1q") == 0)
+ req.ifbr_vlanproto = ETHERTYPE_VLAN;
+ else if (strcmp(proto, "802.1ad") == 0)
+ req.ifbr_vlanproto = ETHERTYPE_QINQ;
+ else
+ errx(1, "unrecognised VLAN protocol: %s", proto);
+
+ if (do_cmd(ctx, BRDGSIFVLANPROTO, &req, sizeof(req), 1) < 0)
+ err(1, "BRDGSIFVLANPROTO");
+}
+
static struct cmd bridge_cmds[] = {
DEF_CMD_ARG("addm", setbridge_add),
DEF_CMD_ARG("deletem", setbridge_delete),
@@ -936,6 +973,7 @@
DEF_CMD_ARG2("tagged", setbridge_tagged),
DEF_CMD_ARG2("+tagged", addbridge_tagged),
DEF_CMD_ARG2("-tagged", delbridge_tagged),
+ DEF_CMD_ARG2("ifvlanproto", setbridge_ifvlanproto),
DEF_CMD_ARG("timeout", setbridge_timeout),
DEF_CMD_ARG("private", setbridge_private),
DEF_CMD_ARG("-private", unsetbridge_private),
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -2765,6 +2765,17 @@
.Cm qinq
option by default on newly added members.
This is the default behavior.
+.It Cm ifvlanproto Ar interface Ar proto
+Set the VLAN encapsulation protocol on
+.Ar interface
+to
+.Ar proto ,
+which must be either
+.Dq 802.1q
+or
+.Dq 802.1ad .
+The default is
+.Dq 802.1q .
.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
@@ -259,6 +259,7 @@
struct epoch_context bif_epoch_ctx;
ether_vlanid_t bif_pvid; /* port vlan id */
ifbvlan_set_t bif_vlan_set; /* if allowed tagged vlans */
+ uint16_t bif_vlanproto; /* vlan protocol */
};
/*
@@ -423,6 +424,7 @@
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_ioctl_svlanproto(struct bridge_softc *, void *);
static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
int);
#ifdef INET
@@ -654,6 +656,9 @@
{ bridge_ioctl_sdefpvid, sizeof(struct ifbrparam),
BC_F_COPYIN|BC_F_SUSER },
+
+ { bridge_ioctl_svlanproto, sizeof(struct ifbreq),
+ BC_F_COPYIN|BC_F_SUSER },
};
static const int bridge_control_table_size = nitems(bridge_control_table);
@@ -1494,6 +1499,7 @@
bif->bif_ifp = ifs;
bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
bif->bif_savedcaps = ifs->if_capenable;
+ bif->bif_vlanproto = ETHERTYPE_VLAN;
if (sc->sc_flags & IFBRF_VLANFILTER)
bif->bif_pvid = sc->sc_defpvid;
if (sc->sc_flags & IFBRF_DEFQINQ)
@@ -1579,6 +1585,7 @@
req->ifbr_addrmax = bif->bif_addrmax;
req->ifbr_addrexceeded = bif->bif_addrexceeded;
req->ifbr_pvid = bif->bif_pvid;
+ req->ifbr_vlanproto = bif->bif_vlanproto;
/* Copy STP state options as flags */
if (bp->bp_operedge)
@@ -2254,6 +2261,24 @@
return (0);
}
+static int
+bridge_ioctl_svlanproto(struct bridge_softc *sc, void *arg)
+{
+ struct ifbreq *req = arg;
+ struct bridge_iflist *bif;
+
+ bif = bridge_lookup_member(sc, req->ifbr_ifsname);
+ if (bif == NULL)
+ return (EXTERROR(ENOENT, "Interface is not a bridge member"));
+
+ if (req->ifbr_vlanproto != ETHERTYPE_VLAN &&
+ req->ifbr_vlanproto != ETHERTYPE_QINQ)
+ return (EXTERROR(EINVAL, "Invalid VLAN protocol"));
+
+ bif->bif_vlanproto = req->ifbr_vlanproto;
+
+ return (0);
+}
/*
* bridge_ifdetach:
*
@@ -2397,12 +2422,15 @@
}
/*
- * If underlying interface can not do VLAN tag insertion itself
- * then attach a packet tag that holds it.
+ * There are two cases where we have to insert our own tag:
+ * if the member interface doesn't support hardware tagging,
+ * or if the tag proto is not 802.1q.
*/
if ((m->m_flags & M_VLANTAG) &&
- (dst_ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) {
- m = ether_vlanencap(m, m->m_pkthdr.ether_vtag);
+ ((dst_ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0 ||
+ bif->bif_vlanproto != ETHERTYPE_VLAN)) {
+ m = ether_vlanencap_proto(m, m->m_pkthdr.ether_vtag,
+ bif->bif_vlanproto);
if (m == NULL) {
if_printf(dst_ifp,
"unable to prepend VLAN header\n");
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
@@ -131,6 +131,7 @@
#define BRDGSFLAGS 35 /* set bridge flags (ifbrparam) */
#define BRDGGDEFPVID 36 /* get default pvid (ifbrparam) */
#define BRDGSDEFPVID 37 /* set default pvid (ifbrparam) */
+#define BRDGSIFVLANPROTO 38 /* set if vlan protocol (ifbreq) */
/* BRDGSFLAGS, Bridge flags (non-interface-specific) */
typedef uint32_t ifbr_flags_t;
@@ -157,6 +158,7 @@
uint32_t ifbr_addrmax; /* member if addr max */
uint32_t ifbr_addrexceeded; /* member if addr violations */
ether_vlanid_t ifbr_pvid; /* member if PVID */
+ uint16_t ifbr_vlanproto; /* member if VLAN protocol */
uint8_t pad[32];
};
@@ -252,6 +254,7 @@
* addresses */
#define ifbrp_flags ifbrp_ifbrpu.ifbrpu_int32 /* bridge flags */
#define ifbrp_defpvid ifbrp_ifbrpu.ifbrpu_int16 /* default pvid */
+#define ifbrp_vlanproto ifbrp_ifbrpu.ifbrpu_int8 /* vlan protocol */
/*
* Bridge current operational parameters structure.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 7:27 PM (8 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31046930
Default Alt Text
D51231.id.diff (6 KB)
Attached To
Mode
D51231: bridge: allow VLAN protocol to be configured
Attached
Detach File
Event Timeline
Log In to Comment