aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
authorpravin shelar <pshelar@ovn.org>2016-12-26 11:31:27 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-27 12:28:07 -0500
commitdf30f7408b187929dbde72661c7f7c615268f1d0 (patch)
tree568e6d73d59770d9afbb69fb0ce5844aae65d993 /net/openvswitch/flow.c
parent56ab6b93007e5000a8812985aec1833c4a6a9ce0 (diff)
openvswitch: upcall: Fix vlan handling.
Networking stack accelerate vlan tag handling by keeping topmost vlan header in skb. This works as long as packet remains in OVS datapath. But during OVS upcall vlan header is pushed on to the packet. When such packet is sent back to OVS datapath, core networking stack might not handle it correctly. Following patch avoids this issue by accelerating the vlan tag during flow key extract. This simplifies datapath by bringing uniform packet processing for packets from all code paths. Fixes: 5108bbaddc ("openvswitch: add processing of L3 packets"). CC: Jarno Rajahalme <jarno@ovn.org> CC: Jiri Benc <jbenc@redhat.com> Signed-off-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
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}