Skip to content

Commit 2d12a0d

Browse files
LorenzoBianconiNobody
authored and
Nobody
committed
veth: allow jumbo frames in xdp mode
Allow increasing the MTU over page boundaries on veth devices if the attached xdp program declares to support xdp fragments. Enable NETIF_F_ALL_TSO when the device is running in xdp mode. Signed-off-by: Lorenzo Bianconi <[email protected]>
1 parent 7fdd12e commit 2d12a0d

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

drivers/net/veth.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -293,20 +293,21 @@ static int veth_forward_skb(struct net_device *dev, struct sk_buff *skb,
293293
/* return true if the specified skb has chances of GRO aggregation
294294
* Don't strive for accuracy, but try to avoid GRO overhead in the most
295295
* common scenarios.
296-
* When XDP is enabled, all traffic is considered eligible, as the xmit
297-
* device has TSO off.
296+
* When XDP is enabled, all traffic is considered eligible.
298297
* When TSO is enabled on the xmit device, we are likely interested only
299298
* in UDP aggregation, explicitly check for that if the skb is suspected
300299
* - the sock_wfree destructor is used by UDP, ICMP and XDP sockets -
301300
* to belong to locally generated UDP traffic.
302301
*/
303302
static bool veth_skb_is_eligible_for_gro(const struct net_device *dev,
304303
const struct net_device *rcv,
304+
const struct veth_rq *rq,
305305
const struct sk_buff *skb)
306306
{
307-
return !(dev->features & NETIF_F_ALL_TSO) ||
308-
(skb->destructor == sock_wfree &&
309-
rcv->features & (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD));
307+
return rcu_access_pointer(rq->xdp_prog) ||
308+
!(dev->features & NETIF_F_ALL_TSO) ||
309+
(skb->destructor == sock_wfree &&
310+
rcv->features & (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD));
310311
}
311312

312313
static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -335,7 +336,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
335336
* Don't bother with napi/GRO if the skb can't be aggregated
336337
*/
337338
use_napi = rcu_access_pointer(rq->napi) &&
338-
veth_skb_is_eligible_for_gro(dev, rcv, skb);
339+
veth_skb_is_eligible_for_gro(dev, rcv, rq, skb);
339340
}
340341

341342
skb_tx_timestamp(skb);
@@ -1525,9 +1526,14 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15251526
goto err;
15261527
}
15271528

1528-
max_mtu = PAGE_SIZE - VETH_XDP_HEADROOM -
1529-
peer->hard_header_len -
1530-
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
1529+
max_mtu = SKB_WITH_OVERHEAD(PAGE_SIZE - VETH_XDP_HEADROOM) -
1530+
peer->hard_header_len;
1531+
/* Allow increasing the max_mtu if the program supports
1532+
* XDP fragments.
1533+
*/
1534+
if (prog->aux->xdp_has_frags)
1535+
max_mtu += PAGE_SIZE * MAX_SKB_FRAGS;
1536+
15311537
if (peer->mtu > max_mtu) {
15321538
NL_SET_ERR_MSG_MOD(extack, "Peer MTU is too large to set XDP");
15331539
err = -ERANGE;
@@ -1549,7 +1555,7 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15491555
}
15501556

15511557
if (!old_prog) {
1552-
peer->hw_features &= ~NETIF_F_GSO_SOFTWARE;
1558+
peer->hw_features &= ~NETIF_F_GSO_FRAGLIST;
15531559
peer->max_mtu = max_mtu;
15541560
}
15551561
}
@@ -1560,7 +1566,7 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15601566
veth_disable_xdp(dev);
15611567

15621568
if (peer) {
1563-
peer->hw_features |= NETIF_F_GSO_SOFTWARE;
1569+
peer->hw_features |= NETIF_F_GSO_FRAGLIST;
15641570
peer->max_mtu = ETH_MAX_MTU;
15651571
}
15661572
}

0 commit comments

Comments
 (0)