net/sched: act_mirred: Fix return code in early mirred redirect error paths
Since retval is set as TC_ACT_STOLEN in the mirred redirect case, returning
retval in cases where redirect failed will make the callers not register
the skb as being dropped.
Fix this by returning TC_ACT_SHOT instead in such scenarios.
Fixes: 16085e48cb ("net/sched: act_mirred: Create function tcf_mirred_to_dev and improve readability")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260413082027.2244884-1-hxzene%40gmail.com
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/20260525122556.973584-8-jhs@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
master
parent
a005fa5d75
commit
e80ad525fc
|
|
@ -372,7 +372,8 @@ assign_prev:
|
||||||
dev_is_mac_header_xmit(dev_prev),
|
dev_is_mac_header_xmit(dev_prev),
|
||||||
m_eaction, retval);
|
m_eaction, retval);
|
||||||
|
|
||||||
return retval;
|
/* If the packet wasn't redirected, we have to register as a drop */
|
||||||
|
return TC_ACT_SHOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcf_blockcast_mirror(struct sk_buff *skb, struct tcf_mirred *m,
|
static int tcf_blockcast_mirror(struct sk_buff *skb, struct tcf_mirred *m,
|
||||||
|
|
@ -410,7 +411,7 @@ static int tcf_blockcast(struct sk_buff *skb, struct tcf_mirred *m,
|
||||||
block = tcf_block_lookup(dev_net(skb->dev), blockid);
|
block = tcf_block_lookup(dev_net(skb->dev), blockid);
|
||||||
if (!block || xa_empty(&block->ports)) {
|
if (!block || xa_empty(&block->ports)) {
|
||||||
tcf_action_inc_overlimit_qstats(&m->common);
|
tcf_action_inc_overlimit_qstats(&m->common);
|
||||||
return retval;
|
return is_redirect ? TC_ACT_SHOT : retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_redirect)
|
if (is_redirect)
|
||||||
|
|
@ -428,8 +429,8 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
struct tcf_mirred *m = to_mirred(a);
|
struct tcf_mirred *m = to_mirred(a);
|
||||||
int retval = READ_ONCE(m->tcf_action);
|
int retval = READ_ONCE(m->tcf_action);
|
||||||
|
bool m_mac_header_xmit, is_redirect;
|
||||||
struct netdev_xmit *xmit;
|
struct netdev_xmit *xmit;
|
||||||
bool m_mac_header_xmit;
|
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
bool want_ingress;
|
bool want_ingress;
|
||||||
int i, m_eaction;
|
int i, m_eaction;
|
||||||
|
|
@ -462,11 +463,13 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_redirect = tcf_mirred_is_act_redirect(m_eaction);
|
||||||
|
|
||||||
dev = rcu_dereference_bh(m->tcfm_dev);
|
dev = rcu_dereference_bh(m->tcfm_dev);
|
||||||
if (unlikely(!dev)) {
|
if (unlikely(!dev)) {
|
||||||
pr_notice_once("tc mirred: target device is gone\n");
|
pr_notice_once("tc mirred: target device is gone\n");
|
||||||
tcf_action_inc_overlimit_qstats(&m->common);
|
tcf_action_inc_overlimit_qstats(&m->common);
|
||||||
return retval;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!want_ingress) {
|
if (!want_ingress) {
|
||||||
|
|
@ -476,7 +479,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
|
||||||
pr_notice_once("tc mirred: loop on device %s\n",
|
pr_notice_once("tc mirred: loop on device %s\n",
|
||||||
netdev_name(dev));
|
netdev_name(dev));
|
||||||
tcf_action_inc_overlimit_qstats(&m->common);
|
tcf_action_inc_overlimit_qstats(&m->common);
|
||||||
return retval;
|
goto err_out;
|
||||||
}
|
}
|
||||||
xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
|
xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
|
||||||
}
|
}
|
||||||
|
|
@ -489,6 +492,11 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
|
||||||
xmit->sched_mirred_nest--;
|
xmit->sched_mirred_nest--;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
if (is_redirect)
|
||||||
|
retval = TC_ACT_SHOT;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
|
static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue