From patchwork Thu Apr 27 11:15:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 755982 X-Patchwork-Delegate: shemminger@vyatta.com 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 3wDDsW70jkz9sNJ for ; Thu, 27 Apr 2017 21:16:15 +1000 (AEST) 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="UzKPsyvb"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S968451AbdD0LQN (ORCPT ); Thu, 27 Apr 2017 07:16:13 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:34466 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754143AbdD0LP7 (ORCPT ); Thu, 27 Apr 2017 07:15:59 -0400 Received: by mail-wm0-f66.google.com with SMTP id z129so3846837wmb.1 for ; Thu, 27 Apr 2017 04:15:58 -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=sjMZbhoE5OczN1ehCkDshceg1GjoUYGQJSbcpflOO0Q=; b=UzKPsyvbP+dj5L9mW8IM4E2sTQ00MS3UyXIC/NqaUwd9g6+CobhFwtahd4lp9JJtr9 Jd9PYaTxrdTmALtTMyMD/vK/Cjlf98uROQeyexrN7atPuzkRDVoR1xjGzLrC+hFWkS7V KJq4QSMHxY0RLNWErJ1V17gXpdwDFRzdNZrv0mVa1m8uQFps3C4K58DXe16JkjRJ7ngV xtM5YryjT2vgNTW7q5L9c/sJmjR0IwwsiKovXM94U5E2iCZBv+YINuTGBBoVzA1MT+NS jg4hCbvTb2bnpbRcaHfHGTJV8HYEi7dW4Er+7/GgO4ZNhUfWeWV29DEZxIGuvYJoyVxQ hgTA== 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=sjMZbhoE5OczN1ehCkDshceg1GjoUYGQJSbcpflOO0Q=; b=Djia8tZ0s2oulDiUUO7eHhYv8sans9bsH2Upzu9rgu4tDbKS1AvQxDfHzBbViw0P3i Ff9Ho5E5OhvZ0FdOA3iyaE3IouJXTEd53EB/NFUu204IhI4V2HqKXHsZZRQ9/izFXGzB 9zwzC0UYWBo3B+RQ4A1+2ONVPv8qdX1ZY3CNPOTlNrfhkrgtrXPhgn5qxvtn5+p0xLVu SB0fCwe+Q+lAFn+qKoGzo7FSJGufQYDpf21Zycu8ySO/WuxR6O77oYrF2FdKoRKw4DFo GxQ+FWzL0Ov7mRyOIFUa4mqHSWvJy6LJYeHXlbZS4eykJ/IG0JIYxQhhQ5vegfHWRY5E TA1g== X-Gm-Message-State: AN3rC/5ixZsJYtTLqvsD4LkrM69Q3fkFvtuT20TWPMGykTjyOTTugMm2 vsGaTRtq9Mx55w== X-Received: by 10.28.127.193 with SMTP id a184mr2010924wmd.110.1493291757356; Thu, 27 Apr 2017 04:15:57 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id w186sm3051814wme.26.2017.04.27.04.15.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Apr 2017 04:15:56 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, dsa@cumulusnetworks.com, edumazet@google.com, stephen@networkplumber.org, daniel@iogearbox.net, alexander.h.duyck@intel.com, mlxsw@mellanox.com, simon.horman@netronome.com Subject: [patch iproute2 1/2] tc_filter: add support for chain index Date: Thu, 27 Apr 2017 13:15:54 +0200 Message-Id: <1493291755-2215-1-git-send-email-jiri@resnulli.us> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493291540-2119-1-git-send-email-jiri@resnulli.us> References: <1493291540-2119-1-git-send-email-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Allow user to put filter to a specific chain identified by index. Signed-off-by: Jiri Pirko --- include/linux/rtnetlink.h | 1 + tc/tc_filter.c | 87 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index a96db83..70c5750 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -549,6 +549,7 @@ enum { TCA_STAB, TCA_PAD, TCA_DUMP_INVISIBLE, + TCA_CHAIN, __TCA_MAX }; diff --git a/tc/tc_filter.c b/tc/tc_filter.c index ff8713b..b13fb91 100644 --- a/tc/tc_filter.c +++ b/tc/tc_filter.c @@ -31,7 +31,7 @@ static void usage(void) fprintf(stderr, "Usage: tc filter [ add | del | change | replace | show ] dev STRING\n" "Usage: tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n" - " [ pref PRIO ] protocol PROTO\n" + " [ pref PRIO ] protocol PROTO [ chain CHAIN_INDEX ]\n" " [ estimator INTERVAL TIME_CONSTANT ]\n" " [ root | ingress | egress | parent CLASSID ]\n" " [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" @@ -59,6 +59,8 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) __u32 prio = 0; __u32 protocol = 0; int protocol_set = 0; + __u32 chain_index; + int chain_index_set = 0; char *fhandle = NULL; char d[16] = {}; char k[16] = {}; @@ -127,6 +129,13 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) invarg("invalid protocol", *argv); protocol = id; protocol_set = 1; + } else if (matches(*argv, "chain") == 0) { + NEXT_ARG(); + if (chain_index_set) + duparg("chain", *argv); + if (get_u32(&chain_index, *argv, 0)) + invarg("invalid chain index value", *argv); + chain_index_set = 1; } else if (matches(*argv, "estimator") == 0) { if (parse_estimator(&argc, &argv, &est) < 0) return -1; @@ -146,6 +155,9 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); + if (chain_index_set) + addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index); + if (k[0]) addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); @@ -167,6 +179,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) return -1; } } + if (est.ewma_log) addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); @@ -193,6 +206,8 @@ static __u32 filter_parent; static int filter_ifindex; static __u32 filter_prio; static __u32 filter_protocol; +static __u32 filter_chain_index; +static int filter_chain_index_set; __u16 f_proto; int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) @@ -270,6 +285,15 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) } } fprintf(fp, "%s ", rta_getattr_str(tb[TCA_KIND])); + + if (tb[TCA_CHAIN]) { + __u32 chain_index = rta_getattr_u32(tb[TCA_CHAIN]); + + if (!filter_chain_index_set || + filter_chain_index != chain_index) + fprintf(fp, "chain %u ", chain_index); + } + q = get_filter_kind(RTA_DATA(tb[TCA_KIND])); if (tb[TCA_OPTIONS]) { if (q) @@ -311,6 +335,8 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) __u32 prio = 0; __u32 protocol = 0; int protocol_set = 0; + __u32 chain_index; + int chain_index_set = 0; __u32 parent_handle = 0; char *fhandle = NULL; char d[16] = {}; @@ -375,6 +401,13 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) invarg("invalid protocol", *argv); protocol = id; protocol_set = 1; + } else if (matches(*argv, "chain") == 0) { + NEXT_ARG(); + if (chain_index_set) + duparg("chain", *argv); + if (get_u32(&chain_index, *argv, 0)) + invarg("invalid chain index value", *argv); + chain_index_set = 1; } else if (matches(*argv, "help") == 0) { usage(); return 0; @@ -401,6 +434,9 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); + if (chain_index_set) + addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index); + if (req.t.tcm_parent == TC_H_UNSPEC) { fprintf(stderr, "Must specify filter parent\n"); return -1; @@ -457,10 +493,20 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) static int tc_filter_list(int argc, char **argv) { - struct tcmsg t = { .tcm_family = AF_UNSPEC }; + struct { + struct nlmsghdr n; + struct tcmsg t; + char buf[MAX_MSG]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)), + .n.nlmsg_type = RTM_GETTFILTER, + .t.tcm_parent = TC_H_UNSPEC, + .t.tcm_family = AF_UNSPEC, + }; char d[16] = {}; __u32 prio = 0; __u32 protocol = 0; + __u32 chain_index; char *fhandle = NULL; while (argc > 0) { @@ -470,39 +516,39 @@ static int tc_filter_list(int argc, char **argv) duparg("dev", *argv); strncpy(d, *argv, sizeof(d)-1); } else if (strcmp(*argv, "root") == 0) { - if (t.tcm_parent) { + if (req.t.tcm_parent) { fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); return -1; } - filter_parent = t.tcm_parent = TC_H_ROOT; + filter_parent = req.t.tcm_parent = TC_H_ROOT; } else if (strcmp(*argv, "ingress") == 0) { - if (t.tcm_parent) { + if (req.t.tcm_parent) { fprintf(stderr, "Error: \"ingress\" is duplicate parent ID\n"); return -1; } filter_parent = TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS); - t.tcm_parent = filter_parent; + req.t.tcm_parent = filter_parent; } else if (strcmp(*argv, "egress") == 0) { - if (t.tcm_parent) { + if (req.t.tcm_parent) { fprintf(stderr, "Error: \"egress\" is duplicate parent ID\n"); return -1; } filter_parent = TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS); - t.tcm_parent = filter_parent; + req.t.tcm_parent = filter_parent; } else if (strcmp(*argv, "parent") == 0) { __u32 handle; NEXT_ARG(); - if (t.tcm_parent) + if (req.t.tcm_parent) duparg("parent", *argv); if (get_tc_classid(&handle, *argv)) invarg("invalid parent ID", *argv); - filter_parent = t.tcm_parent = handle; + filter_parent = req.t.tcm_parent = handle; } else if (strcmp(*argv, "handle") == 0) { NEXT_ARG(); if (fhandle) @@ -526,6 +572,14 @@ static int tc_filter_list(int argc, char **argv) invarg("invalid protocol", *argv); protocol = res; filter_protocol = protocol; + } else if (matches(*argv, "chain") == 0) { + NEXT_ARG(); + if (filter_chain_index_set) + duparg("chain", *argv); + if (get_u32(&chain_index, *argv, 0)) + invarg("invalid chain index value", *argv); + filter_chain_index_set = 1; + filter_chain_index = chain_index; } else if (matches(*argv, "help") == 0) { usage(); } else { @@ -538,20 +592,23 @@ static int tc_filter_list(int argc, char **argv) argc--; argv++; } - t.tcm_info = TC_H_MAKE(prio<<16, protocol); + req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); ll_init_map(&rth); if (d[0]) { - t.tcm_ifindex = ll_name_to_index(d); - if (t.tcm_ifindex == 0) { + req.t.tcm_ifindex = ll_name_to_index(d); + if (req.t.tcm_ifindex == 0) { fprintf(stderr, "Cannot find device \"%s\"\n", d); return 1; } - filter_ifindex = t.tcm_ifindex; + filter_ifindex = req.t.tcm_ifindex; } - if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) { + if (filter_chain_index_set) + addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index); + + if (rtnl_dump_request_n(&rth, &req.n) < 0) { perror("Cannot send dump request"); return 1; }