From patchwork Wed Aug 2 20:56:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yang, Yi" X-Patchwork-Id: 796839 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xN5FX30hFz9s82 for ; Thu, 3 Aug 2017 07:01:04 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id CC10BBAE; Wed, 2 Aug 2017 21:00:33 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 8F3608A1 for ; Wed, 2 Aug 2017 21:00:31 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C93DB488 for ; Wed, 2 Aug 2017 21:00:30 +0000 (UTC) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Aug 2017 14:00:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,313,1498546800"; d="scan'208";a="134659781" Received: from unknown (HELO localhost.localdomain.bj.intel.com) ([10.240.224.185]) by fmsmga005.fm.intel.com with ESMTP; 02 Aug 2017 14:00:29 -0700 From: Yi Yang To: dev@openvswitch.org Date: Thu, 3 Aug 2017 04:56:53 +0800 Message-Id: <1501707417-99701-3-git-send-email-yi.y.yang@intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1501707417-99701-1-git-send-email-yi.y.yang@intel.com> References: <1501707417-99701-1-git-send-email-yi.y.yang@intel.com> X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v2 2/6] userspace: enable set_field support for nsh fields X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Jan Scheurich Signed-off-by: Yi Yang Signed-off-by: Jan Scheurich --- lib/odp-execute.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/odp-util.c | 33 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 7d7d787..f138322 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -270,6 +270,66 @@ odp_set_nd(struct dp_packet *packet, const struct ovs_key_nd *key, } } +/* Set the NSH header. Assumes the NSH header is present and matches the + * MD format of the key. The slow path must take case of that. */ +static void +odp_set_nsh(struct dp_packet *packet, const struct ovs_key_nsh *key, + const struct ovs_key_nsh *mask) +{ + struct nsh_hdr * nsh = (struct nsh_hdr *) dp_packet_l3(packet); + uint16_t *p, *k, *m; + size_t len; + ovs_be32 path_hdr; + uint8_t flags; + int i; + + ovs_assert(nsh != NULL); + + if (!mask) { + nsh->ver_flags_len = htons(key->flags << NSH_FLAGS_SHIFT) | + (nsh->ver_flags_len & ~htons(NSH_FLAGS_MASK)); + put_16aligned_be32((ovs_16aligned_be32 *) &nsh->path_hdr, + key->path_hdr); + switch (nsh->md_type) { + case NSH_M_TYPE1: + /* Avoid the 16/32 bit alignment hassle. */ + memcpy(&nsh->md1, &key->c1, sizeof(struct nsh_md1_ctx)); + break; + case NSH_M_TYPE2: + /* TODO */ + break; + default: + OVS_NOT_REACHED(); + } + } else { + flags = (ntohs(nsh->ver_flags_len) & NSH_FLAGS_MASK) >> NSH_FLAGS_SHIFT; + flags = key->flags | (flags & ~mask->flags); + nsh->ver_flags_len = htons(flags << NSH_FLAGS_SHIFT) | + (nsh->ver_flags_len & ~htons(NSH_FLAGS_MASK)); + path_hdr = get_16aligned_be32((ovs_16aligned_be32 *) &nsh->path_hdr); + path_hdr = key->path_hdr | (path_hdr & ~mask->path_hdr); + put_16aligned_be32((ovs_16aligned_be32 *) &nsh->path_hdr, + path_hdr); + switch (nsh->md_type) { + case NSH_M_TYPE1: + len = sizeof(struct nsh_md1_ctx) >> 1; + /* Avoid the 16/32 bit alignment hassle. */ + p = (uint16_t *) &nsh->md1.c1; + k = (uint16_t *) &key->c1; + m = (uint16_t *) &mask->c1; + for (i=0; iipv4_src, @@ -422,7 +484,10 @@ odp_execute_masked_set_action(struct dp_packet *packet, break; case OVS_KEY_ATTR_NSH: + odp_set_nsh(packet, nl_attr_get(a), + get_mask(a, struct ovs_key_nsh)); break; + case OVS_KEY_ATTR_IPV4: odp_set_ipv4(packet, nl_attr_get(a), get_mask(a, struct ovs_key_ipv4)); diff --git a/lib/odp-util.c b/lib/odp-util.c index 114d45e..369d0cd 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -6497,6 +6497,38 @@ put_nsh_key(const struct ovs_key_nsh *nsh, struct flow *flow, bool is_mask OVS_U } } +static void +commit_set_nsh_action(const struct flow *flow, struct flow *base_flow, + struct ofpbuf *odp_actions, + struct flow_wildcards *wc, + bool use_masked) +{ + struct ovs_key_nsh key, mask, base; + + if (flow->dl_type != htons(ETH_TYPE_NSH) || + !memcmp(&base_flow->nsh, &flow->nsh, sizeof base_flow->nsh)) { + return; + } + + /* Check that mdtype and np remain unchanged. */ + ovs_assert(flow->nsh.mdtype == base_flow->nsh.mdtype && + flow->nsh.np == base_flow->nsh.np); + + get_nsh_key(flow, &key, false); + get_nsh_key(base_flow, &base, false); + get_nsh_key(&wc->masks, &mask, true); + mask.mdtype = 0; /* Not writable. */ + mask.np = 0; /* Not writable. */ + + if (commit(OVS_KEY_ATTR_NSH, use_masked, &key, &base, &mask, sizeof key, + odp_actions)) { + put_nsh_key(&base, base_flow, false); + if (mask.mdtype != 0) { /* Mask was changed by commit(). */ + put_nsh_key(&mask, &wc->masks, true); + } + } +} + /* TCP, UDP, and SCTP keys have the same layout. */ BUILD_ASSERT_DECL(sizeof(struct ovs_key_tcp) == sizeof(struct ovs_key_udp) && sizeof(struct ovs_key_tcp) == sizeof(struct ovs_key_sctp)); @@ -6660,6 +6692,7 @@ commit_odp_actions(const struct flow *flow, struct flow *base, commit_mpls_action(flow, base, odp_actions); mpls_done = true; } + commit_set_nsh_action(flow, base, odp_actions, wc, use_masked); slow1 = commit_set_nw_action(flow, base, odp_actions, wc, use_masked); commit_set_port_action(flow, base, odp_actions, wc, use_masked); slow2 = commit_set_icmp_action(flow, base, odp_actions, wc);