forked from luck/tmp_suning_uos_patched
net/sched: act_skbmod: Skip non-Ethernet packets
[ Upstream commit 727d6a8b7ef3d25080fad228b2c4a1d4da5999c6 ]
Currently tcf_skbmod_act() assumes that packets use Ethernet as their L2
protocol, which is not always the case. As an example, for CAN devices:
$ ip link add dev vcan0 type vcan
$ ip link set up vcan0
$ tc qdisc add dev vcan0 root handle 1: htb
$ tc filter add dev vcan0 parent 1: protocol ip prio 10 \
matchall action skbmod swap mac
Doing the above silently corrupts all the packets. Do not perform skbmod
actions for non-Ethernet packets.
Fixes: 86da71b573
("net_sched: Introduce skbmod action")
Reviewed-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
ee36bb4713
commit
071729150b
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
@ -33,6 +34,13 @@ static int tcf_skbmod_act(struct sk_buff *skb, const struct tc_action *a,
|
|||
tcf_lastuse_update(&d->tcf_tm);
|
||||
bstats_cpu_update(this_cpu_ptr(d->common.cpu_bstats), skb);
|
||||
|
||||
action = READ_ONCE(d->tcf_action);
|
||||
if (unlikely(action == TC_ACT_SHOT))
|
||||
goto drop;
|
||||
|
||||
if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
|
||||
return action;
|
||||
|
||||
/* XXX: if you are going to edit more fields beyond ethernet header
|
||||
* (example when you add IP header replacement or vlan swap)
|
||||
* then MAX_EDIT_LEN needs to change appropriately
|
||||
|
@ -41,10 +49,6 @@ static int tcf_skbmod_act(struct sk_buff *skb, const struct tc_action *a,
|
|||
if (unlikely(err)) /* best policy is to drop on the floor */
|
||||
goto drop;
|
||||
|
||||
action = READ_ONCE(d->tcf_action);
|
||||
if (unlikely(action == TC_ACT_SHOT))
|
||||
goto drop;
|
||||
|
||||
p = rcu_dereference_bh(d->skbmod_p);
|
||||
flags = p->flags;
|
||||
if (flags & SKBMOD_F_DMAC)
|
||||
|
|
Loading…
Reference in New Issue
Block a user