xdp: XDP_REDIRECT should check IFF_UP and MTU
Otherwise we end up with attempting to send packets from down devices
or to send oversized packets, which may cause unexpected driver/device
behaviour. Generic XDP has already done this check, so reuse the logic
in native XDP.
Fixes: 814abfabef
("xdp: add bpf_redirect helper function")
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
4fb126cbcb
Коммит
d8d7218ad8
|
@ -765,8 +765,8 @@ static inline bool bpf_dump_raw_ok(void)
|
|||
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
|
||||
const struct bpf_insn *patch, u32 len);
|
||||
|
||||
static inline int __xdp_generic_ok_fwd_dev(struct sk_buff *skb,
|
||||
struct net_device *fwd)
|
||||
static inline int xdp_ok_fwd_dev(const struct net_device *fwd,
|
||||
unsigned int pktlen)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
|
@ -774,7 +774,7 @@ static inline int __xdp_generic_ok_fwd_dev(struct sk_buff *skb,
|
|||
return -ENETDOWN;
|
||||
|
||||
len = fwd->mtu + fwd->hard_header_len + VLAN_HLEN;
|
||||
if (skb->len > len)
|
||||
if (pktlen > len)
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -334,10 +334,15 @@ int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_buff *xdp,
|
|||
{
|
||||
struct net_device *dev = dst->dev;
|
||||
struct xdp_frame *xdpf;
|
||||
int err;
|
||||
|
||||
if (!dev->netdev_ops->ndo_xdp_xmit)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = xdp_ok_fwd_dev(dev, xdp->data_end - xdp->data);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
xdpf = convert_to_xdp_frame(xdp);
|
||||
if (unlikely(!xdpf))
|
||||
return -EOVERFLOW;
|
||||
|
@ -350,7 +355,7 @@ int dev_map_generic_redirect(struct bpf_dtab_netdev *dst, struct sk_buff *skb,
|
|||
{
|
||||
int err;
|
||||
|
||||
err = __xdp_generic_ok_fwd_dev(skb, dst->dev);
|
||||
err = xdp_ok_fwd_dev(dst->dev, skb->len);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
skb->dev = dst->dev;
|
||||
|
|
|
@ -3128,12 +3128,16 @@ static int __bpf_tx_xdp(struct net_device *dev,
|
|||
u32 index)
|
||||
{
|
||||
struct xdp_frame *xdpf;
|
||||
int sent;
|
||||
int err, sent;
|
||||
|
||||
if (!dev->netdev_ops->ndo_xdp_xmit) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = xdp_ok_fwd_dev(dev, xdp->data_end - xdp->data);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
xdpf = convert_to_xdp_frame(xdp);
|
||||
if (unlikely(!xdpf))
|
||||
return -EOVERFLOW;
|
||||
|
@ -3367,7 +3371,8 @@ int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (unlikely((err = __xdp_generic_ok_fwd_dev(skb, fwd))))
|
||||
err = xdp_ok_fwd_dev(fwd, skb->len);
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
||||
skb->dev = fwd;
|
||||
|
|
Загрузка…
Ссылка в новой задаче