From patchwork Sat Jul 20 03:07:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 260400 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id DA1612C0095 for ; Sat, 20 Jul 2013 13:08:05 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753635Ab3GTDHR (ORCPT ); Fri, 19 Jul 2013 23:07:17 -0400 Received: from kirsty.vergenet.net ([202.4.237.240]:38101 "EHLO kirsty.vergenet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753590Ab3GTDGt (ORCPT ); Fri, 19 Jul 2013 23:06:49 -0400 Received: from penelope.isobedori.kobe.vergenet.net (g1-27-253-132-208.bmobile.ne.jp [27.253.132.208]) by kirsty.vergenet.net (Postfix) with ESMTP id 0A96725BFD3; Sat, 20 Jul 2013 13:06:46 +1000 (EST) Received: by penelope.isobedori.kobe.vergenet.net (Postfix, from userid 7100) id A5F797C01C2; Sat, 20 Jul 2013 12:07:06 +0900 (JST) From: Simon Horman To: dev@openvswitch.org, netdev@vger.kernel.org Cc: Ravi K , Isaku Yamahata , Jesse Gross , Pravin B Shelar , jarno.rajahalme@nsn.com, Joe Stringer Subject: [PATCH v2.35 4/6] ofp-actions: Add separate OpenFlow 1.3 action parser Date: Sat, 20 Jul 2013 12:07:01 +0900 Message-Id: <1374289623-17056-5-git-send-email-horms@verge.net.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1374289623-17056-1-git-send-email-horms@verge.net.au> References: <1374289623-17056-1-git-send-email-horms@verge.net.au> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Joe Stringer This patch adds new ofpact_from_openflow13() and ofpacts_from_openflow13() functions parallel to the existing ofpact handling code. In the OpenFlow 1.3 version, push_mpls is handled differently, but all other actions are handled by the existing code. For push_mpls, ofpact_push_mpls.ofpact.compat is set to OFPUTIL_OFPAT13_PUSH_MPLS, which allows correct VLAN+MPLS datapath behaviour to be determined at odp translation time. Signed-off-by: Joe Stringer Signed-off-by: Simon Horman --- lib/ofp-actions.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 3e8b646..80994bd 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -877,6 +877,40 @@ ofpacts_from_openflow11(const union ofp_action *in, size_t n_in, return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow11); } +static enum ofperr +ofpact_from_openflow13(const union ofp_action *a, struct ofpbuf *out) +{ + enum ofputil_action_code code; + enum ofperr error; + + error = decode_openflow11_action(a, &code); + if (error) { + return error; + } + + if (code == OFPUTIL_OFPAT11_PUSH_MPLS) { + struct ofpact_push_mpls *oam; + struct ofp11_action_push *oap = (struct ofp11_action_push *)a; + if (!eth_type_mpls(oap->ethertype)) { + return OFPERR_OFPBAC_BAD_ARGUMENT; + } + oam = ofpact_put_PUSH_MPLS(out); + oam->ethertype = oap->ethertype; + oam->ofpact.compat = OFPUTIL_OFPAT13_PUSH_MPLS; + } else { + return ofpact_from_openflow11(a, out); + } + + return error; +} + +static enum ofperr +ofpacts_from_openflow13(const union ofp_action *in, size_t n_in, + struct ofpbuf *out) +{ + return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow13); +} + /* OpenFlow 1.1 instructions. */ #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \ @@ -1080,6 +1114,17 @@ get_actions_from_instruction(const struct ofp11_instruction *inst, *n_actions = (ntohs(inst->len) - sizeof *inst) / OFP11_INSTRUCTION_ALIGN; } +static uint8_t +get_version_from_ofpbuf(const struct ofpbuf *openflow) +{ + if (openflow && openflow->l2) { + struct ofp_header *oh = openflow->l2; + return oh->version; + } + + return OFP10_VERSION; +} + /* Attempts to convert 'actions_len' bytes of OpenFlow 1.1 actions from the * front of 'openflow' into ofpacts. On success, replaces any existing content * in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'. @@ -1099,8 +1144,15 @@ ofpacts_pull_openflow11_actions(struct ofpbuf *openflow, unsigned int actions_len, struct ofpbuf *ofpacts) { - return ofpacts_pull_actions(openflow, actions_len, ofpacts, - ofpacts_from_openflow11); + uint8_t version = get_version_from_ofpbuf(openflow); + + if (version < OFP13_VERSION) { + return ofpacts_pull_actions(openflow, actions_len, ofpacts, + ofpacts_from_openflow11); + } else { + return ofpacts_pull_actions(openflow, actions_len, ofpacts, + ofpacts_from_openflow13); + } } enum ofperr @@ -1152,10 +1204,15 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, if (insts[OVSINST_OFPIT11_APPLY_ACTIONS]) { const union ofp_action *actions; size_t n_actions; + uint8_t version = get_version_from_ofpbuf(openflow); get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS], &actions, &n_actions); - error = ofpacts_from_openflow11(actions, n_actions, ofpacts); + if (version < OFP13_VERSION) { + error = ofpacts_from_openflow11(actions, n_actions, ofpacts); + } else { + error = ofpacts_from_openflow13(actions, n_actions, ofpacts); + } if (error) { goto exit; }