Page MenuHomeFreeBSD

D51231.id.diff
No OneTemporary

D51231.id.diff

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

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)

Event Timeline