Skip to content

Commit cd11b16

Browse files
Paolo Abenidavem330
authored andcommitted
net/tc: introduce TC_ACT_REINSERT.
This is similar TC_ACT_REDIRECT, but with a slightly different semantic: - on ingress the mirred skbs are passed to the target device network stack without any additional check not scrubbing. - the rcu-protected stats provided via the tcf_result struct are updated on error conditions. This new tcfa_action value is not exposed to the user-space and can be used only internally by clsact. v1 -> v2: do not touch TC_ACT_REDIRECT code path, introduce a new action type instead v2 -> v3: - rename the new action value TC_ACT_REINJECT, update the helper accordingly - take care of uncloned reinjected packets in XDP generic hook v3 -> v4: - renamed again the new action value (JiriP) v4 -> v5: - fix build error with !NET_CLS_ACT (kbuild bot) Signed-off-by: Paolo Abeni <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7fd4b28 commit cd11b16

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

include/net/pkt_cls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include <net/sch_generic.h>
88
#include <net/act_api.h>
99

10+
/* TC action not accessible from user space */
11+
#define TC_ACT_REINSERT (TC_ACT_VALUE_MAX + 1)
12+
1013
/* Basic packet classifier frontend definitions. */
1114

1215
struct tcf_walker {

include/net/sch_generic.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ struct tcf_result {
235235
u32 classid;
236236
};
237237
const struct tcf_proto *goto_tp;
238+
239+
/* used by the TC_ACT_REINSERT action */
240+
struct {
241+
bool ingress;
242+
struct gnet_stats_queue *qstats;
243+
};
238244
};
239245
};
240246

@@ -569,6 +575,15 @@ static inline void skb_reset_tc(struct sk_buff *skb)
569575
#endif
570576
}
571577

578+
static inline bool skb_is_tc_redirected(const struct sk_buff *skb)
579+
{
580+
#ifdef CONFIG_NET_CLS_ACT
581+
return skb->tc_redirected;
582+
#else
583+
return false;
584+
#endif
585+
}
586+
572587
static inline bool skb_at_tc_ingress(const struct sk_buff *skb)
573588
{
574589
#ifdef CONFIG_NET_CLS_ACT
@@ -1108,4 +1123,17 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp,
11081123
void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
11091124
struct mini_Qdisc __rcu **p_miniq);
11101125

1126+
static inline void skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res)
1127+
{
1128+
struct gnet_stats_queue *stats = res->qstats;
1129+
int ret;
1130+
1131+
if (res->ingress)
1132+
ret = netif_receive_skb(skb);
1133+
else
1134+
ret = dev_queue_xmit(skb);
1135+
if (ret && stats)
1136+
qstats_overlimit_inc(res->qstats);
1137+
}
1138+
11111139
#endif

net/core/dev.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4252,7 +4252,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
42524252
/* Reinjected packets coming from act_mirred or similar should
42534253
* not get XDP generic processing.
42544254
*/
4255-
if (skb_cloned(skb))
4255+
if (skb_cloned(skb) || skb_is_tc_redirected(skb))
42564256
return XDP_PASS;
42574257

42584258
/* XDP packets must be linear and must have sufficient headroom
@@ -4602,6 +4602,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
46024602
__skb_push(skb, skb->mac_len);
46034603
skb_do_redirect(skb);
46044604
return NULL;
4605+
case TC_ACT_REINSERT:
4606+
/* this does not scrub the packet, and updates stats on error */
4607+
skb_tc_reinsert(skb, &cl_res);
4608+
return NULL;
46054609
default:
46064610
break;
46074611
}

0 commit comments

Comments
 (0)