From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pablo Neira Ayuso Subject: [PATCH net-next,v2 03/12] flow_dissector: add flow action infrastructure Date: Mon, 19 Nov 2018 01:15:10 +0100 Message-ID: <20181119001519.12124-4-pablo@netfilter.org> References: <20181119001519.12124-1-pablo@netfilter.org> Cc: davem@davemloft.net, thomas.lendacky@amd.com, f.fainelli@gmail.com, ariel.elior@cavium.com, michael.chan@broadcom.com, santosh@chelsio.com, madalin.bucur@nxp.com, yisen.zhuang@huawei.com, salil.mehta@huawei.com, jeffrey.t.kirsher@intel.com, tariqt@mellanox.com, saeedm@mellanox.com, jiri@mellanox.com, idosch@mellanox.com, jakub.kicinski@netronome.com, peppe.cavallaro@st.com, grygorii.strashko@ti.com, andrew@lunn.ch, vivien.didelot@savoirfairelinux.com, alexandre.torgue@st.com, joabreu@synopsys.com, linux-net-drivers@solarflare.com, ganeshgr@chelsio.com, ogerlitz@mellanox.com To: netdev@vger.kernel.org Return-path: Received: from mail.us.es ([193.147.175.20]:57594 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727068AbeKSKio (ORCPT ); Mon, 19 Nov 2018 05:38:44 -0500 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id F19F617AE53 for ; Mon, 19 Nov 2018 01:16:54 +0100 (CET) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id E335BDA79C for ; Mon, 19 Nov 2018 01:16:54 +0100 (CET) In-Reply-To: <20181119001519.12124-1-pablo@netfilter.org> Sender: netdev-owner@vger.kernel.org List-ID: This new infrastructure defines the nic actions that you can perform from existing network drivers. This infrastructure allows us to avoid a direct dependency with the native software TC action representation. Signed-off-by: Pablo Neira Ayuso --- v2: no changes. include/net/flow_dissector.h | 70 ++++++++++++++++++++++++++++++++++++++++++++ net/core/flow_dissector.c | 18 ++++++++++++ 2 files changed, 88 insertions(+) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 965a82b8d881..925c208816f1 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -402,8 +402,78 @@ void flow_rule_match_enc_keyid(const struct flow_rule *rule, void flow_rule_match_enc_opts(const struct flow_rule *rule, struct flow_match_enc_opts *out); +enum flow_action_key_id { + FLOW_ACTION_KEY_ACCEPT = 0, + FLOW_ACTION_KEY_DROP, + FLOW_ACTION_KEY_TRAP, + FLOW_ACTION_KEY_GOTO, + FLOW_ACTION_KEY_REDIRECT, + FLOW_ACTION_KEY_MIRRED, + FLOW_ACTION_KEY_VLAN_PUSH, + FLOW_ACTION_KEY_VLAN_POP, + FLOW_ACTION_KEY_VLAN_MANGLE, + FLOW_ACTION_KEY_TUNNEL_ENCAP, + FLOW_ACTION_KEY_TUNNEL_DECAP, + FLOW_ACTION_KEY_MANGLE, + FLOW_ACTION_KEY_ADD, + FLOW_ACTION_KEY_CSUM, + FLOW_ACTION_KEY_MARK, +}; + +/* This is mirroring enum pedit_header_type definition for easy mapping between + * tc pedit action. Legacy TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK is mapped to + * FLOW_ACT_MANGLE_UNSPEC, which is supported by no driver. + */ +enum flow_act_mangle_base { + FLOW_ACT_MANGLE_UNSPEC = 0, + FLOW_ACT_MANGLE_HDR_TYPE_ETH, + FLOW_ACT_MANGLE_HDR_TYPE_IP4, + FLOW_ACT_MANGLE_HDR_TYPE_IP6, + FLOW_ACT_MANGLE_HDR_TYPE_TCP, + FLOW_ACT_MANGLE_HDR_TYPE_UDP, +}; + +struct flow_action_key { + enum flow_action_key_id id; + union { + u32 chain_index; /* FLOW_ACTION_KEY_GOTO */ + struct net_device *dev; /* FLOW_ACTION_KEY_REDIRECT */ + struct { /* FLOW_ACTION_KEY_VLAN */ + u16 vid; + __be16 proto; + u8 prio; + } vlan; + struct { /* FLOW_ACTION_KEY_PACKET_EDIT */ + enum flow_act_mangle_base htype; + u32 offset; + u32 mask; + u32 val; + } mangle; + const struct ip_tunnel_info *tunnel; /* FLOW_ACTION_KEY_TUNNEL_ENCAP */ + u32 csum_flags; /* FLOW_ACTION_KEY_CSUM */ + u32 mark; /* FLOW_ACTION_KEY_MARK */ + }; +}; + +struct flow_action { + int num_keys; + struct flow_action_key *keys; +}; + +int flow_action_init(struct flow_action *flow_action, int num_acts); +void flow_action_free(struct flow_action *flow_action); + +static inline bool flow_action_has_keys(const struct flow_action *action) +{ + return action->num_keys; +} + +#define flow_action_for_each(__i, __act, __actions) \ + for (__i = 0, __act = &(__actions)->keys[0]; __i < (__actions)->num_keys; __act = &(__actions)->keys[++__i]) + struct flow_rule { struct flow_match match; + struct flow_action action; }; static inline bool flow_rule_match_key(const struct flow_rule *rule, diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 186089b8d852..b9368349f0f7 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -258,6 +258,24 @@ void flow_rule_match_enc_opts(const struct flow_rule *rule, } EXPORT_SYMBOL(flow_rule_match_enc_opts); +int flow_action_init(struct flow_action *flow_action, int num_acts) +{ + flow_action->keys = kmalloc(sizeof(struct flow_action_key) * num_acts, + GFP_KERNEL); + if (!flow_action->keys) + return -ENOMEM; + + flow_action->num_keys = num_acts; + return 0; +} +EXPORT_SYMBOL(flow_action_init); + +void flow_action_free(struct flow_action *flow_action) +{ + kfree(flow_action->keys); +} +EXPORT_SYMBOL(flow_action_free); + /** * __skb_flow_get_ports - extract the upper layer ports and return them * @skb: sk_buff to extract the ports from -- 2.11.0