Implement tx checksum kfunc for veth by checksumming the packet in software (since there is nothing to offload). The change mostly exists to make it possible to have software-based selftest. Probably should instead set csum_start/csum_offset on the skb itself? Signed-off-by: Stanislav Fomichev <sdf@xxxxxxxxxx> --- drivers/net/veth.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 5af4b15e107c..6f97511a545b 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -1814,6 +1814,34 @@ static int veth_devtx_tx_timestamp(const struct devtx_ctx *_ctx, u64 *timestamp) return 0; } +static int veth_devtx_request_l4_csum(const struct devtx_ctx *_ctx, + u16 csum_start, u16 csum_offset) +{ + struct veth_devtx_ctx *ctx = (struct veth_devtx_ctx *)_ctx; + struct sk_buff *skb = ctx->skb; + __wsum csum; + int ret; + + if (!skb) + return -EINVAL; + + if (skb_transport_header_was_set(skb)) + return -EINVAL; + + if (csum_start >= skb->len) + return -EINVAL; + + ret = skb_ensure_writable(skb, csum_offset + sizeof(__sum16)); + if (ret) + return ret; + + csum = csum_partial(skb->data + csum_start, skb->len - csum_start, 0); + *(__sum16 *)(skb->data + csum_offset) = csum_fold(csum) ?: CSUM_MANGLED_0; + skb->ip_summed = CHECKSUM_UNNECESSARY; + + return 0; +} + static const struct net_device_ops veth_netdev_ops = { .ndo_init = veth_dev_init, .ndo_open = veth_open, @@ -1840,6 +1868,7 @@ static const struct xdp_metadata_ops veth_xdp_metadata_ops = { .xmo_rx_hash = veth_xdp_rx_hash, .xmo_request_tx_timestamp = veth_devtx_request_tx_timestamp, .xmo_tx_timestamp = veth_devtx_tx_timestamp, + .xmo_request_l4_checksum = veth_devtx_request_l4_csum, }; #define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \ -- 2.41.0.255.g8b1d071c50-goog