From patchwork Fri Jan 25 02:33:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Leitner X-Patchwork-Id: 1030784 X-Patchwork-Delegate: dsahern@gmail.com 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=fail (p=none dis=none) header.from=redhat.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43m34J40wKz9s7T for ; Fri, 25 Jan 2019 13:33:52 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728796AbfAYCdv (ORCPT ); Thu, 24 Jan 2019 21:33:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45120 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728461AbfAYCdv (ORCPT ); Thu, 24 Jan 2019 21:33:51 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9BEB8394D34; Fri, 25 Jan 2019 02:33:50 +0000 (UTC) Received: from localhost.localdomain (ovpn-116-7.gru2.redhat.com [10.97.116.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8F8507B539; Fri, 25 Jan 2019 02:33:47 +0000 (UTC) Received: by localhost.localdomain (Postfix, from userid 1000) id 22BCB180CF5; Fri, 25 Jan 2019 00:33:46 -0200 (-02) From: Marcelo Ricardo Leitner To: Guy Shattah , Marcelo Leitner , Aaron Conole , John Hurley , Simon Horman , Justin Pettit , Gregory Rose , Eelco Chaudron , Flavio Leitner , Florian Westphal , Jiri Pirko , Rashid Khan , Sushil Kulkarni , Andy Gospodarek , Roi Dayan , Yossi Kuperman , Or Gerlitz , Rony Efraim , "davem@davemloft.net" Cc: netdev@vger.kernel.org Subject: [RFC PATCH iproute2 1/5] flower: add support for CT fields Date: Fri, 25 Jan 2019 00:33:29 -0200 Message-Id: <863679f1891c9df7f71a1678c35700f9b9aba0da.1548287070.git.mleitner@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 25 Jan 2019 02:33:50 +0000 (UTC) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Except ct_label, just a place holder for now. Parsing of ct_state definitely should be handled better. Signed-off-by: Marcelo Ricardo Leitner --- include/uapi/linux/pkt_cls.h | 9 ++ tc/f_flower.c | 158 ++++++++++++++++++++++++++++++++++- 2 files changed, 165 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index 95d0db2a8350dffb1dd20816591f3b179913fb2e..ba1f3bc01b2fdfd810e37a2b3853a1da1f838acf 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -490,6 +490,15 @@ enum { TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */ TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */ + TCA_FLOWER_KEY_CT_ZONE, /* u16 */ + TCA_FLOWER_KEY_CT_ZONE_MASK, /* u16 */ + TCA_FLOWER_KEY_CT_STATE, /* u8 */ + TCA_FLOWER_KEY_CT_STATE_MASK, /* u8 */ + TCA_FLOWER_KEY_CT_MARK, /* u32 */ + TCA_FLOWER_KEY_CT_MARK_MASK, /* u32 */ + TCA_FLOWER_KEY_CT_LABEL, /* 128 bits */ + TCA_FLOWER_KEY_CT_LABEL_MASK, /* 128 bits */ + __TCA_FLOWER_MAX, }; diff --git a/tc/f_flower.c b/tc/f_flower.c index c563666702b50973703f37c0174bfae3f242fdf3..40706d7156131f0b6603a4abdbe9108451e5cff7 100644 --- a/tc/f_flower.c +++ b/tc/f_flower.c @@ -81,7 +81,11 @@ static void explain(void) " enc_ttl MASKED-IP_TTL |\n" " geneve_opts MASKED-OPTIONS |\n" " ip_flags IP-FLAGS | \n" - " enc_dst_port [ port_number ] }\n" + " enc_dst_port [ port_number ] | \n" + " ct_mark MASKED-MARK | \n" + " ct_zone MASKED-ZONE | \n" + " ct_state MASKED-state | \n" + " ct_label MASKED-label } \n" " FILTERID := X:Y:Z\n" " MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n" " ACTION-SPEC := ... look at individual actions\n" @@ -331,7 +335,7 @@ static int flower_parse_arp_ip_addr(char *str, __be16 eth_type, static int flower_parse_u8(char *str, int value_type, int mask_type, int (*value_from_name)(const char *str, - __u8 *value), + __u8 *value), bool (*value_validate)(__u8 value), struct nlmsghdr *n) { @@ -372,6 +376,92 @@ err: return err; } +static int flower_parse_u16(char *str, int value_type, int mask_type, + int (*value_from_name)(const char *str, + __u16 *value), + bool (*value_validate)(__u16 value), + struct nlmsghdr *n) +{ + char *slash; + int ret, err = -1; + __u16 value, mask; + + slash = strchr(str, '/'); + if (slash) + *slash = '\0'; + + ret = value_from_name ? value_from_name(str, &value) : -1; + if (ret < 0) { + ret = get_u16(&value, str, 10); + if (ret) + goto err; + } + + if (value_validate && !value_validate(value)) + goto err; + + if (slash) { + ret = get_u16(&mask, slash + 1, 10); + if (ret) + goto err; + } + else { + mask = UINT16_MAX; + } + + addattr16(n, MAX_MSG, value_type, value); + addattr16(n, MAX_MSG, mask_type, mask); + + err = 0; +err: + if (slash) + *slash = '/'; + return err; +} + +static int flower_parse_u32(char *str, int value_type, int mask_type, + int (*value_from_name)(const char *str, + __u32 *value), + bool (*value_validate)(__u32 value), + struct nlmsghdr *n) +{ + char *slash; + int ret, err = -1; + __u32 value, mask; + + slash = strchr(str, '/'); + if (slash) + *slash = '\0'; + + ret = value_from_name ? value_from_name(str, &value) : -1; + if (ret < 0) { + ret = get_u32(&value, str, 10); + if (ret) + goto err; + } + + if (value_validate && !value_validate(value)) + goto err; + + if (slash) { + ret = get_u32(&mask, slash + 1, 10); + if (ret) + goto err; + } + else { + mask = UINT32_MAX; + } + + addattr32(n, MAX_MSG, value_type, value); + addattr32(n, MAX_MSG, mask_type, mask); + + err = 0; +err: + if (slash) + *slash = '/'; + return err; +} + static const char *flower_print_arp_op_to_name(__u8 op) { switch (op) { @@ -796,6 +886,40 @@ static int flower_parse_enc_opts(char *str, struct nlmsghdr *n) return 0; } +static int flower_parse_ct_mark(char *str, struct nlmsghdr *n) +{ + return flower_parse_u32(str, + TCA_FLOWER_KEY_CT_MARK, + TCA_FLOWER_KEY_CT_MARK_MASK, + NULL, NULL, n); +} + +static int flower_parse_ct_zone(char *str, struct nlmsghdr *n) +{ + return flower_parse_u16(str, + TCA_FLOWER_KEY_CT_ZONE, + TCA_FLOWER_KEY_CT_ZONE_MASK, + NULL, NULL, n); +} + +static int flower_parse_ct_state(char *str, struct nlmsghdr *n) +{ + return flower_parse_u8(str, + TCA_FLOWER_KEY_CT_STATE, + TCA_FLOWER_KEY_CT_STATE_MASK, + NULL, NULL, n); +} + +/* +static int flower_parse_ct_label(char *str, struct nlmsghdr *n) +{ + return flower_parse_u128_masked(str, + TCA_FLOWER_KEY_CT_LABEL, + TCA_FLOWER_KEY_CT_LABEL_MASK, + n); +} +*/ + static int flower_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { @@ -1255,6 +1379,35 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, fprintf(stderr, "Illegal \"geneve_opts\"\n"); return -1; } + } else if (matches(*argv, "ct_mark") == 0) { + NEXT_ARG(); + ret = flower_parse_ct_mark(*argv, n); + if (ret < 0) { + fprintf(stderr, "Illegal \"ct_mark\"\n"); + return -1; + } + } else if (matches(*argv, "ct_zone") == 0) { + NEXT_ARG(); + ret = flower_parse_ct_zone(*argv, n); + if (ret < 0) { + fprintf(stderr, "Illegal \"ct_zone\"\n"); + return -1; + } + } else if (matches(*argv, "ct_state") == 0) { + NEXT_ARG(); + ret = flower_parse_ct_state(*argv, n); + if (ret < 0) { + fprintf(stderr, "Illegal \"ct_state\"\n"); + return -1; + } +/* } else if (matches(*argv, "ct_label") == 0) { + NEXT_ARG(); + ret = flower_parse_ct_label(*argv, n); + if (ret < 0) { + fprintf(stderr, "Illegal \"ct_label\"\n"); + return -1; + } +*/ } else if (matches(*argv, "action") == 0) { NEXT_ARG(); ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n); @@ -1919,6 +2072,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, tb[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]); flower_print_enc_opts("enc_opt", tb[TCA_FLOWER_KEY_ENC_OPTS], tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]); + /* FIXME: print ct fields */ flower_print_matching_flags("ip_flags", FLOWER_IP_FLAGS, tb[TCA_FLOWER_KEY_FLAGS],