Page MenuHomeFreeBSD

if_epair: also remove vlan metadata from packets
ClosedPublic

Authored by kp on Apr 10 2023, 1:05 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Sep 23, 2:21 AM
Unknown Object (File)
Wed, Sep 18, 7:08 AM
Unknown Object (File)
Thu, Sep 5, 6:10 AM
Unknown Object (File)
Jul 24 2024, 10:34 AM
Unknown Object (File)
Jul 15 2024, 9:00 PM
Unknown Object (File)
Jul 11 2024, 8:27 PM
Unknown Object (File)
Jul 10 2024, 9:56 PM
Unknown Object (File)
Jul 8 2024, 8:43 AM

Details

Summary

We already remove mbuf tags from packets transitting an if_epair, but we
didn't remove vlan information.
In certain configurations this could lead to unexpected vlan tags
turning up on the rx side.

PR: 270736
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 50815
Build 47706: arc lint + arc unit

Event Timeline

kp requested review of this revision.Apr 10 2023, 1:05 PM

Will that mean that one has to create VLAN interfaces on top of a base interface and then bridge individual vlans over various epairs into vnet jails? Does that even work with bridges and vlans that way?

In D39482#898787, @bz wrote:

Will that mean that one has to create VLAN interfaces on top of a base interface and then bridge individual vlans over various epairs into vnet jails? Does that even work with bridges and vlans that way?

I don't quite follow.

Note that we're removing vlan metadata from the mbuf, not vlan tags in the Ethernet packet.

D39483 illustrates the problem this fixes.

markj added inline comments.
sys/net/if_epair.c
145

It looks like this function already assumes M_PKTHDR is set?

In D39482#898808, @kp wrote:
In D39482#898787, @bz wrote:

Will that mean that one has to create VLAN interfaces on top of a base interface and then bridge individual vlans over various epairs into vnet jails? Does that even work with bridges and vlans that way?

I don't quite follow.

Note that we're removing vlan metadata from the mbuf, not vlan tags in the Ethernet packet.

Oh doh. Sorry, maybe make the first line of the commit message more detailed like this.

kp retitled this revision from if_epair: also remove vlan flags from packets to if_epair: also remove vlan metadata from packets.Apr 10 2023, 3:05 PM
kp added inline comments.
sys/net/if_epair.c
145

Ah yes. It will always be called from a path where that's already asserted, but I'll add another one in this function so next time I'm here I might notice I don't need the check.

  • don't check for M_PKTHDR
markj added inline comments.
sys/net/if_epair.c
145

I'm not sure why it's useful to have separate epair_clear_mbuf() and epair_prepare_mbuf() functions, but it doesn't hurt.

This revision is now accepted and ready to land.Apr 10 2023, 3:10 PM
This revision was automatically updated to reflect the committed changes.

For epair(4), I think it can land as is.

Further more, I would proposal to handle the removal of M_VLANTAG in tx side of net stack, instead of in driver stack.

bool
ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
    struct ether_8021q_tag *qtag)
{
...
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);
		if (*mp == NULL) {
			if_printf(ife, "unable to prepend 802.1Q header");
			return (false);
		}
+++         (*mp)->m_flags &= ~M_VLANTAG;
+++         (*mp)->m_pkthdr.ether_vtag = 0;
	}
}

Some tests with ifconfig re(4) -vlanhwtag pcp 3 shows the same symptom with epair(4). I'll test this approach and report later.

This approach however has larger impact, it will affect all drivers (with vlanhwtag off).

In D39482#899185, @zlei wrote:

For epair(4), I think it can land as is.

Further more, I would proposal to handle the removal of M_VLANTAG in tx side of net stack, instead of in driver stack.

bool
ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
    struct ether_8021q_tag *qtag)
{
...
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);
		if (*mp == NULL) {
			if_printf(ife, "unable to prepend 802.1Q header");
			return (false);
		}
+++         (*mp)->m_flags &= ~M_VLANTAG;
+++         (*mp)->m_pkthdr.ether_vtag = 0;
	}
}

That was my initial version of this fix, but my understanding was (based on tcpdump on both ends of the epair) that the problem occurred on the rx side.

Some tests with ifconfig re(4) -vlanhwtag pcp 3 shows the same symptom with epair(4). I'll test this approach and report later.

That's surprising. If it also occurs in that setup I must be misinterpreting what I've seen, and this fix is insufficient.