diff options
author | Benoît Ganne <bganne@cisco.com> | 2021-03-04 14:31:03 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2021-05-01 11:42:37 +0000 |
commit | f89bbbe300dad7bc479db535e7822199f98aca30 (patch) | |
tree | 1163eeac010375a962fcda8c2e0c7a7046161bf1 /src | |
parent | c8983241b9d93d2c3b60b0705efbc3cdee54c534 (diff) |
vlib: refactor trajectory trace debug feature
trajectory trace has been broken for a while because we used to save the
buffer trajectory in a vector pointed to in opaque2. This does not work
well when opaque2 is copied (eg. because of a clone) as 2 buffers end up
sharing the same vector.
This dedicates a full cacheline in the buffer metadata instead when
trajectory is compiled in. No dynamic allocation, no sharing, no tears.
Type: refactor
Change-Id: I6a028ca1b48d38f393a36979e5e452c2dd48ad3f
Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src')
44 files changed, 98 insertions, 275 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3fc72d72884..a291c4d022d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,6 +142,15 @@ if (VPP_ENABLE_SANITIZE_ADDR) endif (VPP_ENABLE_SANITIZE_ADDR) ############################################################################## +# trajectory trace +############################################################################## + +option(VPP_ENABLE_TRAJECTORY_TRACE "Build vpp with trajectory tracing enabled" OFF) +if(VPP_ENABLE_TRAJECTORY_TRACE) + set(CMAKE_C_FLAGS "-DVLIB_BUFFER_TRACE_TRAJECTORY=1 ${CMAKE_C_FLAGS}") +endif() + +############################################################################## # install config ############################################################################## option(VPP_SET_RPATH "Set rpath for resulting binaries and libraries." ON) diff --git a/src/plugins/af_xdp/device.c b/src/plugins/af_xdp/device.c index fabf85adfa6..35ba617d6e3 100644 --- a/src/plugins/af_xdp/device.c +++ b/src/plugins/af_xdp/device.c @@ -208,6 +208,18 @@ af_xdp_create_queue (vlib_main_t * vm, af_xdp_create_if_args_t * args, umem_config.comp_size = args->txq_size; umem_config.frame_size = sizeof (vlib_buffer_t) + vlib_buffer_get_default_data_size (vm); + /* + * Note about headroom: for some reasons, there seem to be a discrepency + * between 0-copy and copy mode: + * - 0-copy: XDP_PACKET_HEADROOM will be added to the user headroom + * - copy: nothing is added to the user headroom + * We privileged 0-copy and set headroom so that frame_headroom + + * XDP_PACKET_HEADROOM == sizeof(vlib_buffer_t), ie data will correctly + * point to vlib_buffer_t->data for 0-copy. In copy mode, we have to add + * XDP_PACKET_HEADROOM to desc offset during refill. + */ + STATIC_ASSERT (sizeof (vlib_buffer_t) >= XDP_PACKET_HEADROOM, "wrong size"); + umem_config.frame_headroom = sizeof (vlib_buffer_t) - XDP_PACKET_HEADROOM; umem_config.flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG; if (xsk_umem__create (umem, uword_to_pointer (vm->buffer_main->buffer_mem_start, void *), diff --git a/src/plugins/af_xdp/input.c b/src/plugins/af_xdp/input.c index 65eee75cb92..da422bdccaf 100644 --- a/src/plugins/af_xdp/input.c +++ b/src/plugins/af_xdp/input.c @@ -130,17 +130,11 @@ af_xdp_device_input_refill (vlib_main_t * vm, /* * Note about headroom: for some reasons, there seem to be a discrepency - * between 0-copy and copy mode: - * - 0-copy: XDP_PACKET_HEADROOM will be added to the user headroom - * - copy: nothing is added to the user headroom - * We privileged 0-copy and set headroom to 0. As XDP_PACKET_HEADROOM == - * sizeof(vlib_buffer_t), data will correctly point to vlib_buffer_t->data. - * In copy mode, we have to add sizeof(vlib_buffer_t) to desc offset during - * refill. + * between 0-copy and copy mode. See + * src/plugins/af_xdp/device.c:af_xdp_create_queue() */ - STATIC_ASSERT (sizeof (vlib_buffer_t) == XDP_PACKET_HEADROOM, "wrong size"); -#define bi2addr(bi) \ - (((bi) << CLIB_LOG2_CACHE_LINE_BYTES) + (copy ? sizeof(vlib_buffer_t) : 0)) +#define bi2addr(bi) \ + (((bi) << CLIB_LOG2_CACHE_LINE_BYTES) + (copy ? XDP_PACKET_HEADROOM : 0)) wrap_around: @@ -218,8 +212,8 @@ af_xdp_device_input_bufs (vlib_main_t * vm, const af_xdp_device_t * ad, const u32 mask = rxq->rx.mask; u32 n = n_rx, *bi = bis, bytes = 0; -#define addr2bi(addr) \ - (((addr) - (copy ? sizeof(vlib_buffer_t) : 0)) >> CLIB_LOG2_CACHE_LINE_BYTES) +#define addr2bi(addr) \ + (((addr) - (copy ? XDP_PACKET_HEADROOM : 0)) >> CLIB_LOG2_CACHE_LINE_BYTES) while (n >= 1) { diff --git a/src/plugins/avf/input.c b/src/plugins/avf/input.c index 03ec2883601..6e437da2a16 100644 --- a/src/plugins/avf/input.c +++ b/src/plugins/avf/input.c @@ -230,11 +230,6 @@ avf_process_rx_burst (vlib_main_t * vm, vlib_node_runtime_t * node, n_rx_bytes += avf_rx_attach_tail (vm, &bt, b[3], qw1[3], tail + 3); } - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[2]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[3]); - /* next */ qw1 += 4; tail += 4; @@ -251,8 +246,6 @@ avf_process_rx_burst (vlib_main_t * vm, vlib_node_runtime_t * node, if (maybe_multiseg) n_rx_bytes += avf_rx_attach_tail (vm, &bt, b[0], qw1[0], tail + 0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - /* next */ qw1 += 1; tail += 1; diff --git a/src/plugins/dhcp/client.c b/src/plugins/dhcp/client.c index e79cb694378..f93643390e9 100644 --- a/src/plugins/dhcp/client.c +++ b/src/plugins/dhcp/client.c @@ -500,7 +500,6 @@ send_dhcp_pkt (dhcp_client_main_t * dcm, dhcp_client_t * c, /* Build a dhcpv4 pkt from whole cloth */ b = vlib_get_buffer (vm, bi); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); ASSERT (b->current_data == 0); diff --git a/src/plugins/dhcp/dhcp4_proxy_node.c b/src/plugins/dhcp/dhcp4_proxy_node.c index 6a3c51018d1..2ddad25bb11 100644 --- a/src/plugins/dhcp/dhcp4_proxy_node.c +++ b/src/plugins/dhcp/dhcp4_proxy_node.c @@ -370,7 +370,6 @@ dhcp_proxy_to_server_input (vlib_main_t * vm, DHCP_PROXY_ERROR_ALLOC_FAIL, 1); continue; } - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (c0); ci0 = vlib_get_buffer_index (vm, c0); server = &proxy->dhcp_servers[ii]; diff --git a/src/plugins/dhcp/dhcp6_proxy_node.c b/src/plugins/dhcp/dhcp6_proxy_node.c index 3b95e7f9f09..33fb8a37992 100644 --- a/src/plugins/dhcp/dhcp6_proxy_node.c +++ b/src/plugins/dhcp/dhcp6_proxy_node.c @@ -443,7 +443,6 @@ dhcpv6_proxy_to_server_input (vlib_main_t * vm, DHCPV6_PROXY_ERROR_ALLOC_FAIL, 1); continue; } - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (c0); ci0 = vlib_get_buffer_index (vm, c0); server = &proxy->dhcp_servers[ii]; diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index be20b4f8551..94b3f6b289a 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -311,11 +311,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, or_flags = b[0]->flags | b[1]->flags | b[2]->flags | b[3]->flags; all_or_flags |= or_flags; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[2]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[3]); - if (or_flags & VLIB_BUFFER_NEXT_PRESENT) { dpdk_validate_rte_mbuf (vm, b[0], 1); @@ -374,9 +369,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, or_flags = b[0]->flags | b[1]->flags; all_or_flags |= or_flags; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]); - if (or_flags & VLIB_BUFFER_NEXT_PRESENT) { dpdk_validate_rte_mbuf (vm, b[0], 1); @@ -412,7 +404,6 @@ VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, { b[0] = vlib_buffer_from_rte_mbuf (mb[0]); all_or_flags |= b[0]->flags; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); dpdk_validate_rte_mbuf (vm, b[0], 1); dpdk_buffer_tx_offload (xd, b[0], mb[0]); diff --git a/src/plugins/dpdk/device/node.c b/src/plugins/dpdk/device/node.c index 2eec74eaab2..98cda4c452f 100644 --- a/src/plugins/dpdk/device/node.c +++ b/src/plugins/dpdk/device/node.c @@ -216,11 +216,6 @@ dpdk_process_rx_burst (vlib_main_t * vm, dpdk_per_thread_data_t * ptd, n_bytes += dpdk_process_subseq_segs (vm, b[3], mb[3], &bt); } - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[2]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[3]); - /* next */ mb += 4; n_left -= 4; @@ -238,7 +233,6 @@ dpdk_process_rx_burst (vlib_main_t * vm, dpdk_per_thread_data_t * ptd, if (maybe_multiseg) n_bytes += dpdk_process_subseq_segs (vm, b[0], mb[0], &bt); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); /* next */ mb += 1; diff --git a/src/plugins/flowprobe/node.c b/src/plugins/flowprobe/node.c index 70dc7267fd8..ab3640ca135 100644 --- a/src/plugins/flowprobe/node.c +++ b/src/plugins/flowprobe/node.c @@ -650,7 +650,6 @@ flowprobe_get_buffer (vlib_main_t * vm, flowprobe_variant_t which) /* Initialize the buffer */ b0 = fm->context[which].buffers_per_worker[my_cpu_number] = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); b0->current_data = 0; b0->current_length = flowprobe_get_headersize (); diff --git a/src/plugins/igmp/igmp_pkt.c b/src/plugins/igmp/igmp_pkt.c index 8912e5af882..c2ce5c71255 100644 --- a/src/plugins/igmp/igmp_pkt.c +++ b/src/plugins/igmp/igmp_pkt.c @@ -38,7 +38,6 @@ igmp_pkt_get_buffer (igmp_pkt_build_t * bk) return (NULL); b = vlib_get_buffer (vm, bi); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; b->flags |= VLIB_BUFFER_IS_TRACED; diff --git a/src/plugins/marvell/pp2/input.c b/src/plugins/marvell/pp2/input.c index 202572dc152..44f01355e39 100644 --- a/src/plugins/marvell/pp2/input.c +++ b/src/plugins/marvell/pp2/input.c @@ -233,9 +233,6 @@ mrvl_pp2_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, clib_memcpy_fast (vnet_buffer (b1)->sw_if_index, sw_if_index, sizeof (sw_if_index)); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b1); - if (PREDICT_FALSE (n_trace > 0)) { mrvl_pp2_input_trace (vm, node, next0, b0, &n_trace, ppif, d); @@ -277,8 +274,6 @@ mrvl_pp2_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, clib_memcpy_fast (vnet_buffer (b0)->sw_if_index, sw_if_index, sizeof (sw_if_index)); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - if (PREDICT_FALSE (n_trace > 0)) mrvl_pp2_input_trace (vm, node, next0, b0, &n_trace, ppif, d); diff --git a/src/plugins/memif/node.c b/src/plugins/memif/node.c index 675acf3b49e..b2422f9e323 100644 --- a/src/plugins/memif/node.c +++ b/src/plugins/memif/node.c @@ -91,8 +91,6 @@ memif_trace_buffer (vlib_main_t * vm, vlib_node_runtime_t * node, memif_if_t * mif, vlib_buffer_t * b, u32 next, u16 qid, uword * n_tracep) { - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); - if (PREDICT_TRUE (b != 0 && vlib_trace_buffer (vm, node, next, b, /* follow_chain */ 0))) { diff --git a/src/plugins/nat/lib/ipfix_logging.c b/src/plugins/nat/lib/ipfix_logging.c index 2a5130e09d0..6e5e4b6c750 100644 --- a/src/plugins/nat/lib/ipfix_logging.c +++ b/src/plugins/nat/lib/ipfix_logging.c @@ -613,7 +613,6 @@ nat_ipfix_logging_nat44_ses (u32 thread_index, u8 nat_event, u32 src_ip, } b0 = sitd->nat44_session_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else @@ -714,7 +713,6 @@ nat_ipfix_logging_addr_exhausted (u32 thread_index, u32 pool_id, int do_flush) } b0 = sitd->addr_exhausted_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else @@ -800,7 +798,6 @@ nat_ipfix_logging_max_entries_per_usr (u32 thread_index, } b0 = sitd->max_entries_per_user_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else @@ -892,7 +889,6 @@ nat_ipfix_logging_max_ses (u32 thread_index, u32 limit, int do_flush) } b0 = sitd->max_sessions_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else @@ -981,7 +977,6 @@ nat_ipfix_logging_max_bib (u32 thread_index, u32 limit, int do_flush) } b0 = sitd->max_bibs_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else @@ -1071,7 +1066,6 @@ nat_ipfix_logging_nat64_bibe (u32 thread_index, u8 nat_event, } b0 = sitd->nat64_bib_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else @@ -1175,7 +1169,6 @@ nat_ipfix_logging_nat64_ses (u32 thread_index, u8 nat_event, } b0 = sitd->nat64_ses_buffer = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; } else diff --git a/src/plugins/nat/nat44-ei/nat44_ei_ha.c b/src/plugins/nat/nat44-ei/nat44_ei_ha.c index d94d07bdbfa..91eea98f84d 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_ha.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_ha.c @@ -749,7 +749,6 @@ nat_ha_event_add (nat_ha_event_t *event, u8 do_flush, u32 session_thread_index, b = td->state_sync_buffer = vlib_get_buffer (vm, bi); clib_memset (vnet_buffer (b), 0, sizeof (*vnet_buffer (b))); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); offset = 0; } else diff --git a/src/plugins/ping/ping.c b/src/plugins/ping/ping.c index f3e238b9cd7..d09babd0be2 100644 --- a/src/plugins/ping/ping.c +++ b/src/plugins/ping/ping.c @@ -964,7 +964,6 @@ send_ip46_ping (vlib_main_t * vm, ERROR_OUT (SEND_PING_ALLOC_FAIL); b0 = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); /* * if the user did not provide a source interface, diff --git a/src/plugins/vmxnet3/output.c b/src/plugins/vmxnet3/output.c index 4c9b7093f73..0de91d9bf21 100644 --- a/src/plugins/vmxnet3/output.c +++ b/src/plugins/vmxnet3/output.c @@ -175,7 +175,6 @@ VNET_DEVICE_CLASS_TX_FN (vmxnet3_device_class) (vlib_main_t * vm, for (i = 0; i < space_needed; i++) { b0 = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); desc_idx = txq->tx_ring.produce; diff --git a/src/plugins/vrrp/vrrp_packet.c b/src/plugins/vrrp/vrrp_packet.c index b77f336930a..8daee500ece 100644 --- a/src/plugins/vrrp/vrrp_packet.c +++ b/src/plugins/vrrp/vrrp_packet.c @@ -313,7 +313,6 @@ vrrp_adv_send (vrrp_vr_t * vr, int shutdown) bi0 = vec_elt (bi, i); b = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; vnet_buffer (b)->sw_if_index[VLIB_RX] = 0; vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index; @@ -500,7 +499,6 @@ vrrp_garp_or_na_send (vrrp_vr_t * vr) addr = vec_elt_at_index (vr->config.vr_addrs, i); b = vlib_get_buffer (vm, bi[i]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; vnet_buffer (b)->sw_if_index[VLIB_RX] = 0; vnet_buffer (b)->sw_if_index[VLIB_TX] = vr->config.sw_if_index; @@ -704,7 +702,6 @@ vrrp_vr_multicast_group_join (vrrp_vr_t * vr) b = vlib_get_buffer (vm, bi); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; vnet_buffer (b)->sw_if_index[VLIB_RX] = 0; diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h index 297240d45f7..349b7324996 100644 --- a/src/vlib/buffer.h +++ b/src/vlib/buffer.h @@ -98,6 +98,15 @@ enum #define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n)) #define VLIB_BUFFER_FLAGS_ALL (0x0f) +/** \brief Compile time buffer trajectory tracing option + Turn this on if you run into "bad monkey" contexts, + and you want to know exactly which nodes they've visited... + See vlib/main.c... +*/ +#ifndef VLIB_BUFFER_TRACE_TRAJECTORY +#define VLIB_BUFFER_TRACE_TRAJECTORY 0 +#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */ + /** VLIB buffer representation. */ typedef union { @@ -169,6 +178,20 @@ typedef union /**< More opaque data, see ../vnet/vnet/buffer.h */ u32 opaque2[14]; +#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 + /** trace trajectory data - we use a specific cacheline for that in the + * buffer when it is compiled-in */ +#define VLIB_BUFFER_TRACE_TRAJECTORY_MAX 31 +#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 64 +#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->trajectory_nb = 0 + CLIB_ALIGN_MARK (trajectory, 64); + u16 trajectory_nb; + u16 trajectory_trace[VLIB_BUFFER_TRACE_TRAJECTORY_MAX]; +#else /* VLIB_BUFFER_TRACE_TRAJECTORY */ +#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 0 +#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) +#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */ + /** start of buffer headroom */ CLIB_ALIGN_MARK (headroom, 64); @@ -191,7 +214,8 @@ typedef union #endif } vlib_buffer_t; -STATIC_ASSERT_SIZEOF (vlib_buffer_t, 128 + VLIB_BUFFER_PRE_DATA_SIZE); +STATIC_ASSERT_SIZEOF (vlib_buffer_t, 128 + VLIB_BUFFER_TRACE_TRAJECTORY_SZ + + VLIB_BUFFER_PRE_DATA_SIZE); STATIC_ASSERT (VLIB_BUFFER_PRE_DATA_SIZE % CLIB_CACHE_LINE_BYTES == 0, "VLIB_BUFFER_PRE_DATA_SIZE must be divisible by cache line size"); @@ -477,26 +501,6 @@ typedef struct clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm); -/* - */ - -/** \brief Compile time buffer trajectory tracing option - Turn this on if you run into "bad monkey" contexts, - and you want to know exactly which nodes they've visited... - See vlib/main.c... -*/ -#define VLIB_BUFFER_TRACE_TRAJECTORY 0 - -#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 -extern void (*vlib_buffer_trace_trajectory_cb) (vlib_buffer_t * b, u32 index); -extern void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b); -extern void vlib_buffer_trace_trajectory_init (vlib_buffer_t * b); -#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) \ - vlib_buffer_trace_trajectory_init (b); -#else -#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) -#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */ - extern u16 __vlib_buffer_external_hdr_size; #define VLIB_BUFFER_SET_EXT_HDR_SIZE(x) \ static void __clib_constructor \ diff --git a/src/vlib/main.c b/src/vlib/main.c index bee63970f3d..f833aa25acf 100644 --- a/src/vlib/main.c +++ b/src/vlib/main.c @@ -934,29 +934,14 @@ vlib_elog_main_loop_event (vlib_main_t * vm, } } -#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 -void (*vlib_buffer_trace_trajectory_cb) (vlib_buffer_t * b, u32 node_index); -void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b); - -void -vlib_buffer_trace_trajectory_init (vlib_buffer_t * b) -{ - if (PREDICT_TRUE (vlib_buffer_trace_trajectory_init_cb != 0)) - { - (*vlib_buffer_trace_trajectory_init_cb) (b); - } -} - -#endif - static inline void add_trajectory_trace (vlib_buffer_t * b, u32 node_index) { #if VLIB_BUFFER_TRACE_TRAJECTORY > 0 - if (PREDICT_TRUE (vlib_buffer_trace_trajectory_cb != 0)) - { - (*vlib_buffer_trace_trajectory_cb) (b, node_index); - } + if (PREDICT_FALSE (b->trajectory_nb >= VLIB_BUFFER_TRACE_TRAJECTORY_MAX)) + return; + b->trajectory_trace[b->trajectory_nb] = node_index; + b->trajectory_nb++; #endif } diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 0a3b7101ab5..6e02efd68a0 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -1340,7 +1340,6 @@ list(APPEND VNET_SOURCES util/radix.c util/refcount.c util/throttle.c - util/trajectory.c ) list(APPEND VNET_HEADERS diff --git a/src/vnet/bfd/bfd_main.c b/src/vnet/bfd/bfd_main.c index 30d98f6ab34..9e575afcaca 100644 --- a/src/vnet/bfd/bfd_main.c +++ b/src/vnet/bfd/bfd_main.c @@ -924,7 +924,6 @@ bfd_send_echo (vlib_main_t * vm, vlib_node_runtime_t * rt, } vlib_buffer_t *b = vlib_get_buffer (vm, bi); ASSERT (b->current_data == 0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); bfd_echo_pkt_t *pkt = vlib_buffer_get_current (b); clib_memset (pkt, 0, sizeof (*pkt)); pkt->discriminator = bs->local_discr; @@ -993,7 +992,6 @@ bfd_send_periodic (vlib_main_t * vm, vlib_node_runtime_t * rt, } vlib_buffer_t *b = vlib_get_buffer (vm, bi); ASSERT (b->current_data == 0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); bfd_init_control_frame (bm, bs, b); switch (bs->poll_state) { diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c index c69d5a40145..8a0c1092251 100644 --- a/src/vnet/bonding/device.c +++ b/src/vnet/bonding/device.c @@ -422,11 +422,6 @@ bond_tx_inline (vlib_main_t * vm, bond_if_t * bif, vlib_buffer_t ** b, CLIB_PREFETCH (pb[3]->data, CLIB_CACHE_LINE_BYTES, LOAD); } - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[2]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[3]); - if (lb_alg == BOND_LB_L2) { h[0] = bond_lb_l2 (b[0]); @@ -474,8 +469,6 @@ bond_tx_inline (vlib_main_t * vm, bond_if_t * bif, vlib_buffer_t ** b, while (n_left > 0) { - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - if (bif->lb == BOND_LB_L2) h[0] = bond_lb_l2 (b[0]); else if (bif->lb == BOND_LB_L34) diff --git a/src/vnet/bonding/node.c b/src/vnet/bonding/node.c index d49894fcb74..21a968177fe 100644 --- a/src/vnet/bonding/node.c +++ b/src/vnet/bonding/node.c @@ -328,11 +328,6 @@ VLIB_NODE_FN (bond_input_node) (vlib_main_t * vm, &n_rx_packets, &n_rx_bytes); } - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[1]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[2]); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[3]); - /* next */ n_left -= 4; b += 4; @@ -352,8 +347,6 @@ VLIB_NODE_FN (bond_input_node) (vlib_main_t * vm, bond_sw_if_idx_rewrite (vm, node, b[0], bond_sw_if_index, &n_rx_packets, &n_rx_bytes); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); - /* next */ n_left -= 1; b += 1; diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h index 00e9aa698c6..19585e22506 100644 --- a/src/vnet/buffer.h +++ b/src/vnet/buffer.h @@ -491,13 +491,6 @@ typedef struct { struct { -#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 - /* buffer trajectory tracing */ - u16 *trajectory_trace; -#endif - }; - struct - { u64 pad[1]; u64 pg_replay_timestamp; }; diff --git a/src/vnet/devices/af_packet/node.c b/src/vnet/devices/af_packet/node.c index 9f1782e2d13..16cd69a52ce 100644 --- a/src/vnet/devices/af_packet/node.c +++ b/src/vnet/devices/af_packet/node.c @@ -332,7 +332,6 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, } /* trace */ - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (first_b0); if (PREDICT_FALSE (n_trace > 0 && vlib_trace_buffer (vm, node, next0, first_b0, /* follow_chain */ 0))) diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index 98df322ea15..df8c0fa9a64 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -522,8 +522,6 @@ virtio_device_input_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } /* trace */ - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - if (PREDICT_FALSE (n_trace > 0 && vlib_trace_buffer (vm, node, next0, b0, /* follow_chain */ 1))) { diff --git a/src/vnet/devices/virtio/vhost_user_input.c b/src/vnet/devices/virtio/vhost_user_input.c index 739125bbcfe..1636bd8c4a9 100644 --- a/src/vnet/devices/virtio/vhost_user_input.c +++ b/src/vnet/devices/virtio/vhost_user_input.c @@ -686,8 +686,6 @@ vhost_user_if_input (vlib_main_t *vm, vhost_user_main_t *vum, last_avail_idx++; last_used_idx++; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b_head); - vnet_buffer (b_head)->sw_if_index[VLIB_RX] = vui->sw_if_index; vnet_buffer (b_head)->sw_if_index[VLIB_TX] = (u32) ~ 0; b_head->error = 0; @@ -1318,8 +1316,6 @@ vhost_user_if_input_packed (vlib_main_t *vm, vhost_user_main_t *vum, b_head->total_length_not_including_first_buffer -= b_head->current_length; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b_head); - vnet_buffer (b_head)->sw_if_index[VLIB_RX] = vui->sw_if_index; vnet_buffer (b_head)->sw_if_index[VLIB_TX] = ~0; b_head->error = 0; diff --git a/src/vnet/dpo/replicate_dpo.c b/src/vnet/dpo/replicate_dpo.c index 929fed0b831..5f88f12b910 100644 --- a/src/vnet/dpo/replicate_dpo.c +++ b/src/vnet/dpo/replicate_dpo.c @@ -791,8 +791,6 @@ replicate_inline (vlib_main_t * vm, { replicate_trace_t *t; - if (c0 != b0) - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (c0); t = vlib_add_trace (vm, node, c0, sizeof (*t)); t->rep_index = repi0; t->dpo = *dpo0; diff --git a/src/vnet/interface.c b/src/vnet/interface.c index cd734cedd5c..32fb1f2e64a 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -1439,11 +1439,6 @@ vnet_interface_init (vlib_main_t * vm) vnm->interface_tag_by_sw_if_index = hash_create (0, sizeof (uword)); -#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 - if ((error = vlib_call_init_function (vm, trajectory_trace_init))) - return error; -#endif - return 0; } diff --git a/src/vnet/ip-neighbor/ip4_neighbor.h b/src/vnet/ip-neighbor/ip4_neighbor.h index 11309af82d5..c330dfa59e7 100644 --- a/src/vnet/ip-neighbor/ip4_neighbor.h +++ b/src/vnet/ip-neighbor/ip4_neighbor.h @@ -61,7 +61,6 @@ ip4_neighbor_probe (vlib_main_t * vm, h0->ip4_over_ethernet[0].ip4 = *src; h0->ip4_over_ethernet[1].ip4 = *dst; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); vnet_buffer (b0)->sw_if_index[VLIB_TX] = adj0->rewrite_header.sw_if_index; vlib_buffer_advance (b0, -adj0->rewrite_header.data_bytes); diff --git a/src/vnet/ip-neighbor/ip6_neighbor.h b/src/vnet/ip-neighbor/ip6_neighbor.h index 681e634861c..ad2ace21948 100644 --- a/src/vnet/ip-neighbor/ip6_neighbor.h +++ b/src/vnet/ip-neighbor/ip6_neighbor.h @@ -86,7 +86,6 @@ ip6_neighbor_probe (vlib_main_t * vm, ip6_tcp_udp_icmp_compute_checksum (vm, 0, &h0->ip, &bogus_length); ASSERT (bogus_length == 0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index; diff --git a/src/vnet/ip/ip_frag.c b/src/vnet/ip/ip_frag.c index 33fbb9b2a9d..cafa9a66d6b 100644 --- a/src/vnet/ip/ip_frag.c +++ b/src/vnet/ip/ip_frag.c @@ -77,7 +77,6 @@ frag_buffer_alloc (vlib_buffer_t * org_b, u32 * bi) return 0; vlib_buffer_t *b = vlib_get_buffer (vm, *bi); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); vlib_buffer_copy_trace_flag (vm, org_b, *bi); return b; diff --git a/src/vnet/ip/punt_node.c b/src/vnet/ip/punt_node.c index 90953e63704..7f9beef0ffe 100644 --- a/src/vnet/ip/punt_node.c +++ b/src/vnet/ip/punt_node.c @@ -546,8 +546,6 @@ punt_socket_rx_fd (vlib_main_t * vm, vlib_node_runtime_t * node, u32 fd) b->flags = VNET_BUFFER_F_LOCALLY_ORIGINATED; b->current_length = size - sizeof (packetdesc); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); - switch (packetdesc.action) { case PUNT_L2: diff --git a/src/vnet/ip6-nd/ip6_ra.c b/src/vnet/ip6-nd/ip6_ra.c index 547ecf31034..270e428afad 100644 --- a/src/vnet/ip6-nd/ip6_ra.c +++ b/src/vnet/ip6-nd/ip6_ra.c @@ -1132,7 +1132,6 @@ create_buffer_for_rs (vlib_main_t * vm, ip6_ra_t * radv_info) } p0 = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (p0); p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; vnet_buffer (p0)->sw_if_index[VLIB_RX] = sw_if_index; diff --git a/src/vnet/ipfix-export/flow_report.c b/src/vnet/ipfix-export/flow_report.c index a831c3cbede..5d25bb5d413 100644 --- a/src/vnet/ipfix-export/flow_report.c +++ b/src/vnet/ipfix-export/flow_report.c @@ -119,9 +119,6 @@ send_template_packet (flow_report_main_t * frm, b0 = vlib_get_buffer (vm, bi0); - /* Initialize the buffer */ - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - ASSERT (vec_len (fr->rewrite) < vlib_buffer_get_default_data_size (vm)); clib_memcpy_fast (b0->data, fr->rewrite, vec_len (fr->rewrite)); diff --git a/src/vnet/ipfix-export/ipfix_doc.md b/src/vnet/ipfix-export/ipfix_doc.md index 1c7aad7750d..edae3f73660 100644 --- a/src/vnet/ipfix-export/ipfix_doc.md +++ b/src/vnet/ipfix-export/ipfix_doc.md @@ -299,7 +299,6 @@ This function creates the packet header for an ipfix data packet } b0 = vlib_get_buffer (vm, bi0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); offset = 0; mlm->buffers_by_thread[thread_index] = b0; } diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index 9fae9996698..d30df33a5e7 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -1141,9 +1141,6 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk, n_left -= 2; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b1); - vec_add1 (wrk->pending_tx_buffers, bi0); vec_add1 (wrk->pending_tx_buffers, bi1); vec_add1 (wrk->pending_tx_nexts, next_index); @@ -1171,8 +1168,6 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk, n_left -= 1; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - vec_add1 (wrk->pending_tx_buffers, bi0); vec_add1 (wrk->pending_tx_nexts, next_index); } diff --git a/src/vnet/syslog/syslog.c b/src/vnet/syslog/syslog.c index 20728b8a17a..8f3313950e8 100644 --- a/src/vnet/syslog/syslog.c +++ b/src/vnet/syslog/syslog.c @@ -170,7 +170,6 @@ syslog_msg_send (syslog_msg_t * syslog_msg) return -1; b = vlib_get_buffer (vm, bi); - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); /* one message per UDP datagram RFC5426 3.1. */ tmp = format (0, "%U", format_syslog_msg, syslog_msg); diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h index 23b61313568..a02a295e72b 100644 --- a/src/vnet/tcp/tcp.h +++ b/src/vnet/tcp/tcp.h @@ -288,15 +288,6 @@ tcp_get_worker (u32 thread_index) return &tcp_main.wrk_ctx[thread_index]; } -#if (VLIB_BUFFER_TRACE_TRAJECTORY) -#define tcp_trajectory_add_start(b, start) \ -{ \ - (*vlib_buffer_trace_trajectory_cb) (b, start); \ -} -#else -#define tcp_trajectory_add_start(b, start) -#endif - tcp_connection_t *tcp_connection_alloc (u8 thread_index); tcp_connection_t *tcp_connection_alloc_w_base (u8 thread_index, tcp_connection_t * base); diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index dac50b5bf40..bde06da87ed 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -345,7 +345,7 @@ tcp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b) b->current_length = 0; b->total_length_not_including_first_buffer = 0; vnet_buffer (b)->tcp.flags = 0; - + VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); /* Leave enough space for headers */ return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN); } @@ -359,7 +359,6 @@ tcp_init_buffer (vlib_main_t * vm, vlib_buffer_t * b) b->total_length_not_including_first_buffer = 0; b->current_data = 0; vnet_buffer (b)->tcp.flags = 0; - VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b); /* Leave enough space for headers */ return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN); } @@ -555,8 +554,6 @@ tcp_enqueue_to_ip_lookup (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi, vnet_buffer (b)->sw_if_index[VLIB_TX] = fib_index; vnet_buffer (b)->sw_if_index[VLIB_RX] = 0; - tcp_trajectory_add_start (b, 1); - session_add_pending_tx_buffer (vm->thread_index, bi, tm->ipl_next_node[!is_ip4]); @@ -633,7 +630,6 @@ tcp_make_reset_in_place (vlib_main_t * vm, vlib_buffer_t * b, u8 is_ip4) } tcp_reuse_buffer (vm, b); - tcp_trajectory_add_start (b, 4); th = vlib_buffer_push_tcp_net_order (b, dst_port, src_port, seq, ack, sizeof (tcp_header_t), flags, 0); @@ -1018,7 +1014,6 @@ tcp_session_push_header (transport_connection_t * tconn, vlib_buffer_t * b) tcp_retransmit_timer_set (&wrk->timer_wheel, tc); tc->rto_boff = 0; } - tcp_trajectory_add_start (b, 3); return 0; } diff --git a/src/vnet/unix/gdb_funcs.c b/src/vnet/unix/gdb_funcs.c index 797cb0eb7d1..886d849c173 100644 --- a/src/vnet/unix/gdb_funcs.c +++ b/src/vnet/unix/gdb_funcs.c @@ -380,6 +380,47 @@ gdb_validate_buffer (vlib_buffer_t * b) return 0; } +/** + * Dump a trajectory trace, reasonably easy to call from gdb + */ +void +gdb_dump_trajectory_trace (u32 bi) +{ +#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 + vlib_main_t *vm = vlib_get_main (); + vlib_node_main_t *vnm = &vm->node_main; + vlib_buffer_t *b; + u16 *trace; + u8 i; + + b = vlib_get_buffer (vm, bi); + + trace = b->trajectory_trace; + + fformat (stderr, "Context trace for bi %d b 0x%llx, visited %d\n", bi, b, + b->trajectory_nb); + + for (i = 0; i < b->trajectory_nb; i++) + { + u32 node_index; + + node_index = trace[i]; + + if (node_index >= vec_len (vnm->nodes)) + { + fformat (stderr, "Skip bogus node index %d\n", node_index); + continue; + } + + fformat (stderr, "%v (%d)\n", vnm->nodes[node_index]->name, node_index); + } +#else + fformat (stderr, "in vlib/buffers.h, " + "#define VLIB_BUFFER_TRACE_TRAJECTORY 1\n"); + +#endif +} + /* Cafeteria plan, maybe you don't want these functions */ clib_error_t * gdb_func_init (vlib_main_t * vm) diff --git a/src/vnet/unix/tuntap.c b/src/vnet/unix/tuntap.c index 50f02df9e82..4a848349ae1 100644 --- a/src/vnet/unix/tuntap.c +++ b/src/vnet/unix/tuntap.c @@ -336,14 +336,6 @@ tuntap_rx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) vnet_buffer (b)->sw_if_index[VLIB_RX] = tm->sw_if_index; vnet_buffer (b)->sw_if_index[VLIB_TX] = (u32) ~ 0; - /* - * Turn this on if you run into - * "bad monkey" contexts, and you want to know exactly - * which nodes they've visited... - */ - if (VLIB_BUFFER_TRACE_TRAJECTORY) - b->pre_data[0] = 0; - b->error = node->errors[0]; if (tm->is_ether) diff --git a/src/vnet/util/trajectory.c b/src/vnet/util/trajectory.c deleted file mode 100644 index 2538c7ee64a..00000000000 --- a/src/vnet/util/trajectory.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2017 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * Buffer trace trajectory utilities - */ - -#include <vnet/vnet.h> - -/** - * Dump a trajectory trace, reasonably easy to call from gdb - */ -void -vnet_dump_trajectory_trace (vlib_main_t * vm, u32 bi) -{ -#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 - vlib_node_main_t *vnm = &vm->node_main; - vlib_buffer_t *b; - u16 *trace; - u8 i; - - b = vlib_get_buffer (vm, bi); - - trace = vnet_buffer2 (b)->trajectory_trace; - - fformat (stderr, "Context trace for bi %d b 0x%llx, visited %d\n", - bi, b, vec_len (trace)); - - for (i = 0; i < vec_len (trace); i++) - { - u32 node_index; - - node_index = trace[i]; - - if (node_index >= vec_len (vnm->nodes)) - { - fformat (stderr, "Skip bogus node index %d\n", node_index); - continue; - } - - fformat (stderr, "%v (%d)\n", vnm->nodes[node_index]->name, node_index); - } -#else - fformat (stderr, "in vlib/buffers.h, " - "#define VLIB_BUFFER_TRACE_TRAJECTORY 1\n"); - -#endif -} - -#if VLIB_BUFFER_TRACE_TRAJECTORY > 0 - -void -init_trajectory_trace (vlib_buffer_t * b) -{ - if (!clib_mem_is_vec (vnet_buffer2 (b)->trajectory_trace)) - { - vnet_buffer2 (b)->trajectory_trace = 0; - vec_validate (vnet_buffer2 (b)->trajectory_trace, 7); - } - _vec_len (vnet_buffer2 (b)->trajectory_trace) = 0; -} - -void -add_trajectory_trace (vlib_buffer_t * b, u32 node_index) -{ - vec_add1 (vnet_buffer2 (b)->trajectory_trace, (u16) node_index); -} - -static clib_error_t * -trajectory_trace_init (vlib_main_t * vm) -{ - vlib_buffer_trace_trajectory_cb = add_trajectory_trace; - vlib_buffer_trace_trajectory_init_cb = init_trajectory_trace; - return 0; -} - -VLIB_INIT_FUNCTION (trajectory_trace_init); - -#endif - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |