The skb_mpls_pop was not updating ethertype of an ethernet packet if the packet was originally received from a non ARPHRD_ETHER device. In the below OVS data path flow, since the device corresponding to port 7 is an l3 device (ARPHRD_NONE) the skb_mpls_pop function does not update the ethertype of the packet even though the previous push_eth action had added an ethernet header to the packet. recirc_id(0),in_port(7),eth_type(0x8847), mpls(label=12/0xfffff,tc=0/0,ttl=0/0x0,bos=1/1), actions:push_eth(src=00:00:00:00:00:00,dst=00:00:00:00:00:00), pop_mpls(eth_type=0x800),4
Unified · Split
| @@ -3530,7 +3530,8 @@ int skb_vlan_pop(struct sk_buff *skb); · 3529 unmodified lines | ||
| 3530 | 3530 | int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); |
| 3531 | 3531 | int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, |
| 3532 | 3532 | int mac_len); |
| 3533 | −int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len); | |
| 3533 | +int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len, | |
| 3534 | + bool ethernet); | |
| 3534 | 3535 | int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse); |
| 3535 | 3536 | int skb_mpls_dec_ttl(struct sk_buff *skb); |
| 3536 | 3537 | struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy, |
| @@ -5529,12 +5529,14 @@ EXPORT_SYMBOL_GPL(skb_mpls_push); · 5528 unmodified lines | ||
| 5529 | 5529 | * @skb: buffer |
| 5530 | 5530 | * @next_proto: ethertype of header after popped MPLS header |
| 5531 | 5531 | * @mac_len: length of the MAC header |
| 5532 | + * @ethernet: flag to indicate if ethernet header is present in packet | |
| 5532 | 5533 | * |
| 5533 | 5534 | * Expects skb->data at mac header. |
| 5534 | 5535 | * |
| 5535 | 5536 | * Returns 0 on success, -errno otherwise. |
| 5536 | 5537 | */ |
| 5537 | −int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len) | |
| 5538 | +int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len, | |
| 5539 | + bool ethernet) | |
| 5538 | 5540 | { |
| 5539 | 5541 | int err; |
| 5540 | 5542 | |
| @@ -5553,7 +5555,7 @@ int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len) · 12 unmodified lines | ||
| 5553 | 5555 | skb_reset_mac_header(skb); |
| 5554 | 5556 | skb_set_network_header(skb, mac_len); |
| 5555 | 5557 | |
| 5556 | − if (skb->dev && skb->dev->type == ARPHRD_ETHER) { | |
| 5558 | + if (ethernet) { | |
| 5557 | 5559 | struct ethhdr *hdr; |
| 5558 | 5560 | |
| 5559 | 5561 | /* use mpls_hdr() to get ethertype to account for VLANs. */ |
| @@ -179,7 +179,8 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, · 178 unmodified lines | ||
| 179 | 179 | { |
| 180 | 180 | int err; |
| 181 | 181 | |
| 182 | − err = skb_mpls_pop(skb, ethertype, skb->mac_len); | |
| 182 | + err = skb_mpls_pop(skb, ethertype, skb->mac_len, | |
| 183 | + ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET); | |
| 183 | 184 | if (err) |
| 184 | 185 | return err; |
| 185 | 186 | |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | 2 | /* Copyright (C) 2019 Netronome Systems, Inc. */ |
| 3 | 3 | |
| 4 | +#include <linux/if_arp.h> | |
| 4 | 5 | #include <linux/init.h> |
| 5 | 6 | #include <linux/kernel.h> |
| 6 | 7 | #include <linux/module.h> |
| @@ -76,7 +77,8 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a, · 69 unmodified lines | ||
| 76 | 77 | |
| 77 | 78 | switch (p->tcfm_action) { |
| 78 | 79 | case TCA_MPLS_ACT_POP: |
| 79 | − if (skb_mpls_pop(skb, p->tcfm_proto, mac_len)) | |
| 80 | + if (skb_mpls_pop(skb, p->tcfm_proto, mac_len, | |
| 81 | + skb->dev && skb->dev->type == ARPHRD_ETHER)) | |
| 80 | 82 | goto drop; |
| 81 | 83 | break; |
| 82 | 84 | case TCA_MPLS_ACT_PUSH: |