}
static_always_inline void
-vnet_interface_output_handle_offload (vlib_main_t *vm, vlib_buffer_t *b)
+vnet_interface_output_handle_offload (vlib_main_t *vm, vlib_buffer_t *b,
+ vnet_hw_if_caps_t caps)
{
+ u8 oflags;
if (b->flags & VNET_BUFFER_F_GSO)
return;
+ oflags = vnet_buffer (b)->oflags;
+
+ if ((caps & VNET_HW_IF_CAP_TX_CKSUM) == VNET_HW_IF_CAP_TX_CKSUM)
+ {
+ if (((oflags & VNET_BUFFER_OFFLOAD_F_TNL_IPIP) !=
+ VNET_BUFFER_OFFLOAD_F_TNL_IPIP) &&
+ ((oflags & VNET_BUFFER_OFFLOAD_F_TNL_VXLAN) !=
+ VNET_BUFFER_OFFLOAD_F_TNL_VXLAN))
+ return;
+
+ if (((oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM) !=
+ VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM) &&
+ ((oflags & VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM) !=
+ VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM))
+ {
+ if ((caps & VNET_HW_IF_CAP_TX_FIXED_OFFSET) !=
+ VNET_HW_IF_CAP_TX_FIXED_OFFSET)
+ return;
+ }
+ }
vnet_calc_checksums_inline (vm, b, b->flags & VNET_BUFFER_F_IS_IP4,
b->flags & VNET_BUFFER_F_IS_IP6);
vnet_calc_outer_checksums_inline (vm, b);
vnet_interface_output_node_inline (vlib_main_t *vm, u32 sw_if_index,
vlib_combined_counter_main_t *ccm,
vlib_buffer_t **b, void **p,
- u32 config_index, u8 arc, u32 n_left,
- int processing_level)
+ vnet_hw_if_caps_t caps, u32 config_index,
+ u8 arc, u32 n_left, int processing_level)
{
u32 n_bytes = 0;
u32 n_bytes0, n_bytes1, n_bytes2, n_bytes3;
if (processing_level >= 1 && (or_flags & VNET_BUFFER_F_OFFLOAD))
{
- vnet_interface_output_handle_offload (vm, b[0]);
- vnet_interface_output_handle_offload (vm, b[1]);
- vnet_interface_output_handle_offload (vm, b[2]);
- vnet_interface_output_handle_offload (vm, b[3]);
+ vnet_interface_output_handle_offload (vm, b[0], caps);
+ vnet_interface_output_handle_offload (vm, b[1], caps);
+ vnet_interface_output_handle_offload (vm, b[2], caps);
+ vnet_interface_output_handle_offload (vm, b[3], caps);
}
n_left -= 4;
vlib_increment_combined_counter (ccm, ti, tx_swif0, 1, n_bytes0);
}
- if (processing_level >= 1)
- vnet_interface_output_handle_offload (vm, b[0]);
+ if ((processing_level >= 1) && (b[0]->flags & VNET_BUFFER_F_OFFLOAD))
+ vnet_interface_output_handle_offload (vm, b[0], caps);
n_left -= 1;
b += 1;
ccm = im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX;
- /* if not all three flags IP4_,TCP_,UDP_CKSUM set, do compute them
- * here before sending to the interface */
- if ((hi->caps & VNET_HW_IF_CAP_TX_CKSUM) != VNET_HW_IF_CAP_TX_CKSUM)
+ /* if not all three flags IP4_,TCP_,UDP_, IP4_OUTER_, UDP_OUTER_CKSUM set, do
+ * compute them here before sending to the interface */
+ if ((hi->caps & VNET_HW_IF_CAP_TX_CKSUM_MASK) !=
+ VNET_HW_IF_CAP_TX_CKSUM_MASK)
do_tx_offloads = 1;
// basic processing
if (do_tx_offloads == 0 && arc_or_subif == 0 && is_parr == 0)
n_bytes = vnet_interface_output_node_inline (
- vm, sw_if_index, ccm, bufs, NULL, config_index, arc, n_buffers, 0);
+ vm, sw_if_index, ccm, bufs, NULL, 0, config_index, arc, n_buffers, 0);
// basic processing + tx offloads
else if (do_tx_offloads == 1 && arc_or_subif == 0 && is_parr == 0)
- n_bytes = vnet_interface_output_node_inline (
- vm, sw_if_index, ccm, bufs, NULL, config_index, arc, n_buffers, 1);
+ n_bytes = vnet_interface_output_node_inline (vm, sw_if_index, ccm, bufs,
+ NULL, hi->caps, config_index,
+ arc, n_buffers, 1);
// basic processing + tx offloads + vlans + arcs
else if (do_tx_offloads == 1 && arc_or_subif == 1 && is_parr == 0)
- n_bytes = vnet_interface_output_node_inline (
- vm, sw_if_index, ccm, bufs, NULL, config_index, arc, n_buffers, 2);
+ n_bytes = vnet_interface_output_node_inline (vm, sw_if_index, ccm, bufs,
+ NULL, hi->caps, config_index,
+ arc, n_buffers, 2);
// basic processing + tx offloads + vlans + arcs + multi-txqs
else
- n_bytes = vnet_interface_output_node_inline (
- vm, sw_if_index, ccm, bufs, p, config_index, arc, n_buffers, 3);
+ n_bytes = vnet_interface_output_node_inline (vm, sw_if_index, ccm, bufs, p,
+ hi->caps, config_index, arc,
+ n_buffers, 3);
from = vlib_frame_vector_args (frame);
if (PREDICT_TRUE (next_index == VNET_INTERFACE_OUTPUT_NEXT_TX))