diff options
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r-- | net/openvswitch/flow.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 08aa926cd5cf..2c0a00f7f1b7 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -312,7 +312,8 @@ static bool icmp6hdr_ok(struct sk_buff *skb) | |||
312 | * Returns 0 if it encounters a non-vlan or incomplete packet. | 312 | * Returns 0 if it encounters a non-vlan or incomplete packet. |
313 | * Returns 1 after successfully parsing vlan tag. | 313 | * Returns 1 after successfully parsing vlan tag. |
314 | */ | 314 | */ |
315 | static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh) | 315 | static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh, |
316 | bool untag_vlan) | ||
316 | { | 317 | { |
317 | struct vlan_head *vh = (struct vlan_head *)skb->data; | 318 | struct vlan_head *vh = (struct vlan_head *)skb->data; |
318 | 319 | ||
@@ -330,7 +331,20 @@ static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh) | |||
330 | key_vh->tci = vh->tci | htons(VLAN_TAG_PRESENT); | 331 | key_vh->tci = vh->tci | htons(VLAN_TAG_PRESENT); |
331 | key_vh->tpid = vh->tpid; | 332 | key_vh->tpid = vh->tpid; |
332 | 333 | ||
333 | __skb_pull(skb, sizeof(struct vlan_head)); | 334 | if (unlikely(untag_vlan)) { |
335 | int offset = skb->data - skb_mac_header(skb); | ||
336 | u16 tci; | ||
337 | int err; | ||
338 | |||
339 | __skb_push(skb, offset); | ||
340 | err = __skb_vlan_pop(skb, &tci); | ||
341 | __skb_pull(skb, offset); | ||
342 | if (err) | ||
343 | return err; | ||
344 | __vlan_hwaccel_put_tag(skb, key_vh->tpid, tci); | ||
345 | } else { | ||
346 | __skb_pull(skb, sizeof(struct vlan_head)); | ||
347 | } | ||
334 | return 1; | 348 | return 1; |
335 | } | 349 | } |
336 | 350 | ||
@@ -351,13 +365,13 @@ static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) | |||
351 | key->eth.vlan.tpid = skb->vlan_proto; | 365 | key->eth.vlan.tpid = skb->vlan_proto; |
352 | } else { | 366 | } else { |
353 | /* Parse outer vlan tag in the non-accelerated case. */ | 367 | /* Parse outer vlan tag in the non-accelerated case. */ |
354 | res = parse_vlan_tag(skb, &key->eth.vlan); | 368 | res = parse_vlan_tag(skb, &key->eth.vlan, true); |
355 | if (res <= 0) | 369 | if (res <= 0) |
356 | return res; | 370 | return res; |
357 | } | 371 | } |
358 | 372 | ||
359 | /* Parse inner vlan tag. */ | 373 | /* Parse inner vlan tag. */ |
360 | res = parse_vlan_tag(skb, &key->eth.cvlan); | 374 | res = parse_vlan_tag(skb, &key->eth.cvlan, false); |
361 | if (res <= 0) | 375 | if (res <= 0) |
362 | return res; | 376 | return res; |
363 | 377 | ||
@@ -800,29 +814,15 @@ int ovs_flow_key_extract_userspace(struct net *net, const struct nlattr *attr, | |||
800 | if (err) | 814 | if (err) |
801 | return err; | 815 | return err; |
802 | 816 | ||
803 | if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) { | 817 | /* key_extract assumes that skb->protocol is set-up for |
804 | /* key_extract assumes that skb->protocol is set-up for | 818 | * layer 3 packets which is the case for other callers, |
805 | * layer 3 packets which is the case for other callers, | 819 | * in particular packets received from the network stack. |
806 | * in particular packets recieved from the network stack. | 820 | * Here the correct value can be set from the metadata |
807 | * Here the correct value can be set from the metadata | 821 | * extracted above. |
808 | * extracted above. | 822 | * For L2 packet key eth type would be zero. skb protocol |
809 | */ | 823 | * would be set to correct value later during key-extact. |
810 | skb->protocol = key->eth.type; | 824 | */ |
811 | } else { | ||
812 | struct ethhdr *eth; | ||
813 | |||
814 | skb_reset_mac_header(skb); | ||
815 | eth = eth_hdr(skb); | ||
816 | |||
817 | /* Normally, setting the skb 'protocol' field would be | ||
818 | * handled by a call to eth_type_trans(), but it assumes | ||
819 | * there's a sending device, which we may not have. | ||
820 | */ | ||
821 | if (eth_proto_is_802_3(eth->h_proto)) | ||
822 | skb->protocol = eth->h_proto; | ||
823 | else | ||
824 | skb->protocol = htons(ETH_P_802_2); | ||
825 | } | ||
826 | 825 | ||
826 | skb->protocol = key->eth.type; | ||
827 | return key_extract(skb, key); | 827 | return key_extract(skb, key); |
828 | } | 828 | } |