virtio: use the internal hdr offsets of buffer metadata for offloads

Type: improvement

Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Change-Id: Ie63c360f2e42e9e5799f5c536453823ea95ed3b8
This commit is contained in:
Mohsin Kazmi 2022-05-18 16:51:57 +00:00 committed by Beno�t Ganne
parent cada9eb789
commit 096c8cc680
2 changed files with 23 additions and 39 deletions

View File

@ -294,17 +294,14 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr,
if (b->flags & VNET_BUFFER_F_IS_IP4)
{
ip4_header_t *ip4;
generic_header_offset_t gho = { 0 };
vnet_generic_header_offset_parser (b, &gho, is_l2, 1 /* ip4 */ ,
0 /* ip6 */ );
hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
hdr->csum_start = gho.l4_hdr_offset; // 0x22;
hdr->csum_start = vnet_buffer (b)->l4_hdr_offset; // 0x22;
/*
* virtio devices do not support IP4 checksum offload. So driver takes
* care of it while doing tx.
*/
ip4 = (ip4_header_t *) (vlib_buffer_get_current (b) + gho.l3_hdr_offset);
ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
if (oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM)
ip4->checksum = ip4_header_checksum (ip4);
@ -315,14 +312,14 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr,
if (oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM)
{
tcp_header_t *tcp =
(tcp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
(tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
tcp->checksum = ip4_pseudo_header_cksum (ip4);
hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
}
else if (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM)
{
udp_header_t *udp =
(udp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
(udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
udp->checksum = ip4_pseudo_header_cksum (ip4);
hdr->csum_offset = STRUCT_OFFSET_OF (udp_header_t, checksum);
}
@ -330,12 +327,9 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr,
else if (b->flags & VNET_BUFFER_F_IS_IP6)
{
ip6_header_t *ip6;
generic_header_offset_t gho = { 0 };
vnet_generic_header_offset_parser (b, &gho, is_l2, 0 /* ip4 */ ,
1 /* ip6 */ );
hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
hdr->csum_start = gho.l4_hdr_offset; // 0x36;
ip6 = (ip6_header_t *) (vlib_buffer_get_current (b) + gho.l3_hdr_offset);
hdr->csum_start = vnet_buffer (b)->l4_hdr_offset; // 0x36;
ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
/*
* virtio devices assume the l4 header is set to the checksum of the
@ -344,14 +338,14 @@ set_checksum_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr,
if (oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM)
{
tcp_header_t *tcp =
(tcp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
(tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
tcp->checksum = ip6_pseudo_header_cksum (ip6);
hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
}
else if (oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM)
{
udp_header_t *udp =
(udp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
(udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
udp->checksum = ip6_pseudo_header_cksum (ip6);
hdr->csum_offset = STRUCT_OFFSET_OF (udp_header_t, checksum);
}
@ -367,17 +361,15 @@ set_gso_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr,
if (b->flags & VNET_BUFFER_F_IS_IP4)
{
ip4_header_t *ip4;
generic_header_offset_t gho = { 0 };
vnet_generic_header_offset_parser (b, &gho, is_l2, 1 /* ip4 */ ,
0 /* ip6 */ );
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
hdr->gso_size = vnet_buffer2 (b)->gso_size;
hdr->hdr_len = gho.hdr_sz;
hdr->hdr_len = vnet_buffer (b)->l4_hdr_offset -
vnet_buffer (b)->l2_hdr_offset +
vnet_buffer2 (b)->gso_l4_hdr_sz;
hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
hdr->csum_start = gho.l4_hdr_offset; // 0x22;
hdr->csum_start = vnet_buffer (b)->l4_hdr_offset; // 0x22;
hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
ip4 =
(ip4_header_t *) (vlib_buffer_get_current (b) + gho.l3_hdr_offset);
ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
/*
* virtio devices do not support IP4 checksum offload. So driver takes care
* of it while doing tx.
@ -387,14 +379,13 @@ set_gso_offsets (vlib_buffer_t *b, vnet_virtio_net_hdr_v1_t *hdr,
}
else if (b->flags & VNET_BUFFER_F_IS_IP6)
{
generic_header_offset_t gho = { 0 };
vnet_generic_header_offset_parser (b, &gho, is_l2, 0 /* ip4 */ ,
1 /* ip6 */ );
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
hdr->gso_size = vnet_buffer2 (b)->gso_size;
hdr->hdr_len = gho.hdr_sz;
hdr->hdr_len = vnet_buffer (b)->l4_hdr_offset -
vnet_buffer (b)->l2_hdr_offset +
vnet_buffer2 (b)->gso_l4_hdr_sz;
hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
hdr->csum_start = gho.l4_hdr_offset; // 0x36;
hdr->csum_start = vnet_buffer (b)->l4_hdr_offset; // 0x36;
hdr->csum_offset = STRUCT_OFFSET_OF (tcp_header_t, checksum);
}
}

View File

@ -91,8 +91,7 @@ virtio_needs_csum (vlib_buffer_t *b0, vnet_virtio_net_hdr_v1_t *hdr,
}
else
{
ethernet_header_t *eh =
(ethernet_header_t *) vlib_buffer_get_current (b0);
ethernet_header_t *eh = (ethernet_header_t *) b0->data;
ethertype = clib_net_to_host_u16 (eh->type);
l2hdr_sz = sizeof (ethernet_header_t);
@ -117,8 +116,7 @@ virtio_needs_csum (vlib_buffer_t *b0, vnet_virtio_net_hdr_v1_t *hdr,
if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP4))
{
ip4_header_t *ip4 =
(ip4_header_t *) (vlib_buffer_get_current (b0) + l2hdr_sz);
ip4_header_t *ip4 = (ip4_header_t *) (b0->data + l2hdr_sz);
vnet_buffer (b0)->l4_hdr_offset = l2hdr_sz + ip4_header_bytes (ip4);
*l4_proto = ip4->protocol;
oflags |= VNET_BUFFER_OFFLOAD_F_IP_CKSUM;
@ -129,8 +127,7 @@ virtio_needs_csum (vlib_buffer_t *b0, vnet_virtio_net_hdr_v1_t *hdr,
}
else if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP6))
{
ip6_header_t *ip6 =
(ip6_header_t *) (vlib_buffer_get_current (b0) + l2hdr_sz);
ip6_header_t *ip6 = (ip6_header_t *) (b0->data + l2hdr_sz);
vnet_buffer (b0)->l4_hdr_offset = l2hdr_sz + sizeof (ip6_header_t);
/* FIXME IPv6 EH traversal */
*l4_proto = ip6->protocol;
@ -142,18 +139,14 @@ virtio_needs_csum (vlib_buffer_t *b0, vnet_virtio_net_hdr_v1_t *hdr,
if (*l4_proto == IP_PROTOCOL_TCP)
{
oflags |= VNET_BUFFER_OFFLOAD_F_TCP_CKSUM;
tcp_header_t *tcp = (tcp_header_t *) (vlib_buffer_get_current (b0) +
vnet_buffer
(b0)->l4_hdr_offset);
tcp_header_t *tcp =
(tcp_header_t *) (b0->data + vnet_buffer (b0)->l4_hdr_offset);
*l4_hdr_sz = tcp_header_bytes (tcp);
}
else if (*l4_proto == IP_PROTOCOL_UDP)
{
oflags |= VNET_BUFFER_OFFLOAD_F_UDP_CKSUM;
udp_header_t *udp = (udp_header_t *) (vlib_buffer_get_current (b0) +
vnet_buffer
(b0)->l4_hdr_offset);
*l4_hdr_sz = sizeof (*udp);
*l4_hdr_sz = sizeof (udp_header_t);
}
if (oflags)
vnet_buffer_offload_flags_set (b0, oflags);