From patchwork Thu Sep 18 01:55:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 390627 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 938D5140096 for ; Thu, 18 Sep 2014 11:57:59 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757358AbaIRB5z (ORCPT ); Wed, 17 Sep 2014 21:57:55 -0400 Received: from mail-pd0-f177.google.com ([209.85.192.177]:47121 "EHLO mail-pd0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757052AbaIRB5y (ORCPT ); Wed, 17 Sep 2014 21:57:54 -0400 Received: by mail-pd0-f177.google.com with SMTP id r10so321296pdi.36 for ; Wed, 17 Sep 2014 18:57:53 -0700 (PDT) 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=IYbVqaMZU9TvJqdQx0uGDt8PJ+mdZpMWfwtYM0fFZX4=; b=E7ZtT/m8r4pw61C0ZZSn4GYi0p622jE/Lvh3Q16UEc/UgHbpV1I/Jb2fHyKt8dUZPd DB9iVE7ppLdjyMzMnesYDRqVfxy1Jj8uSOMIRH/JbTolzKRtgcbzqceY6yHF8LW7Eyls Vk1meEMalBLLl793BQA6EHHogOWtGuMyEFRgDTTUiPiA92vfNlkg8r05P1Num7DjOgB0 PvcXBtDmUjBZCIGSUYQgHEmInRLOYXdPEPpDQNYfojjgu785RuGs4Edeka06ZZsjTe8D 6N9nq0kQ7dqH7QK57JgtHKjs/H+3gM38yaGf20M8ryZ0lndEizsMtxIY+JZRwCJlPX4U J9Qw== X-Gm-Message-State: ALoCoQnCEWgxgL39z6UxSxqoGuhMFiSba+TK7yCPaJuoGH0vy+v7RX3dcFSajEWKYH5+dHLCrFzH X-Received: by 10.66.220.230 with SMTP id pz6mr1129399pac.145.1411005473751; Wed, 17 Sep 2014 18:57:53 -0700 (PDT) Received: from ayumi.isobedori.kobe.vergenet.net (p4222-ipbfp1605kobeminato.hyogo.ocn.ne.jp. [114.154.95.222]) by mx.google.com with ESMTPSA id qj2sm18032134pbc.78.2014.09.17.18.57.50 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Sep 2014 18:57:52 -0700 (PDT) From: Simon Horman To: dev@openvswitch.org, netdev@vger.kernel.org Cc: Pravin Shelar , Jesse Gross , Thomas Graf , Simon Horman Subject: [PATCH/RFC repost 6/8] datapath: validation of select group action Date: Thu, 18 Sep 2014 10:55:09 +0900 Message-Id: <1411005311-11752-7-git-send-email-simon.horman@netronome.com> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1411005311-11752-1-git-send-email-simon.horman@netronome.com> References: <1411005311-11752-1-git-send-email-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Allow validation and copying of select group actions. This completes the prototype select group action implementation in the datapath. Subsequent patches will add support to ovs-vswtichd. Signed-off-by: Simon Horman --- datapath/flow_netlink.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c index 6c74841..90eddba 100644 --- a/datapath/flow_netlink.c +++ b/datapath/flow_netlink.c @@ -1497,6 +1497,94 @@ static int validate_and_copy_sample(const struct nlattr *attr, return 0; } +static int validate_and_copy_bucket(const struct nlattr *attr, + const struct sw_flow_key *key, int depth, + struct sw_flow_actions **sfa, + __be16 eth_type, __be16 vlan_tci) +{ + const struct nlattr *attrs[OVS_BUCKET_ATTR_MAX + 1]; + const struct nlattr *weight, *actions; + const struct nlattr *a; + int rem, start, err, st_acts; + + memset(attrs, 0, sizeof(attrs)); + nla_for_each_nested(a, attr, rem) { + int type = nla_type(a); + if (!type || type > OVS_BUCKET_ATTR_MAX || attrs[type]) + return -EINVAL; + attrs[type] = a; + } + if (rem) + return -EINVAL; + + weight = attrs[OVS_BUCKET_ATTR_WEIGHT]; + if (!weight || nla_len(weight) != sizeof(u16)) + return -EINVAL; + + actions = attrs[OVS_BUCKET_ATTR_ACTIONS]; + if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN)) + return -EINVAL; + + /* validation done, copy sample action. */ + start = add_nested_action_start(sfa, OVS_SELECT_GROUP_ATTR_BUCKET); + if (start < 0) + return start; + err = add_action(sfa, OVS_BUCKET_ATTR_WEIGHT, + nla_data(weight), sizeof(u16)); + if (err) + return err; + st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS); + if (st_acts < 0) + return st_acts; + + err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa, + eth_type, vlan_tci); + if (err) + return err; + + add_nested_action_end(*sfa, st_acts); + add_nested_action_end(*sfa, start); + + return 0; +} + +static int validate_and_copy_select_group(const struct nlattr *attr, + const struct sw_flow_key *key, + int depth, + struct sw_flow_actions **sfa, + __be16 eth_type, __be16 vlan_tci) +{ + bool have_bucket = false; + const struct nlattr *a; + int rem, start, err; + + start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SELECT_GROUP); + if (start < 0) + return start; + + nla_for_each_nested(a, attr, rem) { + int type = nla_type(a); + + if (!type || type > OVS_SAMPLE_ATTR_MAX) + return -EINVAL; + + /* Only possible type is OVS_SELECT_GROUP_ATTR_BUCKET */ + if ((nla_len(a) && nla_len(a) < NLA_HDRLEN)) + return -EINVAL; + err = validate_and_copy_bucket(a, key, depth, sfa, + eth_type, vlan_tci); + if (err < 0) + return err; + have_bucket = true; + } + if (rem || !have_bucket) + return -EINVAL; + + add_nested_action_end(*sfa, start); + + return 0; +} + static int validate_tp_port(const struct sw_flow_key *flow_key, __be16 eth_type) { @@ -1750,6 +1838,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, [OVS_ACTION_ATTR_POP_VLAN] = 0, [OVS_ACTION_ATTR_SET] = (u32)-1, [OVS_ACTION_ATTR_SAMPLE] = (u32)-1, + [OVS_ACTION_ATTR_SELECT_GROUP] = (u32)-1, [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash) }; const struct ovs_action_push_vlan *vlan; @@ -1856,6 +1945,19 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, skip_copy = true; break; + case OVS_ACTION_ATTR_SELECT_GROUP: + /* Nothing may come after a select group */ + if (!last_action(a, rem)) + return -EINVAL; + + err = validate_and_copy_select_group(a, key, depth, + sfa, eth_type, + vlan_tci); + if (err) + return err; + skip_copy = true; + break; + default: return -EINVAL; }