From patchwork Mon Aug 8 16:14:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 656864 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 3s7Mxd0ppjz9syB for ; Tue, 9 Aug 2016 02:17:09 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 84D0B10A14; Mon, 8 Aug 2016 09:15:01 -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 6AB6710A12 for ; Mon, 8 Aug 2016 09:15:00 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id F02A742038B for ; Mon, 8 Aug 2016 10:14:59 -0600 (MDT) X-ASG-Debug-ID: 1470672899-09eadd4f1614490001-byXFYA Received: from mx3-pf3.cudamail.com ([192.168.14.3]) by bar5.cudamail.com with ESMTP id e0zfOaaegF1QhJeb (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 08 Aug 2016 10:14:59 -0600 (MDT) X-Barracuda-Envelope-From: blp@ovn.org X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.3 Received: from unknown (HELO relay5-d.mail.gandi.net) (217.70.183.197) by mx3-pf3.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 8 Aug 2016 16:14:59 -0000 Received-SPF: pass (mx3-pf3.cudamail.com: SPF record at ovn.org designates 217.70.183.197 as permitted sender) X-Barracuda-Apparent-Source-IP: 217.70.183.197 X-Barracuda-RBL-IP: 217.70.183.197 Received: from mfilter19-d.gandi.net (mfilter19-d.gandi.net [217.70.178.147]) by relay5-d.mail.gandi.net (Postfix) with ESMTP id 805E241C090; Mon, 8 Aug 2016 18:14:57 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter19-d.gandi.net Received: from relay5-d.mail.gandi.net ([IPv6:::ffff:217.70.183.197]) by mfilter19-d.gandi.net (mfilter19-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id Ey5F3eS6ltvO; Mon, 8 Aug 2016 18:14:55 +0200 (CEST) X-Originating-IP: 173.228.112.241 Received: from sigabrt.gateway.sonic.net (173-228-112-241.dsl.dynamic.fusionbroadband.com [173.228.112.241]) (Authenticated sender: blp@ovn.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 1D82141C08A; Mon, 8 Aug 2016 18:14:54 +0200 (CEST) X-CudaMail-Envelope-Sender: blp@ovn.org From: Ben Pfaff To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-V3-807024327 X-CudaMail-DTE: 080816 X-CudaMail-Originating-IP: 217.70.183.197 Date: Mon, 8 Aug 2016 09:14:28 -0700 X-ASG-Orig-Subj: [##CM-V3-807024327##][PATCH v2 17/21] meta-flow: New functions mf_subfield_copy() and mf_subfield_swap(). Message-Id: <1470672872-19450-18-git-send-email-blp@ovn.org> X-Mailer: git-send-email 2.1.3 In-Reply-To: <1470672872-19450-1-git-send-email-blp@ovn.org> References: <1470672872-19450-1-git-send-email-blp@ovn.org> X-Barracuda-Connect: UNKNOWN[192.168.14.3] X-Barracuda-Start-Time: 1470672899 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Cc: Ben Pfaff Subject: [ovs-dev] [PATCH v2 17/21] meta-flow: New functions mf_subfield_copy() and mf_subfield_swap(). 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" The function nxm_execute_reg_move() was almost a general-purpose function for manipulating subfields, except for its awkward interface that took a struct ofpact_reg_move instead of a plain source and destination. This commit introduces a general-purpose function in meta-flow that corrects this flaw, and updates the callers. An upcoming commit will introduce a new user of the function. This commit also introduces a related function mf_subfield_swap() to swap the contents of subfields. An upcoming commit will introduce the first user. Signed-off-by: Ben Pfaff --- include/openvswitch/meta-flow.h | 6 ++++ lib/meta-flow.c | 74 +++++++++++++++++++++++++++++++++++++++++ lib/nx-match.c | 31 ----------------- lib/nx-match.h | 2 -- ofproto/ofproto-dpif-xlate.c | 3 +- 5 files changed, 82 insertions(+), 34 deletions(-) diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h index 76d915c..f209fc2 100644 --- a/include/openvswitch/meta-flow.h +++ b/include/openvswitch/meta-flow.h @@ -2116,6 +2116,12 @@ void mf_read_subfield(const struct mf_subfield *, const struct flow *, union mf_subvalue *); uint64_t mf_get_subfield(const struct mf_subfield *, const struct flow *); +void mf_subfield_copy(const struct mf_subfield *src, + const struct mf_subfield *dst, + struct flow *, struct flow_wildcards *); +void mf_subfield_swap(const struct mf_subfield *, + const struct mf_subfield *, + struct flow *flow, struct flow_wildcards *); enum ofperr mf_check_src(const struct mf_subfield *, const struct flow *); enum ofperr mf_check_dst(const struct mf_subfield *, const struct flow *); diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 2c89613..a7d3131 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -1962,6 +1962,80 @@ mf_check__(const struct mf_subfield *sf, const struct flow *flow, } } +/* Sets all the bits in 'sf' to 1 within 'wc', if 'wc' is nonnull. */ +static void +unwildcard_subfield(const struct mf_subfield *sf, struct flow_wildcards *wc) +{ + if (wc) { + union mf_value mask; + + memset(&mask, 0, sizeof mask); + bitwise_one(&mask, sf->field->n_bytes, sf->ofs, sf->n_bits); + mf_mask_field_masked(sf->field, &mask, wc); + } +} + +/* Copies 'src' into 'dst' within 'flow', and sets all the bits in 'src' and + * 'dst to 1s in 'wc', if 'wc' is nonnull. + * + * 'src' and 'dst may overlap. */ +void +mf_subfield_copy(const struct mf_subfield *src, + const struct mf_subfield *dst, + struct flow *flow, struct flow_wildcards *wc) +{ + ovs_assert(src->n_bits == dst->n_bits); + if (mf_are_prereqs_ok(dst->field, flow, wc) + && mf_are_prereqs_ok(src->field, flow, wc)) { + unwildcard_subfield(src, wc); + unwildcard_subfield(dst, wc); + + union mf_value src_value; + union mf_value dst_value; + mf_get_value(dst->field, flow, &dst_value); + mf_get_value(src->field, flow, &src_value); + bitwise_copy(&src_value, src->field->n_bytes, src->ofs, + &dst_value, dst->field->n_bytes, dst->ofs, + src->n_bits); + mf_set_flow_value(dst->field, &dst_value, flow); + } +} + +/* Swaps the bits in 'src' and 'dst' within 'flow', and sets all the bits in + * 'src' and 'dst to 1s in 'wc', if 'wc' is nonnull. + * + * 'src' and 'dst may overlap. */ +void +mf_subfield_swap(const struct mf_subfield *a, + const struct mf_subfield *b, + struct flow *flow, struct flow_wildcards *wc) +{ + ovs_assert(a->n_bits == b->n_bits); + if (mf_are_prereqs_ok(a->field, flow, wc) + && mf_are_prereqs_ok(b->field, flow, wc)) { + unwildcard_subfield(a, wc); + unwildcard_subfield(b, wc); + + union mf_value a_value; + union mf_value b_value; + mf_get_value(a->field, flow, &a_value); + mf_get_value(b->field, flow, &b_value); + union mf_value b2_value = b_value; + + /* Copy 'a' into 'b'. */ + bitwise_copy(&a_value, a->field->n_bytes, a->ofs, + &b_value, b->field->n_bytes, b->ofs, + a->n_bits); + mf_set_flow_value(b->field, &b_value, flow); + + /* Copy original 'b' into 'a'. */ + bitwise_copy(&b2_value, b->field->n_bytes, b->ofs, + &a_value, a->field->n_bytes, a->ofs, + b->n_bits); + mf_set_flow_value(a->field, &a_value, flow); + } +} + /* Checks whether 'sf' is valid for reading a subfield out of 'flow'. Returns * 0 if so, otherwise an OpenFlow error code (e.g. as returned by * ofp_mkerr()). */ diff --git a/lib/nx-match.c b/lib/nx-match.c index 89c6e3e..b03ccf2 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -1623,37 +1623,6 @@ nxm_reg_move_check(const struct ofpact_reg_move *move, const struct flow *flow) /* nxm_execute_reg_move(). */ void -nxm_execute_reg_move(const struct ofpact_reg_move *move, - struct flow *flow, struct flow_wildcards *wc) -{ - /* Check that the fields exist. */ - if (mf_are_prereqs_ok(move->dst.field, flow, wc) - && mf_are_prereqs_ok(move->src.field, flow, wc)) { - union mf_value src_value; - union mf_value dst_value; - union mf_value mask; - - /* Should only mask the bits affected. */ - memset(&mask, 0, sizeof mask); - bitwise_one(&mask, move->dst.field->n_bytes, move->dst.ofs, - move->src.n_bits); - mf_mask_field_masked(move->dst.field, &mask, wc); - - memset(&mask, 0, sizeof mask); - bitwise_one(&mask, move->src.field->n_bytes, move->src.ofs, - move->src.n_bits); - mf_mask_field_masked(move->src.field, &mask, wc); - - mf_get_value(move->dst.field, flow, &dst_value); - mf_get_value(move->src.field, flow, &src_value); - bitwise_copy(&src_value, move->src.field->n_bytes, move->src.ofs, - &dst_value, move->dst.field->n_bytes, move->dst.ofs, - move->src.n_bits); - mf_set_flow_value(move->dst.field, &dst_value, flow); - } -} - -void nxm_reg_load(const struct mf_subfield *dst, uint64_t src_data, struct flow *flow, struct flow_wildcards *wc) { diff --git a/lib/nx-match.h b/lib/nx-match.h index 51d6414..c366a04 100644 --- a/lib/nx-match.h +++ b/lib/nx-match.h @@ -107,8 +107,6 @@ void nxm_format_reg_move(const struct ofpact_reg_move *, struct ds *); enum ofperr nxm_reg_move_check(const struct ofpact_reg_move *, const struct flow *); -void nxm_execute_reg_move(const struct ofpact_reg_move *, struct flow *, - struct flow_wildcards *); void nxm_reg_load(const struct mf_subfield *, uint64_t src_data, struct flow *, struct flow_wildcards *); diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 393854e..7b71c6a 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -4908,7 +4908,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_REG_MOVE: - nxm_execute_reg_move(ofpact_get_REG_MOVE(a), flow, wc); + mf_subfield_copy(&ofpact_get_REG_MOVE(a)->src, + &ofpact_get_REG_MOVE(a)->dst, flow, wc); break; case OFPACT_SET_FIELD: