dev_is_mac_header_xmit(dev_prev),
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,
block = tcf_block_lookup(dev_net(skb->dev), blockid);
if (!block || xa_empty(&block->ports)) {
tcf_action_inc_overlimit_qstats(&m->common);
- return retval;
+ return is_redirect ? TC_ACT_SHOT : retval;
}
if (is_redirect)
{
struct tcf_mirred *m = to_mirred(a);
int retval = READ_ONCE(m->tcf_action);
+ bool m_mac_header_xmit, is_redirect;
struct netdev_xmit *xmit;
- bool m_mac_header_xmit;
struct net_device *dev;
bool want_ingress;
int i, m_eaction;
return retval;
}
+ is_redirect = tcf_mirred_is_act_redirect(m_eaction);
+
dev = rcu_dereference_bh(m->tcfm_dev);
if (unlikely(!dev)) {
pr_notice_once("tc mirred: target device is gone\n");
tcf_action_inc_overlimit_qstats(&m->common);
- return retval;
+ goto err_out;
}
if (!want_ingress) {
pr_notice_once("tc mirred: loop on device %s\n",
netdev_name(dev));
tcf_action_inc_overlimit_qstats(&m->common);
- return retval;
+ goto err_out;
}
xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
}
xmit->sched_mirred_nest--;
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,