Skip to content

Commit

Permalink
flow_offload: add flow action infrastructure
Browse files Browse the repository at this point in the history
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 <pablo@netfilter.org>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Pablo Neira Ayuso authored and David S. Miller committed Feb 6, 2019
1 parent c500c86 commit e3ab786
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
69 changes: 68 additions & 1 deletion include/net/flow_offload.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,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_id {
FLOW_ACTION_ACCEPT = 0,
FLOW_ACTION_DROP,
FLOW_ACTION_TRAP,
FLOW_ACTION_GOTO,
FLOW_ACTION_REDIRECT,
FLOW_ACTION_MIRRED,
FLOW_ACTION_VLAN_PUSH,
FLOW_ACTION_VLAN_POP,
FLOW_ACTION_VLAN_MANGLE,
FLOW_ACTION_TUNNEL_ENCAP,
FLOW_ACTION_TUNNEL_DECAP,
FLOW_ACTION_MANGLE,
FLOW_ACTION_ADD,
FLOW_ACTION_CSUM,
FLOW_ACTION_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_action_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_entry {
enum flow_action_id id;
union {
u32 chain_index; /* FLOW_ACTION_GOTO */
struct net_device *dev; /* FLOW_ACTION_REDIRECT */
struct { /* FLOW_ACTION_VLAN */
u16 vid;
__be16 proto;
u8 prio;
} vlan;
struct { /* FLOW_ACTION_PACKET_EDIT */
enum flow_action_mangle_base htype;
u32 offset;
u32 mask;
u32 val;
} mangle;
const struct ip_tunnel_info *tunnel; /* FLOW_ACTION_TUNNEL_ENCAP */
u32 csum_flags; /* FLOW_ACTION_CSUM */
u32 mark; /* FLOW_ACTION_MARK */
};
};

struct flow_action {
unsigned int num_entries;
struct flow_action_entry entries[0];
};

static inline bool flow_action_has_entries(const struct flow_action *action)
{
return action->num_entries;
}

#define flow_action_for_each(__i, __act, __actions) \
for (__i = 0, __act = &(__actions)->entries[0]; __i < (__actions)->num_entries; __act = &(__actions)->entries[__i++])

struct flow_rule {
struct flow_match match;
struct flow_action action;
};

struct flow_rule *flow_rule_alloc(void);
struct flow_rule *flow_rule_alloc(unsigned int num_actions);

static inline bool flow_rule_match_key(const struct flow_rule *rule,
enum flow_dissector_key_id key)
Expand Down
1 change: 1 addition & 0 deletions include/net/pkt_cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)

int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type,
void *type_data, bool err_stop);
unsigned int tcf_exts_num_actions(struct tcf_exts *exts);

enum tc_block_command {
TC_BLOCK_BIND,
Expand Down
14 changes: 12 additions & 2 deletions net/core/flow_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@
#include <linux/slab.h>
#include <net/flow_offload.h>

struct flow_rule *flow_rule_alloc(void)
struct flow_rule *flow_rule_alloc(unsigned int num_actions)
{
return kzalloc(sizeof(struct flow_rule), GFP_KERNEL);
struct flow_rule *rule;

rule = kzalloc(sizeof(struct flow_rule) +
sizeof(struct flow_action_entry) * num_actions,
GFP_KERNEL);
if (!rule)
return NULL;

rule->action.num_entries = num_actions;

return rule;
}
EXPORT_SYMBOL(flow_rule_alloc);

Expand Down
17 changes: 17 additions & 0 deletions net/sched/cls_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <net/pkt_cls.h>
#include <net/tc_act/tc_pedit.h>

extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];

Expand Down Expand Up @@ -2515,6 +2516,22 @@ int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type,
}
EXPORT_SYMBOL(tc_setup_cb_call);

unsigned int tcf_exts_num_actions(struct tcf_exts *exts)
{
unsigned int num_acts = 0;
struct tc_action *act;
int i;

tcf_exts_for_each_action(i, act, exts) {
if (is_tcf_pedit(act))
num_acts += tcf_pedit_nkeys(act);
else
num_acts++;
}
return num_acts;
}
EXPORT_SYMBOL(tcf_exts_num_actions);

static __net_init int tcf_net_init(struct net *net)
{
struct tcf_net *tn = net_generic(net, tcf_net_id);
Expand Down
7 changes: 4 additions & 3 deletions net/sched/cls_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
bool skip_sw = tc_skip_sw(f->flags);
int err;

cls_flower.rule = flow_rule_alloc();
cls_flower.rule = flow_rule_alloc(tcf_exts_num_actions(&f->exts));
if (!cls_flower.rule)
return -ENOMEM;

Expand Down Expand Up @@ -1469,7 +1469,8 @@ static int fl_reoffload(struct tcf_proto *tp, bool add, tc_setup_cb_t *cb,
if (tc_skip_hw(f->flags))
continue;

cls_flower.rule = flow_rule_alloc();
cls_flower.rule =
flow_rule_alloc(tcf_exts_num_actions(&f->exts));
if (!cls_flower.rule)
return -ENOMEM;

Expand Down Expand Up @@ -1508,7 +1509,7 @@ static int fl_hw_create_tmplt(struct tcf_chain *chain,
struct tcf_block *block = chain->block;
struct tcf_exts dummy_exts = { 0, };

cls_flower.rule = flow_rule_alloc();
cls_flower.rule = flow_rule_alloc(0);
if (!cls_flower.rule)
return -ENOMEM;

Expand Down

0 comments on commit e3ab786

Please sign in to comment.