From patchwork Fri Jan 12 15:49:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 860023 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="D/ziC0Y0"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zJ6cs02Dxz9t3B for ; Sat, 13 Jan 2018 02:49:33 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934203AbeALPt3 (ORCPT ); Fri, 12 Jan 2018 10:49:29 -0500 Received: from mail-wr0-f196.google.com ([209.85.128.196]:35568 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934069AbeALPt0 (ORCPT ); Fri, 12 Jan 2018 10:49:26 -0500 Received: by mail-wr0-f196.google.com with SMTP id g38so2493702wrd.2 for ; Fri, 12 Jan 2018 07:49:25 -0800 (PST) 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=dZRhFW/k3ARDNU4vGgxWtTJhLbqDmTWgBqtBztkn11M=; b=D/ziC0Y0jlj4hrF0Z8EVZG0RVehcA7YgPlDAeuc+s+IRRv2rcp4QtIzAz913Jpv74c YPJD3vIaWW4CzM/e8ZB6Np8ogkyPv5SK/dLDqsWwpz6iI7tHJA2aqLB6snPaLUJlqKwj nGH24T672AF3OLflC3hxJgVMk7D2yJmCOWcHe4OnA+SpUBTiNKxPpD6uQGPW8AaNr0IM MjRxHx3W5/BlrAsAT3XzN6WQsEA2HH9TjL3J3b/cIuO0Vk8QIXiSsMVr3WNSQufALjWp iQaKfwFroWe0jxWz9e20xr9NBn+c0/V8aj2Nd8bTxIlphcsT2dpTBw5Ao+VlfgHEa322 KXqg== 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=dZRhFW/k3ARDNU4vGgxWtTJhLbqDmTWgBqtBztkn11M=; b=jqt9LVq3dkA6/7/5PCrTs5MUXm9hQVGnzXzlnTudAVLnvt43sutp5wtojEgtnnxU8U nFODr0Wab/uJR+6j80nibo68c+e+lJ7db4S5k9y0Pwh/7SshatVOw3XwmGTyTzRvdl8V QETiEoLqmpWxRfAgJjvGjniky8N5UV9MeY01Nb6K5wgXOeW2mBGNYcDAVvMjfmxq5avB BMSEFc3+EwmI3lPCSKHXKE7buY6ou+OROzw/reVwU951ueU54cxYecc3VRvLudLV4avf ayi6IgIcNWhONVlr7zMwcfa2NxLwHrWZinHk5YJcMfKUkLTO3sbkcGCQxpcHOIoI3ryc Fh8Q== X-Gm-Message-State: AKGB3mK/NAdyenObQihvcRUSgT7S0Rv7RtANK/V2kNXvOfTr51IP/aDY sU16yiIffKRLA7HnP8JoCgwugreO X-Google-Smtp-Source: ACJfBoupPGlkyZiBmI62VsKe+ywXNPgt2Gy7SUd1KXQcHr7dh5hLNf1m/BAcMq3sRZqPrzRQ1vMK8Q== X-Received: by 10.223.141.206 with SMTP id o72mr16284951wrb.0.1515772165077; Fri, 12 Jan 2018 07:49:25 -0800 (PST) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id r64sm3108212wma.15.2018.01.12.07.49.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 12 Jan 2018 07:49:24 -0800 (PST) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, mlxsw@mellanox.com, andrew@lunn.ch, vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com, michael.chan@broadcom.com, ganeshgr@chelsio.com, saeedm@mellanox.com, matanb@mellanox.com, leonro@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, pieter.jansenvanvuuren@netronome.com, john.hurley@netronome.com, alexander.h.duyck@intel.com, ogerlitz@mellanox.com, john.fastabend@gmail.com, daniel@iogearbox.net, dsahern@gmail.com Subject: [patch iproute2 net-next v8 2/3] tc: introduce support for block-handle for filter operations Date: Fri, 12 Jan 2018 16:49:22 +0100 Message-Id: <20180112154923.1853-2-jiri@resnulli.us> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180112154704.1694-1-jiri@resnulli.us> References: <20180112154704.1694-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Signed-off-by: Jiri Pirko --- tc/tc_filter.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 17 deletions(-) diff --git a/tc/tc_filter.c b/tc/tc_filter.c index 545cc3a..67a0577 100644 --- a/tc/tc_filter.c +++ b/tc/tc_filter.c @@ -28,14 +28,17 @@ 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" + "Usage: tc filter [ add | del | change | replace | show ] [ dev STRING ]\n" + " tc filter [ add | del | change | replace | show ] [ block BLOCK_INDEX ]\n" + " tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n" + " tc filter get block BLOCK_INDEX protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\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" "\n" " tc filter show [ dev STRING ] [ root | ingress | egress | parent CLASSID ]\n" + " tc filter show [ block BLOCK_INDEX ]\n" "Where:\n" "FILTER_TYPE := { rsvp | u32 | bpf | fw | route | etc. }\n" "FILTERID := ... format depends on classifier, see there\n" @@ -60,6 +63,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) int protocol_set = 0; __u32 chain_index; int chain_index_set = 0; + __u32 block_index = 0; char *fhandle = NULL; char d[IFNAMSIZ] = {}; char k[FILTER_NAMESZ] = {}; @@ -73,7 +77,21 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) NEXT_ARG(); if (d[0]) duparg("dev", *argv); + if (block_index) { + fprintf(stderr, "Error: \"dev\" cannot be used in the same time as \"block\"\n"); + return -1; + } strncpy(d, *argv, sizeof(d)-1); + } else if (matches(*argv, "block") == 0) { + NEXT_ARG(); + if (block_index) + duparg("block", *argv); + if (d[0]) { + fprintf(stderr, "Error: \"block\" cannot be used in the same time as \"dev\"\n"); + return -1; + } + if (get_u32(&block_index, *argv, 0) || !block_index) + invarg("invalid block index value", *argv); } else if (strcmp(*argv, "root") == 0) { if (req.t.tcm_parent) { fprintf(stderr, @@ -168,6 +186,9 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv) fprintf(stderr, "Cannot find device \"%s\"\n", d); return 1; } + } else if (block_index) { + req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + req.t.tcm_block_index = block_index; } if (q) { @@ -206,6 +227,7 @@ static __u32 filter_prio; static __u32 filter_protocol; static __u32 filter_chain_index; static int filter_chain_index_set; +static __u32 filter_block_index; __u16 f_proto; int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) @@ -252,20 +274,27 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) print_bool(PRINT_ANY, "added", "added ", true); print_string(PRINT_FP, NULL, "filter ", NULL); - if (!filter_ifindex || filter_ifindex != t->tcm_ifindex) - print_string(PRINT_ANY, "dev", "dev %s ", - ll_index_to_name(t->tcm_ifindex)); - - if (!filter_parent || filter_parent != t->tcm_parent) { - if (t->tcm_parent == TC_H_ROOT) - print_bool(PRINT_ANY, "root", "root ", true); - else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS)) - print_bool(PRINT_ANY, "ingress", "ingress ", true); - else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS)) - print_bool(PRINT_ANY, "egress", "egress ", true); - else { - print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); - print_string(PRINT_ANY, "parent", "parent %s ", abuf); + if (t->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) { + if (!filter_block_index || + filter_block_index != t->tcm_block_index) + print_uint(PRINT_ANY, "block", "block %u ", + t->tcm_block_index); + } else { + if (!filter_ifindex || filter_ifindex != t->tcm_ifindex) + print_string(PRINT_ANY, "dev", "dev %s ", + ll_index_to_name(t->tcm_ifindex)); + + if (!filter_parent || filter_parent != t->tcm_parent) { + if (t->tcm_parent == TC_H_ROOT) + print_bool(PRINT_ANY, "root", "root ", true); + else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS)) + print_bool(PRINT_ANY, "ingress", "ingress ", true); + else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS)) + print_bool(PRINT_ANY, "egress", "egress ", true); + else { + print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); + print_string(PRINT_ANY, "parent", "parent %s ", abuf); + } } } @@ -345,6 +374,7 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) int protocol_set = 0; __u32 chain_index; int chain_index_set = 0; + __u32 block_index = 0; __u32 parent_handle = 0; char *fhandle = NULL; char d[IFNAMSIZ] = {}; @@ -355,7 +385,21 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) NEXT_ARG(); if (d[0]) duparg("dev", *argv); + if (block_index) { + fprintf(stderr, "Error: \"dev\" cannot be used in the same time as \"block\"\n"); + return -1; + } strncpy(d, *argv, sizeof(d)-1); + } else if (matches(*argv, "block") == 0) { + NEXT_ARG(); + if (block_index) + duparg("block", *argv); + if (d[0]) { + fprintf(stderr, "Error: \"block\" cannot be used in the same time as \"dev\"\n"); + return -1; + } + if (get_u32(&block_index, *argv, 0) || !block_index) + invarg("invalid block index value", *argv); } else if (strcmp(*argv, "root") == 0) { if (req.t.tcm_parent) { fprintf(stderr, @@ -469,8 +513,12 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) return 1; } filter_ifindex = req.t.tcm_ifindex; + } else if (block_index) { + req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + req.t.tcm_block_index = block_index; + filter_block_index = block_index; } else { - fprintf(stderr, "Must specify netdevice \"dev\"\n"); + fprintf(stderr, "Must specify netdevice \"dev\" or block index \"block\"\n"); return -1; } @@ -504,6 +552,30 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv) return 0; } +static bool block_index_exists(__u32 block_index) +{ + struct { + struct nlmsghdr n; + struct tcmsg t; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)), + .n.nlmsg_flags = NLM_F_REQUEST, + .n.nlmsg_type = RTM_GETBLOCK, + .t.tcm_parent = TC_H_UNSPEC, + .t.tcm_family = AF_UNSPEC, + }; + struct nlmsghdr *answer; + + req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + req.t.tcm_block_index = block_index; + + if (rtnl_talk(&rth, &req.n, &answer) < 0) + return false; + + free(answer); + return true; +} + static int tc_filter_list(int argc, char **argv) { struct { @@ -520,6 +592,7 @@ static int tc_filter_list(int argc, char **argv) __u32 prio = 0; __u32 protocol = 0; __u32 chain_index; + __u32 block_index = 0; char *fhandle = NULL; while (argc > 0) { @@ -527,7 +600,21 @@ static int tc_filter_list(int argc, char **argv) NEXT_ARG(); if (d[0]) duparg("dev", *argv); + if (block_index) { + fprintf(stderr, "Error: \"dev\" cannot be used in the same time as \"block\"\n"); + return -1; + } strncpy(d, *argv, sizeof(d)-1); + } else if (matches(*argv, "block") == 0) { + NEXT_ARG(); + if (block_index) + duparg("block", *argv); + if (d[0]) { + fprintf(stderr, "Error: \"block\" cannot be used in the same time as \"dev\"\n"); + return -1; + } + if (get_u32(&block_index, *argv, 0) || !block_index) + invarg("invalid block index value", *argv); } else if (strcmp(*argv, "root") == 0) { if (req.t.tcm_parent) { fprintf(stderr, @@ -616,6 +703,12 @@ static int tc_filter_list(int argc, char **argv) return 1; } filter_ifindex = req.t.tcm_ifindex; + } else if (block_index) { + if (!block_index_exists(block_index)) + return 1; + req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + req.t.tcm_block_index = block_index; + filter_block_index = block_index; } if (filter_chain_index_set)