net: Fixed updating of ethertype in skb_mpls_push()

The skb_mpls_push 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_push 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(0x0800),ipv4(tos=0/0xfc,ttl=64,frag=no),
actions:push_eth(src=00:00:00:00:00:00,dst=00:00:00:00:00:00),
push_mpls(label=13,tc=0,ttl=64,bos=1,eth_type=0x8847),4

Fixes: 8822e270d6 ("net: core: move push MPLS functionality from OvS to core helper")
Signed-off-by: Martin Varghese <martin.varghese@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Martin Varghese 2019-12-05 05:57:22 +05:30 committed by David S. Miller
parent 099ffd7edd
commit d04ac224b1
4 changed files with 7 additions and 5 deletions

View File

@ -3529,7 +3529,7 @@ int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci);
int skb_vlan_pop(struct sk_buff *skb); int skb_vlan_pop(struct sk_buff *skb);
int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);
int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto,
int mac_len); int mac_len, bool ethernet);
int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len, int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len,
bool ethernet); bool ethernet);
int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse); int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse);

View File

@ -5484,7 +5484,7 @@ static void skb_mod_eth_type(struct sk_buff *skb, struct ethhdr *hdr,
* Returns 0 on success, -errno otherwise. * Returns 0 on success, -errno otherwise.
*/ */
int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto,
int mac_len) int mac_len, bool ethernet)
{ {
struct mpls_shim_hdr *lse; struct mpls_shim_hdr *lse;
int err; int err;
@ -5515,7 +5515,7 @@ int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto,
lse->label_stack_entry = mpls_lse; lse->label_stack_entry = mpls_lse;
skb_postpush_rcsum(skb, lse, MPLS_HLEN); skb_postpush_rcsum(skb, lse, MPLS_HLEN);
if (skb->dev && skb->dev->type == ARPHRD_ETHER) if (ethernet)
skb_mod_eth_type(skb, eth_hdr(skb), mpls_proto); skb_mod_eth_type(skb, eth_hdr(skb), mpls_proto);
skb->protocol = mpls_proto; skb->protocol = mpls_proto;

View File

@ -166,7 +166,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
int err; int err;
err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype, err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype,
skb->mac_len); skb->mac_len,
ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET);
if (err) if (err)
return err; return err;

View File

@ -83,7 +83,8 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a,
break; break;
case TCA_MPLS_ACT_PUSH: case TCA_MPLS_ACT_PUSH:
new_lse = tcf_mpls_get_lse(NULL, p, !eth_p_mpls(skb->protocol)); new_lse = tcf_mpls_get_lse(NULL, p, !eth_p_mpls(skb->protocol));
if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len)) if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len,
skb->dev && skb->dev->type == ARPHRD_ETHER))
goto drop; goto drop;
break; break;
case TCA_MPLS_ACT_MODIFY: case TCA_MPLS_ACT_MODIFY: