diff options
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r-- | net/openvswitch/flow.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index dbe2379329c5..f039064ce922 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -579,6 +579,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
579 | return -EINVAL; | 579 | return -EINVAL; |
580 | 580 | ||
581 | skb_reset_network_header(skb); | 581 | skb_reset_network_header(skb); |
582 | key->eth.type = skb->protocol; | ||
582 | } else { | 583 | } else { |
583 | eth = eth_hdr(skb); | 584 | eth = eth_hdr(skb); |
584 | ether_addr_copy(key->eth.src, eth->h_source); | 585 | ether_addr_copy(key->eth.src, eth->h_source); |
@@ -592,15 +593,23 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
592 | if (unlikely(parse_vlan(skb, key))) | 593 | if (unlikely(parse_vlan(skb, key))) |
593 | return -ENOMEM; | 594 | return -ENOMEM; |
594 | 595 | ||
595 | skb->protocol = parse_ethertype(skb); | 596 | key->eth.type = parse_ethertype(skb); |
596 | if (unlikely(skb->protocol == htons(0))) | 597 | if (unlikely(key->eth.type == htons(0))) |
597 | return -ENOMEM; | 598 | return -ENOMEM; |
598 | 599 | ||
600 | /* Multiple tagged packets need to retain TPID to satisfy | ||
601 | * skb_vlan_pop(), which will later shift the ethertype into | ||
602 | * skb->protocol. | ||
603 | */ | ||
604 | if (key->eth.cvlan.tci & htons(VLAN_TAG_PRESENT)) | ||
605 | skb->protocol = key->eth.cvlan.tpid; | ||
606 | else | ||
607 | skb->protocol = key->eth.type; | ||
608 | |||
599 | skb_reset_network_header(skb); | 609 | skb_reset_network_header(skb); |
600 | __skb_push(skb, skb->data - skb_mac_header(skb)); | 610 | __skb_push(skb, skb->data - skb_mac_header(skb)); |
601 | } | 611 | } |
602 | skb_reset_mac_len(skb); | 612 | skb_reset_mac_len(skb); |
603 | key->eth.type = skb->protocol; | ||
604 | 613 | ||
605 | /* Network layer. */ | 614 | /* Network layer. */ |
606 | if (key->eth.type == htons(ETH_P_IP)) { | 615 | if (key->eth.type == htons(ETH_P_IP)) { |