Merge branch 'vlan-reorder'
Vladislav Yasevich says: ==================== Fix issues with vlans without REORDER_HEADER A while ago Phil Sutter brought up an issue with vlans without REORDER_HEADER and bridges. The problem was that if a vlan without REORDER_HEADER was a port in the bridge, the bridge ended up forwarding corrupted packets that still contained the vlan header. The same issue exists for bridge mode macvlan/macvtap devices. An additional issue with vlans without REORDER_HEADER is that stacking them also doesn't work. The reason here is that skb_reorder_vlan_header() function assumes that it on ETH_HLEN bytes deep into the packet. That is not the case, when you a vlan without REORRDER_HEADER flag set. This series attempts to correct these 2 issues. 1) To solve the stacked vlans problem, the patch simply use skb->mac_len as an offset to start copying mac addresses that is part of header reordering. 2) To fix the issue with bridge/macvlan/macvtap, the second patch simply doesn't write the vlan header back to the packet if the vlan device is either a bridge or a macvlan port. This ends up being the simplest and least performance intrussive solution. I've considered extending patch 2 to all stacked devices (essentially checked for the presense of rx_handler), but that feels like a broader restriction and _may_ break existing uses. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
eb3f8b42aa
|
@ -3857,6 +3857,11 @@ static inline bool netif_is_bridge_master(const struct net_device *dev)
|
|||
return dev->priv_flags & IFF_EBRIDGE;
|
||||
}
|
||||
|
||||
static inline bool netif_is_bridge_port(const struct net_device *dev)
|
||||
{
|
||||
return dev->priv_flags & IFF_BRIDGE_PORT;
|
||||
}
|
||||
|
||||
static inline bool netif_is_ovs_master(const struct net_device *dev)
|
||||
{
|
||||
return dev->priv_flags & IFF_OPENVSWITCH;
|
||||
|
|
|
@ -30,7 +30,9 @@ bool vlan_do_receive(struct sk_buff **skbp)
|
|||
skb->pkt_type = PACKET_HOST;
|
||||
}
|
||||
|
||||
if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) {
|
||||
if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR) &&
|
||||
!netif_is_macvlan_port(vlan_dev) &&
|
||||
!netif_is_bridge_port(vlan_dev)) {
|
||||
unsigned int offset = skb->data - skb_mac_header(skb);
|
||||
|
||||
/*
|
||||
|
|
|
@ -4268,7 +4268,8 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
|
||||
memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len,
|
||||
2 * ETH_ALEN);
|
||||
skb->mac_header += VLAN_HLEN;
|
||||
return skb;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue