Skip to content

Commit c54e1d9

Browse files
zhengbaowendavem330
authored andcommitted
flow_offload: add ops to tc_action_ops for flow action setup
Add a new ops to tc_action_ops for flow action setup. Refactor function tc_setup_flow_action to use this new ops. We make this change to facilitate to add standalone action module. We will also use this ops to offload action independent of filter in following patch. Signed-off-by: Baowen Zheng <[email protected]> Signed-off-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9c1c0e1 commit c54e1d9

File tree

14 files changed

+406
-208
lines changed

14 files changed

+406
-208
lines changed

include/net/act_api.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm)
8888
dtm->expires = jiffies_to_clock_t(stm->expires);
8989
}
9090

91+
static inline enum flow_action_hw_stats tc_act_hw_stats(u8 hw_stats)
92+
{
93+
if (WARN_ON_ONCE(hw_stats > TCA_ACT_HW_STATS_ANY))
94+
return FLOW_ACTION_HW_STATS_DONT_CARE;
95+
else if (!hw_stats)
96+
return FLOW_ACTION_HW_STATS_DISABLED;
97+
98+
return hw_stats;
99+
}
100+
91101
#ifdef CONFIG_NET_CLS_ACT
92102

93103
#define ACT_P_CREATED 1
@@ -121,6 +131,8 @@ struct tc_action_ops {
121131
struct psample_group *
122132
(*get_psample_group)(const struct tc_action *a,
123133
tc_action_priv_destructor *destructor);
134+
int (*offload_act_setup)(struct tc_action *act, void *entry_data,
135+
u32 *index_inc, bool bind);
124136
};
125137

126138
struct tc_action_net {

net/sched/act_csum.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,22 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act)
695695
return nla_total_size(sizeof(struct tc_csum));
696696
}
697697

698+
static int tcf_csum_offload_act_setup(struct tc_action *act, void *entry_data,
699+
u32 *index_inc, bool bind)
700+
{
701+
if (bind) {
702+
struct flow_action_entry *entry = entry_data;
703+
704+
entry->id = FLOW_ACTION_CSUM;
705+
entry->csum_flags = tcf_csum_update_flags(act);
706+
*index_inc = 1;
707+
} else {
708+
return -EOPNOTSUPP;
709+
}
710+
711+
return 0;
712+
}
713+
698714
static struct tc_action_ops act_csum_ops = {
699715
.kind = "csum",
700716
.id = TCA_ID_CSUM,
@@ -706,6 +722,7 @@ static struct tc_action_ops act_csum_ops = {
706722
.walk = tcf_csum_walker,
707723
.lookup = tcf_csum_search,
708724
.get_fill_size = tcf_csum_get_fill_size,
725+
.offload_act_setup = tcf_csum_offload_act_setup,
709726
.size = sizeof(struct tcf_csum),
710727
};
711728

net/sched/act_ct.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,24 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
14931493
c->tcf_tm.lastuse = max_t(u64, c->tcf_tm.lastuse, lastuse);
14941494
}
14951495

1496+
static int tcf_ct_offload_act_setup(struct tc_action *act, void *entry_data,
1497+
u32 *index_inc, bool bind)
1498+
{
1499+
if (bind) {
1500+
struct flow_action_entry *entry = entry_data;
1501+
1502+
entry->id = FLOW_ACTION_CT;
1503+
entry->ct.action = tcf_ct_action(act);
1504+
entry->ct.zone = tcf_ct_zone(act);
1505+
entry->ct.flow_table = tcf_ct_ft(act);
1506+
*index_inc = 1;
1507+
} else {
1508+
return -EOPNOTSUPP;
1509+
}
1510+
1511+
return 0;
1512+
}
1513+
14961514
static struct tc_action_ops act_ct_ops = {
14971515
.kind = "ct",
14981516
.id = TCA_ID_CT,
@@ -1504,6 +1522,7 @@ static struct tc_action_ops act_ct_ops = {
15041522
.walk = tcf_ct_walker,
15051523
.lookup = tcf_ct_search,
15061524
.stats_update = tcf_stats_update,
1525+
.offload_act_setup = tcf_ct_offload_act_setup,
15071526
.size = sizeof(struct tcf_ct),
15081527
};
15091528

net/sched/act_gact.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,32 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act)
252252
return sz;
253253
}
254254

255+
static int tcf_gact_offload_act_setup(struct tc_action *act, void *entry_data,
256+
u32 *index_inc, bool bind)
257+
{
258+
if (bind) {
259+
struct flow_action_entry *entry = entry_data;
260+
261+
if (is_tcf_gact_ok(act)) {
262+
entry->id = FLOW_ACTION_ACCEPT;
263+
} else if (is_tcf_gact_shot(act)) {
264+
entry->id = FLOW_ACTION_DROP;
265+
} else if (is_tcf_gact_trap(act)) {
266+
entry->id = FLOW_ACTION_TRAP;
267+
} else if (is_tcf_gact_goto_chain(act)) {
268+
entry->id = FLOW_ACTION_GOTO;
269+
entry->chain_index = tcf_gact_goto_chain_index(act);
270+
} else {
271+
return -EOPNOTSUPP;
272+
}
273+
*index_inc = 1;
274+
} else {
275+
return -EOPNOTSUPP;
276+
}
277+
278+
return 0;
279+
}
280+
255281
static struct tc_action_ops act_gact_ops = {
256282
.kind = "gact",
257283
.id = TCA_ID_GACT,
@@ -263,6 +289,7 @@ static struct tc_action_ops act_gact_ops = {
263289
.walk = tcf_gact_walker,
264290
.lookup = tcf_gact_search,
265291
.get_fill_size = tcf_gact_get_fill_size,
292+
.offload_act_setup = tcf_gact_offload_act_setup,
266293
.size = sizeof(struct tcf_gact),
267294
};
268295

net/sched/act_gate.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,52 @@ static size_t tcf_gate_get_fill_size(const struct tc_action *act)
597597
return nla_total_size(sizeof(struct tc_gate));
598598
}
599599

600+
static void tcf_gate_entry_destructor(void *priv)
601+
{
602+
struct action_gate_entry *oe = priv;
603+
604+
kfree(oe);
605+
}
606+
607+
static int tcf_gate_get_entries(struct flow_action_entry *entry,
608+
const struct tc_action *act)
609+
{
610+
entry->gate.entries = tcf_gate_get_list(act);
611+
612+
if (!entry->gate.entries)
613+
return -EINVAL;
614+
615+
entry->destructor = tcf_gate_entry_destructor;
616+
entry->destructor_priv = entry->gate.entries;
617+
618+
return 0;
619+
}
620+
621+
static int tcf_gate_offload_act_setup(struct tc_action *act, void *entry_data,
622+
u32 *index_inc, bool bind)
623+
{
624+
int err;
625+
626+
if (bind) {
627+
struct flow_action_entry *entry = entry_data;
628+
629+
entry->id = FLOW_ACTION_GATE;
630+
entry->gate.prio = tcf_gate_prio(act);
631+
entry->gate.basetime = tcf_gate_basetime(act);
632+
entry->gate.cycletime = tcf_gate_cycletime(act);
633+
entry->gate.cycletimeext = tcf_gate_cycletimeext(act);
634+
entry->gate.num_entries = tcf_gate_num_entries(act);
635+
err = tcf_gate_get_entries(entry, act);
636+
if (err)
637+
return err;
638+
*index_inc = 1;
639+
} else {
640+
return -EOPNOTSUPP;
641+
}
642+
643+
return 0;
644+
}
645+
600646
static struct tc_action_ops act_gate_ops = {
601647
.kind = "gate",
602648
.id = TCA_ID_GATE,
@@ -609,6 +655,7 @@ static struct tc_action_ops act_gate_ops = {
609655
.stats_update = tcf_gate_stats_update,
610656
.get_fill_size = tcf_gate_get_fill_size,
611657
.lookup = tcf_gate_search,
658+
.offload_act_setup = tcf_gate_offload_act_setup,
612659
.size = sizeof(struct tcf_gate),
613660
};
614661

net/sched/act_mirred.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,44 @@ static size_t tcf_mirred_get_fill_size(const struct tc_action *act)
450450
return nla_total_size(sizeof(struct tc_mirred));
451451
}
452452

453+
static void tcf_offload_mirred_get_dev(struct flow_action_entry *entry,
454+
const struct tc_action *act)
455+
{
456+
entry->dev = act->ops->get_dev(act, &entry->destructor);
457+
if (!entry->dev)
458+
return;
459+
entry->destructor_priv = entry->dev;
460+
}
461+
462+
static int tcf_mirred_offload_act_setup(struct tc_action *act, void *entry_data,
463+
u32 *index_inc, bool bind)
464+
{
465+
if (bind) {
466+
struct flow_action_entry *entry = entry_data;
467+
468+
if (is_tcf_mirred_egress_redirect(act)) {
469+
entry->id = FLOW_ACTION_REDIRECT;
470+
tcf_offload_mirred_get_dev(entry, act);
471+
} else if (is_tcf_mirred_egress_mirror(act)) {
472+
entry->id = FLOW_ACTION_MIRRED;
473+
tcf_offload_mirred_get_dev(entry, act);
474+
} else if (is_tcf_mirred_ingress_redirect(act)) {
475+
entry->id = FLOW_ACTION_REDIRECT_INGRESS;
476+
tcf_offload_mirred_get_dev(entry, act);
477+
} else if (is_tcf_mirred_ingress_mirror(act)) {
478+
entry->id = FLOW_ACTION_MIRRED_INGRESS;
479+
tcf_offload_mirred_get_dev(entry, act);
480+
} else {
481+
return -EOPNOTSUPP;
482+
}
483+
*index_inc = 1;
484+
} else {
485+
return -EOPNOTSUPP;
486+
}
487+
488+
return 0;
489+
}
490+
453491
static struct tc_action_ops act_mirred_ops = {
454492
.kind = "mirred",
455493
.id = TCA_ID_MIRRED,
@@ -462,6 +500,7 @@ static struct tc_action_ops act_mirred_ops = {
462500
.walk = tcf_mirred_walker,
463501
.lookup = tcf_mirred_search,
464502
.get_fill_size = tcf_mirred_get_fill_size,
503+
.offload_act_setup = tcf_mirred_offload_act_setup,
465504
.size = sizeof(struct tcf_mirred),
466505
.get_dev = tcf_mirred_get_dev,
467506
};

net/sched/act_mpls.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,43 @@ static int tcf_mpls_search(struct net *net, struct tc_action **a, u32 index)
384384
return tcf_idr_search(tn, a, index);
385385
}
386386

387+
static int tcf_mpls_offload_act_setup(struct tc_action *act, void *entry_data,
388+
u32 *index_inc, bool bind)
389+
{
390+
if (bind) {
391+
struct flow_action_entry *entry = entry_data;
392+
393+
switch (tcf_mpls_action(act)) {
394+
case TCA_MPLS_ACT_PUSH:
395+
entry->id = FLOW_ACTION_MPLS_PUSH;
396+
entry->mpls_push.proto = tcf_mpls_proto(act);
397+
entry->mpls_push.label = tcf_mpls_label(act);
398+
entry->mpls_push.tc = tcf_mpls_tc(act);
399+
entry->mpls_push.bos = tcf_mpls_bos(act);
400+
entry->mpls_push.ttl = tcf_mpls_ttl(act);
401+
break;
402+
case TCA_MPLS_ACT_POP:
403+
entry->id = FLOW_ACTION_MPLS_POP;
404+
entry->mpls_pop.proto = tcf_mpls_proto(act);
405+
break;
406+
case TCA_MPLS_ACT_MODIFY:
407+
entry->id = FLOW_ACTION_MPLS_MANGLE;
408+
entry->mpls_mangle.label = tcf_mpls_label(act);
409+
entry->mpls_mangle.tc = tcf_mpls_tc(act);
410+
entry->mpls_mangle.bos = tcf_mpls_bos(act);
411+
entry->mpls_mangle.ttl = tcf_mpls_ttl(act);
412+
break;
413+
default:
414+
return -EOPNOTSUPP;
415+
}
416+
*index_inc = 1;
417+
} else {
418+
return -EOPNOTSUPP;
419+
}
420+
421+
return 0;
422+
}
423+
387424
static struct tc_action_ops act_mpls_ops = {
388425
.kind = "mpls",
389426
.id = TCA_ID_MPLS,
@@ -394,6 +431,7 @@ static struct tc_action_ops act_mpls_ops = {
394431
.cleanup = tcf_mpls_cleanup,
395432
.walk = tcf_mpls_walker,
396433
.lookup = tcf_mpls_search,
434+
.offload_act_setup = tcf_mpls_offload_act_setup,
397435
.size = sizeof(struct tcf_mpls),
398436
};
399437

net/sched/act_pedit.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,39 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)
487487
return tcf_idr_search(tn, a, index);
488488
}
489489

490+
static int tcf_pedit_offload_act_setup(struct tc_action *act, void *entry_data,
491+
u32 *index_inc, bool bind)
492+
{
493+
if (bind) {
494+
struct flow_action_entry *entry = entry_data;
495+
int k;
496+
497+
for (k = 0; k < tcf_pedit_nkeys(act); k++) {
498+
switch (tcf_pedit_cmd(act, k)) {
499+
case TCA_PEDIT_KEY_EX_CMD_SET:
500+
entry->id = FLOW_ACTION_MANGLE;
501+
break;
502+
case TCA_PEDIT_KEY_EX_CMD_ADD:
503+
entry->id = FLOW_ACTION_ADD;
504+
break;
505+
default:
506+
return -EOPNOTSUPP;
507+
}
508+
entry->mangle.htype = tcf_pedit_htype(act, k);
509+
entry->mangle.mask = tcf_pedit_mask(act, k);
510+
entry->mangle.val = tcf_pedit_val(act, k);
511+
entry->mangle.offset = tcf_pedit_offset(act, k);
512+
entry->hw_stats = tc_act_hw_stats(act->hw_stats);
513+
entry++;
514+
}
515+
*index_inc = k;
516+
} else {
517+
return -EOPNOTSUPP;
518+
}
519+
520+
return 0;
521+
}
522+
490523
static struct tc_action_ops act_pedit_ops = {
491524
.kind = "pedit",
492525
.id = TCA_ID_PEDIT,
@@ -498,6 +531,7 @@ static struct tc_action_ops act_pedit_ops = {
498531
.init = tcf_pedit_init,
499532
.walk = tcf_pedit_walker,
500533
.lookup = tcf_pedit_search,
534+
.offload_act_setup = tcf_pedit_offload_act_setup,
501535
.size = sizeof(struct tcf_pedit),
502536
};
503537

net/sched/act_police.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,28 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
405405
return tcf_idr_search(tn, a, index);
406406
}
407407

408+
static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
409+
u32 *index_inc, bool bind)
410+
{
411+
if (bind) {
412+
struct flow_action_entry *entry = entry_data;
413+
414+
entry->id = FLOW_ACTION_POLICE;
415+
entry->police.burst = tcf_police_burst(act);
416+
entry->police.rate_bytes_ps =
417+
tcf_police_rate_bytes_ps(act);
418+
entry->police.burst_pkt = tcf_police_burst_pkt(act);
419+
entry->police.rate_pkt_ps =
420+
tcf_police_rate_pkt_ps(act);
421+
entry->police.mtu = tcf_police_tcfp_mtu(act);
422+
*index_inc = 1;
423+
} else {
424+
return -EOPNOTSUPP;
425+
}
426+
427+
return 0;
428+
}
429+
408430
MODULE_AUTHOR("Alexey Kuznetsov");
409431
MODULE_DESCRIPTION("Policing actions");
410432
MODULE_LICENSE("GPL");
@@ -420,6 +442,7 @@ static struct tc_action_ops act_police_ops = {
420442
.walk = tcf_police_walker,
421443
.lookup = tcf_police_search,
422444
.cleanup = tcf_police_cleanup,
445+
.offload_act_setup = tcf_police_offload_act_setup,
423446
.size = sizeof(struct tcf_police),
424447
};
425448

0 commit comments

Comments
 (0)