From: Shubham Kulkarni skulkarni@mvista.com
Hi Greg/All,
This patch series backports the fix for CVE-2022-4269 along with its 7 dependency commits to 5.4 stable kernel. These patches are already part of the next stable kernel v5.10.y and I have referred to those commits to generate this series for v5.4.
[CVE-2022-4269 - kernel: net: CPU soft lockup in TC mirred egress-to-ingress action]
Patch 1: Dependency Patch #1 - mainline commit c8ecebd04cbb (v5.5-rc1) Patch 2: Dependency Patch #2 - mainline commit 5e1ad95b630e (v5.5-rc1) Patch 3: Dependency Patch #3 - mainline commit 26b537a88ca5 (v5.5-rc1) Patch 4: Dependency Patch #4 - mainline commit ef816f3c49c1 (v5.5-rc1) Patch 5: Dependency Patch #5 - mainline commit 075c8aa79d54 (v5.8-rc1) Patch 6: Dependency Patch #6 - v5.10.y commit bba7ebe10baf (v5.10.181) Patch 7: Dependency Patch #7 - v5.10.y commit f5bf8e3ca13e (v5.10.181) Patch 8: CVE-2022-4269 fix - v5.10.y commit 532451037863 (v5.10.181)
---
Davide Caratti (2): net/sched: act_mirred: better wording on protection against excessive stack growth act_mirred: use the backlog for nested calls to mirred ingress
Jiri Pirko (1): selftests: forwarding: tc_actions.sh: add matchall mirror test
Vlad Buslov (4): net: sched: extract common action counters update code into function net: sched: extract bstats update code into function net: sched: extract qstats update code into functions net: sched: don't expose action qstats to skb_tc_reinsert()
wenxu (1): net/sched: act_mirred: refactor the handle of xmit
include/net/act_api.h | 25 +++++++ include/net/sch_generic.h | 13 ---- net/sched/act_api.c | 14 ++++ net/sched/act_csum.c | 4 +- net/sched/act_ct.c | 10 +-- net/sched/act_gact.c | 14 +--- net/sched/act_mirred.c | 55 ++++++++------ net/sched/act_police.c | 5 +- net/sched/act_tunnel_key.c | 2 +- net/sched/act_vlan.c | 9 +-- .../selftests/net/forwarding/tc_actions.sh | 72 ++++++++++++++++--- 11 files changed, 150 insertions(+), 73 deletions(-)
From: Vlad Buslov vladbu@mellanox.com
[ Upstream commit c8ecebd04cbb6badb46d42fe54282e7883ed63cc ]
Currently, all implementations of tc_action_ops->stats_update() callback have almost exactly the same implementation of counters update code (besides gact which also updates drop counter). In order to simplify support for using both percpu-allocated and regular action counters depending on run-time flag in following patches, extract action counters update code into standalone function in act API.
This commit doesn't change functionality.
Signed-off-by: Vlad Buslov vladbu@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- include/net/act_api.h | 2 ++ net/sched/act_api.c | 14 ++++++++++++++ net/sched/act_ct.c | 6 +----- net/sched/act_gact.c | 10 +--------- net/sched/act_mirred.c | 5 +---- net/sched/act_police.c | 5 +---- net/sched/act_vlan.c | 5 +---- 7 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h index 4dabe4730f00..39374348510c 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -186,6 +186,8 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind, int ref); int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); +void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, + bool drop, bool hw); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
int tcf_action_check_ctrlact(int action, struct tcf_proto *tp, diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 52394e45bac5..b2a537f1a1ea 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -1032,6 +1032,20 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, return err; }
+void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, + bool drop, bool hw) +{ + _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); + + if (drop) + this_cpu_ptr(a->cpu_qstats)->drops += packets; + + if (hw) + _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), + bytes, packets); +} +EXPORT_SYMBOL(tcf_action_update_stats); + int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p, int compat_mode) { diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 02d4491991b5..d72c9888fad2 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -917,11 +917,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets, { struct tcf_ct *c = to_ct(a);
- _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); c->tcf_tm.lastuse = max_t(u64, c->tcf_tm.lastuse, lastuse); }
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index faf68a44b845..d58a6c75349f 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -175,15 +175,7 @@ static void tcf_gact_stats_update(struct tc_action *a, u64 bytes, u32 packets, int action = READ_ONCE(gact->tcf_action); struct tcf_t *tm = &gact->tcf_tm;
- _bstats_cpu_update(this_cpu_ptr(gact->common.cpu_bstats), bytes, - packets); - if (action == TC_ACT_SHOT) - this_cpu_ptr(gact->common.cpu_qstats)->drops += packets; - - if (hw) - _bstats_cpu_update(this_cpu_ptr(gact->common.cpu_bstats_hw), - bytes, packets); - + tcf_action_update_stats(a, bytes, packets, action == TC_ACT_SHOT, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); }
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index e3f28cb03f7e..f38fd459ea45 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -324,10 +324,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets, struct tcf_mirred *m = to_mirred(a); struct tcf_t *tm = &m->tcf_tm;
- _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); }
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index a7660b602237..b67da92955b1 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -306,10 +306,7 @@ static void tcf_police_stats_update(struct tc_action *a, struct tcf_police *police = to_police(a); struct tcf_t *tm = &police->tcf_tm;
- _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); }
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 7dc76c68ec52..43c5be18241b 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -308,10 +308,7 @@ static void tcf_vlan_stats_update(struct tc_action *a, u64 bytes, u32 packets, struct tcf_vlan *v = to_vlan(a); struct tcf_t *tm = &v->tcf_tm;
- _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); }
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: c8ecebd04cbb6badb46d42fe54282e7883ed63cc
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Vlad Buslov vladbu@mellanox.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1) 5.10.y | Present (exact SHA1)
Note: The patch differs from the upstream commit: --- 1: c8ecebd04cbb ! 1: 0dd3ddfe6d2c net: sched: extract common action counters update code into function @@ Metadata ## Commit message ## net: sched: extract common action counters update code into function
+ [ Upstream commit c8ecebd04cbb6badb46d42fe54282e7883ed63cc ] + Currently, all implementations of tc_action_ops->stats_update() callback have almost exactly the same implementation of counters update code (besides gact which also updates drop counter). In order to simplify @@ Commit message Signed-off-by: Vlad Buslov vladbu@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net + Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") + Signed-off-by: Shubham Kulkarni skulkarni@mvista.com
## include/net/act_api.h ## @@ include/net/act_api.h: int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind,
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: Vlad Buslov vladbu@mellanox.com
[ Upstream commit 5e1ad95b630e652d3467d1fd1f0b5e5ea2c441e2 ]
Extract common code that increments cpu_bstats counter into standalone act API function. Change hardware offloaded actions that use percpu counter allocation to use the new function instead of incrementing cpu_bstats directly.
This commit doesn't change functionality.
Signed-off-by: Vlad Buslov vladbu@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- include/net/act_api.h | 7 +++++++ net/sched/act_csum.c | 2 +- net/sched/act_ct.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_mirred.c | 2 +- net/sched/act_tunnel_key.c | 2 +- net/sched/act_vlan.c | 2 +- 7 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h index 39374348510c..46009acb198b 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -186,6 +186,13 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind, int ref); int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); + +static inline void tcf_action_update_bstats(struct tc_action *a, + struct sk_buff *skb) +{ + bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb); +} + void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, bool drop, bool hw); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index fa1b1fd10c44..e502e256ad67 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -577,7 +577,7 @@ static int tcf_csum_act(struct sk_buff *skb, const struct tc_action *a, params = rcu_dereference_bh(p->params);
tcf_lastuse_update(&p->tcf_tm); - bstats_cpu_update(this_cpu_ptr(p->common.cpu_bstats), skb); + tcf_action_update_bstats(&p->common, skb);
action = READ_ONCE(p->tcf_action); if (unlikely(action == TC_ACT_SHOT)) diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index d72c9888fad2..0727a2516736 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -482,7 +482,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, skb_push_rcsum(skb, nh_ofs);
out: - bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb); + tcf_action_update_bstats(&c->common, skb); return retval;
drop: diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index d58a6c75349f..ff78de432871 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -159,7 +159,7 @@ static int tcf_gact_act(struct sk_buff *skb, const struct tc_action *a, action = gact_rand[ptype](gact); } #endif - bstats_cpu_update(this_cpu_ptr(gact->common.cpu_bstats), skb); + tcf_action_update_bstats(&gact->common, skb); if (action == TC_ACT_SHOT) qstats_drop_inc(this_cpu_ptr(gact->common.cpu_qstats));
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index f38fd459ea45..52830e0339f9 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -233,7 +233,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, }
tcf_lastuse_update(&m->tcf_tm); - bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb); + tcf_action_update_bstats(&m->common, skb);
m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit); m_eaction = READ_ONCE(m->tcfm_eaction); diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index a5a2bf01eb9b..e5b0c13d6d58 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c @@ -31,7 +31,7 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a, params = rcu_dereference_bh(t->params);
tcf_lastuse_update(&t->tcf_tm); - bstats_cpu_update(this_cpu_ptr(t->common.cpu_bstats), skb); + tcf_action_update_bstats(&t->common, skb); action = READ_ONCE(t->tcf_action);
switch (params->tcft_action) { diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 43c5be18241b..ffa5df8765b7 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -29,7 +29,7 @@ static int tcf_vlan_act(struct sk_buff *skb, const struct tc_action *a, u16 tci;
tcf_lastuse_update(&v->tcf_tm); - bstats_cpu_update(this_cpu_ptr(v->common.cpu_bstats), skb); + tcf_action_update_bstats(&v->common, skb);
/* Ensure 'data' points at mac_header prior calling vlan manipulating * functions.
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 5e1ad95b630e652d3467d1fd1f0b5e5ea2c441e2
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Vlad Buslov vladbu@mellanox.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1) 5.10.y | Present (exact SHA1)
Note: Could not generate a diff with upstream commit: --- Note: Could not generate diff - patch failed to apply for comparison ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: Vlad Buslov vladbu@mellanox.com
[ Upstream commit 26b537a88ca5b7399c7ab0656e06dbd9da9513c1 ]
Extract common code that increments cpu_qstats counters into standalone act API functions. Change hardware offloaded actions that use percpu counter allocation to use the new functions instead of accessing cpu_qstats directly.
This commit doesn't change functionality.
Signed-off-by: Vlad Buslov vladbu@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- include/net/act_api.h | 16 ++++++++++++++++ net/sched/act_csum.c | 2 +- net/sched/act_ct.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_mirred.c | 2 +- net/sched/act_vlan.c | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/include/net/act_api.h b/include/net/act_api.h index 46009acb198b..25d9a12118ba 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -193,6 +193,22 @@ static inline void tcf_action_update_bstats(struct tc_action *a, bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb); }
+static inline struct gnet_stats_queue * +tcf_action_get_qstats(struct tc_action *a) +{ + return this_cpu_ptr(a->cpu_qstats); +} + +static inline void tcf_action_inc_drop_qstats(struct tc_action *a) +{ + qstats_drop_inc(this_cpu_ptr(a->cpu_qstats)); +} + +static inline void tcf_action_inc_overlimit_qstats(struct tc_action *a) +{ + qstats_overlimit_inc(this_cpu_ptr(a->cpu_qstats)); +} + void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, bool drop, bool hw); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index e502e256ad67..5a1f9c8be8b7 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -621,7 +621,7 @@ static int tcf_csum_act(struct sk_buff *skb, const struct tc_action *a, return action;
drop: - qstats_drop_inc(this_cpu_ptr(p->common.cpu_qstats)); + tcf_action_inc_drop_qstats(&p->common); action = TC_ACT_SHOT; goto out; } diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 0727a2516736..077cef97527f 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -486,7 +486,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, return retval;
drop: - qstats_drop_inc(this_cpu_ptr(a->cpu_qstats)); + tcf_action_inc_drop_qstats(&c->common); return TC_ACT_SHOT; }
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index ff78de432871..ef08fd58f28a 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -161,7 +161,7 @@ static int tcf_gact_act(struct sk_buff *skb, const struct tc_action *a, #endif tcf_action_update_bstats(&gact->common, skb); if (action == TC_ACT_SHOT) - qstats_drop_inc(this_cpu_ptr(gact->common.cpu_qstats)); + tcf_action_inc_drop_qstats(&gact->common);
tcf_lastuse_update(&gact->tcf_tm);
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 52830e0339f9..5602b5de194b 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -309,7 +309,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
if (err) { out: - qstats_overlimit_inc(this_cpu_ptr(m->common.cpu_qstats)); + tcf_action_inc_overlimit_qstats(&m->common); if (tcf_mirred_is_act_redirect(m_eaction)) retval = TC_ACT_SHOT; } diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index ffa5df8765b7..b4b09c0c8589 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -88,7 +88,7 @@ static int tcf_vlan_act(struct sk_buff *skb, const struct tc_action *a, return action;
drop: - qstats_drop_inc(this_cpu_ptr(v->common.cpu_qstats)); + tcf_action_inc_drop_qstats(&v->common); return TC_ACT_SHOT; }
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 26b537a88ca5b7399c7ab0656e06dbd9da9513c1
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Vlad Buslov vladbu@mellanox.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1) 5.10.y | Present (exact SHA1)
Note: Could not generate a diff with upstream commit: --- Note: Could not generate diff - patch failed to apply for comparison ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: Vlad Buslov vladbu@mellanox.com
[ Upstream commit ef816f3c49c1c404ababc50e10d4cbe5109da678 ]
Previous commit introduced helper function for updating qstats and refactored set of actions to use the helpers, instead of modifying qstats directly. However, one of the affected action exposes its qstats to skb_tc_reinsert(), which then modifies it.
Refactor skb_tc_reinsert() to return integer error code and don't increment overlimit qstats in case of error, and use the returned error code in tcf_mirred_act() to manually increment the overlimit counter with new helper function.
Signed-off-by: Vlad Buslov vladbu@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net [ skulkarni: Adjusted patch for file 'sch_generic.h' wrt the mainline commit ] Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- include/net/sch_generic.h | 12 ++---------- net/sched/act_mirred.c | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 6d934ce54c8d..ee47d65b9b20 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1320,17 +1320,9 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc, struct mini_Qdisc __rcu **p_miniq);
-static inline void skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) +static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) { - struct gnet_stats_queue *stats = res->qstats; - int ret; - - if (res->ingress) - ret = netif_receive_skb(skb); - else - ret = dev_queue_xmit(skb); - if (ret && stats) - qstats_overlimit_inc(res->qstats); + return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb); }
/* Make sure qdisc is no longer in SCHED state. */ diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 5602b5de194b..a7e924806c2c 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -295,8 +295,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, /* let's the caller reinsert the packet, if possible */ if (use_reinsert) { res->ingress = want_ingress; - res->qstats = this_cpu_ptr(m->common.cpu_qstats); - skb_tc_reinsert(skb, res); + if (skb_tc_reinsert(skb, res)) + tcf_action_inc_overlimit_qstats(&m->common); __this_cpu_dec(mirred_rec_level); return TC_ACT_CONSUMED; }
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: ef816f3c49c1c404ababc50e10d4cbe5109da678
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Vlad Buslov vladbu@mellanox.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1) 5.10.y | Present (exact SHA1)
Note: The patch differs from the upstream commit: --- 1: ef816f3c49c1 ! 1: 6b25ed64fd0d net: sched: don't expose action qstats to skb_tc_reinsert() @@ Metadata ## Commit message ## net: sched: don't expose action qstats to skb_tc_reinsert()
+ [ Upstream commit ef816f3c49c1c404ababc50e10d4cbe5109da678 ] + Previous commit introduced helper function for updating qstats and refactored set of actions to use the helpers, instead of modifying qstats directly. However, one of the affected action exposes its qstats to @@ Commit message Signed-off-by: Vlad Buslov vladbu@mellanox.com Acked-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net + [ skulkarni: Adjusted patch for file 'sch_generic.h' wrt the mainline commit ] + Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") + Signed-off-by: Shubham Kulkarni skulkarni@mvista.com
## include/net/sch_generic.h ## @@ include/net/sch_generic.h: void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, @@ include/net/sch_generic.h: void mini_qdisc_pair_swap(struct mini_Qdisc_pair *min + return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb); }
- #endif + /* Make sure qdisc is no longer in SCHED state. */
## net/sched/act_mirred.c ## @@ net/sched/act_mirred.c: static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: Jiri Pirko jiri@mellanox.com
[ Upstream commit 075c8aa79d541ea08c67a2e6d955f6457e98c21c ]
Add test for matchall classifier with mirred egress mirror action.
Signed-off-by: Jiri Pirko jiri@mellanox.com Signed-off-by: Ido Schimmel idosch@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- .../selftests/net/forwarding/tc_actions.sh | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh index 813d02d1939d..d9eca227136b 100755 --- a/tools/testing/selftests/net/forwarding/tc_actions.sh +++ b/tools/testing/selftests/net/forwarding/tc_actions.sh @@ -2,7 +2,8 @@ # SPDX-License-Identifier: GPL-2.0
ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \ - mirred_egress_mirror_test gact_trap_test" + mirred_egress_mirror_test matchall_mirred_egress_mirror_test \ + gact_trap_test" NUM_NETIFS=4 source tc_common.sh source lib.sh @@ -50,6 +51,9 @@ switch_destroy() mirred_egress_test() { local action=$1 + local protocol=$2 + local classifier=$3 + local classifier_args=$4
RET=0
@@ -62,9 +66,9 @@ mirred_egress_test() tc_check_packets "dev $h2 ingress" 101 1 check_fail $? "Matched without redirect rule inserted"
- tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \ - $tcflags dst_ip 192.0.2.2 action mirred egress $action \ - dev $swp2 + tc filter add dev $swp1 ingress protocol $protocol pref 1 handle 101 \ + $classifier $tcflags $classifier_args \ + action mirred egress $action dev $swp2
$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ -t ip -q @@ -72,10 +76,11 @@ mirred_egress_test() tc_check_packets "dev $h2 ingress" 101 1 check_err $? "Did not match incoming $action packet"
- tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower + tc filter del dev $swp1 ingress protocol $protocol pref 1 handle 101 \ + $classifier tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
- log_test "mirred egress $action ($tcflags)" + log_test "mirred egress $classifier $action ($tcflags)" }
gact_drop_and_ok_test() @@ -187,12 +192,17 @@ cleanup()
mirred_egress_redirect_test() { - mirred_egress_test "redirect" + mirred_egress_test "redirect" "ip" "flower" "dst_ip 192.0.2.2" }
mirred_egress_mirror_test() { - mirred_egress_test "mirror" + mirred_egress_test "mirror" "ip" "flower" "dst_ip 192.0.2.2" +} + +matchall_mirred_egress_mirror_test() +{ + mirred_egress_test "mirror" "all" "matchall" "" }
trap cleanup EXIT
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 075c8aa79d541ea08c67a2e6d955f6457e98c21c
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Jiri Pirko jiri@mellanox.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1) 5.10.y | Present (exact SHA1)
Note: The patch differs from the upstream commit: --- 1: 075c8aa79d54 ! 1: 95b6e294fcde selftests: forwarding: tc_actions.sh: add matchall mirror test @@ Metadata ## Commit message ## selftests: forwarding: tc_actions.sh: add matchall mirror test
+ [ Upstream commit 075c8aa79d541ea08c67a2e6d955f6457e98c21c ] + Add test for matchall classifier with mirred egress mirror action.
Signed-off-by: Jiri Pirko jiri@mellanox.com Signed-off-by: Ido Schimmel idosch@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net + Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") + Signed-off-by: Shubham Kulkarni skulkarni@mvista.com
## tools/testing/selftests/net/forwarding/tc_actions.sh ## @@
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: wenxu wenxu@ucloud.cn
[ Upstream commit fa6d639930ee5cd3f932cc314f3407f07a06582d ]
This one is prepare for the next patch.
Signed-off-by: wenxu wenxu@ucloud.cn Signed-off-by: Jakub Kicinski kuba@kernel.org [ skulkarni: Adjusted patch for file 'sch_generic.h' wrt the mainline commit ] Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- include/net/sch_generic.h | 5 ----- net/sched/act_mirred.c | 21 +++++++++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index ee47d65b9b20..a9a68714b58f 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1320,11 +1320,6 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc, struct mini_Qdisc __rcu **p_miniq);
-static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) -{ - return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb); -} - /* Make sure qdisc is no longer in SCHED state. */ static inline void qdisc_synchronize(const struct Qdisc *q) { diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index a7e924806c2c..9e094c984217 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -206,6 +206,18 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, return err; }
+static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb) +{ + int err; + + if (!want_ingress) + err = dev_queue_xmit(skb); + else + err = netif_receive_skb(skb); + + return err; +} + static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { @@ -295,18 +307,15 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, /* let's the caller reinsert the packet, if possible */ if (use_reinsert) { res->ingress = want_ingress; - if (skb_tc_reinsert(skb, res)) + err = tcf_mirred_forward(res->ingress, skb); + if (err) tcf_action_inc_overlimit_qstats(&m->common); __this_cpu_dec(mirred_rec_level); return TC_ACT_CONSUMED; } }
- if (!want_ingress) - err = dev_queue_xmit(skb2); - else - err = netif_receive_skb(skb2); - + err = tcf_mirred_forward(want_ingress, skb2); if (err) { out: tcf_action_inc_overlimit_qstats(&m->common);
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: fa6d639930ee5cd3f932cc314f3407f07a06582d
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: wenxu wenxu@ucloud.cn
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1) 5.10.y | Present (different SHA1: bba7ebe10baf)
Note: Could not generate a diff with upstream commit: --- Note: Could not generate diff - patch failed to apply for comparison ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: Davide Caratti dcaratti@redhat.com
[ Upstream commit 78dcdffe0418ac8f3f057f26fe71ccf4d8ed851f ]
with commit e2ca070f89ec ("net: sched: protect against stack overflow in TC act_mirred"), act_mirred protected itself against excessive stack growth using per_cpu counter of nested calls to tcf_mirred_act(), and capping it to MIRRED_RECURSION_LIMIT. However, such protection does not detect recursion/loops in case the packet is enqueued to the backlog (for example, when the mirred target device has RPS or skb timestamping enabled). Change the wording from "recursion" to "nesting" to make it more clear to readers.
CC: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Davide Caratti dcaratti@redhat.com Reviewed-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Paolo Abeni pabeni@redhat.com [ skulkarni: Adjusted patch for file 'act_mirred.c' - hunk #4/4 wrt the mainline commit ] Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- net/sched/act_mirred.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9e094c984217..5181eac5860e 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -28,8 +28,8 @@ static LIST_HEAD(mirred_list); static DEFINE_SPINLOCK(mirred_list_lock);
-#define MIRRED_RECURSION_LIMIT 4 -static DEFINE_PER_CPU(unsigned int, mirred_rec_level); +#define MIRRED_NEST_LIMIT 4 +static DEFINE_PER_CPU(unsigned int, mirred_nest_level);
static bool tcf_mirred_is_act_redirect(int action) { @@ -225,7 +225,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, struct sk_buff *skb2 = skb; bool m_mac_header_xmit; struct net_device *dev; - unsigned int rec_level; + unsigned int nest_level; int retval, err = 0; bool use_reinsert; bool want_ingress; @@ -236,11 +236,11 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, int mac_len; bool at_nh;
- rec_level = __this_cpu_inc_return(mirred_rec_level); - if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) { + nest_level = __this_cpu_inc_return(mirred_nest_level); + if (unlikely(nest_level > MIRRED_NEST_LIMIT)) { net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n", netdev_name(skb->dev)); - __this_cpu_dec(mirred_rec_level); + __this_cpu_dec(mirred_nest_level); return TC_ACT_SHOT; }
@@ -310,7 +310,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, err = tcf_mirred_forward(res->ingress, skb); if (err) tcf_action_inc_overlimit_qstats(&m->common); - __this_cpu_dec(mirred_rec_level); + __this_cpu_dec(mirred_nest_level); return TC_ACT_CONSUMED; } } @@ -322,7 +322,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, if (tcf_mirred_is_act_redirect(m_eaction)) retval = TC_ACT_SHOT; } - __this_cpu_dec(mirred_rec_level); + __this_cpu_dec(mirred_nest_level);
return retval; }
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 78dcdffe0418ac8f3f057f26fe71ccf4d8ed851f
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Davide Caratti dcaratti@redhat.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (different SHA1: e0c12b9bfffc) 5.15.y | Present (different SHA1: 5b347652aebd) 5.10.y | Present (different SHA1: f5bf8e3ca13e)
Note: Could not generate a diff with upstream commit: --- Note: Could not generate diff - patch failed to apply for comparison ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
From: Davide Caratti dcaratti@redhat.com
[ Upstream commit ca22da2fbd693b54dc8e3b7b54ccc9f7e9ba3640 ]
William reports kernel soft-lockups on some OVS topologies when TC mirred egress->ingress action is hit by local TCP traffic [1]. The same can also be reproduced with SCTP (thanks Xin for verifying), when client and server reach themselves through mirred egress to ingress, and one of the two peers sends a "heartbeat" packet (from within a timer).
Enqueueing to backlog proved to fix this soft lockup; however, as Cong noticed [2], we should preserve - when possible - the current mirred behavior that counts as "overlimits" any eventual packet drop subsequent to the mirred forwarding action [3]. A compromise solution might use the backlog only when tcf_mirred_act() has a nest level greater than one: change tcf_mirred_forward() accordingly.
Also, add a kselftest that can reproduce the lockup and verifies TC mirred ability to account for further packet drops after TC mirred egress->ingress (when the nest level is 1).
[1] https://lore.kernel.org/netdev/33dc43f587ec1388ba456b4915c75f02a8aae226.1663... [2] https://lore.kernel.org/netdev/Y0w%2FWWY60gqrtGLp@pop-os.localdomain/ [3] such behavior is not guaranteed: for example, if RPS or skb RX timestamping is enabled on the mirred target device, the kernel can defer receiving the skb and return NET_RX_SUCCESS inside tcf_mirred_forward().
Reported-by: William Zhao wizhao@redhat.com CC: Xin Long lucien.xin@gmail.com Signed-off-by: Davide Caratti dcaratti@redhat.com Reviewed-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Paolo Abeni pabeni@redhat.com [ skulkarni: Adjusted patch for file 'tc_actions.sh' wrt the mainline commit ] Signed-off-by: Shubham Kulkarni skulkarni@mvista.com --- net/sched/act_mirred.c | 7 +++ .../selftests/net/forwarding/tc_actions.sh | 48 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 5181eac5860e..f1392de686ba 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -206,12 +206,19 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, return err; }
+static bool is_mirred_nested(void) +{ + return unlikely(__this_cpu_read(mirred_nest_level) > 1); +} + static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb) { int err;
if (!want_ingress) err = dev_queue_xmit(skb); + else if (is_mirred_nested()) + err = netif_rx(skb); else err = netif_receive_skb(skb);
diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh index d9eca227136b..1e27031288c8 100755 --- a/tools/testing/selftests/net/forwarding/tc_actions.sh +++ b/tools/testing/selftests/net/forwarding/tc_actions.sh @@ -3,7 +3,7 @@
ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \ mirred_egress_mirror_test matchall_mirred_egress_mirror_test \ - gact_trap_test" + gact_trap_test mirred_egress_to_ingress_tcp_test" NUM_NETIFS=4 source tc_common.sh source lib.sh @@ -153,6 +153,52 @@ gact_trap_test() log_test "trap ($tcflags)" }
+mirred_egress_to_ingress_tcp_test() +{ + local tmpfile=$(mktemp) tmpfile1=$(mktemp) + + RET=0 + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile + tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \ + $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \ + action ct commit nat src addr 192.0.2.2 pipe \ + action ct clear pipe \ + action ct commit nat dst addr 192.0.2.1 pipe \ + action ct clear pipe \ + action skbedit ptype host pipe \ + action mirred ingress redirect dev $h1 + tc filter add dev $h1 protocol ip pref 101 handle 101 egress flower \ + $tcflags ip_proto icmp \ + action mirred ingress redirect dev $h1 + tc filter add dev $h1 protocol ip pref 102 handle 102 ingress flower \ + ip_proto icmp \ + action drop + + ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 & + local rpid=$! + ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile + wait -n $rpid + cmp -s $tmpfile $tmpfile1 + check_err $? "server output check failed" + + $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \ + -t icmp "ping,id=42,seq=5" -q + tc_check_packets "dev $h1 egress" 101 10 + check_err $? "didn't mirred redirect ICMP" + tc_check_packets "dev $h1 ingress" 102 10 + check_err $? "didn't drop mirred ICMP" + local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits) + test ${overlimits} = 10 + check_err $? "wrong overlimits, expected 10 got ${overlimits}" + + tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower + tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower + tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower + + rm -f $tmpfile $tmpfile1 + log_test "mirred_egress_to_ingress_tcp ($tcflags)" +} + setup_prepare() { h1=${NETIFS[p1]}
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues: ℹ️ This is part 8/8 of a series ⚠️ Found follow-up fixes in mainline
The upstream commit SHA1 provided is correct: ca22da2fbd693b54dc8e3b7b54ccc9f7e9ba3640
WARNING: Author mismatch between patch and upstream commit: Backport author: skulkarni@mvista.com Commit author: Davide Caratti dcaratti@redhat.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (different SHA1: 4c8fc3fe28e4) 5.15.y | Present (different SHA1: 169a41073993) 5.10.y | Present (different SHA1: 532451037863)
Found fixes commits: 5e8670610b93 selftests: forwarding: tc_actions: Use ncat instead of nc
Note: Could not generate a diff with upstream commit: --- Note: Could not generate diff - patch failed to apply for comparison ---
NOTE: These results are for this patch alone. Full series testing will be performed when all parts are received.
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | 5.4 | Success | Success |
linux-stable-mirror@lists.linaro.org