Commit 8267fc71 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Alexei Starovoitov

veth: take into account peer device for NETDEV_XDP_ACT_NDO_XMIT xdp_features flag

For veth pairs, NETDEV_XDP_ACT_NDO_XMIT is supported by the current
device if the peer one is running a XDP program or if it has GRO enabled.
Fix the xdp_features flags reporting considering peer device and not
current one for NETDEV_XDP_ACT_NDO_XMIT.

Fixes: fccca038 ("veth: take into account device reconfiguration for xdp_features flag")
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/4f1ca6f6f6b42ae125bfdb5c7782217c83968b2e.1681767806.git.lorenzo@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent c730fce7
...@@ -1262,11 +1262,12 @@ static void veth_set_xdp_features(struct net_device *dev) ...@@ -1262,11 +1262,12 @@ static void veth_set_xdp_features(struct net_device *dev)
peer = rtnl_dereference(priv->peer); peer = rtnl_dereference(priv->peer);
if (peer && peer->real_num_tx_queues <= dev->real_num_rx_queues) { if (peer && peer->real_num_tx_queues <= dev->real_num_rx_queues) {
struct veth_priv *priv_peer = netdev_priv(peer);
xdp_features_t val = NETDEV_XDP_ACT_BASIC | xdp_features_t val = NETDEV_XDP_ACT_BASIC |
NETDEV_XDP_ACT_REDIRECT | NETDEV_XDP_ACT_REDIRECT |
NETDEV_XDP_ACT_RX_SG; NETDEV_XDP_ACT_RX_SG;
if (priv->_xdp_prog || veth_gro_requested(dev)) if (priv_peer->_xdp_prog || veth_gro_requested(peer))
val |= NETDEV_XDP_ACT_NDO_XMIT | val |= NETDEV_XDP_ACT_NDO_XMIT |
NETDEV_XDP_ACT_NDO_XMIT_SG; NETDEV_XDP_ACT_NDO_XMIT_SG;
xdp_set_features_flag(dev, val); xdp_set_features_flag(dev, val);
...@@ -1504,19 +1505,23 @@ static int veth_set_features(struct net_device *dev, ...@@ -1504,19 +1505,23 @@ static int veth_set_features(struct net_device *dev,
{ {
netdev_features_t changed = features ^ dev->features; netdev_features_t changed = features ^ dev->features;
struct veth_priv *priv = netdev_priv(dev); struct veth_priv *priv = netdev_priv(dev);
struct net_device *peer;
int err; int err;
if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog) if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog)
return 0; return 0;
peer = rtnl_dereference(priv->peer);
if (features & NETIF_F_GRO) { if (features & NETIF_F_GRO) {
err = veth_napi_enable(dev); err = veth_napi_enable(dev);
if (err) if (err)
return err; return err;
xdp_features_set_redirect_target(dev, true); if (peer)
xdp_features_set_redirect_target(peer, true);
} else { } else {
xdp_features_clear_redirect_target(dev); if (peer)
xdp_features_clear_redirect_target(peer);
veth_napi_del(dev); veth_napi_del(dev);
} }
return 0; return 0;
...@@ -1598,13 +1603,13 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, ...@@ -1598,13 +1603,13 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
peer->max_mtu = max_mtu; peer->max_mtu = max_mtu;
} }
xdp_features_set_redirect_target(dev, true); xdp_features_set_redirect_target(peer, true);
} }
if (old_prog) { if (old_prog) {
if (!prog) { if (!prog) {
if (!veth_gro_requested(dev)) if (peer && !veth_gro_requested(dev))
xdp_features_clear_redirect_target(dev); xdp_features_clear_redirect_target(peer);
if (dev->flags & IFF_UP) if (dev->flags & IFF_UP)
veth_disable_xdp(dev); veth_disable_xdp(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment