From patchwork Tue Jun 26 07:59:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934708 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="dkx+m+iE"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJQc22Tnz9ryk for ; Tue, 26 Jun 2018 18:01:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752793AbeFZIB0 (ORCPT ); Tue, 26 Jun 2018 04:01:26 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:36547 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752708AbeFZIBY (ORCPT ); Tue, 26 Jun 2018 04:01:24 -0400 Received: by mail-wr0-f193.google.com with SMTP id f16-v6so16200858wrm.3 for ; Tue, 26 Jun 2018 01:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=We0KcyAG8FISfs355CQ1QAksEboPCRQ4sicrnZIx5Gc=; b=dkx+m+iEkbO9g+JJfopK0GIz2M8PfxSmhR+XZqKD3ACU3YRpgsl070Dfni88JPhqUZ qHdkIzqFndRUkayMaiyFGCZvZN2yRJk6VrbB9m4gqtOUGye7faJc4BiJhTCGPeTcwGvV +e4BKcCgMpYhdBDWAewLYxi5G3WmyPUUochBVXuWPylWamuo63f/l9T5JlZskXmfKwdQ cCKsrTOzlv1H6GWl18Xjt/B3JV6NSHVSHgjLxK6FN21T1awoPGuzAK0i0nPjcLqs9u+4 TwHpThBlAd0yGxw/1NKDArsnl6309jQ5vYDNDHtlFa2aHLgdZz8d8mO4yobAjUkxJNfw 4llA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=We0KcyAG8FISfs355CQ1QAksEboPCRQ4sicrnZIx5Gc=; b=A4H8XOLl5ZaIFhE+8AVdOjw1MekUTpwBRkQZO24SJOa9As7zftxlVlIoKWpZTylBzb 2E0ybfVZdiIouTBjZv8RqoLR3sIEojSYQe7EAedSbhHVvjf8dEVqgH9lyn1Iy+MZ4V7R cc8SwflyEqsMB06M8Pslfd0U/qAKc+nOoqZV/oVAdpNIX00q/V6iXwy8I7R9rO9SLWnv YsFp/CfFBwn0F6oxzfnX+VIAdM5Us2vjV1O1tLMJcxFY0kJ+lwLJDehCwRsu0i2g3U4u O1se6rjHmNbw1JbEOE1tJH3XsZ8V+ChgREQPGORXqrCQ2lI+4jMGphVmXEp1vDrN75VR PcOQ== X-Gm-Message-State: APt69E3YJb+54sDUFZRcQGV8U3Og+jAv2qRb45zeQMy1jy8VCdhEdpua toKlb1KZG0RDSOrVzr72g/7JwBnU X-Google-Smtp-Source: AAOMgpdSfeqY1GeQlHIyRbZJmlIVvK6aswtM5mHN9BQzDr7Q16ivq1lv0l1PcAeSWfq3tT8BYqWbWQ== X-Received: by 2002:adf:ebc3:: with SMTP id v3-v6mr475220wrn.33.1530000083150; Tue, 26 Jun 2018 01:01:23 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id e63-v6sm1417496wma.46.2018.06.26.01.01.22 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:22 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 1/9] net: sched: push ops lookup bits into tcf_proto_lookup_ops() Date: Tue, 26 Jun 2018 09:59:52 +0200 Message-Id: <20180626080000.12964-2-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Push all bits that take care of ops lookup, including module loading outside tcf_proto_create() function, into tcf_proto_lookup_ops() Signed-off-by: Jiri Pirko --- net/sched/cls_api.c | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index cdc3c87c53e6..db45931bbada 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -39,7 +39,7 @@ static DEFINE_RWLOCK(cls_mod_lock); /* Find classifier type by string name */ -static const struct tcf_proto_ops *tcf_proto_lookup_ops(const char *kind) +static const struct tcf_proto_ops *__tcf_proto_lookup_ops(const char *kind) { const struct tcf_proto_ops *t, *res = NULL; @@ -57,6 +57,33 @@ static const struct tcf_proto_ops *tcf_proto_lookup_ops(const char *kind) return res; } +static const struct tcf_proto_ops * +tcf_proto_lookup_ops(const char *kind, struct netlink_ext_ack *extack) +{ + const struct tcf_proto_ops *ops; + + ops = __tcf_proto_lookup_ops(kind); + if (ops) + return ops; +#ifdef CONFIG_MODULES + rtnl_unlock(); + request_module("cls_%s", kind); + rtnl_lock(); + ops = __tcf_proto_lookup_ops(kind); + /* We dropped the RTNL semaphore in order to perform + * the module load. So, even if we succeeded in loading + * the module we have to replay the request. We indicate + * this using -EAGAIN. + */ + if (ops) { + module_put(ops->owner); + return ERR_PTR(-EAGAIN); + } +#endif + NL_SET_ERR_MSG(extack, "TC classifier not found"); + return ERR_PTR(-ENOENT); +} + /* Register(unregister) new classifier type */ int register_tcf_proto_ops(struct tcf_proto_ops *ops) @@ -133,27 +160,9 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol, if (!tp) return ERR_PTR(-ENOBUFS); - err = -ENOENT; - tp->ops = tcf_proto_lookup_ops(kind); - if (!tp->ops) { -#ifdef CONFIG_MODULES - rtnl_unlock(); - request_module("cls_%s", kind); - rtnl_lock(); - tp->ops = tcf_proto_lookup_ops(kind); - /* We dropped the RTNL semaphore in order to perform - * the module load. So, even if we succeeded in loading - * the module we have to replay the request. We indicate - * this using -EAGAIN. - */ - if (tp->ops) { - module_put(tp->ops->owner); - err = -EAGAIN; - } else { - NL_SET_ERR_MSG(extack, "TC classifier not found"); - err = -ENOENT; - } -#endif + tp->ops = tcf_proto_lookup_ops(kind, extack); + if (IS_ERR(tp->ops)) { + err = PTR_ERR(tp->ops); goto errout; } tp->classify = tp->ops->classify; From patchwork Tue Jun 26 07:59:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934709 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="p/+QJNZd"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJQh3Rfrz9ryk for ; Tue, 26 Jun 2018 18:01:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752850AbeFZIBa (ORCPT ); Tue, 26 Jun 2018 04:01:30 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:35084 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752695AbeFZIB0 (ORCPT ); Tue, 26 Jun 2018 04:01:26 -0400 Received: by mail-wr0-f194.google.com with SMTP id c13-v6so6235441wrq.2 for ; Tue, 26 Jun 2018 01:01:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5tflepWCHL5bpPOx2ADYRd69og5OCljW81WIVzLRIL0=; b=p/+QJNZdgNE7g/GwrvtuS/PWOH4WsbHfscnSxfRbGKpqoSGqYcBM0ZCUyABF3bTGfO jcI0ieruNpf4ABdpanUwzRMxHdOhNp4SsKr1SK3vwQv5Vttcr/b6kOO5FNm3eWMSH7JF o2qD3v6mVYVIwv8WoN2OvYnTowlDbxBNsH2s7bsTIt5bF2Zrp5xDbkoAdjwVtbnk/g+n JMA7QlruYe25PTBnOC4MEE7QfoX6DEW9GkHSdc1wBgTLButSYMbu9ob36y94k+4DD1Rg konNvEXgFgheQIDnsi18y9bK6FLQnxgm4LjXrMluznC0j4naRYUyA05ZNC6IwXt06mKu +kkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5tflepWCHL5bpPOx2ADYRd69og5OCljW81WIVzLRIL0=; b=hqoGkgYz9XtBUeBdRCsfPGiFNpvK/NtCuE0CbkLRmP1qJYqU54F2KwHHogFyevSBBC t2i7ISwv1ur1bW//gUdwUqajG2AGAECcVnuXQrQMA7debDHT1/D7o6ecwFiIv6QssDnW OXEqItErYXQxc27LUqovz++055bIFBVJ/rJnCCr6UjhvJabsf2frtk6xY24XSRIWUfC9 lIec8e0y9WCugPhSrvs6kUn8z2jdb3wk+CWnReYm7rbY4BI31dDlBn/G2Zo+PQra9p8Q t4l42U+tPNU9xnU/ZQRZVZJAXwb6HgyWo1JAWNgC1X2gprzjKisydK5Uk6IeM222CAJI oP0A== X-Gm-Message-State: APt69E1rba5luHwRhYCPJDVTqTX2SmZv25vtSoT2c8XVqJmbTNeWBDhT eBE9PK0DT5zKb0TWJylGjzRYXrO/ X-Google-Smtp-Source: AAOMgpf3VGMtE8Ck8vtw7xpBLwVUVtAHHRQH4NALXSWILvkbKV4++K6ujDy5uvkxAOyHn4kbdvm7ow== X-Received: by 2002:adf:b964:: with SMTP id b33-v6mr479378wrg.265.1530000084240; Tue, 26 Jun 2018 01:01:24 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id i193-v6sm1486862wmf.13.2018.06.26.01.01.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:23 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 2/9] net: sched: introduce chain templates Date: Tue, 26 Jun 2018 09:59:53 +0200 Message-Id: <20180626080000.12964-3-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Introduce a group of new tc-rtnl commands to allow user to set per-chain template. Templates lock down individual chains for particular classifier type/options combinations. The classifier needs to support templates, otherwise kernel would reply with error. For example, to lock chain 22 to allow only filters of type flower with destination mac address, user needs to do: chain 22 flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF In case the chain already contains some filters it is not possible to add or remove template. That is permitted only for empty chains. Alongside with add/del commands, introduce also get/dump and notifications. Signed-off-by: Jiri Pirko --- include/net/sch_generic.h | 14 +- include/uapi/linux/rtnetlink.h | 7 + net/sched/cls_api.c | 371 ++++++++++++++++++++++++++++++++++++++++- net/sched/cls_basic.c | 2 +- net/sched/cls_bpf.c | 3 +- net/sched/cls_cgroup.c | 2 +- net/sched/cls_flow.c | 3 +- net/sched/cls_flower.c | 3 +- net/sched/cls_fw.c | 3 +- net/sched/cls_matchall.c | 3 +- net/sched/cls_route.c | 2 +- net/sched/cls_rsvp.h | 3 +- net/sched/cls_tcindex.c | 2 +- net/sched/cls_u32.c | 2 +- security/selinux/nlmsgtab.c | 2 +- 15 files changed, 405 insertions(+), 17 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 6488daa32f82..f2a27d41fed5 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -235,6 +235,8 @@ struct tcf_result { }; }; +struct tcf_chain; + struct tcf_proto_ops { struct list_head head; char kind[IFNAMSIZ]; @@ -250,17 +252,25 @@ struct tcf_proto_ops { int (*change)(struct net *net, struct sk_buff *, struct tcf_proto*, unsigned long, u32 handle, struct nlattr **, - void **, bool, + void **, bool, void *tmplt_priv, struct netlink_ext_ack *); int (*delete)(struct tcf_proto *tp, void *arg, bool *last, struct netlink_ext_ack *); void (*walk)(struct tcf_proto*, struct tcf_walker *arg); void (*bind_class)(void *, u32, unsigned long); + void * (*tmplt_create)(struct net *net, + struct tcf_chain *chain, + struct nlattr **tca, + struct netlink_ext_ack *extack); + void (*tmplt_destroy)(void *tmplt_priv); /* rtnetlink specific */ int (*dump)(struct net*, struct tcf_proto*, void *, struct sk_buff *skb, struct tcmsg*); + int (*tmplt_dump)(struct sk_buff *skb, + struct net *net, + void *tmplt_priv); struct module *owner; }; @@ -299,6 +309,8 @@ struct tcf_chain { struct tcf_block *block; u32 index; /* chain index */ unsigned int refcnt; + const struct tcf_proto_ops *tmplt_ops; + void *tmplt_priv; }; struct tcf_block { diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index 7d8502313c99..45fd8cc1fdb2 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -150,6 +150,13 @@ enum { RTM_NEWCACHEREPORT = 96, #define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT + RTM_NEWCHAINTMPLT = 100, +#define RTM_NEWCHAINTMPLT RTM_NEWCHAINTMPLT + RTM_DELCHAINTMPLT, +#define RTM_DELCHAINTMPLT RTM_DELCHAINTMPLT + RTM_GETCHAINTMPLT, +#define RTM_GETCHAINTMPLT RTM_GETCHAINTMPLT + __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index db45931bbada..0c88520f80f2 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -227,7 +227,7 @@ static void tcf_chain_head_change(struct tcf_chain *chain, tcf_chain_head_change_item(item, tp_head); } -static void tcf_chain_flush(struct tcf_chain *chain) +static void tcf_chain_flush(struct tcf_chain *chain, bool destroy_template) { struct tcf_proto *tp = rtnl_dereference(chain->filter_chain); @@ -238,6 +238,11 @@ static void tcf_chain_flush(struct tcf_chain *chain) tp = rtnl_dereference(chain->filter_chain); tcf_chain_put(chain); } + if (destroy_template && chain->tmplt_ops) { + chain->tmplt_ops->tmplt_destroy(chain->tmplt_priv); + module_put(chain->tmplt_ops->owner); + tcf_chain_put(chain); + } } static void tcf_chain_destroy(struct tcf_chain *chain) @@ -691,7 +696,7 @@ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, tcf_chain_hold(chain); list_for_each_entry(chain, &block->chain_list, list) - tcf_chain_flush(chain); + tcf_chain_flush(chain, true); } tcf_block_offload_unbind(block, q, ei); @@ -1191,9 +1196,15 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, goto errout; } + if (chain->tmplt_ops && chain->tmplt_ops != tp->ops) { + NL_SET_ERR_MSG(extack, "Chain template is set to a different filter kind"); + err = -EINVAL; + goto errout; + } + err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh, n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE, - extack); + chain->tmplt_priv, extack); if (err == 0) { if (tp_created) tcf_chain_tp_insert(chain, &chain_info, tp); @@ -1274,7 +1285,7 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n, if (prio == 0) { tfilter_notify_chain(net, skb, block, q, parent, n, chain, RTM_DELTFILTER); - tcf_chain_flush(chain); + tcf_chain_flush(chain, false); err = 0; goto errout; } @@ -1570,6 +1581,354 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } +static int tc_tmplt_fill_node(struct tcf_chain *chain, struct net *net, + struct sk_buff *skb, struct tcf_block *block, + struct Qdisc *q, u32 parent, + u32 portid, u32 seq, u16 flags, int event) +{ + unsigned char *b = skb_tail_pointer(skb); + const struct tcf_proto_ops *ops; + struct nlmsghdr *nlh; + struct tcmsg *tcm; + void *priv; + + ops = chain->tmplt_ops; + priv = chain->tmplt_priv; + + nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); + if (!nlh) + goto out_nlmsg_trim; + tcm = nlmsg_data(nlh); + tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; + tcm->tcm_handle = 0; + if (q) { + tcm->tcm_ifindex = qdisc_dev(q)->ifindex; + tcm->tcm_parent = parent; + } else { + tcm->tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + tcm->tcm_block_index = block->index; + } + + if (nla_put_string(skb, TCA_KIND, ops->kind)) + goto nla_put_failure; + if (nla_put_u32(skb, TCA_CHAIN, chain->index)) + goto nla_put_failure; + if (ops->tmplt_dump(skb, net, priv) < 0) + goto nla_put_failure; + + nlh->nlmsg_len = skb_tail_pointer(skb) - b; + return skb->len; + +out_nlmsg_trim: +nla_put_failure: + nlmsg_trim(skb, b); + return -EMSGSIZE; +} + +static int tc_tmplt_notify(struct tcf_chain *chain, struct net *net, + struct sk_buff *oskb, struct nlmsghdr *n, + struct tcf_block *block, struct Qdisc *q, + u32 parent, int event, bool unicast) +{ + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + struct sk_buff *skb; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tc_tmplt_fill_node(chain, net, skb, block, q, parent, portid, + n->nlmsg_seq, n->nlmsg_flags, event) <= 0) { + kfree_skb(skb); + return -EINVAL; + } + + if (unicast) + return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); + + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); +} + +static int tc_ctl_tmplt_add(struct tcf_chain *chain, struct net *net, + struct sk_buff *skb, struct nlmsghdr *n, + struct tcf_block *block, struct Qdisc *q, + u32 parent, struct nlattr **tca, + struct netlink_ext_ack *extack) +{ + const struct tcf_proto_ops *ops; + void *tmplt_priv; + + if (chain->tmplt_ops) { + NL_SET_ERR_MSG(extack, "A template is already set for the chain"); + return -EBUSY; + } + if (chain->filter_chain) { + NL_SET_ERR_MSG(extack, "The chain is not empty, unable to add template"); + return -EBUSY; + } + if (!(n->nlmsg_flags & NLM_F_CREATE)) { + NL_SET_ERR_MSG(extack, "Need NLM_F_CREATE to create a new chain template"); + return -ENOENT; + } + ops = tcf_proto_lookup_ops(nla_data(tca[TCA_KIND]), extack); + if (IS_ERR(ops)) + return PTR_ERR(ops); + if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) { + NL_SET_ERR_MSG(extack, "Chain templates are not supported with this classifier"); + return -EOPNOTSUPP; + } + + tmplt_priv = ops->tmplt_create(net, chain, tca, extack); + if (IS_ERR(tmplt_priv)) { + module_put(ops->owner); + return PTR_ERR(tmplt_priv); + } + chain->tmplt_ops = ops; + chain->tmplt_priv = tmplt_priv; + tc_tmplt_notify(chain, net, skb, n, block, q, parent, + RTM_NEWCHAINTMPLT, false); + return 0; +} + +static int tc_ctl_tmplt_del(struct tcf_chain *chain, struct net *net, + struct sk_buff *skb, struct nlmsghdr *n, + struct tcf_block *block, struct Qdisc *q, + u32 parent, struct netlink_ext_ack *extack) +{ + const struct tcf_proto_ops *ops = chain->tmplt_ops; + + if (!ops) { + NL_SET_ERR_MSG(extack, "Unable to delete template as this chain does not have template"); + return -ENOENT; + } + if (chain->filter_chain) { + NL_SET_ERR_MSG(extack, "The chain is not empty, unable to delete template"); + return -EBUSY; + } + if (!ops->tmplt_create) { + NL_SET_ERR_MSG(extack, "Chain templates are not supported with this classifier"); + return -EOPNOTSUPP; + } + tc_tmplt_notify(chain, net, skb, n, block, q, parent, + RTM_DELCHAINTMPLT, false); + ops->tmplt_destroy(chain->tmplt_priv); + module_put(ops->owner); + chain->tmplt_ops = NULL; + chain->tmplt_priv = NULL; + return 0; +} + +static int tc_ctl_tmplt_get(struct tcf_chain *chain, struct net *net, + struct sk_buff *skb, struct nlmsghdr *n, + struct tcf_block *block, struct Qdisc *q, + u32 parent, struct netlink_ext_ack *extack) +{ + const struct tcf_proto_ops *ops = chain->tmplt_ops; + int err; + + if (!ops) { + NL_SET_ERR_MSG(extack, "Unable to get template as this chain does not have template"); + return -ENOENT; + } + err = tc_tmplt_notify(chain, net, skb, n, block, q, parent, + RTM_NEWCHAINTMPLT, true); + if (err < 0) + NL_SET_ERR_MSG(extack, "Failed to send chain template notify message"); + return err; +} + +/* Add/delete/get a chain template */ + +static int tc_ctl_tmplt(struct sk_buff *skb, struct nlmsghdr *n, + struct netlink_ext_ack *extack) +{ + struct net *net = sock_net(skb->sk); + struct nlattr *tca[TCA_MAX + 1]; + struct tcmsg *t; + u32 parent; + u32 chain_index; + struct Qdisc *q = NULL; + struct tcf_chain *chain = NULL; + struct tcf_block *block; + unsigned long cl; + int err; + + if (n->nlmsg_type != RTM_GETCHAINTMPLT && + !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + +replay: + err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL, extack); + if (err < 0) + return err; + + t = nlmsg_data(n); + parent = t->tcm_parent; + cl = 0; + + /* Find filter chain. */ + + block = tcf_block_find(net, &q, &parent, &cl, + t->tcm_ifindex, t->tcm_block_index, extack); + if (IS_ERR(block)) { + err = PTR_ERR(block); + goto errout; + } + + chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0; + if (chain_index > TC_ACT_EXT_VAL_MASK) { + NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit"); + err = -EINVAL; + goto errout; + } + chain = tcf_chain_get(block, chain_index, + n->nlmsg_type == RTM_NEWCHAINTMPLT); + if (!chain) { + NL_SET_ERR_MSG(extack, "Cannot find specified filter chain"); + err = n->nlmsg_type == RTM_NEWTFILTER ? -ENOMEM : -EINVAL; + goto errout; + } + + switch (n->nlmsg_type) { + case RTM_NEWCHAINTMPLT: + err = tc_ctl_tmplt_add(chain, net, skb, n, block, + q, parent, tca, extack); + /* In case the chain template was successfully added, + * take a reference to the chain. This ensures that + * an empty chain with template does not disappear + * at the end of this function. + */ + if (!err) + tcf_chain_hold(chain); + break; + case RTM_DELCHAINTMPLT: + err = tc_ctl_tmplt_del(chain, net, skb, n, block, + q, parent, extack); + /* In case the chain template was successfully deleted, + * put a reference to the chain previously taken + * during template addition. + */ + if (!err) + tcf_chain_put(chain); + break; + case RTM_GETCHAINTMPLT: + err = tc_ctl_tmplt_get(chain, net, skb, n, block, + q, parent, extack); + break; + default: + err = -EOPNOTSUPP; + NL_SET_ERR_MSG(extack, "Unsupported message type"); + break; + } +errout: + if (chain) + tcf_chain_put(chain); + if (err == -EAGAIN) + /* Replay the request. */ + goto replay; + return err; +} + +/* called with RTNL */ +static int tc_dump_tmplt(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct net *net = sock_net(skb->sk); + struct nlattr *tca[TCA_MAX + 1]; + struct Qdisc *q = NULL; + struct tcf_block *block; + struct tcf_chain *chain; + struct tcmsg *tcm = nlmsg_data(cb->nlh); + long index_start; + long index; + u32 parent; + int err; + + if (nlmsg_len(cb->nlh) < sizeof(*tcm)) + return skb->len; + + err = nlmsg_parse(cb->nlh, sizeof(*tcm), tca, TCA_MAX, NULL, NULL); + if (err) + return err; + + if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) { + block = tcf_block_lookup(net, tcm->tcm_block_index); + if (!block) + goto out; + /* If we work with block index, q is NULL and parent value + * will never be used in the following code. The check + * in tcf_fill_node prevents it. However, compiler does not + * see that far, so set parent to zero to silence the warning + * about parent being uninitialized. + */ + parent = 0; + } else { + const struct Qdisc_class_ops *cops; + struct net_device *dev; + unsigned long cl = 0; + + dev = __dev_get_by_index(net, tcm->tcm_ifindex); + if (!dev) + return skb->len; + + parent = tcm->tcm_parent; + if (!parent) { + q = dev->qdisc; + parent = q->handle; + } else { + q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); + } + if (!q) + goto out; + cops = q->ops->cl_ops; + if (!cops) + goto out; + if (!cops->tcf_block) + goto out; + if (TC_H_MIN(tcm->tcm_parent)) { + cl = cops->find(q, tcm->tcm_parent); + if (cl == 0) + goto out; + } + block = cops->tcf_block(q, cl, NULL); + if (!block) + goto out; + if (tcf_block_shared(block)) + q = NULL; + } + + index_start = cb->args[0]; + index = 0; + + list_for_each_entry(chain, &block->chain_list, list) { + if ((tca[TCA_CHAIN] && + nla_get_u32(tca[TCA_CHAIN]) != chain->index) || + !chain->tmplt_ops) + continue; + if (index < index_start) { + index++; + continue; + } + err = tc_tmplt_fill_node(chain, net, skb, block, q, parent, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, + RTM_NEWCHAINTMPLT); + if (err <= 0) + break; + index++; + } + + cb->args[0] = index; + +out: + /* If we did no progress, the error (EMSGSIZE) is real */ + if (skb->len == 0 && err) + return err; + return skb->len; +} + void tcf_exts_destroy(struct tcf_exts *exts) { #ifdef CONFIG_NET_CLS_ACT @@ -1795,6 +2154,10 @@ static int __init tc_filter_init(void) rtnl_register(PF_UNSPEC, RTM_DELTFILTER, tc_del_tfilter, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETTFILTER, tc_get_tfilter, tc_dump_tfilter, 0); + rtnl_register(PF_UNSPEC, RTM_NEWCHAINTMPLT, tc_ctl_tmplt, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELCHAINTMPLT, tc_ctl_tmplt, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_GETCHAINTMPLT, tc_ctl_tmplt, + tc_dump_tmplt, 0); return 0; diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 95367f37098d..a690acac7e6e 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -168,7 +168,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp, static int basic_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, void **arg, bool ovr, - struct netlink_ext_ack *extack) + void *tmplt_priv, struct netlink_ext_ack *extack) { int err; struct basic_head *head = rtnl_dereference(tp->root); diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 1aa7f6511065..363c43dfb894 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -455,7 +455,8 @@ static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp, static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - void **arg, bool ovr, struct netlink_ext_ack *extack) + void **arg, bool ovr, void *tmplt_priv, + struct netlink_ext_ack *extack) { struct cls_bpf_head *head = rtnl_dereference(tp->root); struct cls_bpf_prog *oldprog = *arg; diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 3bc01bdde165..ca5d0315432c 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -78,7 +78,7 @@ static void cls_cgroup_destroy_work(struct work_struct *work) static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - void **arg, bool ovr, + void **arg, bool ovr, void *tmplt_priv, struct netlink_ext_ack *extack) { struct nlattr *tb[TCA_CGROUP_MAX + 1]; diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 2bb043cd436b..2a21e26fcee0 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -391,7 +391,8 @@ static void flow_destroy_filter_work(struct work_struct *work) static int flow_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - void **arg, bool ovr, struct netlink_ext_ack *extack) + void **arg, bool ovr, void *tmplt_priv, + struct netlink_ext_ack *extack) { struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *fold, *fnew; diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 9e8b26a80fb3..09d6c6e67f9d 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -927,7 +927,8 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp, static int fl_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - void **arg, bool ovr, struct netlink_ext_ack *extack) + void **arg, bool ovr, void *tmplt_priv, + struct netlink_ext_ack *extack) { struct cls_fl_head *head = rtnl_dereference(tp->root); struct cls_fl_filter *fold = *arg; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 29eeeaf3ea44..a1d40d48aa24 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -250,7 +250,8 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp, static int fw_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, void **arg, - bool ovr, struct netlink_ext_ack *extack) + bool ovr, void *tmplt_priv, + struct netlink_ext_ack *extack) { struct fw_head *head = rtnl_dereference(tp->root); struct fw_filter *f = *arg; diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index 47b207ef7762..481e77cbf501 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -152,7 +152,8 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp, static int mall_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - void **arg, bool ovr, struct netlink_ext_ack *extack) + void **arg, bool ovr, void *tmplt_priv, + struct netlink_ext_ack *extack) { struct cls_mall_head *head = rtnl_dereference(tp->root); struct nlattr *tb[TCA_MATCHALL_MAX + 1]; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 0404aa5fa7cb..321eb746fe01 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -468,7 +468,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp, static int route4_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, void **arg, bool ovr, - struct netlink_ext_ack *extack) + void *tmplt_priv, struct netlink_ext_ack *extack) { struct route4_head *head = rtnl_dereference(tp->root); struct route4_filter __rcu **fp; diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index e9ccf7daea7d..371618720ef2 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -477,7 +477,8 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, - void **arg, bool ovr, struct netlink_ext_ack *extack) + void **arg, bool ovr, void *tmplt_priv, + struct netlink_ext_ack *extack) { struct rsvp_head *data = rtnl_dereference(tp->root); struct rsvp_filter *f, *nfp; diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 32f4bbd82f35..d9fb5d56c60d 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -500,7 +500,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, static int tcindex_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, - struct nlattr **tca, void **arg, bool ovr, + struct nlattr **tca, void **arg, bool ovr, void *tmplt_priv, struct netlink_ext_ack *extack) { struct nlattr *opt = tca[TCA_OPTIONS]; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index fb861f90fde6..b500ce62ef3c 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -903,7 +903,7 @@ static struct tc_u_knode *u32_init_knode(struct tcf_proto *tp, static int u32_change(struct net *net, struct sk_buff *in_skb, struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, void **arg, bool ovr, - struct netlink_ext_ack *extack) + void *tmplt_priv, struct netlink_ext_ack *extack) { struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *ht; diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 7b7433a1a34c..825777efc83e 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -159,7 +159,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) switch (sclass) { case SECCLASS_NETLINK_ROUTE_SOCKET: /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */ - BUILD_BUG_ON(RTM_MAX != (RTM_NEWCACHEREPORT + 3)); + BUILD_BUG_ON(RTM_MAX != (RTM_NEWCHAINTMPLT + 3)); err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, sizeof(nlmsg_route_perms)); break; From patchwork Tue Jun 26 07:59:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934714 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="Ytf9Hx6k"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJR73JWfz9ryk for ; Tue, 26 Jun 2018 18:01:55 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752834AbeFZIB3 (ORCPT ); Tue, 26 Jun 2018 04:01:29 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:44981 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752758AbeFZIB0 (ORCPT ); Tue, 26 Jun 2018 04:01:26 -0400 Received: by mail-wr0-f195.google.com with SMTP id p12-v6so14547474wrn.11 for ; Tue, 26 Jun 2018 01:01:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RoKpiUqkyLFQI3MVAhgUzsKmTKYxHvibBipVpo3tPhU=; b=Ytf9Hx6k9JLxvR7pui8NUqpH25AE9QX+bsDRyFcDn/0lcgrdtz9NOdmAqVkD9V/+0i L+QI30s8ZeCSu5QtUDsuMvM5TLKKOIV5XkQmi2CS3goYTNBHPnlnz+jF4A8o2LwgBCjd 1SagSmTKgyXlqBqP0VUYLlG6UCcno6mmqAhTtFx3NolPfU0hMcRD1+5Oz1B/h0BseJz+ a+RI0r+D6dtQr0GdrxTgrRmIEGaG9hXu5BAji6xm3MDf05nx5oi2e7XAL5InnSxQeEW2 z5kR8puUIpMRSqgYmG7OD0VXCaoBQt9hAW0x2KBpUNj7G3aoXK4NxJH4I5hB3TVVKw0M /WAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RoKpiUqkyLFQI3MVAhgUzsKmTKYxHvibBipVpo3tPhU=; b=e6owK1aJfEYYZwC25wTz0LGFcMtXMu5wZ5E8+ElUVQsDOOiUjx509Fhvk1sKxLztfA X4031CuZgRChfmO30nX+qgp0jRnKOC8VGYt0eU14cxFrxFlORFwbnXJXe4o914O/BRxA Qr1B337Xkzm+YZ4UJHFM6guHat4gSnfULOgxnJIW+zaviL8v9gaVaSGMM2OdXiPEdJty Bev8lRfgY2NWJLaBJTjx4HM8wGfOSIOR11b4NxK0M6a2jiITu/jUSmw7CqIn2xJFGKVr 20bowcU9HyQoAvKubjeHcxesj8dNjc911khhE63RBhZsRmrR2Tiyi2xPLPGog5YvyTZk tAEg== X-Gm-Message-State: APt69E1Ahg68KWjmnjecTrIWcRUSDLyLP09tgyn+bKnn8hf6S6oCdvZ+ NzIKYP+nQQW9Cjw5TBZtvrnOUBOh X-Google-Smtp-Source: AAOMgpcSLbhQYNymzbmHzuUVai5Kqw0nZvZDkZ6JmeUoMsRmhyUXJ9xqDGORDD0YnM5UZfpGB7+KGQ== X-Received: by 2002:adf:8e10:: with SMTP id n16-v6mr511639wrb.100.1530000085288; Tue, 26 Jun 2018 01:01:25 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id m145-v6sm1201949wma.19.2018.06.26.01.01.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:24 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 3/9] net: sched: cls_flower: move key/mask dumping into a separate function Date: Tue, 26 Jun 2018 09:59:54 +0200 Message-Id: <20180626080000.12964-4-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Push key/mask dumping from fl_dump() into a separate function fl_dump_key(), that will be reused for template dumping. Signed-off-by: Jiri Pirko --- net/sched/cls_flower.c | 62 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 09d6c6e67f9d..76c5516357d5 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1217,29 +1217,9 @@ static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask) return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask); } -static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, - struct sk_buff *skb, struct tcmsg *t) +static int fl_dump_key(struct sk_buff *skb, struct net *net, + struct fl_flow_key *key, struct fl_flow_key *mask) { - struct cls_fl_filter *f = fh; - struct nlattr *nest; - struct fl_flow_key *key, *mask; - - if (!f) - return skb->len; - - t->tcm_handle = f->handle; - - nest = nla_nest_start(skb, TCA_OPTIONS); - if (!nest) - goto nla_put_failure; - - if (f->res.classid && - nla_put_u32(skb, TCA_FLOWER_CLASSID, f->res.classid)) - goto nla_put_failure; - - key = &f->key; - mask = &f->mask->key; - if (mask->indev_ifindex) { struct net_device *dev; @@ -1248,9 +1228,6 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, goto nla_put_failure; } - if (!tc_skip_hw(f->flags)) - fl_hw_update_stats(tp, f); - if (fl_dump_key_val(skb, key->eth.dst, TCA_FLOWER_KEY_ETH_DST, mask->eth.dst, TCA_FLOWER_KEY_ETH_DST_MASK, sizeof(key->eth.dst)) || @@ -1404,6 +1381,41 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags)) goto nla_put_failure; + return 0; + +nla_put_failure: + return -EMSGSIZE; +} + +static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, + struct sk_buff *skb, struct tcmsg *t) +{ + struct cls_fl_filter *f = fh; + struct nlattr *nest; + struct fl_flow_key *key, *mask; + + if (!f) + return skb->len; + + t->tcm_handle = f->handle; + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (!nest) + goto nla_put_failure; + + if (f->res.classid && + nla_put_u32(skb, TCA_FLOWER_CLASSID, f->res.classid)) + goto nla_put_failure; + + key = &f->key; + mask = &f->mask->key; + + if (fl_dump_key(skb, net, key, mask)) + goto nla_put_failure; + + if (!tc_skip_hw(f->flags)) + fl_hw_update_stats(tp, f); + if (f->flags && nla_put_u32(skb, TCA_FLOWER_FLAGS, f->flags)) goto nla_put_failure; From patchwork Tue Jun 26 07:59:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934710 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="rF5Cbp+x"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJQk3LY3z9ryk for ; Tue, 26 Jun 2018 18:01:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932129AbeFZIBb (ORCPT ); Tue, 26 Jun 2018 04:01:31 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:55562 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752708AbeFZIB1 (ORCPT ); Tue, 26 Jun 2018 04:01:27 -0400 Received: by mail-wm0-f67.google.com with SMTP id v16-v6so732741wmv.5 for ; Tue, 26 Jun 2018 01:01:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=y/iHoil75MHSH4mA2Vs4N7xjVU5nluizKlyYDs2nZ9k=; b=rF5Cbp+xCjU1nuRGoYcBOZ5ri7wkqSRNQctFAh9AZFymfJQahlbD8Ef1+V6fjYLnIw BRWOsAUYD7N9kgQTaJA66Tig2dQ7XXydqwma7g91U95TbXVqdFTL1TRzRQ0X4DOfbe5R ODsQVo64rOmMBMZnu/GBYtwYg4JsZTyPnVuVvVrhS4IPl8sblLt6TzgGyZxR1OYlQZkc mtKYaXw9DATrBh8MDPzwQnws4OcqJkg1+5ZMdanGgxZCF8dfA4s9GSzgv3JvxXv0plVm HIQpxhf9FGtVjYZxQ41Qj0C75zi7gRA76WFUfCtzlOeDCYleZxkcPWss6KvZo7EhfUT5 jpTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=y/iHoil75MHSH4mA2Vs4N7xjVU5nluizKlyYDs2nZ9k=; b=pDTV+eF0gkaswpODh8m3YxnWoicHu1bmZmefhXUtFQVQuR1GwrYoHmKiEYdWitns7m iOhj+X4p6TeQwN9I2mzL3ED4CJHLYV8zYfJQCOYrVahZJ81r3ERlwoA2xOQeLwbMM897 jbFIWTOQkXCAryvxXdWaiZk2UYKjcUL/6Z53F45zQ02sduaP8mDK+lSW+qLGU+zaDzW3 6ozVPIE57ZAwcGiwprJhgGnIti6SRjeICJX7Fd/Jd0rMbBMjuKpVeO3TVn7AU/6mOzpW R6H/nRROxW+piMI/xtZ000Js6Jb1lv5DSb7KO5YTJYcmgiZRifoCyHRiORnP6v1KJFqw 7biA== X-Gm-Message-State: APt69E1Y7ylkdQeY7593C95G9UqPMtesw7MNZoRqueg+3mdAYFQ7sbKN iF7xppbQDSFAATNK2qzF94DwL4wE X-Google-Smtp-Source: AAOMgpf4m/FIpXED2MxV3wmtBbxP/P4P8PRpBJp/SwEnIGTpGPG9eLRta/tJPEEtw9n5+Fyn/LhuIw== X-Received: by 2002:a1c:d8:: with SMTP id 207-v6mr650849wma.99.1530000086332; Tue, 26 Jun 2018 01:01:26 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id l78-v6sm1856544wmb.39.2018.06.26.01.01.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:25 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 4/9] net: sched: cls_flower: change fl_init_dissector to accept mask and dissector Date: Tue, 26 Jun 2018 09:59:55 +0200 Message-Id: <20180626080000.12964-5-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko This function is going to be used for templates as well, so we need to pass the pointer separately. Signed-off-by: Jiri Pirko --- net/sched/cls_flower.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 76c5516357d5..9ce4375b3252 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -793,47 +793,48 @@ static int fl_init_mask_hashtable(struct fl_flow_mask *mask) FL_KEY_SET(keys, cnt, id, member); \ } while(0); -static void fl_init_dissector(struct fl_flow_mask *mask) +static void fl_init_dissector(struct flow_dissector *dissector, + struct fl_flow_key *mask) { struct flow_dissector_key keys[FLOW_DISSECTOR_KEY_MAX]; size_t cnt = 0; FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_CONTROL, control); FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_BASIC, basic); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ETH_ADDRS, eth); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_PORTS, tp); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_IP, ip); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_TCP, tcp); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ICMP, icmp); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ARP, arp); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_MPLS, mpls); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_VLAN, vlan); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, enc_ipv4); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, enc_ipv6); - if (FL_KEY_IS_MASKED(&mask->key, enc_ipv4) || - FL_KEY_IS_MASKED(&mask->key, enc_ipv6)) + if (FL_KEY_IS_MASKED(mask, enc_ipv4) || + FL_KEY_IS_MASKED(mask, enc_ipv6)) FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_ENC_CONTROL, enc_control); - FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ENC_PORTS, enc_tp); - skb_flow_dissector_init(&mask->dissector, keys, cnt); + skb_flow_dissector_init(dissector, keys, cnt); } static struct fl_flow_mask *fl_create_new_mask(struct cls_fl_head *head, @@ -852,7 +853,7 @@ static struct fl_flow_mask *fl_create_new_mask(struct cls_fl_head *head, if (err) goto errout_free; - fl_init_dissector(newmask); + fl_init_dissector(&newmask->dissector, &newmask->key); INIT_LIST_HEAD_RCU(&newmask->filters); From patchwork Tue Jun 26 07:59:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934715 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="lDkWDU4k"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJRC25C5z9ryk for ; Tue, 26 Jun 2018 18:01:59 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932246AbeFZIBz (ORCPT ); Tue, 26 Jun 2018 04:01:55 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:37852 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752794AbeFZIB3 (ORCPT ); Tue, 26 Jun 2018 04:01:29 -0400 Received: by mail-wm0-f66.google.com with SMTP id n17-v6so169976wmh.2 for ; Tue, 26 Jun 2018 01:01:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4fFbW3hF0FGHiWjJvPy4FF4QBMOfv7ebk88XXxM6tDg=; b=lDkWDU4kYBi/ag6aqZ3SojEqf1j7T0dCQlsO6HkvSi03hHWOPdwPF3G7XOruoxE+ZW iS1TSHIbxmTFfvrE58GodcJU3lJwIIeRhDg8LVRzn4yzezmeZo4xCgKueC2YpFBhdfzM DDcREpaFV3hDnl3ZUON0X5HVTRlICCi34+T0nSW6Fp2GIewQJ/nc+ggqC2Te/XBIxBP5 cmRZndz8C+mkdHy9G4HQIFVhzZxK9F8nXmcJLNWri7ptX9n8+ZzB9aw49wblWQGztL9V HvYjbPGitRmkx+GLUd7ozBPj7t3IwTiemZ0WBARoec/hKh6/+NC7SKJESthh+pfxK3Wk Qbsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4fFbW3hF0FGHiWjJvPy4FF4QBMOfv7ebk88XXxM6tDg=; b=tsImap+8WLFsmr6OBSOpmr2Hz2/sKoG0WsmuXmEW5p+LUZmor2p/IONRqZ9Cde7R/p 8HOpyMAZMq/fu006QWoeiueZJ1O8srvY69++T+7pJIjXMdkEn4Pe4OGZb9nbucI0Br1l WOxa7CW7YoGUu11wZRvsQ69LMfSC58rOQ8Zx0cGbTz2fkrXhcxQ12YbQVhTAsda69wOo EMeV9JxquBqwKopVncw1kbwsfAtaCUHkcCdQys7gvbAjlaBJChx7SnkYckNjtdxxmanV p31xKZQT97JiJ1ee9uRQ4gdaVchomDP8sFiOVvtjOBlpJz6vEEbYfweiH1mWHuzMG4OZ bzww== X-Gm-Message-State: APt69E0BwtCQAckp3R/D68fVyBsVuri3ZCStH8czMYjep/egEPfy+4dr EtTAEkaxaw4I33vhZmWw1VsKyU1D X-Google-Smtp-Source: AAOMgpfu3uiOYPo5S/rrw78ijjEv7WsWhXMSacZ+tHnF5E5/+pt70LJQGhiFbouXkvb92HXPsBaVOA== X-Received: by 2002:a1c:1983:: with SMTP id 125-v6mr408750wmz.79.1530000087330; Tue, 26 Jun 2018 01:01:27 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id u16-v6sm917035wrp.44.2018.06.26.01.01.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:26 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 5/9] net: sched: cls_flower: implement chain templates Date: Tue, 26 Jun 2018 09:59:56 +0200 Message-Id: <20180626080000.12964-6-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Use the previously introduced template extension and implement callback to create, destroy and dump chain template. The existing parsing and dumping functions are re-used. Also, check if newly added filters fit the template if it is set. Signed-off-by: Jiri Pirko --- net/sched/cls_flower.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 9ce4375b3252..d64d43843a3a 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -70,6 +70,13 @@ struct fl_flow_mask { struct list_head list; }; +struct fl_flow_tmplt { + struct fl_flow_key dummy_key; + struct fl_flow_key mask; + struct flow_dissector dissector; + struct tcf_chain *chain; +}; + struct cls_fl_head { struct rhashtable ht; struct list_head masks; @@ -144,6 +151,23 @@ static void fl_set_masked_key(struct fl_flow_key *mkey, struct fl_flow_key *key, *lmkey++ = *lkey++ & *lmask++; } +static bool fl_mask_fits_tmplt(struct fl_flow_tmplt *tmplt, + struct fl_flow_mask *mask) +{ + const long *lmask = fl_key_get_start(&mask->key, mask); + const long *ltmplt; + int i; + + if (!tmplt) + return true; + ltmplt = fl_key_get_start(&tmplt->mask, mask); + for (i = 0; i < fl_mask_range(mask); i += sizeof(long)) { + if (~*ltmplt++ & *lmask++) + return false; + } + return true; +} + static void fl_clear_masked_range(struct fl_flow_key *key, struct fl_flow_mask *mask) { @@ -902,6 +926,7 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp, struct cls_fl_filter *f, struct fl_flow_mask *mask, unsigned long base, struct nlattr **tb, struct nlattr *est, bool ovr, + struct fl_flow_tmplt *tmplt, struct netlink_ext_ack *extack) { int err; @@ -922,6 +947,11 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp, fl_mask_update_range(mask); fl_set_masked_key(&f->mkey, &f->key, mask); + if (!fl_mask_fits_tmplt(tmplt, mask)) { + NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template"); + return -EINVAL; + } + return 0; } @@ -932,6 +962,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, struct netlink_ext_ack *extack) { struct cls_fl_head *head = rtnl_dereference(tp->root); + struct fl_flow_tmplt *tmplt = tmplt_priv; struct cls_fl_filter *fold = *arg; struct cls_fl_filter *fnew; struct nlattr **tb; @@ -988,7 +1019,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, } err = fl_set_parms(net, tp, fnew, &mask, base, tb, tca[TCA_RATE], ovr, - extack); + tmplt, extack); if (err) goto errout_idr; @@ -1089,6 +1120,52 @@ static void fl_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } +static void *fl_tmplt_create(struct net *net, struct tcf_chain *chain, + struct nlattr **tca, + struct netlink_ext_ack *extack) +{ + struct fl_flow_tmplt *tmplt; + struct nlattr **tb; + int err; + + if (!tca[TCA_OPTIONS]) + return ERR_PTR(-EINVAL); + + tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL); + if (!tb) + return ERR_PTR(-ENOBUFS); + err = nla_parse_nested(tb, TCA_FLOWER_MAX, tca[TCA_OPTIONS], + fl_policy, NULL); + if (err) + goto errout_tb; + + tmplt = kzalloc(sizeof(*tmplt), GFP_KERNEL); + if (!tmplt) + goto errout_tb; + tmplt->chain = chain; + err = fl_set_key(net, tb, &tmplt->dummy_key, &tmplt->mask, extack); + if (err) + goto errout_tmplt; + kfree(tb); + + fl_init_dissector(&tmplt->dissector, &tmplt->mask); + + return tmplt; + +errout_tmplt: + kfree(tmplt); +errout_tb: + kfree(tb); + return ERR_PTR(err); +} + +static void fl_tmplt_destroy(void *tmplt_priv) +{ + struct fl_flow_tmplt *tmplt = tmplt_priv; + + kfree(tmplt); +} + static int fl_dump_key_val(struct sk_buff *skb, void *val, int val_type, void *mask, int mask_type, int len) @@ -1435,6 +1512,31 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, return -1; } +static int fl_tmplt_dump(struct sk_buff *skb, struct net *net, void *tmplt_priv) +{ + struct fl_flow_tmplt *tmplt = tmplt_priv; + struct fl_flow_key *key, *mask; + struct nlattr *nest; + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (!nest) + goto nla_put_failure; + + key = &tmplt->dummy_key; + mask = &tmplt->mask; + + if (fl_dump_key(skb, net, key, mask)) + goto nla_put_failure; + + nla_nest_end(skb, nest); + + return skb->len; + +nla_put_failure: + nla_nest_cancel(skb, nest); + return -EMSGSIZE; +} + static void fl_bind_class(void *fh, u32 classid, unsigned long cl) { struct cls_fl_filter *f = fh; @@ -1454,6 +1556,9 @@ static struct tcf_proto_ops cls_fl_ops __read_mostly = { .walk = fl_walk, .dump = fl_dump, .bind_class = fl_bind_class, + .tmplt_create = fl_tmplt_create, + .tmplt_destroy = fl_tmplt_destroy, + .tmplt_dump = fl_tmplt_dump, .owner = THIS_MODULE, }; From patchwork Tue Jun 26 07:59:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934716 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="fpLXDk6W"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJRG10Kzz9ryk for ; Tue, 26 Jun 2018 18:02:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932206AbeFZIBy (ORCPT ); Tue, 26 Jun 2018 04:01:54 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:39238 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752826AbeFZIB3 (ORCPT ); Tue, 26 Jun 2018 04:01:29 -0400 Received: by mail-wm0-f66.google.com with SMTP id p11-v6so698756wmc.4 for ; Tue, 26 Jun 2018 01:01:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5mpN/atdS9l0bp7bINmGTZjAVzzs98+XGdPA0YAmXXs=; b=fpLXDk6WeOSZlKFj5jbSGIqXCeORWy5Puy7MvkFN1Rdxh+dtsf8uB/QpJ491LbbzL9 Gclbhwr/1OUljcl8s94spAw/HIFZB80lj+P5L8cu0MZIERywzzlIYjzkKHnym3K7orUn 0itUAKm1cdYAFp6O6hoDfF6M10BjUM/h1YPA8VCXGqv1RDg/1jHoU3y5RHev5MK7tBwB Smfg+b/E94ZkcpLZ2cwqflE8H1VyzW4+pWlEgWyooYW4t6R68gpw7xY7m/zxxouUveJq OFwYCMKraPIEHLqQ3xHER0RUPicd1uJTMZrc4nIfnwEYQ7Qw9I0c7HuyCIhGadVmliIp Y/ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5mpN/atdS9l0bp7bINmGTZjAVzzs98+XGdPA0YAmXXs=; b=CxXWXGyYEejtwUoRvqSonfQQco4NKiCzePHurp2BWA7L1kLBKgglxkFONEShC170i1 upq4+oVPatVgS2AVudpdiKQt5HWatEhVMAEMLS+tNXZwaJv3YvuFy5vIrKRrS1K4oRe8 SuQeYR81nUD4scEO5mviM4i0CSiyDhVFa01sTeuHUFK+dexV4BJJfPJk6oYGVmBcAAvp GLH1sBUXk1IY0zigdvJk9B1ybGUtkek+6kQ+aUyaKECaH1GfDUAYtp7IMf+CiazOX367 5zf4cuWMlgMUL0zwvBLMefljjyzrG0ydyG+4zDjtMYCuuz6KvN1odZ/snjyh9ryFXnFJ pMhA== X-Gm-Message-State: APt69E1n7gvqH6jGOIiAjiVZ3VUSas26soGW/roRnKsxndBYFMWyEzew UsOSUsZcFoRCfvelWRbQGwjcy6I9 X-Google-Smtp-Source: AAOMgpecn9HE73Hx+sk7pAAmEEb6Lzbd6UjIAANZ2ZZoodA9GR3vOCwyQUIcmEj6QsiDC7iNWYZK1Q== X-Received: by 2002:a1c:8893:: with SMTP id k141-v6mr694097wmd.133.1530000088333; Tue, 26 Jun 2018 01:01:28 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id k82-v6sm2184483wmg.10.2018.06.26.01.01.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:27 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 6/9] net: sched: cls_flower: propagate chain teplate creation and destruction to drivers Date: Tue, 26 Jun 2018 09:59:57 +0200 Message-Id: <20180626080000.12964-7-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Introduce a couple of flower offload commands in order to propagate template creation/destruction events down to device drivers. Drivers may use this information to prepare HW in an optimal way for future filter insertions. Signed-off-by: Jiri Pirko --- v1->v2: - remove leftover extack arg in fl_hw_create_tmplt() --- include/net/pkt_cls.h | 2 ++ net/sched/cls_flower.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index a3c1a2c47cd4..e83968cf9a70 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -715,6 +715,8 @@ enum tc_fl_command { TC_CLSFLOWER_REPLACE, TC_CLSFLOWER_DESTROY, TC_CLSFLOWER_STATS, + TC_CLSFLOWER_TMPLT_CREATE, + TC_CLSFLOWER_TMPLT_DESTROY, }; struct tc_cls_flower_offload { diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index d64d43843a3a..614dd558d5f1 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1120,6 +1120,42 @@ static void fl_walk(struct tcf_proto *tp, struct tcf_walker *arg) } } +static void fl_hw_create_tmplt(struct tcf_chain *chain, + struct fl_flow_tmplt *tmplt) +{ + struct tc_cls_flower_offload cls_flower = {}; + struct tcf_block *block = chain->block; + struct tcf_exts dummy_exts = { 0, }; + + cls_flower.common.chain_index = chain->index; + cls_flower.command = TC_CLSFLOWER_TMPLT_CREATE; + cls_flower.cookie = (unsigned long) tmplt; + cls_flower.dissector = &tmplt->dissector; + cls_flower.mask = &tmplt->mask; + cls_flower.key = &tmplt->dummy_key; + cls_flower.exts = &dummy_exts; + + /* We don't care if driver (any of them) fails to handle this + * call. It serves just as a hint for it. + */ + tc_setup_cb_call(block, NULL, TC_SETUP_CLSFLOWER, + &cls_flower, false); +} + +static void fl_hw_destroy_tmplt(struct tcf_chain *chain, + struct fl_flow_tmplt *tmplt) +{ + struct tc_cls_flower_offload cls_flower = {}; + struct tcf_block *block = chain->block; + + cls_flower.common.chain_index = chain->index; + cls_flower.command = TC_CLSFLOWER_TMPLT_DESTROY; + cls_flower.cookie = (unsigned long) tmplt; + + tc_setup_cb_call(block, NULL, TC_SETUP_CLSFLOWER, + &cls_flower, false); +} + static void *fl_tmplt_create(struct net *net, struct tcf_chain *chain, struct nlattr **tca, struct netlink_ext_ack *extack) @@ -1150,6 +1186,8 @@ static void *fl_tmplt_create(struct net *net, struct tcf_chain *chain, fl_init_dissector(&tmplt->dissector, &tmplt->mask); + fl_hw_create_tmplt(chain, tmplt); + return tmplt; errout_tmplt: @@ -1163,6 +1201,7 @@ static void fl_tmplt_destroy(void *tmplt_priv) { struct fl_flow_tmplt *tmplt = tmplt_priv; + fl_hw_destroy_tmplt(tmplt->chain, tmplt); kfree(tmplt); } From patchwork Tue Jun 26 07:59:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934713 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="XrSWsujK"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJR13Rhsz9ryk for ; Tue, 26 Jun 2018 18:01:49 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752869AbeFZIBq (ORCPT ); Tue, 26 Jun 2018 04:01:46 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:38915 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752846AbeFZIBb (ORCPT ); Tue, 26 Jun 2018 04:01:31 -0400 Received: by mail-wr0-f194.google.com with SMTP id b8-v6so10744599wro.6 for ; Tue, 26 Jun 2018 01:01:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6g2qFZm9+5XC+TNiR0ClAha5hI5p7cMIb2/8yeRJSFc=; b=XrSWsujKRrl/OTOb6AeXZVgDk5JlVQStpbM4z0hg8JQPt/l6SCf6gMhMVUzgDPtPJC 0pxXdCnwKDh6dYOlBIUewNn1n6KI/VI91PlsqvrkDMaHNnxReep0XTPrm0OnLutinMqA Yq9pIivrnvOrRufXBb5x+Zo3uHxO1fz8TGtg9XH3K8kcHdGUGTiEvY+tptYxAJTuf1Zg /oqCaAEyAZ2ljj7M21alkUbawc4vQjsOSmlOdgsQnrd3HJ3HUrM+t/Wq9/DBloPBp1lW pMk0lTYb9OqEjL374gyFjf0TfCFK3NftjqR2VA87Cov8ZFC3bjDUXXxEr+YaDSfMMSKd 6WkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6g2qFZm9+5XC+TNiR0ClAha5hI5p7cMIb2/8yeRJSFc=; b=b0pSqehGlEoLSNk2ANncD4ozGxZJjM2+pv8o2L9FbW8iLC9JsGkzj0kk5Wt/E6G7J3 R4ImhwjyKSwdQnHcuMXUiMPnK0l5tfkNM6JA0FZfcmxTLm2QIpG9NfhfNc6d6jb1391x w48XE0tp5nWn45/AyikheYwqxowBNcTFIegOjpyHX1MeSYU6KRyo7HdnKMgnhz3Cfw+v c/y5tyIwd9DK8VqnztLUTDEBQoN+/nTNumAm7c9eOlv31sIQnZsNbWX8oKQDj1VFpxHq OTQUxmuVuxKCPMjXO3oW/hBBYVgrM7riTgxSJzyNd+qqJ/9ZujffQd4HVjuHC1xhpyld WzQQ== X-Gm-Message-State: APt69E0ivDrc1a8oxONFIAKxcfJwA9LkVcRHAssJeSGawqHrXS+pCuCi RL+Ks/Uv4ZuKesP1W5bO89uvQruz X-Google-Smtp-Source: AAOMgpfK6a2PsTj4JdahC6ooNhBeCF3s5KHB/QstAu3nfkJbyWxFupSj/TjZGJqKJi1UzRARNB6Rtg== X-Received: by 2002:adf:fc47:: with SMTP id e7-v6mr474707wrs.157.1530000089393; Tue, 26 Jun 2018 01:01:29 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id a1-v6sm1125586wrq.54.2018.06.26.01.01.28 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:28 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 7/9] mlxsw: spectrum: Implement chain template hinting Date: Tue, 26 Jun 2018 09:59:58 +0200 Message-Id: <20180626080000.12964-8-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Since cld_flower provides information about the filter template for specific chain, use this information in order to prepare a region. Use the template to find out what elements are going to be used and pass that down to mlxsw_sp_acl_tcam_group_add(). Later on, when the first filter is inserted, the mlxsw_sp_acl_tcam_group_use_patterns() function would use this element usage information instead of looking up a pattern. Signed-off-by: Jiri Pirko Reviewed-by: Ido Schimmel --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 5 +++ drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 12 +++++- drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 12 ++++-- .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 25 ++++++++++-- .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 44 ++++++++++++++++++++-- 5 files changed, 86 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 968b88af2ef5..da19fa343d0b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1441,6 +1441,11 @@ mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block, return 0; case TC_CLSFLOWER_STATS: return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f); + case TC_CLSFLOWER_TMPLT_CREATE: + return mlxsw_sp_flower_tmplt_create(mlxsw_sp, acl_block, f); + case TC_CLSFLOWER_TMPLT_DESTROY: + mlxsw_sp_flower_tmplt_destroy(mlxsw_sp, acl_block, f); + return 0; default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 4a519d8edec8..b0a8e611e730 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -459,7 +459,8 @@ enum mlxsw_sp_acl_profile { struct mlxsw_sp_acl_profile_ops { size_t ruleset_priv_size; int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp, - void *priv, void *ruleset_priv); + void *priv, void *ruleset_priv, + struct mlxsw_afk_element_usage *tmplt_elusage); void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv); int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv, struct mlxsw_sp_port *mlxsw_sp_port, @@ -514,7 +515,8 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ruleset * mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, u32 chain_index, - enum mlxsw_sp_acl_profile profile); + enum mlxsw_sp_acl_profile profile, + struct mlxsw_afk_element_usage *tmplt_elusage); void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ruleset *ruleset); u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset); @@ -594,6 +596,12 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, struct tc_cls_flower_offload *f); +int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f); +void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f); /* spectrum_qdisc.c */ int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c index 79b1fa27a9a4..ea42605c451d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c @@ -319,7 +319,8 @@ int mlxsw_sp_acl_block_unbind(struct mlxsw_sp *mlxsw_sp, static struct mlxsw_sp_acl_ruleset * mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, u32 chain_index, - const struct mlxsw_sp_acl_profile_ops *ops) + const struct mlxsw_sp_acl_profile_ops *ops, + struct mlxsw_afk_element_usage *tmplt_elusage) { struct mlxsw_sp_acl *acl = mlxsw_sp->acl; struct mlxsw_sp_acl_ruleset *ruleset; @@ -339,7 +340,8 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp, if (err) goto err_rhashtable_init; - err = ops->ruleset_add(mlxsw_sp, acl->priv, ruleset->priv); + err = ops->ruleset_add(mlxsw_sp, acl->priv, ruleset->priv, + tmplt_elusage); if (err) goto err_ops_ruleset_add; @@ -421,7 +423,8 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ruleset * mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, u32 chain_index, - enum mlxsw_sp_acl_profile profile) + enum mlxsw_sp_acl_profile profile, + struct mlxsw_afk_element_usage *tmplt_elusage) { const struct mlxsw_sp_acl_profile_ops *ops; struct mlxsw_sp_acl *acl = mlxsw_sp->acl; @@ -436,7 +439,8 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_ruleset_ref_inc(ruleset); return ruleset; } - return mlxsw_sp_acl_ruleset_create(mlxsw_sp, block, chain_index, ops); + return mlxsw_sp_acl_ruleset_create(mlxsw_sp, block, chain_index, ops, + tmplt_elusage); } void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c index ad1b548e3cac..d6e4e00dfd3d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c @@ -157,6 +157,8 @@ struct mlxsw_sp_acl_tcam_group { struct mlxsw_sp_acl_tcam_group_ops *ops; const struct mlxsw_sp_acl_tcam_pattern *patterns; unsigned int patterns_count; + bool tmplt_elusage_set; + struct mlxsw_afk_element_usage tmplt_elusage; }; struct mlxsw_sp_acl_tcam_region { @@ -216,13 +218,19 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_tcam *tcam, struct mlxsw_sp_acl_tcam_group *group, const struct mlxsw_sp_acl_tcam_pattern *patterns, - unsigned int patterns_count) + unsigned int patterns_count, + struct mlxsw_afk_element_usage *tmplt_elusage) { int err; group->tcam = tcam; group->patterns = patterns; group->patterns_count = patterns_count; + if (tmplt_elusage) { + group->tmplt_elusage_set = true; + memcpy(&group->tmplt_elusage, tmplt_elusage, + sizeof(group->tmplt_elusage)); + } INIT_LIST_HEAD(&group->region_list); err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id); if (err) @@ -431,6 +439,15 @@ mlxsw_sp_acl_tcam_group_use_patterns(struct mlxsw_sp_acl_tcam_group *group, const struct mlxsw_sp_acl_tcam_pattern *pattern; int i; + /* In case the template is set, we don't have to look up the pattern + * and just use the template. + */ + if (group->tmplt_elusage_set) { + memcpy(out, &group->tmplt_elusage, sizeof(*out)); + WARN_ON(!mlxsw_afk_element_usage_subset(elusage, out)); + return; + } + for (i = 0; i < group->patterns_count; i++) { pattern = &group->patterns[i]; mlxsw_afk_element_usage_fill(out, pattern->elements, @@ -1019,14 +1036,16 @@ struct mlxsw_sp_acl_tcam_flower_rule { static int mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp, - void *priv, void *ruleset_priv) + void *priv, void *ruleset_priv, + struct mlxsw_afk_element_usage *tmplt_elusage) { struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv; struct mlxsw_sp_acl_tcam *tcam = priv; return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group, mlxsw_sp_acl_tcam_patterns, - MLXSW_SP_ACL_TCAM_PATTERNS_COUNT); + MLXSW_SP_ACL_TCAM_PATTERNS_COUNT, + tmplt_elusage); } static void diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 89dbf569dff5..f34b410e5048 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -401,7 +401,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, - MLXSW_SP_ACL_PROFILE_FLOWER); + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (IS_ERR(ruleset)) return PTR_ERR(ruleset); @@ -445,7 +445,7 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, - MLXSW_SP_ACL_PROFILE_FLOWER); + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (IS_ERR(ruleset)) return; @@ -471,7 +471,7 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, - MLXSW_SP_ACL_PROFILE_FLOWER); + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (WARN_ON(IS_ERR(ruleset))) return -EINVAL; @@ -493,3 +493,41 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); return err; } + +int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f) +{ + struct mlxsw_sp_acl_ruleset *ruleset; + struct mlxsw_sp_acl_rule_info rulei; + int err; + + memset(&rulei, 0, sizeof(rulei)); + err = mlxsw_sp_flower_parse(mlxsw_sp, block, &rulei, f); + if (err) + return err; + ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, + f->common.chain_index, + MLXSW_SP_ACL_PROFILE_FLOWER, + &rulei.values.elusage); + if (IS_ERR(ruleset)) + return PTR_ERR(ruleset); + /* keep the reference to the ruleset */ + return 0; +} + +void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f) +{ + struct mlxsw_sp_acl_ruleset *ruleset; + + ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, + f->common.chain_index, + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); + if (IS_ERR(ruleset)) + return; + /* put the reference to the ruleset kept in create */ + mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); + mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); +} From patchwork Tue Jun 26 07:59:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934711 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="QITvA9CD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJQm70Dcz9ryk for ; Tue, 26 Jun 2018 18:01:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752864AbeFZIBe (ORCPT ); Tue, 26 Jun 2018 04:01:34 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:38756 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932103AbeFZIBb (ORCPT ); Tue, 26 Jun 2018 04:01:31 -0400 Received: by mail-wm0-f49.google.com with SMTP id 69-v6so698968wmf.3 for ; Tue, 26 Jun 2018 01:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LLaVJ+ucguO9uCvcrB5UuB06EdoqBCw/hld2helsiKU=; b=QITvA9CD5YH+La8p7pe6Atu9v5KwOIVAXODEcgE/5MR5UjPb0e2BeSvPCReGumhxml PwOIsEb8s99SJp8xyE/xWdiZ2KzncDBSE6d41OkP6s58aqeW5xXgnkfpblynagJ0Hz62 pHuuyrGy+lHl+oFcxnlqAnfO+F8CkDu/L8fK61D6fsacIR+H3XYlrVqVSuPnPPCq8EiC N+EKCO+iTWkWjTpeXOuYLWPwQXwYVNDctJTp27z3qQghSHNeJu0VqeipXLsvL3z9dISo XxRepPBOmcYEVhM0Zp7W7Pl9ueO9xsTd6BgHgwVuxILT5cflIew4yuNurCFmOg1n0+t2 R9eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LLaVJ+ucguO9uCvcrB5UuB06EdoqBCw/hld2helsiKU=; b=tQj7vnmZo0m8ErDgV5ZoHThe2uAcOYhR1/YIWLvPruLZKgfNDg8p6E8as1f+8mYaDj lZD41d0HWkqPVKEGkl+QE10HjdyX9iG89LImmGy9tSl2Y3An5myWejGjMiakGqGeaRAi qkl+nuuEu93hjrMoXRN14ny0NVUpHF+mgDvTrW4BdHF527eFYm7sRPG0E2UP6C23ZoCe MJNHBIy/D1ojMTev4VaqWHLawONq1uxwQBAjLkUyC7DgooI0MHLLsL0CxSykrTy0rS/G YH119v5l4Mho7TuIotGd6LmQNRHgzKH0ZudSGEN11voNj1OhhkZ9eCKKa6Z9xr6PU2Ql wOZg== X-Gm-Message-State: APt69E0KF1meBIvHFEFIJaXbGs+hR7rskH89Fjg4cn8ODiLVyyEg5qlA LKtnFvCmH9v26ROe1zZjecbOOUZ2 X-Google-Smtp-Source: AAOMgpdvfCP+JVU4mkV68s9o3SsCfylILZAMyynv4v+3jXAmRSiuTURdf2roUNMh6xjmnq5BB4g0UQ== X-Received: by 2002:a1c:8ec1:: with SMTP id q184-v6mr672810wmd.48.1530000090384; Tue, 26 Jun 2018 01:01:30 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id u204-v6sm1699725wmd.7.2018.06.26.01.01.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:30 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 8/9] selftests: forwarding: move shblock tc support check to a separate helper Date: Tue, 26 Jun 2018 09:59:59 +0200 Message-Id: <20180626080000.12964-9-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko The shared block support is only needed for tc_shblock.sh. No need to require that for other test. Signed-off-by: Jiri Pirko --- tools/testing/selftests/net/forwarding/lib.sh | 3 +++ tools/testing/selftests/net/forwarding/tc_shblocks.sh | 2 ++ 2 files changed, 5 insertions(+) diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index 7b18a53aa556..a736d1d7ecdb 100644 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -28,7 +28,10 @@ check_tc_version() echo "SKIP: iproute2 too old; tc is missing JSON support" exit 1 fi +} +check_tc_shblock_support() +{ tc filter help 2>&1 | grep block &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing shared block support" diff --git a/tools/testing/selftests/net/forwarding/tc_shblocks.sh b/tools/testing/selftests/net/forwarding/tc_shblocks.sh index b5b917203815..9826a446e2c0 100755 --- a/tools/testing/selftests/net/forwarding/tc_shblocks.sh +++ b/tools/testing/selftests/net/forwarding/tc_shblocks.sh @@ -105,6 +105,8 @@ cleanup() ip link set $swp2 address $swp2origmac } +check_tc_shblock_support + trap cleanup EXIT setup_prepare From patchwork Tue Jun 26 08:00:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 934712 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="InXyWmHX"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41FJQt2j11z9ryk for ; Tue, 26 Jun 2018 18:01:42 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932135AbeFZIBk (ORCPT ); Tue, 26 Jun 2018 04:01:40 -0400 Received: from mail-wr0-f182.google.com ([209.85.128.182]:41823 "EHLO mail-wr0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752695AbeFZIBd (ORCPT ); Tue, 26 Jun 2018 04:01:33 -0400 Received: by mail-wr0-f182.google.com with SMTP id h10-v6so16171000wrq.8 for ; Tue, 26 Jun 2018 01:01:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=n2GNi12+3DAoBBqkFsvhP6k1ejD/eMJAM3D+842g/uc=; b=InXyWmHX3W4EB7GZ0X7rjNiqXUTBe772tZQai1+c4IvO/lrRmT7w7xJKNf1iRoDUhu cmM97agVPWow6ywQv1+2FEtgRrFO35l5mAxtThaymxblmpkTyZNkEGhIYFzVb8r+s7Je 2tw2Y8qrmqfO6MLD3o0VANBYVVR1vYhfZl+WuK6JvyDcZ5gxIdKjJfyjCDCx4mi9JeBX jRuCFt+mu5CPBRsk3Yr9LfxUe3ovmJmt6NNKafO0oPQxogcPJ62n0thO9Yu1QHRL5zOz unrF907fuio0ZPLgucK2YZUJpXHxTSSFMzAz/Z5x8dgqEBNuNYnmWQqDPnOGL8ZcdPpD 7E/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=n2GNi12+3DAoBBqkFsvhP6k1ejD/eMJAM3D+842g/uc=; b=KfgFqoNLOuSBRxcKE8xPCaw+gNj2PHJ9/o7N6+6+/9duMxIsO9f6HJY4YyMOHqrWQo Zu5NRAV7vXUP1fAAN3McxL2vqc8dLQSJX4H/M/yv8WBLd2Pge+ueb3p2a2qAGi+kL6+L gikV63Zk1HRjGc/GJfZhNYPsOOXWWlUO6aBfJBmwnmeEH/nB2vuPu8BPFJy56FebdQgk NxH/miXKe6ZXpoubTqDffxFLa2JXwENlFRI+sixw/w4KXh1+0PdvztGBGyabCWsjUbfb 6/tmNiZPE5Usw0ImC8hyyKTDGbOYdNujHG7jenRtZ19phI8DKqzDHHrB3gJiKfL6bVox F5OQ== X-Gm-Message-State: APt69E0lIJJUp26B8yg/9SNwu/dp1a8aVLAIBRHi1lqhTHHOjXqKDLq8 fDsmAOO+xPRTqIe25AKvKBCBSKlq X-Google-Smtp-Source: AAOMgpeMbYOQWm4cr3kDwCGIHVqj4tvTtOvc92+fJzndg8aqD57lONsgBibM+nU5K7jcEjnrN0H3QQ== X-Received: by 2002:adf:8f23:: with SMTP id p32-v6mr463232wrb.193.1530000091371; Tue, 26 Jun 2018 01:01:31 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id n71-v6sm2109591wmi.14.2018.06.26.01.01.30 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Jun 2018 01:01:31 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com Subject: [patch net-next v2 9/9] selftests: forwarding: add tests for TC chain templates Date: Tue, 26 Jun 2018 10:00:00 +0200 Message-Id: <20180626080000.12964-10-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180626080000.12964-1-jiri@resnulli.us> References: <20180626080000.12964-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Add basic sanity tests for TC chain templates. Signed-off-by: Jiri Pirko --- tools/testing/selftests/net/forwarding/lib.sh | 9 ++ .../selftests/net/forwarding/tc_chaintemplates.sh | 160 +++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100755 tools/testing/selftests/net/forwarding/tc_chaintemplates.sh diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index a736d1d7ecdb..128a5b5a8ea9 100644 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -39,6 +39,15 @@ check_tc_shblock_support() fi } +check_tc_chaintemplate_support() +{ + tc filter help 2>&1|grep template &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing chain template support" + exit 1 + fi +} + if [[ "$(id -u)" -ne 0 ]]; then echo "SKIP: need root privileges" exit 0 diff --git a/tools/testing/selftests/net/forwarding/tc_chaintemplates.sh b/tools/testing/selftests/net/forwarding/tc_chaintemplates.sh new file mode 100755 index 000000000000..21f2c18e973a --- /dev/null +++ b/tools/testing/selftests/net/forwarding/tc_chaintemplates.sh @@ -0,0 +1,160 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +ALL_TESTS="template_create_destroy template_filter_fits \ + template_create_nonempty template_destroy_nonempty" +NUM_NETIFS=2 +source tc_common.sh +source lib.sh + +h1_create() +{ + simple_if_init $h1 192.0.2.1/24 +} + +h1_destroy() +{ + simple_if_fini $h1 192.0.2.1/24 +} + +h2_create() +{ + simple_if_init $h2 192.0.2.2/24 + tc qdisc add dev $h2 clsact +} + +h2_destroy() +{ + tc qdisc del dev $h2 clsact + simple_if_fini $h2 192.0.2.2/24 +} + +template_create_destroy() +{ + RET=0 + + tc filter template add dev $h2 ingress protocol ip \ + flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF + check_err $? "Failed to create template for default chain" + + tc filter template add dev $h2 ingress chain 1 protocol ip \ + flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF + check_err $? "Failed to create template for chain 1" + + tc filter template del dev $h2 ingress + check_err $? "Failed to destroy template for default chain" + + tc filter template del dev $h2 ingress chain 1 + check_err $? "Failed to destroy template for chain 1" + + log_test "template create destroy" +} + +template_filter_fits() +{ + RET=0 + + tc filter template add dev $h2 ingress protocol ip \ + flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null + tc filter template add dev $h2 ingress chain 1 protocol ip \ + flower src_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null + + tc filter add dev $h2 ingress protocol ip pref 1 handle 1101 \ + flower dst_mac $h2mac action drop + check_err $? "Failed to insert filter which fits template" + + tc filter add dev $h2 ingress protocol ip pref 1 handle 1102 \ + flower src_mac $h2mac action drop &> /dev/null + check_fail $? "Incorrectly succeded to insert filter which does not template" + + tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \ + flower src_mac $h2mac action drop + check_err $? "Failed to insert filter which fits template" + + tc filter add dev $h2 ingress chain 1protocol ip pref 1 handle 1102 \ + flower dst_mac $h2mac action drop &> /dev/null + check_fail $? "Incorrectly succeded to insert filter which does not template" + + tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \ + flower &> /dev/null + tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \ + flower &> /dev/null + + tc filter del dev $h2 ingress protocol ip pref 1 handle 1102 \ + flower &> /dev/null + tc filter del dev $h2 ingress protocol ip pref 1 handle 1101 \ + flower &> /dev/null + + tc filter template del dev $h2 ingress chain 1 + tc filter template del dev $h2 ingress + + log_test "template filter fits" +} + +template_create_nonempty() +{ + RET=0 + + tc filter add dev $h2 ingress protocol ip pref 1 handle 1101 \ + flower dst_mac $h2mac action drop + tc filter template add dev $h2 ingress protocol ip \ + flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null + check_fail $? "Incorrectly succeded to create template for non-empty chain" + + tc filter template del dev $h2 ingress &> /dev/null + tc filter del dev $h2 ingress protocol ip pref 1 handle 1101 flower + + log_test "template create non-empty" +} + +template_destroy_nonempty() +{ + RET=0 + + tc filter template add dev $h2 ingress protocol ip \ + flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF + tc filter add dev $h2 ingress protocol ip pref 1 handle 1101 \ + flower dst_mac $h2mac action drop + + tc filter template del dev $h2 ingress &> /dev/null + check_fail $? "Incorrectly succeded to destroy template for non-empty chain" + tc filter del dev $h2 ingress protocol ip pref 1 handle 1101 flower + tc filter template del dev $h2 ingress &> /dev/null + check_err $? "Failed to destroy template for empty chain" + + log_test "template destroy non-empty" +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + h2=${NETIFS[p2]} + h1mac=$(mac_get $h1) + h2mac=$(mac_get $h2) + + vrf_prepare + + h1_create + h2_create +} + +cleanup() +{ + pre_cleanup + + h2_destroy + h1_destroy + + vrf_cleanup +} + +check_tc_chaintemplate_support + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS