aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/ioam/encap
diff options
context:
space:
mode:
authorAkshayaNadahalli <anadahal@cisco.com>2016-12-01 16:33:51 +0530
committerNeale Ranns <nranns@cisco.com>2017-02-13 08:36:59 +0000
commitfdd81af6afe6c782ad2c1a139210378badec626b (patch)
treeb562b391bded3afc0f5b4d0f83eceb20f2c8e772 /src/plugins/ioam/encap
parentfed79e83910459ed700615d2a5a24024f835a66c (diff)
VPP-632 : InBand OAM Analyser
Refer to jira ticket for more details. Change-Id: I6facb9ef8553a21464f9a2e612706f152badbb68 Signed-off-by: AkshayaNadahalli <anadahal@cisco.com>
Diffstat (limited to 'src/plugins/ioam/encap')
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_e2e.c4
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_e2e.h17
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_pot.c21
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_pot.h40
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_seqno.c43
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_seqno.h42
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_seqno_analyse.c141
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_trace.c50
-rw-r--r--src/plugins/ioam/encap/ip6_ioam_trace.h38
9 files changed, 128 insertions, 268 deletions
diff --git a/src/plugins/ioam/encap/ip6_ioam_e2e.c b/src/plugins/ioam/encap/ip6_ioam_e2e.c
index 2831a351..cdaf740d 100644
--- a/src/plugins/ioam/encap/ip6_ioam_e2e.c
+++ b/src/plugins/ioam/encap/ip6_ioam_e2e.c
@@ -37,7 +37,7 @@ static u8 * ioam_e2e_trace_handler (u8 * s,
if (e2e)
{
- seqno = clib_net_to_host_u32 (e2e->e2e_data);
+ seqno = clib_net_to_host_u32 (e2e->e2e_hdr.e2e_data);
}
s = format (s, "SeqNo = 0x%Lx", seqno);
@@ -108,7 +108,7 @@ ioam_e2e_flow_handler (u32 ctx, u8 add)
{
pool_get(ioam_e2e_main.e2e_data, data);
data->flow_ctx = ctx;
- ioam_seqno_init_bitmap(&data->seqno_data);
+ ioam_seqno_init_data(&data->seqno_data);
return ((u32) (data - ioam_e2e_main.e2e_data));
}
diff --git a/src/plugins/ioam/encap/ip6_ioam_e2e.h b/src/plugins/ioam/encap/ip6_ioam_e2e.h
index 18f35f80..fcec4a14 100644
--- a/src/plugins/ioam/encap/ip6_ioam_e2e.h
+++ b/src/plugins/ioam/encap/ip6_ioam_e2e.h
@@ -16,8 +16,16 @@
#ifndef __included_ip6_ioam_e2e_h__
#define __included_ip6_ioam_e2e_h__
+#include "../lib-e2e/e2e_util.h"
#include "ip6_ioam_seqno.h"
+/* *INDENT-OFF* */
+typedef CLIB_PACKED(struct {
+ ip6_hop_by_hop_option_t hdr;
+ ioam_e2e_packet_t e2e_hdr;
+}) ioam_e2e_option_t;
+/* *INDENT-ON* */
+
typedef struct ioam_e2e_data_t_ {
u32 flow_ctx;
u32 pad;
@@ -44,4 +52,13 @@ ioam_e2ec_get_seqno_data_from_flow_ctx (u32 flow_ctx)
return &(data->seqno_data);
}
+static inline u32
+ioam_e2e_get_cur_seqno_from_flow_ctx (u32 flow_ctx)
+{
+ ioam_seqno_data *data = NULL;
+
+ data = ioam_e2ec_get_seqno_data_from_flow_ctx(flow_ctx);
+ return data->seq_num;
+}
+
#endif /* __included_ioam_e2e_h__ */
diff --git a/src/plugins/ioam/encap/ip6_ioam_pot.c b/src/plugins/ioam/encap/ip6_ioam_pot.c
index 05f42c91..9a761233 100644
--- a/src/plugins/ioam/encap/ip6_ioam_pot.c
+++ b/src/plugins/ioam/encap/ip6_ioam_pot.c
@@ -16,26 +16,15 @@
#include <vnet/vnet.h>
#include <vnet/pg/pg.h>
#include <vppinfra/error.h>
-
#include <vnet/ip/ip6.h>
-#include <vnet/ip/ip6_hop_by_hop.h>
-#include <vnet/ip/ip6_hop_by_hop_packet.h>
#include <vppinfra/hash.h>
#include <vppinfra/error.h>
#include <vppinfra/elog.h>
+#include <ioam/encap/ip6_ioam_pot.h>
#include <ioam/lib-pot/pot_util.h>
-typedef CLIB_PACKED(struct {
- ip6_hop_by_hop_option_t hdr;
- u8 pot_type;
-#define PROFILE_ID_MASK 0xF
- u8 reserved_profile_id; /* 4 bits reserved, 4 bits to carry profile id */
- u64 random;
- u64 cumulative;
-}) ioam_pot_option_t;
-
#define foreach_ip6_hop_by_hop_ioam_pot_stats \
_(PROCESSED, "Pkts with ip6 hop-by-hop pot options") \
_(PROFILE_MISS, "Pkts with ip6 hop-by-hop pot options but no profile set") \
@@ -180,19 +169,19 @@ ip6_hbh_ioam_proof_of_transit_pop_handler (vlib_buffer_t *b, ip6_header_t *ip,
int rv = 0;
pot_profile *pot_profile = 0;
u8 result = 0;
-
+
pot0 = (ioam_pot_option_t *) opt0;
random = clib_net_to_host_u64(pot0->random);
cumulative = clib_net_to_host_u64(pot0->cumulative);
pot_profile = pot_profile_get_active();
result = pot_validate (pot_profile,
cumulative, random);
-
- if (result == 1)
+
+ if (result == 1)
{
ip6_ioam_stats_increment_counter (IP6_IOAM_POT_PASSED, 1);
}
- else
+ else
{
ip6_ioam_stats_increment_counter (IP6_IOAM_POT_FAILED, 1);
}
diff --git a/src/plugins/ioam/encap/ip6_ioam_pot.h b/src/plugins/ioam/encap/ip6_ioam_pot.h
new file mode 100644
index 00000000..01ce4ac5
--- /dev/null
+++ b/src/plugins/ioam/encap/ip6_ioam_pot.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef PLUGINS_IOAM_PLUGIN_IOAM_ENCAP_IP6_IOAM_POT_H_
+#define PLUGINS_IOAM_PLUGIN_IOAM_ENCAP_IP6_IOAM_POT_H_
+
+#include <vnet/ip/ip6_hop_by_hop_packet.h>
+
+/* *INDENT-OFF* */
+typedef CLIB_PACKED (struct {
+ ip6_hop_by_hop_option_t hdr;
+ u8 pot_type;
+ #define PROFILE_ID_MASK 0xF
+ u8 reserved_profile_id; /* 4 bits reserved, 4 bits to carry profile id */
+ u64 random;
+ u64 cumulative;
+}) ioam_pot_option_t;
+/* *INDENT-ON* */
+
+#endif /* PLUGINS_IOAM_PLUGIN_IOAM_ENCAP_IP6_IOAM_POT_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/ioam/encap/ip6_ioam_seqno.c b/src/plugins/ioam/encap/ip6_ioam_seqno.c
index 0b4d4192..01977123 100644
--- a/src/plugins/ioam/encap/ip6_ioam_seqno.c
+++ b/src/plugins/ioam/encap/ip6_ioam_seqno.c
@@ -28,20 +28,6 @@
#include "ip6_ioam_seqno.h"
#include "ip6_ioam_e2e.h"
-ioam_seqno_data_main_t ioam_seqno_main;
-
-void ioam_seqno_init_bitmap (ioam_seqno_data *data)
-{
- seqno_bitmap *bitmap = &data->seqno_rx.bitmap;
- bitmap->window_size = SEQNO_WINDOW_SIZE;
- bitmap->array_size = SEQNO_WINDOW_ARRAY_SIZE;
- bitmap->mask = 32 * SEQNO_WINDOW_ARRAY_SIZE - 1;
- bitmap->array[0] = 0x00000000;/* pretend we haven seen sequence numbers 0*/
- bitmap->highest = 0;
-
- data->seq_num = 0;
- return ;
-}
/*
* This Routine gets called from IPv6 hop-by-hop option handling.
@@ -60,7 +46,7 @@ ioam_seqno_encap_handler (vlib_buffer_t *b, ip6_header_t *ip,
data = ioam_e2ec_get_seqno_data_from_flow_ctx(opaque_index);
e2e = (ioam_e2e_option_t *) opt;
- e2e->e2e_data = clib_host_to_net_u32(++data->seq_num);
+ e2e->e2e_hdr.e2e_data = clib_host_to_net_u32(++data->seq_num);
return (rv);
}
@@ -79,31 +65,8 @@ ioam_seqno_decap_handler (vlib_buffer_t *b, ip6_header_t *ip,
data = ioam_e2ec_get_seqno_data_from_flow_ctx(opaque_index);
e2e = (ioam_e2e_option_t *) opt;
- ioam_analyze_seqno(&data->seqno_rx, (u64) clib_net_to_host_u32(e2e->e2e_data));
+ ioam_analyze_seqno(&data->seqno_rx,
+ (u64) clib_net_to_host_u32(e2e->e2e_hdr.e2e_data));
return (rv);
}
-
-u8 *
-show_ioam_seqno_cmd_fn (u8 *s, ioam_seqno_data *seqno_data, u8 enc)
-{
- seqno_rx_info *rx;
-
- s = format(s, "SeqNo Data:\n");
- if (enc)
- {
- s = format(s, " Current Seq. Number : %llu\n", seqno_data->seq_num);
- }
- else
- {
- rx = &seqno_data->seqno_rx;
- s = format(s, " Highest Seq. Number : %llu\n", rx->bitmap.highest);
- s = format(s, " Packets received : %llu\n", rx->rx_packets);
- s = format(s, " Lost packets : %llu\n", rx->lost_packets);
- s = format(s, " Reordered packets : %llu\n", rx->reordered_packets);
- s = format(s, " Duplicate packets : %llu\n", rx->dup_packets);
- }
-
- format(s, "\n");
- return s;
-}
diff --git a/src/plugins/ioam/encap/ip6_ioam_seqno.h b/src/plugins/ioam/encap/ip6_ioam_seqno.h
index 13a84db0..5c140246 100644
--- a/src/plugins/ioam/encap/ip6_ioam_seqno.h
+++ b/src/plugins/ioam/encap/ip6_ioam_seqno.h
@@ -18,42 +18,7 @@
#include <vnet/ip/ip6_packet.h>
#include <vnet/ip/ip6_hop_by_hop.h>
-
-#define SEQ_CHECK_VALUE 0x80000000 /* for seq number wraparound detection */
-
-#define SEQNO_WINDOW_SIZE 2048
-#define SEQNO_WINDOW_ARRAY_SIZE 64
-
-typedef struct seqno_bitmap_ {
- u32 window_size;
- u32 array_size;
- u32 mask;
- u32 pad;
- u64 highest;
- u64 array[SEQNO_WINDOW_ARRAY_SIZE]; /* Will be alloc to array_size */
-} seqno_bitmap;
-
-typedef struct seqno_rx_info_ {
- u64 rx_packets;
- u64 lost_packets;
- u64 reordered_packets;
- u64 dup_packets;
- seqno_bitmap bitmap;
-} seqno_rx_info;
-
-/* This structure is 64-byte aligned */
-typedef struct ioam_seqno_data_ {
- union {
- u32 seq_num; /* Useful only for encap node */
- seqno_rx_info seqno_rx;
- };
-} ioam_seqno_data;
-
-typedef struct ioam_seqno_data_main_t_ {
- ioam_seqno_data *seqno_data;
-} ioam_seqno_data_main_t;
-
-void ioam_seqno_init_bitmap(ioam_seqno_data *data);
+#include <ioam/lib-e2e/e2e_util.h>
int ioam_seqno_encap_handler(vlib_buffer_t *b, ip6_header_t *ip,
ip6_hop_by_hop_option_t *opt);
@@ -62,9 +27,4 @@ int
ioam_seqno_decap_handler(vlib_buffer_t *b, ip6_header_t *ip,
ip6_hop_by_hop_option_t *opt);
-void ioam_analyze_seqno(seqno_rx_info *ppc_rx, u64 seqno);
-
-u8 *
-show_ioam_seqno_cmd_fn(u8 *s, ioam_seqno_data *seqno_data, u8 enc);
-
#endif
diff --git a/src/plugins/ioam/encap/ip6_ioam_seqno_analyse.c b/src/plugins/ioam/encap/ip6_ioam_seqno_analyse.c
deleted file mode 100644
index 4638871c..00000000
--- a/src/plugins/ioam/encap/ip6_ioam_seqno_analyse.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2016 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.
- */
-
-#include <vnet/vnet.h>
-#include "ip6_ioam_seqno.h"
-
-static inline void BIT_SET (u64 *p, u32 n)
-{
- p[ n>>5 ] |= (1 << (n&31));
-}
-
-static inline int BIT_TEST (u64 *p, u32 n)
-{
- return p[ n>>5 ] & (1 << (n&31));
-}
-
-static void BIT_CLEAR (u64 *p, u64 start, int num_bits, u32 mask)
-{
- int n, t;
- int start_index = (start >> 5);
- int mask_index = (mask >> 5);
-
- start_index &= mask_index;
- if (start & 0x1f)
- {
- int start_bit = (start & 0x1f);
-
- n = (1 << start_bit)-1;
- t = start_bit + num_bits;
- if (t < 32)
- {
- n |= ~((1 << t)-1);
- p[ start_index ] &= n;
- return;
- }
- p[ start_index ] &= n;
- start_index = (start_index + 1) & mask_index;
- num_bits -= (32 - start_bit);
- }
- while (num_bits >= 32)
- {
- p[ start_index ] = 0;
- start_index = (start_index + 1) & mask_index;
- num_bits -= 32;
- }
- n = ~((1 << num_bits) - 1);
- p[ start_index ] &= n;
-}
-
-static inline u8 seqno_check_wraparound(u32 a, u32 b)
-{
- if ((a != b) && (a > b) && ((a - b) > SEQ_CHECK_VALUE))
- {
- return 1;
- }
- return 0;
-}
-
-/*
- * Function to analyze the PPC value recevied.
- * - Updates the bitmap with received sequence number
- * - counts the received/lost/duplicate/reordered packets
- */
-void ioam_analyze_seqno (seqno_rx_info *seqno_rx, u64 seqno)
-{
- int diff;
- static int peer_dead_count;
- seqno_bitmap *bitmap = &seqno_rx->bitmap;
-
- seqno_rx->rx_packets++;
-
- if (seqno > bitmap->highest)
- { /* new larger sequence number */
- peer_dead_count = 0;
- diff = seqno - bitmap->highest;
- if (diff < bitmap->window_size)
- {
- if (diff > 1)
- { /* diff==1 is *such* a common case it's a win to optimize it */
- BIT_CLEAR(bitmap->array, bitmap->highest+1, diff-1, bitmap->mask);
- seqno_rx->lost_packets += diff -1;
- }
- }
- else
- {
- seqno_rx->lost_packets += diff -1;
- memset( bitmap->array, 0, bitmap->array_size * sizeof(u64) );
- }
- BIT_SET(bitmap->array, seqno & bitmap->mask);
- bitmap->highest = seqno;
- return;
- }
-
- /* we've seen a bigger seq number before */
- diff = bitmap->highest - seqno;
- if (diff >= bitmap->window_size)
- {
- if (seqno_check_wraparound(bitmap->highest, seqno))
- {
- memset( bitmap->array, 0, bitmap->array_size * sizeof(u64));
- BIT_SET(bitmap->array, seqno & bitmap->mask);
- bitmap->highest = seqno;
- return;
- }
- else
- {
- peer_dead_count++;
- if (peer_dead_count > 25)
- {
- peer_dead_count = 0;
- memset( bitmap->array, 0, bitmap->array_size * sizeof(u64) );
- BIT_SET(bitmap->array, seqno & bitmap->mask);
- bitmap->highest = seqno;
- }
- //ppc_rx->reordered_packets++;
- }
- return;
- }
-
- if (BIT_TEST(bitmap->array, seqno & bitmap->mask))
- {
- seqno_rx->dup_packets++;
- return; /* Already seen */
- }
- seqno_rx->reordered_packets++;
- seqno_rx->lost_packets--;
- BIT_SET(bitmap->array, seqno & bitmap->mask);
- return;
-}
diff --git a/src/plugins/ioam/encap/ip6_ioam_trace.c b/src/plugins/ioam/encap/ip6_ioam_trace.c
index a836dfe8..6972ba4b 100644
--- a/src/plugins/ioam/encap/ip6_ioam_trace.c
+++ b/src/plugins/ioam/encap/ip6_ioam_trace.c
@@ -27,7 +27,7 @@
#include <vppinfra/elog.h>
#include <vnet/plugin/plugin.h>
-#include <ioam/lib-trace/trace_util.h>
+#include <ioam/encap/ip6_ioam_trace.h>
/* Timestamp precision multipliers for seconds, milliseconds, microseconds
* and nanoseconds respectively.
@@ -40,15 +40,6 @@ typedef union
u32 as_u32[2];
} time_u64_t;
-/* *INDENT-OFF* */
-typedef CLIB_PACKED(struct {
- ip6_hop_by_hop_option_t hdr;
- u8 ioam_trace_type;
- u8 data_list_elts_left;
- u32 elts[0]; /* Variable type. So keep it generic */
-}) ioam_trace_option_t;
-/* *INDENT-ON* */
-
extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
extern ip6_main_t ip6_main;
@@ -201,8 +192,9 @@ ip6_hop_by_hop_ioam_trace_rewrite_handler (u8 * rewrite_string,
HBH_OPTION_TYPE_DATA_CHANGE_ENROUTE;
trace_option->hdr.length = 2 /*ioam_trace_type,data_list_elts_left */ +
trace_option_elts * trace_data_size;
- trace_option->ioam_trace_type = profile->trace_type & TRACE_TYPE_MASK;
- trace_option->data_list_elts_left = trace_option_elts;
+ trace_option->trace_hdr.ioam_trace_type =
+ profile->trace_type & TRACE_TYPE_MASK;
+ trace_option->trace_hdr.data_list_elts_left = trace_option_elts;
*rewrite_size =
sizeof (ioam_trace_option_t) + (trace_option_elts * trace_data_size);
@@ -238,24 +230,24 @@ ip6_hbh_ioam_trace_data_list_handler (vlib_buffer_t * b, ip6_header_t * ip,
time_u64.as_u64 = 0;
- if (PREDICT_TRUE (trace->data_list_elts_left))
+ if (PREDICT_TRUE (trace->trace_hdr.data_list_elts_left))
{
- trace->data_list_elts_left--;
+ trace->trace_hdr.data_list_elts_left--;
/* fetch_trace_data_size returns in bytes. Convert it to 4-bytes
* to skip to this node's location.
*/
elt_index =
- trace->data_list_elts_left *
- fetch_trace_data_size (trace->ioam_trace_type) / 4;
- elt = &trace->elts[elt_index];
- if (trace->ioam_trace_type & BIT_TTL_NODEID)
+ trace->trace_hdr.data_list_elts_left *
+ fetch_trace_data_size (trace->trace_hdr.ioam_trace_type) / 4;
+ elt = &trace->trace_hdr.elts[elt_index];
+ if (trace->trace_hdr.ioam_trace_type & BIT_TTL_NODEID)
{
*elt =
clib_host_to_net_u32 ((ip->hop_limit << 24) | profile->node_id);
elt++;
}
- if (trace->ioam_trace_type & BIT_ING_INTERFACE)
+ if (trace->trace_hdr.ioam_trace_type & BIT_ING_INTERFACE)
{
*elt =
(vnet_buffer (b)->sw_if_index[VLIB_RX] & 0xFFFF) << 16 |
@@ -264,7 +256,7 @@ ip6_hbh_ioam_trace_data_list_handler (vlib_buffer_t * b, ip6_header_t * ip,
elt++;
}
- if (trace->ioam_trace_type & BIT_TIMESTAMP)
+ if (trace->trace_hdr.ioam_trace_type & BIT_TIMESTAMP)
{
/* Send least significant 32 bits */
f64 time_f64 =
@@ -276,7 +268,7 @@ ip6_hbh_ioam_trace_data_list_handler (vlib_buffer_t * b, ip6_header_t * ip,
elt++;
}
- if (trace->ioam_trace_type & BIT_APPDATA)
+ if (trace->trace_hdr.ioam_trace_type & BIT_APPDATA)
{
/* $$$ set elt0->app_data */
*elt = clib_host_to_net_u32 (profile->app_data);
@@ -302,17 +294,19 @@ ip6_hbh_ioam_trace_data_list_trace_handler (u8 * s,
trace = (ioam_trace_option_t *) opt;
s =
- format (s, " Trace Type 0x%x , %d elts left\n", trace->ioam_trace_type,
- trace->data_list_elts_left);
+ format (s, " Trace Type 0x%x , %d elts left\n",
+ trace->trace_hdr.ioam_trace_type,
+ trace->trace_hdr.data_list_elts_left);
trace_data_size_in_words =
- fetch_trace_data_size (trace->ioam_trace_type) / 4;
- elt = &trace->elts[0];
- while ((u8 *) elt < ((u8 *) (&trace->elts[0]) + trace->hdr.length - 2
- /* -2 accounts for ioam_trace_type,elts_left */ ))
+ fetch_trace_data_size (trace->trace_hdr.ioam_trace_type) / 4;
+ elt = &trace->trace_hdr.elts[0];
+ while ((u8 *) elt <
+ ((u8 *) (&trace->trace_hdr.elts[0]) + trace->hdr.length - 2
+ /* -2 accounts for ioam_trace_type,elts_left */ ))
{
s = format (s, " [%d] %U\n", elt_index,
format_ioam_data_list_element,
- elt, &trace->ioam_trace_type);
+ elt, &trace->trace_hdr.ioam_trace_type);
elt_index++;
elt += trace_data_size_in_words;
}
diff --git a/src/plugins/ioam/encap/ip6_ioam_trace.h b/src/plugins/ioam/encap/ip6_ioam_trace.h
new file mode 100644
index 00000000..b332b319
--- /dev/null
+++ b/src/plugins/ioam/encap/ip6_ioam_trace.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef PLUGINS_IOAM_PLUGIN_IOAM_ENCAP_IP6_IOAM_TRACE_H_
+#define PLUGINS_IOAM_PLUGIN_IOAM_ENCAP_IP6_IOAM_TRACE_H_
+
+#include <vnet/ip/ip6_hop_by_hop_packet.h>
+#include <ioam/lib-trace/trace_util.h>
+
+/* *INDENT-OFF* */
+typedef CLIB_PACKED(struct {
+ ip6_hop_by_hop_option_t hdr;
+ ioam_trace_hdr_t trace_hdr;
+}) ioam_trace_option_t;
+/* *INDENT-ON* */
+
+
+#endif /* PLUGINS_IOAM_PLUGIN_IOAM_ENCAP_IP6_IOAM_TRACE_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */