Commit fccca038 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Jakub Kicinski

veth: take into account device reconfiguration for xdp_features flag

Take into account tx/rx queues reconfiguration setting device
xdp_features flag. Moreover consider NETIF_F_GRO flag in order to enable
ndo_xdp_xmit callback.

Fixes: 66c0e13a ("drivers: net: turn on XDP features")
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7aa6dc35
...@@ -1257,6 +1257,26 @@ static int veth_enable_range_safe(struct net_device *dev, int start, int end) ...@@ -1257,6 +1257,26 @@ static int veth_enable_range_safe(struct net_device *dev, int start, int end)
return 0; return 0;
} }
static void veth_set_xdp_features(struct net_device *dev)
{
struct veth_priv *priv = netdev_priv(dev);
struct net_device *peer;
peer = rcu_dereference(priv->peer);
if (peer && peer->real_num_tx_queues <= dev->real_num_rx_queues) {
xdp_features_t val = NETDEV_XDP_ACT_BASIC |
NETDEV_XDP_ACT_REDIRECT |
NETDEV_XDP_ACT_RX_SG;
if (priv->_xdp_prog || veth_gro_requested(dev))
val |= NETDEV_XDP_ACT_NDO_XMIT |
NETDEV_XDP_ACT_NDO_XMIT_SG;
xdp_set_features_flag(dev, val);
} else {
xdp_clear_features_flag(dev);
}
}
static int veth_set_channels(struct net_device *dev, static int veth_set_channels(struct net_device *dev,
struct ethtool_channels *ch) struct ethtool_channels *ch)
{ {
...@@ -1323,6 +1343,12 @@ static int veth_set_channels(struct net_device *dev, ...@@ -1323,6 +1343,12 @@ static int veth_set_channels(struct net_device *dev,
if (peer) if (peer)
netif_carrier_on(peer); netif_carrier_on(peer);
} }
/* update XDP supported features */
veth_set_xdp_features(dev);
if (peer)
veth_set_xdp_features(peer);
return err; return err;
revert: revert:
...@@ -1489,7 +1515,10 @@ static int veth_set_features(struct net_device *dev, ...@@ -1489,7 +1515,10 @@ static int veth_set_features(struct net_device *dev,
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);
} else { } else {
xdp_features_clear_redirect_target(dev);
veth_napi_del(dev); veth_napi_del(dev);
} }
return 0; return 0;
...@@ -1570,10 +1599,15 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, ...@@ -1570,10 +1599,15 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
peer->hw_features &= ~NETIF_F_GSO_SOFTWARE; peer->hw_features &= ~NETIF_F_GSO_SOFTWARE;
peer->max_mtu = max_mtu; peer->max_mtu = max_mtu;
} }
xdp_features_set_redirect_target(dev, true);
} }
if (old_prog) { if (old_prog) {
if (!prog) { if (!prog) {
if (!veth_gro_requested(dev))
xdp_features_clear_redirect_target(dev);
if (dev->flags & IFF_UP) if (dev->flags & IFF_UP)
veth_disable_xdp(dev); veth_disable_xdp(dev);
...@@ -1686,10 +1720,6 @@ static void veth_setup(struct net_device *dev) ...@@ -1686,10 +1720,6 @@ static void veth_setup(struct net_device *dev)
dev->hw_enc_features = VETH_FEATURES; dev->hw_enc_features = VETH_FEATURES;
dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE; dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
netif_set_tso_max_size(dev, GSO_MAX_SIZE); netif_set_tso_max_size(dev, GSO_MAX_SIZE);
dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
NETDEV_XDP_ACT_NDO_XMIT_SG;
} }
/* /*
...@@ -1857,6 +1887,10 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, ...@@ -1857,6 +1887,10 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
goto err_queues; goto err_queues;
veth_disable_gro(dev); veth_disable_gro(dev);
/* update XDP supported features */
veth_set_xdp_features(dev);
veth_set_xdp_features(peer);
return 0; return 0;
err_queues: err_queues:
......
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