|
@@ -35,6 +35,7 @@ struct pcpu_vstats {
|
|
struct veth_priv {
|
|
struct veth_priv {
|
|
struct net_device __rcu *peer;
|
|
struct net_device __rcu *peer;
|
|
atomic64_t dropped;
|
|
atomic64_t dropped;
|
|
|
|
+ unsigned requested_headroom;
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -271,6 +272,29 @@ static int veth_get_iflink(const struct net_device *dev)
|
|
return iflink;
|
|
return iflink;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void veth_set_rx_headroom(struct net_device *dev, int new_hr)
|
|
|
|
+{
|
|
|
|
+ struct veth_priv *peer_priv, *priv = netdev_priv(dev);
|
|
|
|
+ struct net_device *peer;
|
|
|
|
+
|
|
|
|
+ if (new_hr < 0)
|
|
|
|
+ new_hr = 0;
|
|
|
|
+
|
|
|
|
+ rcu_read_lock();
|
|
|
|
+ peer = rcu_dereference(priv->peer);
|
|
|
|
+ if (unlikely(!peer))
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ peer_priv = netdev_priv(peer);
|
|
|
|
+ priv->requested_headroom = new_hr;
|
|
|
|
+ new_hr = max(priv->requested_headroom, peer_priv->requested_headroom);
|
|
|
|
+ dev->needed_headroom = new_hr;
|
|
|
|
+ peer->needed_headroom = new_hr;
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ rcu_read_unlock();
|
|
|
|
+}
|
|
|
|
+
|
|
static const struct net_device_ops veth_netdev_ops = {
|
|
static const struct net_device_ops veth_netdev_ops = {
|
|
.ndo_init = veth_dev_init,
|
|
.ndo_init = veth_dev_init,
|
|
.ndo_open = veth_open,
|
|
.ndo_open = veth_open,
|
|
@@ -285,6 +309,7 @@ static const struct net_device_ops veth_netdev_ops = {
|
|
#endif
|
|
#endif
|
|
.ndo_get_iflink = veth_get_iflink,
|
|
.ndo_get_iflink = veth_get_iflink,
|
|
.ndo_features_check = passthru_features_check,
|
|
.ndo_features_check = passthru_features_check,
|
|
|
|
+ .ndo_set_rx_headroom = veth_set_rx_headroom,
|
|
};
|
|
};
|
|
|
|
|
|
#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
|
|
#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
|
|
@@ -301,6 +326,7 @@ static void veth_setup(struct net_device *dev)
|
|
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
|
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
|
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
dev->priv_flags |= IFF_NO_QUEUE;
|
|
|
|
+ dev->priv_flags |= IFF_PHONY_HEADROOM;
|
|
|
|
|
|
dev->netdev_ops = &veth_netdev_ops;
|
|
dev->netdev_ops = &veth_netdev_ops;
|
|
dev->ethtool_ops = &veth_ethtool_ops;
|
|
dev->ethtool_ops = &veth_ethtool_ops;
|