aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r--net/openvswitch/flow.c54
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 */
315static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh) 315static 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}