Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

if_ethersubr.c: fix ether_8021q_frame to respect VID from ether_vtag #1347

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sys/net/ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ void ether_vlan_mtap(struct bpf_if *, struct mbuf *,
void *, u_int);
struct mbuf *ether_vlanencap_proto(struct mbuf *, uint16_t, uint16_t);
bool ether_8021q_frame(struct mbuf **mp, struct ifnet *ife,
struct ifnet *p, const struct ether_8021q_tag *);
struct ifnet *p, const uint16_t proto);
void ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr);
void ether_gen_addr_byname(const char *nameunit, struct ether_addr *hwaddr);

Expand Down
35 changes: 10 additions & 25 deletions sys/net/if_ethersubr.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,6 @@ bad: if (m != NULL)
static bool
ether_set_pcp(struct mbuf **mp, struct ifnet *ifp, uint8_t pcp)
{
struct ether_8021q_tag qtag;
struct ether_header *eh;

eh = mtod(*mp, struct ether_header *);
Expand All @@ -452,10 +451,8 @@ ether_set_pcp(struct mbuf **mp, struct ifnet *ifp, uint8_t pcp)
return (true);
}

qtag.vid = 0;
qtag.pcp = pcp;
qtag.proto = ETHERTYPE_VLAN;
if (ether_8021q_frame(mp, ifp, ifp, &qtag))
EVL_APPLY_PRI((*mp), pcp);
if (ether_8021q_frame(mp, ifp, ifp, ETHERTYPE_VLAN))
return (true);
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return (false);
Expand Down Expand Up @@ -1401,13 +1398,11 @@ ether_do_pcp(struct ifnet *ifp, struct mbuf *m)

bool
ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
const struct ether_8021q_tag *qtag)
const uint16_t proto)
{
struct m_tag *mtag;
int n;
uint16_t tag;
uint8_t pcp = qtag->pcp;
static const char pad[8]; /* just zeros */
static const char pad[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* Just zeros. */

/*
* Pad the frame to the minimum size allowed if told to.
Expand Down Expand Up @@ -1435,13 +1430,6 @@ ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
}
}

/*
* If PCP is set in mbuf, use it
*/
if ((*mp)->m_flags & M_VLANTAG) {
pcp = EVL_PRIOFTAG((*mp)->m_pkthdr.ether_vtag);
}

/*
* If underlying interface can do VLAN tag insertion itself,
* just pass the packet along. However, we need some way to
Expand All @@ -1451,15 +1439,12 @@ ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
*/
if (V_vlan_mtag_pcp && (mtag = m_tag_locate(*mp, MTAG_8021Q,
MTAG_8021Q_PCP_OUT, NULL)) != NULL)
tag = EVL_MAKETAG(qtag->vid, *(uint8_t *)(mtag + 1), 0);
else
tag = EVL_MAKETAG(qtag->vid, pcp, 0);
if ((p->if_capenable & IFCAP_VLAN_HWTAGGING) &&
(qtag->proto == ETHERTYPE_VLAN)) {
(*mp)->m_pkthdr.ether_vtag = tag;
(*mp)->m_flags |= M_VLANTAG;
} else {
*mp = ether_vlanencap_proto(*mp, tag, qtag->proto);
EVL_APPLY_PRI((*mp), *(uint8_t *)(mtag + 1));

if ((p->if_capenable & IFCAP_VLAN_HWTAGGING) == 0 ||
(proto != ETHERTYPE_VLAN)) {
*mp = ether_vlanencap_proto(*mp,
(*mp)->m_pkthdr.ether_vtag, proto);
if (*mp == NULL) {
if_printf(ife, "unable to prepend 802.1Q header");
return (false);
Expand Down
13 changes: 8 additions & 5 deletions sys/net/if_vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,10 @@
int ifv_encaplen; /* encapsulation length */
int ifv_mtufudge; /* MTU fudged by this much */
int ifv_mintu; /* min transmission unit */
struct ether_8021q_tag ifv_qtag;
#define ifv_proto ifv_qtag.proto
#define ifv_vid ifv_qtag.vid
#define ifv_pcp ifv_qtag.pcp
uint16_t ifv_proto;
uint16_t ifv_vid;
uint8_t ifv_pcp;
/*uint8_t ifv_cfi; TBD */
struct task lladdr_task;
CK_SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead;
#ifndef VLAN_ARRAY
Expand Down Expand Up @@ -1472,7 +1472,10 @@
return (ENETDOWN);
}

if (!ether_8021q_frame(&m, ifp, p, &ifv->ifv_qtag)) {
m->m_pkthdr.ether_vtag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp,
/*ifv->ifv_pcp TBD*/ 0);

Check warning on line 1476 in sys/net/if_vlan.c

View workflow job for this annotation

GitHub Actions / Style Checker

Block comments use a leading /* on a separate line
m->m_flags |= M_VLANTAG;
if (!ether_8021q_frame(&m, ifp, p, ifv->ifv_proto)) {
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return (0);
}
Expand Down
9 changes: 0 additions & 9 deletions sys/net/if_vlan_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,9 @@
#define DOT1Q_VID_DEF_SR_PVID 0x2
#define DOT1Q_VID_RSVD_IMPL 0xfff

/*
* 802.1q full tag. Proto and vid are stored in host byte order.
*/
struct ether_8021q_tag {
uint16_t proto;
uint16_t vid;
uint8_t pcp;
};

#define VLAN_CAPABILITIES(_ifp) do { \
if (if_getvlantrunk(_ifp) != NULL) \
(*vlan_trunk_cap_p)(_ifp); \

Check warning on line 136 in sys/net/if_vlan_var.h

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line
} while (0)

#define VLAN_TRUNKDEV(_ifp) \
Expand Down
Loading