diff options
author | Jiri Benc <jbenc@redhat.com> | 2016-11-10 10:28:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-13 00:51:02 -0500 |
commit | 5108bbaddc37c1c8583f0cf2562d7d3463cd12cb (patch) | |
tree | 6f3b06a52f5ef5b64c66eefb94f51c76dad00d79 /net/openvswitch/flow.c | |
parent | 1560a074df6297e76278e459ca3eb9ff83a6f878 (diff) |
openvswitch: add processing of L3 packets
Support receiving, extracting flow key and sending of L3 packets (packets
without an Ethernet header).
Note that even after this patch, non-Ethernet interfaces are still not
allowed to be added to bridges. Similarly, netlink interface for sending and
receiving L3 packets to/from user space is not in place yet.
Based on previous versions by Lorand Jakab and Simon Horman.
Signed-off-by: Lorand Jakab <lojakab@cisco.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: Jiri Benc <jbenc@redhat.com>
Acked-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.c | 106 |
1 files changed, 81 insertions, 25 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 96c8c4716603..08aa926cd5cf 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -334,14 +334,17 @@ static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh) | |||
334 | return 1; | 334 | return 1; |
335 | } | 335 | } |
336 | 336 | ||
337 | static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) | 337 | static void clear_vlan(struct sw_flow_key *key) |
338 | { | 338 | { |
339 | int res; | ||
340 | |||
341 | key->eth.vlan.tci = 0; | 339 | key->eth.vlan.tci = 0; |
342 | key->eth.vlan.tpid = 0; | 340 | key->eth.vlan.tpid = 0; |
343 | key->eth.cvlan.tci = 0; | 341 | key->eth.cvlan.tci = 0; |
344 | key->eth.cvlan.tpid = 0; | 342 | key->eth.cvlan.tpid = 0; |
343 | } | ||
344 | |||
345 | static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) | ||
346 | { | ||
347 | int res; | ||
345 | 348 | ||
346 | if (skb_vlan_tag_present(skb)) { | 349 | if (skb_vlan_tag_present(skb)) { |
347 | key->eth.vlan.tci = htons(skb->vlan_tci); | 350 | key->eth.vlan.tci = htons(skb->vlan_tci); |
@@ -483,17 +486,20 @@ invalid: | |||
483 | * | 486 | * |
484 | * Returns 0 if successful, otherwise a negative errno value. | 487 | * Returns 0 if successful, otherwise a negative errno value. |
485 | * | 488 | * |
486 | * Initializes @skb header pointers as follows: | 489 | * Initializes @skb header fields as follows: |
487 | * | 490 | * |
488 | * - skb->mac_header: the Ethernet header. | 491 | * - skb->mac_header: the L2 header. |
489 | * | 492 | * |
490 | * - skb->network_header: just past the Ethernet header, or just past the | 493 | * - skb->network_header: just past the L2 header, or just past the |
491 | * VLAN header, to the first byte of the Ethernet payload. | 494 | * VLAN header, to the first byte of the L2 payload. |
492 | * | 495 | * |
493 | * - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6 | 496 | * - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6 |
494 | * on output, then just past the IP header, if one is present and | 497 | * on output, then just past the IP header, if one is present and |
495 | * of a correct length, otherwise the same as skb->network_header. | 498 | * of a correct length, otherwise the same as skb->network_header. |
496 | * For other key->eth.type values it is left untouched. | 499 | * For other key->eth.type values it is left untouched. |
500 | * | ||
501 | * - skb->protocol: the type of the data starting at skb->network_header. | ||
502 | * Equals to key->eth.type. | ||
497 | */ | 503 | */ |
498 | static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | 504 | static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) |
499 | { | 505 | { |
@@ -505,28 +511,35 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
505 | 511 | ||
506 | skb_reset_mac_header(skb); | 512 | skb_reset_mac_header(skb); |
507 | 513 | ||
508 | /* Link layer. We are guaranteed to have at least the 14 byte Ethernet | 514 | /* Link layer. */ |
509 | * header in the linear data area. | 515 | clear_vlan(key); |
510 | */ | 516 | if (key->mac_proto == MAC_PROTO_NONE) { |
511 | eth = eth_hdr(skb); | 517 | if (unlikely(eth_type_vlan(skb->protocol))) |
512 | ether_addr_copy(key->eth.src, eth->h_source); | 518 | return -EINVAL; |
513 | ether_addr_copy(key->eth.dst, eth->h_dest); | ||
514 | 519 | ||
515 | __skb_pull(skb, 2 * ETH_ALEN); | 520 | skb_reset_network_header(skb); |
516 | /* We are going to push all headers that we pull, so no need to | 521 | } else { |
517 | * update skb->csum here. | 522 | eth = eth_hdr(skb); |
518 | */ | 523 | ether_addr_copy(key->eth.src, eth->h_source); |
524 | ether_addr_copy(key->eth.dst, eth->h_dest); | ||
519 | 525 | ||
520 | if (unlikely(parse_vlan(skb, key))) | 526 | __skb_pull(skb, 2 * ETH_ALEN); |
521 | return -ENOMEM; | 527 | /* We are going to push all headers that we pull, so no need to |
528 | * update skb->csum here. | ||
529 | */ | ||
522 | 530 | ||
523 | key->eth.type = parse_ethertype(skb); | 531 | if (unlikely(parse_vlan(skb, key))) |
524 | if (unlikely(key->eth.type == htons(0))) | 532 | return -ENOMEM; |
525 | return -ENOMEM; | 533 | |
534 | skb->protocol = parse_ethertype(skb); | ||
535 | if (unlikely(skb->protocol == htons(0))) | ||
536 | return -ENOMEM; | ||
526 | 537 | ||
527 | skb_reset_network_header(skb); | 538 | skb_reset_network_header(skb); |
539 | __skb_push(skb, skb->data - skb_mac_header(skb)); | ||
540 | } | ||
528 | skb_reset_mac_len(skb); | 541 | skb_reset_mac_len(skb); |
529 | __skb_push(skb, skb->data - skb_mac_header(skb)); | 542 | key->eth.type = skb->protocol; |
530 | 543 | ||
531 | /* Network layer. */ | 544 | /* Network layer. */ |
532 | if (key->eth.type == htons(ETH_P_IP)) { | 545 | if (key->eth.type == htons(ETH_P_IP)) { |
@@ -721,9 +734,25 @@ int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key) | |||
721 | return key_extract(skb, key); | 734 | return key_extract(skb, key); |
722 | } | 735 | } |
723 | 736 | ||
737 | static int key_extract_mac_proto(struct sk_buff *skb) | ||
738 | { | ||
739 | switch (skb->dev->type) { | ||
740 | case ARPHRD_ETHER: | ||
741 | return MAC_PROTO_ETHERNET; | ||
742 | case ARPHRD_NONE: | ||
743 | if (skb->protocol == htons(ETH_P_TEB)) | ||
744 | return MAC_PROTO_ETHERNET; | ||
745 | return MAC_PROTO_NONE; | ||
746 | } | ||
747 | WARN_ON_ONCE(1); | ||
748 | return -EINVAL; | ||
749 | } | ||
750 | |||
724 | int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, | 751 | int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, |
725 | struct sk_buff *skb, struct sw_flow_key *key) | 752 | struct sk_buff *skb, struct sw_flow_key *key) |
726 | { | 753 | { |
754 | int res; | ||
755 | |||
727 | /* Extract metadata from packet. */ | 756 | /* Extract metadata from packet. */ |
728 | if (tun_info) { | 757 | if (tun_info) { |
729 | key->tun_proto = ip_tunnel_info_af(tun_info); | 758 | key->tun_proto = ip_tunnel_info_af(tun_info); |
@@ -751,7 +780,10 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, | |||
751 | key->phy.skb_mark = skb->mark; | 780 | key->phy.skb_mark = skb->mark; |
752 | ovs_ct_fill_key(skb, key); | 781 | ovs_ct_fill_key(skb, key); |
753 | key->ovs_flow_hash = 0; | 782 | key->ovs_flow_hash = 0; |
754 | key->mac_proto = MAC_PROTO_ETHERNET; | 783 | res = key_extract_mac_proto(skb); |
784 | if (res < 0) | ||
785 | return res; | ||
786 | key->mac_proto = res; | ||
755 | key->recirc_id = 0; | 787 | key->recirc_id = 0; |
756 | 788 | ||
757 | return key_extract(skb, key); | 789 | return key_extract(skb, key); |
@@ -768,5 +800,29 @@ int ovs_flow_key_extract_userspace(struct net *net, const struct nlattr *attr, | |||
768 | if (err) | 800 | if (err) |
769 | return err; | 801 | return err; |
770 | 802 | ||
803 | if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) { | ||
804 | /* key_extract assumes that skb->protocol is set-up for | ||
805 | * layer 3 packets which is the case for other callers, | ||
806 | * in particular packets recieved from the network stack. | ||
807 | * Here the correct value can be set from the metadata | ||
808 | * extracted above. | ||
809 | */ | ||
810 | skb->protocol = key->eth.type; | ||
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 | |||
771 | return key_extract(skb, key); | 827 | return key_extract(skb, key); |
772 | } | 828 | } |