{
int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4;
u32 tso = b->flags & VNET_BUFFER_F_GSO, max_pkt_len;
- u32 ip_cksum, tcp_cksum, udp_cksum;
+ u32 ip_cksum, tcp_cksum, udp_cksum, outer_hdr_len = 0;
+ u32 outer_ip_cksum, vxlan_tunnel;
u64 ol_flags;
vnet_buffer_oflags_t oflags = 0;
ip_cksum = oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM;
tcp_cksum = oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM;
udp_cksum = oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM;
+ outer_ip_cksum = oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM;
+ vxlan_tunnel = oflags & VNET_BUFFER_OFFLOAD_F_TNL_VXLAN;
- mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data;
- mb->l3_len = vnet_buffer (b)->l4_hdr_offset -
- vnet_buffer (b)->l3_hdr_offset;
- mb->outer_l3_len = 0;
- mb->outer_l2_len = 0;
ol_flags = is_ip4 ? PKT_TX_IPV4 : PKT_TX_IPV6;
ol_flags |= ip_cksum ? PKT_TX_IP_CKSUM : 0;
ol_flags |= tcp_cksum ? PKT_TX_TCP_CKSUM : 0;
ol_flags |= udp_cksum ? PKT_TX_UDP_CKSUM : 0;
+ if (vxlan_tunnel)
+ {
+ ol_flags |= outer_ip_cksum ? PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IP_CKSUM :
+ PKT_TX_OUTER_IPV6;
+ ol_flags |= PKT_TX_TUNNEL_VXLAN;
+ mb->l2_len =
+ vnet_buffer (b)->l3_hdr_offset - vnet_buffer2 (b)->outer_l4_hdr_offset;
+ mb->l3_len =
+ vnet_buffer (b)->l4_hdr_offset - vnet_buffer (b)->l3_hdr_offset;
+ mb->outer_l2_len =
+ vnet_buffer2 (b)->outer_l3_hdr_offset - b->current_data;
+ mb->outer_l3_len = vnet_buffer2 (b)->outer_l4_hdr_offset -
+ vnet_buffer2 (b)->outer_l3_hdr_offset;
+ outer_hdr_len = mb->outer_l2_len + mb->outer_l3_len;
+ }
+ else
+ {
+ mb->l2_len =
+ vnet_buffer (b)->l3_hdr_offset - vnet_buffer (b)->l2_hdr_offset;
+ mb->l3_len =
+ vnet_buffer (b)->l4_hdr_offset - vnet_buffer (b)->l3_hdr_offset;
+ mb->outer_l2_len = 0;
+ mb->outer_l3_len = 0;
+ }
+
if (tso)
{
mb->l4_len = vnet_buffer2 (b)->gso_l4_hdr_sz;
mb->tso_segsz = vnet_buffer2 (b)->gso_size;
/* ensure packet is large enough to require tso */
- max_pkt_len = mb->l2_len + mb->l3_len + mb->l4_len + mb->tso_segsz;
+ max_pkt_len =
+ outer_hdr_len + mb->l2_len + mb->l3_len + mb->l4_len + mb->tso_segsz;
if (mb->tso_segsz != 0 && mb->pkt_len > max_pkt_len)
ol_flags |= (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG);
}
xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_UDP_CKSUM;
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_CKSUM;
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+
+ if (dm->conf->enable_outer_checksum_offload)
+ {
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)
+ xd->port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+ if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
+ xd->port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_OUTER_UDP_CKSUM;
+ }
}
if (dm->conf->enable_lro)
{
xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
- xd->flags |=
- DPDK_DEVICE_FLAG_TX_OFFLOAD |
- DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
}
xd->port_conf.intr_conf.rxq = 1;
hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_IP4_CKSUM |
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM;
+ if (dm->conf->enable_outer_checksum_offload)
+ {
+ hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_IP4_OUTER_CKSUM |
+ VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_OUTER_CKSUM;
+ }
}
if (devconf->tso == DPDK_DEVICE_TSO_ON && hi != NULL)
{
if ((dm->conf->enable_tcp_udp_checksum) &&
(hi->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM))
{
- hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
- VNET_HW_INTERFACE_CAP_SUPPORTS_UDP_GSO;
- xd->port_conf.txmode.offloads |=
- DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_UDP_TSO;
+ hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO;
+
+ if (dm->conf->enable_outer_checksum_offload &&
+ (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO))
+ {
+ xd->port_conf.txmode.offloads |=
+ DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+ hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_VXLAN_TNL_GSO;
+ }
}
else
clib_warning ("%s: TCP/UDP checksum offload must be enabled",
conf->enable_telemetry = 1;
else if (unformat (input, "enable-tcp-udp-checksum"))
- conf->enable_tcp_udp_checksum = 1;
-
+ {
+ conf->enable_tcp_udp_checksum = 1;
+ if (unformat (input, "enable-outer-checksum-offload"))
+ conf->enable_outer_checksum_offload = 1;
+ }
else if (unformat (input, "no-tx-checksum-offload"))
conf->no_tx_checksum_offload = 1;