The skb->mac_len is used for the skb_push before inserting the vlan tag to the packet payload. After that the skb is pulled only ETH_HLEN and the network header is being reset to get the correct packet mac header. This avoids sending packets with incorrect mac header when vlan tags are pushed with tc-vlan and the bridge tpid does not match the inserted vlan tpid. The vlan tag is inserted at the right place of the header. Signed-off-by: Zahari Doychev <zahari.doychev@xxxxxxxxx> --- net/bridge/br_vlan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 4a2f31157ef5..f857487245c6 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -460,13 +460,14 @@ static bool __allowed_ingress(const struct net_bridge *br, /* Tagged frame */ if (skb->vlan_proto != br->vlan_proto) { /* Protocol-mismatch, empty out vlan_tci for new tag */ - skb_push(skb, ETH_HLEN); + skb_push(skb, skb->mac_len); skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, skb_vlan_tag_get(skb)); if (unlikely(!skb)) return false; skb_pull(skb, ETH_HLEN); + skb_reset_network_header(skb); skb_reset_mac_len(skb); *vid = 0; tagged = false; -- 2.20.1