X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface_output.c;h=b09f7996e18b3ce2a93cb321f3e651fdef3ac8da;hb=c1f5a43;hp=abac50b68370f4ac9f6b742d29c6956744497c6a;hpb=363640db0ea658f268082407e767f37f6ec336b0;p=vpp.git diff --git a/src/vnet/interface_output.c b/src/vnet/interface_output.c index abac50b6837..b09f7996e18 100644 --- a/src/vnet/interface_output.c +++ b/src/vnet/interface_output.c @@ -38,6 +38,10 @@ */ #include +#include +#include +#include +#include #include typedef struct @@ -55,7 +59,7 @@ format_vnet_interface_output_trace (u8 * s, va_list * va) interface_output_trace_t *t = va_arg (*va, interface_output_trace_t *); vnet_main_t *vnm = vnet_get_main (); vnet_sw_interface_t *si; - uword indent; + u32 indent; if (t->sw_if_index != (u32) ~ 0) { @@ -95,7 +99,7 @@ vnet_interface_output_trace (vlib_main_t * vm, u32 n_left, *from; n_left = n_buffers; - from = vlib_frame_args (frame); + from = vlib_frame_vector_args (frame); while (n_left >= 4) { @@ -117,15 +121,15 @@ vnet_interface_output_trace (vlib_main_t * vm, { t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0])); t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - clib_memcpy (t0->data, vlib_buffer_get_current (b0), - sizeof (t0->data)); + clib_memcpy_fast (t0->data, vlib_buffer_get_current (b0), + sizeof (t0->data)); } if (b1->flags & VLIB_BUFFER_IS_TRACED) { t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0])); t1->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_TX]; - clib_memcpy (t1->data, vlib_buffer_get_current (b1), - sizeof (t1->data)); + clib_memcpy_fast (t1->data, vlib_buffer_get_current (b1), + sizeof (t1->data)); } from += 2; n_left -= 2; @@ -145,290 +149,69 @@ vnet_interface_output_trace (vlib_main_t * vm, { t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0])); t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX]; - clib_memcpy (t0->data, vlib_buffer_get_current (b0), - sizeof (t0->data)); + clib_memcpy_fast (t0->data, vlib_buffer_get_current (b0), + sizeof (t0->data)); } from += 1; n_left -= 1; } } -static never_inline u32 -slow_path (vlib_main_t * vm, - u32 bi, - vlib_buffer_t * b, - u32 n_left_to_tx, u32 * to_tx, u32 * n_slow_bytes_result) -{ - /* We've already enqueued a single buffer. */ - u32 n_buffers = 0; - u32 n_slow_bytes = 0; - - while (n_left_to_tx > 0) - { - to_tx[0] = bi; - to_tx += 1; - n_left_to_tx -= 1; - n_buffers += 1; - n_slow_bytes += vlib_buffer_length_in_chain (vm, b); - - /* Be grumpy about zero length buffers for benefit of - driver tx function. */ - ASSERT (b->current_length > 0); - - if (!(b->flags & VLIB_BUFFER_NEXT_PRESENT)) - break; - - bi = b->next_buffer; - b = vlib_get_buffer (vm, bi); - } - - /* Ran out of space in next frame trying to enqueue buffers? */ - if (b->flags & VLIB_BUFFER_NEXT_PRESENT) - return 0; - - *n_slow_bytes_result = n_slow_bytes; - return n_buffers; -} - -/* - * Increment TX stats. Roll up consecutive increments to the same sw_if_index - * into one increment. - */ static_always_inline void -incr_output_stats (vnet_main_t * vnm, - u32 cpu_index, - u32 length, - u32 sw_if_index, - u32 * last_sw_if_index, u32 * n_packets, u32 * n_bytes) +calc_checksums (vlib_main_t * vm, vlib_buffer_t * b) { - vnet_interface_main_t *im; + ip4_header_t *ip4; + ip6_header_t *ip6; + tcp_header_t *th; + udp_header_t *uh; - if (PREDICT_TRUE (sw_if_index == *last_sw_if_index)) - { - *n_packets += 1; - *n_bytes += length; - } - else - { - if (PREDICT_TRUE (*last_sw_if_index != ~0)) - { - im = &vnm->interface_main; + int is_ip4 = (b->flags & VNET_BUFFER_F_IS_IP4) != 0; + int is_ip6 = (b->flags & VNET_BUFFER_F_IS_IP6) != 0; - vlib_increment_combined_counter (im->combined_sw_if_counters - + VNET_INTERFACE_COUNTER_TX, - cpu_index, - *last_sw_if_index, - *n_packets, *n_bytes); - } - *last_sw_if_index = sw_if_index; - *n_packets = 1; - *n_bytes = length; - } -} - - -/* Interface output functions. */ -uword -vnet_interface_output_node_flatten (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - vnet_main_t *vnm = vnet_get_main (); - vnet_interface_output_runtime_t *rt = (void *) node->runtime_data; - vnet_sw_interface_t *si; - vnet_hw_interface_t *hi; - u32 n_left_to_tx, *from, *from_end, *to_tx; - u32 n_bytes, n_buffers, n_packets; - u32 last_sw_if_index; - u32 cpu_index = vm->cpu_index; - - n_buffers = frame->n_vectors; - - if (node->flags & VLIB_NODE_FLAG_TRACE) - vnet_interface_output_trace (vm, node, frame, n_buffers); - - from = vlib_frame_args (frame); + ASSERT (!(is_ip4 && is_ip6)); - if (rt->is_deleted) - return vlib_error_drop_buffers (vm, node, from, - /* buffer stride */ 1, - n_buffers, - VNET_INTERFACE_OUTPUT_NEXT_DROP, - node->node_index, - VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED); + ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset); + ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset); + th = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset); + uh = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset); - si = vnet_get_sw_interface (vnm, rt->sw_if_index); - hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index); - if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) || - !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) + if (is_ip4) { - vlib_simple_counter_main_t *cm; - - cm = vec_elt_at_index (vnm->interface_main.sw_if_counters, - VNET_INTERFACE_COUNTER_TX_ERROR); - vlib_increment_simple_counter (cm, cpu_index, - rt->sw_if_index, n_buffers); - return vlib_error_drop_buffers (vm, node, from, - /* buffer stride */ 1, - n_buffers, - VNET_INTERFACE_OUTPUT_NEXT_DROP, - node->node_index, - VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN); + ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset); + if (b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM) + ip4->checksum = ip4_header_checksum (ip4); + if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM) + th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ip4); + if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) + uh->checksum = ip4_tcp_udp_compute_checksum (vm, b, ip4); } - - from_end = from + n_buffers; - - /* Total byte count of all buffers. */ - n_bytes = 0; - n_packets = 0; - last_sw_if_index = ~0; - - while (from < from_end) + if (is_ip6) { - /* Get new next frame since previous incomplete frame may have less - than VNET_FRAME_SIZE vectors in it. */ - vlib_get_new_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX, - to_tx, n_left_to_tx); - - while (from + 4 <= from_end && n_left_to_tx >= 2) - { - u32 bi0, bi1; - vlib_buffer_t *b0, *b1; - - /* Prefetch next iteration. */ - vlib_prefetch_buffer_with_index (vm, from[2], LOAD); - vlib_prefetch_buffer_with_index (vm, from[3], LOAD); - - bi0 = from[0]; - bi1 = from[1]; - to_tx[0] = bi0; - to_tx[1] = bi1; - from += 2; - to_tx += 2; - n_left_to_tx -= 2; - - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); - - /* Be grumpy about zero length buffers for benefit of - driver tx function. */ - ASSERT (b0->current_length > 0); - ASSERT (b1->current_length > 0); - - if (PREDICT_FALSE - ((b0->flags | b1->flags) & VLIB_BUFFER_NEXT_PRESENT)) - { - u32 n_buffers, n_slow_bytes, i; - - /* Undo. */ - from -= 2; - to_tx -= 2; - n_left_to_tx += 2; - - /* Do slow path two times. */ - for (i = 0; i < 2; i++) - { - u32 bi = i ? bi1 : bi0; - vlib_buffer_t *b = i ? b1 : b0; - - n_buffers = slow_path (vm, bi, b, - n_left_to_tx, to_tx, &n_slow_bytes); - - /* Not enough room for single packet? */ - if (n_buffers == 0) - goto put; - - from += 1; - to_tx += n_buffers; - n_left_to_tx -= n_buffers; - incr_output_stats (vnm, cpu_index, n_slow_bytes, - vnet_buffer (b)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); - } - } - else - { - incr_output_stats (vnm, cpu_index, - vlib_buffer_length_in_chain (vm, b0), - vnet_buffer (b0)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); - incr_output_stats (vnm, cpu_index, - vlib_buffer_length_in_chain (vm, b0), - vnet_buffer (b1)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); - } - } - - while (from + 1 <= from_end && n_left_to_tx >= 1) - { - u32 bi0; - vlib_buffer_t *b0; - - bi0 = from[0]; - to_tx[0] = bi0; - from += 1; - to_tx += 1; - n_left_to_tx -= 1; - - b0 = vlib_get_buffer (vm, bi0); - - /* Be grumpy about zero length buffers for benefit of - driver tx function. */ - ASSERT (b0->current_length > 0); - - if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_NEXT_PRESENT)) - { - u32 n_buffers, n_slow_bytes; - - /* Undo. */ - from -= 1; - to_tx -= 1; - n_left_to_tx += 1; - - n_buffers = slow_path (vm, bi0, b0, - n_left_to_tx, to_tx, &n_slow_bytes); - - /* Not enough room for single packet? */ - if (n_buffers == 0) - goto put; - - from += 1; - to_tx += n_buffers; - n_left_to_tx -= n_buffers; - } - incr_output_stats (vnm, cpu_index, - vlib_buffer_length_in_chain (vm, b0), - vnet_buffer (b0)->sw_if_index[VLIB_TX], - &last_sw_if_index, &n_packets, &n_bytes); - } - - put: - vlib_put_next_frame (vm, node, VNET_INTERFACE_OUTPUT_NEXT_TX, - n_left_to_tx); + int bogus; + if (b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM) + th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus); + if (b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM) + uh->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus); } - /* Final update of interface stats. */ - incr_output_stats (vnm, cpu_index, 0, ~0, /* ~0 will flush stats */ - &last_sw_if_index, &n_packets, &n_bytes); - - return n_buffers; + b->flags &= ~VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; + b->flags &= ~VNET_BUFFER_F_OFFLOAD_UDP_CKSUM; + b->flags &= ~VNET_BUFFER_F_OFFLOAD_IP_CKSUM; } -VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node_flatten); -CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node_flatten); - -uword -vnet_interface_output_node (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) +static_always_inline uword +vnet_interface_output_node_inline (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame, vnet_main_t * vnm, + vnet_hw_interface_t * hi, + int do_tx_offloads) { - vnet_main_t *vnm = vnet_get_main (); vnet_interface_output_runtime_t *rt = (void *) node->runtime_data; vnet_sw_interface_t *si; - vnet_hw_interface_t *hi; u32 n_left_to_tx, *from, *from_end, *to_tx; u32 n_bytes, n_buffers, n_packets; u32 n_bytes_b0, n_bytes_b1, n_bytes_b2, n_bytes_b3; - u32 cpu_index = vm->cpu_index; + u32 thread_index = vm->thread_index; vnet_interface_main_t *im = &vnm->interface_main; u32 next_index = VNET_INTERFACE_OUTPUT_NEXT_TX; u32 current_config_index = ~0; @@ -439,7 +222,7 @@ vnet_interface_output_node (vlib_main_t * vm, if (node->flags & VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace (vm, node, frame, n_buffers); - from = vlib_frame_args (frame); + from = vlib_frame_vector_args (frame); if (rt->is_deleted) return vlib_error_drop_buffers (vm, node, from, @@ -451,14 +234,15 @@ vnet_interface_output_node (vlib_main_t * vm, si = vnet_get_sw_interface (vnm, rt->sw_if_index); hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index); - if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) || + if (!(si->flags & (VNET_SW_INTERFACE_FLAG_ADMIN_UP | + VNET_SW_INTERFACE_FLAG_BOND_SLAVE)) || !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)) { vlib_simple_counter_main_t *cm; cm = vec_elt_at_index (vnm->interface_main.sw_if_counters, VNET_INTERFACE_COUNTER_TX_ERROR); - vlib_increment_simple_counter (cm, cpu_index, + vlib_increment_simple_counter (cm, thread_index, rt->sw_if_index, n_buffers); return vlib_error_drop_buffers (vm, node, from, @@ -497,6 +281,7 @@ vnet_interface_output_node (vlib_main_t * vm, u32 bi0, bi1, bi2, bi3; vlib_buffer_t *b0, *b1, *b2, *b3; u32 tx_swif0, tx_swif1, tx_swif2, tx_swif3; + u32 or_flags; /* Prefetch next iteration. */ vlib_prefetch_buffer_with_index (vm, from[4], LOAD); @@ -543,10 +328,10 @@ vnet_interface_output_node (vlib_main_t * vm, if (PREDICT_FALSE (current_config_index != ~0)) { - b0->feature_arc_index = arc; - b1->feature_arc_index = arc; - b2->feature_arc_index = arc; - b3->feature_arc_index = arc; + vnet_buffer (b0)->feature_arc_index = arc; + vnet_buffer (b1)->feature_arc_index = arc; + vnet_buffer (b2)->feature_arc_index = arc; + vnet_buffer (b3)->feature_arc_index = arc; b0->current_config_index = current_config_index; b1->current_config_index = current_config_index; b2->current_config_index = current_config_index; @@ -558,7 +343,7 @@ vnet_interface_output_node (vlib_main_t * vm, { vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, - cpu_index, tx_swif0, 1, + thread_index, tx_swif0, 1, n_bytes_b0); } @@ -567,7 +352,7 @@ vnet_interface_output_node (vlib_main_t * vm, vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, - cpu_index, tx_swif1, 1, + thread_index, tx_swif1, 1, n_bytes_b1); } @@ -576,7 +361,7 @@ vnet_interface_output_node (vlib_main_t * vm, vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, - cpu_index, tx_swif2, 1, + thread_index, tx_swif2, 1, n_bytes_b2); } if (PREDICT_FALSE (tx_swif3 != rt->sw_if_index)) @@ -584,9 +369,25 @@ vnet_interface_output_node (vlib_main_t * vm, vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, - cpu_index, tx_swif3, 1, + thread_index, tx_swif3, 1, n_bytes_b3); } + + or_flags = b0->flags | b1->flags | b2->flags | b3->flags; + + if (do_tx_offloads) + { + if (or_flags & + (VNET_BUFFER_F_OFFLOAD_TCP_CKSUM | + VNET_BUFFER_F_OFFLOAD_UDP_CKSUM | + VNET_BUFFER_F_OFFLOAD_IP_CKSUM)) + { + calc_checksums (vm, b0); + calc_checksums (vm, b1); + calc_checksums (vm, b2); + calc_checksums (vm, b3); + } + } } while (from + 1 <= from_end && n_left_to_tx >= 1) @@ -614,7 +415,7 @@ vnet_interface_output_node (vlib_main_t * vm, if (PREDICT_FALSE (current_config_index != ~0)) { - b0->feature_arc_index = arc; + vnet_buffer (b0)->feature_arc_index = arc; b0->current_config_index = current_config_index; } @@ -623,9 +424,12 @@ vnet_interface_output_node (vlib_main_t * vm, vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, - cpu_index, tx_swif0, 1, + thread_index, tx_swif0, 1, n_bytes_b0); } + + if (do_tx_offloads) + calc_checksums (vm, b0); } vlib_put_next_frame (vm, node, next_index, n_left_to_tx); @@ -634,11 +438,28 @@ vnet_interface_output_node (vlib_main_t * vm, /* Update main interface stats. */ vlib_increment_combined_counter (im->combined_sw_if_counters + VNET_INTERFACE_COUNTER_TX, - cpu_index, + thread_index, rt->sw_if_index, n_packets, n_bytes); return n_buffers; } +static uword +vnet_interface_output_node (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * frame) +{ + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hi; + vnet_interface_output_runtime_t *rt = (void *) node->runtime_data; + hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index); + + if (hi->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD) + return vnet_interface_output_node_inline (vm, node, frame, vnm, hi, + /* do_tx_offloads */ 0); + else + return vnet_interface_output_node_inline (vm, node, frame, vnm, hi, + /* do_tx_offloads */ 1); +} + VLIB_NODE_FUNCTION_MULTIARCH_CLONE (vnet_interface_output_node); CLIB_MULTIARCH_SELECT_FN (vnet_interface_output_node); @@ -654,7 +475,7 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, n_left_from = frame->n_vectors; - from = vlib_frame_args (frame); + from = vlib_frame_vector_args (frame); next_index = node->cached_next_index; while (n_left_from > 0) @@ -692,8 +513,8 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, vnet_buffer (b1)->sw_if_index [VLIB_TX]); - next0 = hi0->hw_if_index; - next1 = hi1->hw_if_index; + next0 = hi0->output_node_next_index; + next1 = hi1->output_node_next_index; vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, @@ -720,7 +541,7 @@ vnet_per_buffer_interface_output (vlib_main_t * vm, vnet_buffer (b0)->sw_if_index [VLIB_TX]); - next0 = hi0->hw_if_index; + next0 = hi0->output_node_next_index; vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); @@ -848,7 +669,7 @@ static u8 * validate_error_frame (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f) { - u32 *buffers = vlib_frame_args (f); + u32 *buffers = vlib_frame_vector_args (f); vlib_buffer_t *b; u8 *msg = 0; uword i; @@ -893,12 +714,12 @@ process_drop_punt (vlib_main_t * vm, u32 current_sw_if_index, n_errors_current_sw_if_index; u64 current_counter; vlib_simple_counter_main_t *cm; - u32 cpu_index = vm->cpu_index; + u32 thread_index = vm->thread_index; static vlib_error_t memory[VNET_ERROR_N_DISPOSITION]; static char memory_init[VNET_ERROR_N_DISPOSITION]; - buffers = vlib_frame_args (frame); + buffers = vlib_frame_vector_args (frame); first_buffer = buffers; { @@ -965,19 +786,19 @@ process_drop_punt (vlib_main_t * vm, current_counter -= 2; n_errors_current_sw_if_index -= 2; - vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1); - vlib_increment_simple_counter (cm, cpu_index, sw_if_index1, 1); + vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1); + vlib_increment_simple_counter (cm, thread_index, sw_if_index1, 1); /* Increment super-interface drop/punt counters for sub-interfaces. */ sw_if0 = vnet_get_sw_interface (vnm, sw_if_index0); vlib_increment_simple_counter - (cm, cpu_index, sw_if0->sup_sw_if_index, + (cm, thread_index, sw_if0->sup_sw_if_index, sw_if0->sup_sw_if_index != sw_if_index0); sw_if1 = vnet_get_sw_interface (vnm, sw_if_index1); vlib_increment_simple_counter - (cm, cpu_index, sw_if1->sup_sw_if_index, + (cm, thread_index, sw_if1->sup_sw_if_index, sw_if1->sup_sw_if_index != sw_if_index1); em->counters[current_counter_index] = current_counter; @@ -1013,11 +834,12 @@ process_drop_punt (vlib_main_t * vm, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; /* Increment drop/punt counters. */ - vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1); + vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1); /* Increment super-interface drop/punt counters for sub-interfaces. */ sw_if0 = vnet_get_sw_interface (vnm, sw_if_index0); - vlib_increment_simple_counter (cm, cpu_index, sw_if0->sup_sw_if_index, + vlib_increment_simple_counter (cm, thread_index, + sw_if0->sup_sw_if_index, sw_if0->sup_sw_if_index != sw_if_index0); if (PREDICT_FALSE (e0 != current_error)) @@ -1041,12 +863,12 @@ process_drop_punt (vlib_main_t * vm, { vnet_sw_interface_t *si; - vlib_increment_simple_counter (cm, cpu_index, current_sw_if_index, + vlib_increment_simple_counter (cm, thread_index, current_sw_if_index, n_errors_current_sw_if_index); si = vnet_get_sw_interface (vnm, current_sw_if_index); if (si->sup_sw_if_index != current_sw_if_index) - vlib_increment_simple_counter (cm, cpu_index, si->sup_sw_if_index, + vlib_increment_simple_counter (cm, thread_index, si->sup_sw_if_index, n_errors_current_sw_if_index); } @@ -1258,7 +1080,6 @@ VNET_FEATURE_ARC_INIT (interface_output, static) = { .arc_name = "interface-output", .start_nodes = VNET_FEATURES (0), - .end_node = "interface-tx", .arc_index_ptr = &vnet_main.interface_main.output_feature_arc_index, }; @@ -1268,6 +1089,12 @@ VNET_FEATURE_INIT (span_tx, static) = { .runs_before = VNET_FEATURES ("interface-tx"), }; +VNET_FEATURE_INIT (ipsec_if_tx, static) = { + .arc_name = "interface-output", + .node_name = "ipsec-if-output", + .runs_before = VNET_FEATURES ("interface-tx"), +}; + VNET_FEATURE_INIT (interface_tx, static) = { .arc_name = "interface-output", .node_name = "interface-tx", @@ -1283,12 +1110,13 @@ vnet_per_buffer_interface_output_hw_interface_add_del (vnet_main_t * vnm, vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); u32 next_index; - next_index = vlib_node_add_next_with_slot - (vnm->vlib_main, vnet_per_buffer_interface_output_node.index, - hi->output_node_index, - /* next_index */ hw_if_index); + if (hi->output_node_index == 0) + return 0; - ASSERT (next_index == hw_if_index); + next_index = vlib_node_add_next + (vnm->vlib_main, vnet_per_buffer_interface_output_node.index, + hi->output_node_index); + hi->output_node_next_index = next_index; return 0; } @@ -1296,6 +1124,18 @@ vnet_per_buffer_interface_output_hw_interface_add_del (vnet_main_t * vnm, VNET_HW_INTERFACE_ADD_DEL_FUNCTION (vnet_per_buffer_interface_output_hw_interface_add_del); +void +vnet_set_interface_output_node (vnet_main_t * vnm, + u32 hw_if_index, u32 node_index) +{ + ASSERT (node_index); + vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); + u32 next_index = vlib_node_add_next + (vnm->vlib_main, vnet_per_buffer_interface_output_node.index, node_index); + hi->output_node_next_index = next_index; + hi->output_node_index = node_index; +} + static clib_error_t * pcap_drop_trace_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -1317,7 +1157,7 @@ pcap_drop_trace_command_fn (vlib_main_t * vm, if (im->pcap_filename == 0) im->pcap_filename = format (0, "/tmp/drop.pcap%c", 0); - memset (&im->pcap_main, 0, sizeof (im->pcap_main)); + clib_memset (&im->pcap_main, 0, sizeof (im->pcap_main)); im->pcap_main.file_name = (char *) im->pcap_filename; im->pcap_main.n_packets_to_capture = 100; if (im->pcap_pkts_to_capture) @@ -1392,8 +1232,8 @@ pcap_drop_trace_command_fn (vlib_main_t * vm, if (im->pcap_filename) vec_free (im->pcap_filename); - vec_add1 (filename, 0); im->pcap_filename = chroot_filename; + im->pcap_main.file_name = (char *) im->pcap_filename; matched = 1; } else if (unformat (input, "status"))