summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/dpdk/device/device.c38
-rw-r--r--src/plugins/dpdk/device/dpdk.h1
-rw-r--r--src/plugins/dpdk/device/init.c43
3 files changed, 66 insertions, 16 deletions
diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c
index 7c083e1dcf4..095036fcb5c 100644
--- a/src/plugins/dpdk/device/device.c
+++ b/src/plugins/dpdk/device/device.c
@@ -221,7 +221,8 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
{
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;
@@ -233,23 +234,46 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
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);
}
diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h
index dd43137aebe..51f80a80462 100644
--- a/src/plugins/dpdk/device/dpdk.h
+++ b/src/plugins/dpdk/device/dpdk.h
@@ -304,6 +304,7 @@ typedef struct
u8 no_multi_seg;
u8 enable_lro;
u8 enable_tcp_udp_checksum;
+ u8 enable_outer_checksum_offload;
u8 no_tx_checksum_offload;
u8 enable_telemetry;
u16 max_simd_bitwidth;
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c
index f7c1cc106ba..18124c32ff0 100644
--- a/src/plugins/dpdk/device/init.c
+++ b/src/plugins/dpdk/device/init.c
@@ -370,6 +370,18 @@ dpdk_lib_init (dpdk_main_t * dm)
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)
@@ -480,9 +492,8 @@ dpdk_lib_init (dpdk_main_t * dm)
{
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;
@@ -816,6 +827,11 @@ dpdk_lib_init (dpdk_main_t * dm)
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)
{
@@ -823,10 +839,16 @@ dpdk_lib_init (dpdk_main_t * dm)
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",
@@ -1391,8 +1413,11 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
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;