diff options
Diffstat (limited to 'src/plugins/dpdk/device/device.c')
-rw-r--r-- | src/plugins/dpdk/device/device.c | 38 |
1 files changed, 31 insertions, 7 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); } |