From patchwork Wed May 4 07:34:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 618291 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3r08vd19K7z9ssM for ; Wed, 4 May 2016 17:35:09 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b=hNvH6+nD; dkim-atps=neutral Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 0E49B1068D; Wed, 4 May 2016 00:34:54 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id B191D10687 for ; Wed, 4 May 2016 00:34:52 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id 34A2D420380 for ; Wed, 4 May 2016 01:34:52 -0600 (MDT) X-ASG-Debug-ID: 1462347291-09eadd6043275bc0001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar5.cudamail.com with ESMTP id lUWXatMdbEq1YVHE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 04 May 2016 01:34:51 -0600 (MDT) X-Barracuda-Envelope-From: simon.horman@netronome.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO mail-pa0-f49.google.com) (209.85.220.49) by mx1-pf1.cudamail.com with ESMTPS (RC4-SHA encrypted); 4 May 2016 07:34:51 -0000 Received-SPF: neutral (mx1-pf1.cudamail.com: 209.85.220.49 is neither permitted nor denied by SPF record at spf.mandrillapp.com) X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.49 Received: by mail-pa0-f49.google.com with SMTP id xk12so21262655pac.0 for ; Wed, 04 May 2016 00:34:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eMLmVqMUmWiSXb3iiEVimbBJRchxRAcgswyJTq/ebqw=; b=hNvH6+nDUEkPfmG0Cr2CegRBLev2bmdWWW0Q5zOe46YXX6QgdXaqI6H6Xp/ZYyZqPZ IT1NK4b1X4nVlpT3MF1RvkaKt/eKXbxq2a2LndoT76mbsCQl+rL8bi2z1t+TmTLEiBQi UDXa6OQq7tqCJROrMs6AwDZd9QvO4auBef5rbF7sZ15hsYA6glXN9Ezc8ZbcMh2EO+67 aCM9Y7zjx9Xv0LFth2CgHd4Sy2bsjZPpZOBjdgPgdKaExKM67zxE2oRp8ws+sZeo7bpu XsYe/Kf9CLq6yxkKBnBXJDnYIvm4sxCTA9Mw6BpuK/G0ctGOOtXJgge1FJHY+SjOOnbL JXBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eMLmVqMUmWiSXb3iiEVimbBJRchxRAcgswyJTq/ebqw=; b=mfD40aZgeC2vEnnCx8yggC3lV2EtIvo8EgG6YVy39LiiKZfeHzd+NMfUgdXSnP4tdp cPuRNhcWuZPSdGfnCMlZuTgR1SXx+vX68ohHjXWlPPgRn9+bNPZ82Pa4nTOnViCmTdUR dXsBi+uWd0xbb9wbc7aodIrv0mp6EOBkdLNMizsbS/CFpSLW9q5v3Ms0kLjM9lj7fOoG lu1BjHooIxn4gnJTGuct39x4klEfZfi8i8QuDYjffaZ2t3ahrxcYVvjM/hxRv4235GDW XDWINHZQ+gk3roOBHd94WGnE69PuI1IbbFQ32SSwAF9QmQV0aaFUD4K9UPnvGhS0oKc9 FISQ== X-Gm-Message-State: AOPr4FXzmoeRI0MONIzv+cNyLSyMTEbGj5mgDNVVVVR3opQC2z12Lbd50WJ2dXf5tpfqJYr/ X-Received: by 10.66.26.43 with SMTP id i11mr10150481pag.58.1462347290526; Wed, 04 May 2016 00:34:50 -0700 (PDT) Received: from penelope.kanocho.kobe.vergenet.net (121-80-211-180f1.hyg1.eonet.ne.jp. [121.80.211.180]) by smtp.gmail.com with ESMTPSA id ey12sm3469775pac.26.2016.05.04.00.34.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 04 May 2016 00:34:49 -0700 (PDT) X-CudaMail-Envelope-Sender: simon.horman@netronome.com X-Barracuda-Apparent-Source-IP: 121.80.211.180 From: Simon Horman To: dev@openvswitch.org X-CudaMail-MID: CM-E1-503001764 X-CudaMail-DTE: 050416 X-CudaMail-Originating-IP: 209.85.220.49 Date: Wed, 4 May 2016 16:34:23 +0900 X-ASG-Orig-Subj: [##CM-E1-503001764##][PATCH v10 3/5] userspace: add layer 3 support to packet metadata Message-Id: <1462347265-21887-4-git-send-email-simon.horman@netronome.com> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 In-Reply-To: <1462347265-21887-1-git-send-email-simon.horman@netronome.com> References: <1462347265-21887-1-git-send-email-simon.horman@netronome.com> X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1462347291 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.10 X-Barracuda-Spam-Status: No, SCORE=1.10 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_RULE7568M, BSF_SC5_MJ1963, DKIM_SIGNED, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.29282 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.50 BSF_RULE7568M Custom Rule 7568M 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Cc: Simon Horman Subject: [ovs-dev] [PATCH v10 3/5] userspace: add layer 3 support to packet metadata X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" From: Lorand Jakab This is needed for sending a packet back to the datapath after a miss upcall was processed. The presence of a layer 2 packet is signaled by adding OVS_KEY_ATTR_ETHERNET to the packet metadata sent with the ovs_packet netlink message. Layer 3 packets need to be accompanied by OVS_KEY_ATTR_PACKET_ETHERTYPE to indicate network protocol. Signed-off-by: Lorand Jakab Signed-off-by: Simon Horman Acked-by: Ben Pfaff --- v10 [Simon Horman] * Update BUILD_BUG_ON() call in ovs_key_attr_size() * Set packet_ethtype in set_ethertype() * Do not include zero-value OVS_KEY_ATTR_PACKET_ETHERTYPE attribute in flow key of layer 2 packets as this creates an unnecessary incompatibility with kernel datapaths that are unaware of that attribute. v9 [Simon Horman] * Rebase v8 - v8 [Lorand Jakab] v7 [Lorand Jakab] * New patch --- datapath/flow_netlink.c | 2 +- datapath/linux/compat/include/linux/openvswitch.h | 2 ++ include/openvswitch/match.h | 1 + lib/flow.c | 4 ++++ lib/flow.h | 2 ++ lib/match.c | 7 +++++++ lib/odp-execute.c | 9 ++++++++ lib/odp-util.c | 25 ++++++++++++++++++++++- lib/packets.c | 1 + lib/packets.h | 2 ++ ofproto/ofproto-dpif-sflow.c | 1 + 11 files changed, 54 insertions(+), 2 deletions(-) diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c index 6ffcc53ea1ca..c7dfb677fb86 100644 --- a/datapath/flow_netlink.c +++ b/datapath/flow_netlink.c @@ -284,7 +284,7 @@ size_t ovs_key_attr_size(void) /* Whenever adding new OVS_KEY_ FIELDS, we should consider * updating this function. */ - BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 26); + BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 27); return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */ + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */ diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h index 8548d3b8b86b..502e8f1aca66 100644 --- a/datapath/linux/compat/include/linux/openvswitch.h +++ b/datapath/linux/compat/include/linux/openvswitch.h @@ -352,6 +352,8 @@ enum ovs_key_attr { OVS_KEY_ATTR_CT_ZONE, /* u16 connection tracking zone. */ OVS_KEY_ATTR_CT_MARK, /* u32 connection tracking mark */ OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking labels */ + OVS_KEY_ATTR_PACKET_ETHERTYPE, /* be16 Ethernet type for packet + * execution. */ #ifdef __KERNEL__ /* Only used within kernel data path. */ diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h index c955753d70a9..60da412eb695 100644 --- a/include/openvswitch/match.h +++ b/include/openvswitch/match.h @@ -96,6 +96,7 @@ void match_set_ct_mark(struct match *, uint32_t ct_mark); void match_set_ct_mark_masked(struct match *, uint32_t ct_mark, uint32_t mask); void match_set_ct_label(struct match *, ovs_u128 ct_label); void match_set_ct_label_masked(struct match *, ovs_u128 ct_label, ovs_u128 mask); +void match_set_base_layer(struct match *, uint8_t base_layer); void match_set_skb_priority(struct match *, uint32_t skb_priority); void match_set_dl_type(struct match *, ovs_be16); void match_set_dl_src(struct match *, const struct eth_addr ); diff --git a/lib/flow.c b/lib/flow.c index 566dbd0feb06..3896531c0936 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -933,6 +933,10 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata) if (!ovs_u128_is_zero(&flow->ct_label)) { match_set_ct_label(flow_metadata, flow->ct_label); } + + if (flow->base_layer != LAYER_2) { + match_set_base_layer(flow_metadata, flow->base_layer); + } } const char *ct_state_to_string(uint32_t state) diff --git a/lib/flow.h b/lib/flow.h index 68810b9a35cb..95a8a5a1b198 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -828,6 +828,8 @@ pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow) md->ct_zone = flow->ct_zone; md->ct_mark = flow->ct_mark; md->ct_label = flow->ct_label; + md->base_layer = flow->base_layer; + md->packet_ethertype = flow->dl_type; } static inline bool is_ip_any(const struct flow *flow) diff --git a/lib/match.c b/lib/match.c index fd22c1962aac..27fdd0071846 100644 --- a/lib/match.c +++ b/lib/match.c @@ -369,6 +369,13 @@ match_set_ct_label_masked(struct match *match, ovs_u128 value, ovs_u128 mask) } void +match_set_base_layer(struct match *match, uint8_t base_layer) +{ + match->flow.base_layer = base_layer; + match->wc.masks.base_layer = UINT8_MAX; +} + +void match_set_dl_type(struct match *match, ovs_be16 dl_type) { match->wc.masks.dl_type = OVS_BE16_MAX; diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 4befde2427fc..579f323a1e82 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -326,6 +326,10 @@ odp_execute_set_action(struct dp_packet *packet, const struct nlattr *a) md->recirc_id = nl_attr_get_u32(a); break; + case OVS_KEY_ATTR_PACKET_ETHERTYPE: + md->packet_ethertype = nl_attr_get_be16(a); + break; + case OVS_KEY_ATTR_UNSPEC: case OVS_KEY_ATTR_ENCAP: case OVS_KEY_ATTR_ETHERTYPE: @@ -422,6 +426,11 @@ odp_execute_masked_set_action(struct dp_packet *packet, | (md->recirc_id & ~*get_mask(a, uint32_t)); break; + case OVS_KEY_ATTR_PACKET_ETHERTYPE: + md->packet_ethertype = nl_attr_get_be16(a) + | (md->packet_ethertype & ~*get_mask(a, ovs_be16)); + break; + case OVS_KEY_ATTR_TUNNEL: /* Masked data not supported for tunnel. */ case OVS_KEY_ATTR_UNSPEC: case OVS_KEY_ATTR_CT_STATE: diff --git a/lib/odp-util.c b/lib/odp-util.c index bc54496b04c4..0345963a5f17 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -165,6 +165,7 @@ ovs_key_attr_to_string(enum ovs_key_attr attr, char *namebuf, size_t bufsize) case OVS_KEY_ATTR_MPLS: return "mpls"; case OVS_KEY_ATTR_DP_HASH: return "dp_hash"; case OVS_KEY_ATTR_RECIRC_ID: return "recirc_id"; + case OVS_KEY_ATTR_PACKET_ETHERTYPE: return "pkt_eth"; case __OVS_KEY_ATTR_MAX: default: @@ -1819,6 +1820,7 @@ static const struct attr_len_tbl ovs_flow_key_attr_lens[OVS_KEY_ATTR_MAX + 1] = [OVS_KEY_ATTR_CT_ZONE] = { .len = 2 }, [OVS_KEY_ATTR_CT_MARK] = { .len = 4 }, [OVS_KEY_ATTR_CT_LABELS] = { .len = sizeof(struct ovs_key_ct_labels) }, + [OVS_KEY_ATTR_PACKET_ETHERTYPE] = { .len = 2 }, }; /* Returns the correct length of the payload for a flow key attribute of the @@ -2839,6 +2841,7 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma, break; } case OVS_KEY_ATTR_ETHERTYPE: + case OVS_KEY_ATTR_PACKET_ETHERTYPE: ds_put_format(ds, "0x%04"PRIx16, ntohs(nl_attr_get_be16(a))); if (!is_exact) { ds_put_format(ds, "/0x%04"PRIx16, ntohs(nl_attr_get_be16(ma))); @@ -4520,6 +4523,11 @@ odp_key_from_pkt_metadata(struct ofpbuf *buf, const struct pkt_metadata *md) if (md->in_port.odp_port != ODPP_NONE) { nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, md->in_port.odp_port); } + + if (md->base_layer == LAYER_3) { + nl_msg_put_be16(buf, OVS_KEY_ATTR_PACKET_ETHERTYPE, + md->packet_ethertype); + } } /* Generate packet metadata from the given ODP flow key. */ @@ -4531,10 +4539,13 @@ odp_key_to_pkt_metadata(const struct nlattr *key, size_t key_len, size_t left; uint32_t wanted_attrs = 1u << OVS_KEY_ATTR_PRIORITY | 1u << OVS_KEY_ATTR_SKB_MARK | 1u << OVS_KEY_ATTR_TUNNEL | - 1u << OVS_KEY_ATTR_IN_PORT; + 1u << OVS_KEY_ATTR_IN_PORT | 1u << OVS_KEY_ATTR_ETHERNET | + 1u << OVS_KEY_ATTR_IPV4 | 1u << OVS_KEY_ATTR_IPV6; pkt_metadata_init(md, ODPP_NONE); + md->base_layer = LAYER_3; + NL_ATTR_FOR_EACH (nla, left, key, key_len) { uint16_t type = nl_attr_type(nla); size_t len = nl_attr_get_size(nla); @@ -4596,6 +4607,18 @@ odp_key_to_pkt_metadata(const struct nlattr *key, size_t key_len, md->in_port.odp_port = nl_attr_get_odp_port(nla); wanted_attrs &= ~(1u << OVS_KEY_ATTR_IN_PORT); break; + case OVS_KEY_ATTR_ETHERNET: + md->base_layer = LAYER_2; + wanted_attrs &= ~(1u << OVS_KEY_ATTR_ETHERNET); + break; + case OVS_KEY_ATTR_IPV4: + md->packet_ethertype = htons(ETH_TYPE_IP); + wanted_attrs &= ~(1u << OVS_KEY_ATTR_IPV4); + break; + case OVS_KEY_ATTR_IPV6: + md->packet_ethertype = htons(ETH_TYPE_IPV6); + wanted_attrs &= ~(1u << OVS_KEY_ATTR_IPV6); + break; default: break; } diff --git a/lib/packets.c b/lib/packets.c index 277b2445f2a0..b9e2182827cb 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -252,6 +252,7 @@ set_ethertype(struct dp_packet *packet, ovs_be16 eth_type) struct eth_header *eh = dp_packet_l2(packet); if (!eh) { + packet->md.packet_ethertype = eth_type; return; } diff --git a/lib/packets.h b/lib/packets.h index 97528f931b2c..560eaa729fcb 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -104,6 +104,8 @@ struct pkt_metadata { uint32_t ct_mark; /* Connection mark. */ ovs_u128 ct_label; /* Connection label. */ union flow_in_port in_port; /* Input port. */ + ovs_be16 packet_ethertype; /* Ethertype of the packet */ + uint8_t base_layer; /* Packet starts at this layer */ struct flow_tnl tunnel; /* Encapsulating tunnel parameters. Note that * if 'ip_dst' == 0, the rest of the fields may * be uninitialized. */ diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index 80cb37aa0104..29808517aeb3 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -976,6 +976,7 @@ sflow_read_set_action(const struct nlattr *attr, case OVS_KEY_ATTR_IN_PORT: case OVS_KEY_ATTR_ETHERNET: case OVS_KEY_ATTR_VLAN: + case OVS_KEY_ATTR_PACKET_ETHERTYPE: break; case OVS_KEY_ATTR_MPLS: {