*/
#include <vlib/vlib.h>
#include <vnet/vnet.h>
-#include <vnet/pg/pg.h>
#include <vppinfra/error.h>
#include <vpp/app/version.h>
#include <vppinfra/elog.h>
#include <vnet/plugin/plugin.h>
+#include <ioam/lib-trace/trace_util.h>
+#include <ioam/lib-trace/trace_config.h>
#include <ioam/encap/ip6_ioam_trace.h>
+#include <ioam/udp-ping/udp_ping.h>
+#include <ioam/udp-ping/udp_ping_packet.h>
+#include <ioam/udp-ping/udp_ping_util.h>
/* Timestamp precision multipliers for seconds, milliseconds, microseconds
* and nanoseconds respectively.
_(PROCESSED, "Pkts with ip6 hop-by-hop trace options") \
_(PROFILE_MISS, "Pkts with ip6 hop-by-hop trace options but no profile set") \
_(UPDATED, "Pkts with trace updated") \
- _(FULL, "Pkts with trace options but no space")
+ _(FULL, "Pkts with trace options but no space") \
+ _(LOOPBACK, "Pkts with trace options Loopback") \
+ _(LOOPBACK_REPLY, "Pkts with trace options Loopback Reply")
static char *ip6_hop_by_hop_ioam_trace_stats_strings[] = {
#define _(sym,string) string,
return 0;
}
+always_inline void
+ip6_hbh_ioam_loopback_handler (vlib_buffer_t * b, ip6_header_t * ip,
+ ioam_trace_option_t * trace)
+{
+ u32 buf_index;
+ ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
+ vlib_buffer_t *b0;
+ vlib_frame_t *nf = 0;
+ u32 *to_next;
+ vlib_node_t *next_node;
+ ip6_header_t *ip6;
+ ip6_hop_by_hop_header_t *hbh;
+ ioam_trace_option_t *opt;
+ udp_ping_t *udp;
+
+ b0 = vlib_buffer_copy (hm->vlib_main, b);
+ if (b0 == NULL)
+ return;
+
+ buf_index = vlib_get_buffer_index (hm->vlib_main, b0);
+ next_node = vlib_get_node_by_name (hm->vlib_main, (u8 *) "ip6-lookup");
+ nf = vlib_get_frame_to_node (hm->vlib_main, next_node->index);
+ nf->n_vectors = 0;
+ to_next = vlib_frame_vector_args (nf);
+
+ vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+
+ ip6 = vlib_buffer_get_current (b0);
+ hbh = (ip6_hop_by_hop_header_t *) (ip6 + 1);
+ opt = (ioam_trace_option_t *)
+ ip6_hbh_get_option (hbh, HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST);
+
+ udp = (udp_ping_t *) ((u8 *) hbh + ((hbh->length + 1) << 3));
+ udp_ping_create_reply_from_probe_ip6 (ip6, hbh, udp);
+ ip6_hbh_ioam_trace_set_bit (opt, BIT_LOOPBACK_REPLY);
+
+ *to_next = buf_index;
+ nf->n_vectors++;
+ to_next++;
+
+ vlib_put_frame_to_node (hm->vlib_main, next_node->index, nf);
+ ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_LOOPBACK, 1);
+}
int
ip6_hbh_ioam_trace_data_list_handler (vlib_buffer_t * b, ip6_header_t * ip,
ip6_hop_by_hop_option_t * opt)
{
- ip6_main_t *im = &ip6_main;
- ip_lookup_main_t *lm = &im->lookup_main;
ip6_hop_by_hop_ioam_main_t *hm = &ip6_hop_by_hop_ioam_main;
u8 elt_index = 0;
ioam_trace_option_t *trace = (ioam_trace_option_t *) opt;
u32 adj_index = vnet_buffer (b)->ip.adj_index[VLIB_TX];
- ip_adjacency_t *adj = ip_get_adjacency (lm, adj_index);
+ ip_adjacency_t *adj = adj_get (adj_index);
time_u64_t time_u64;
u32 *elt;
int rv = 0;
return (-1);
}
+ /* Don't trace loopback reply packets */
+ if (trace->trace_hdr.ioam_trace_type & BIT_LOOPBACK_REPLY)
+ {
+ ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_LOOPBACK_REPLY,
+ 1);
+ return rv;
+ }
time_u64.as_u64 = 0;
*elt = clib_host_to_net_u32 (profile->app_data);
elt++;
}
+
+
+ if (PREDICT_FALSE (trace->trace_hdr.ioam_trace_type & BIT_LOOPBACK))
+ {
+ /* if loopback flag set then copy the packet
+ * and send it back to source */
+ ip6_hbh_ioam_loopback_handler (b, ip, trace);
+ }
+
ip6_ioam_trace_stats_increment_counter (IP6_IOAM_TRACE_UPDATED, 1);
}
else
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
+ .description = "Inbound Operations, Administration, and Maintenance (OAM)",
};
/* *INDENT-ON* */
ip6_hop_by_hop_ioam_trace_init (vlib_main_t * vm)
{
ip6_hop_by_hop_ioam_trace_main_t *hm = &ip6_hop_by_hop_ioam_trace_main;
- clib_error_t *error;
-
- if ((error = vlib_call_init_function (vm, ip_main_init)))
- return (error);
-
- if ((error = vlib_call_init_function (vm, ip6_lookup_init)))
- return error;
-
- if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init)))
- return (error);
hm->vlib_main = vm;
hm->vnet_main = vnet_get_main ();
- memset (hm->counters, 0, sizeof (hm->counters));
+ clib_memset (hm->counters, 0, sizeof (hm->counters));
if (ip6_hbh_register_option
return (0);
}
+/* *INDENT-OFF* */
+VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_trace_init) =
+{
+ .runs_after = VLIB_INITS ("ip_main_init", "ip6_lookup_init",
+ "ip6_hop_by_hop_ioam_init"),
+};
+/* *INDENT-ON* */
+
int
ip6_trace_profile_cleanup (void)
{
return (0);
}
-
-VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_trace_init);
-
/*
* fd.io coding-style-patch-verification: ON
*