summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/ila-plugin/ila/ila.c124
-rw-r--r--plugins/ila-plugin/ila/ila.h13
2 files changed, 103 insertions, 34 deletions
diff --git a/plugins/ila-plugin/ila/ila.c b/plugins/ila-plugin/ila/ila.c
index 88ea58e8..69fbb82a 100644
--- a/plugins/ila-plugin/ila/ila.c
+++ b/plugins/ila-plugin/ila/ila.c
@@ -49,9 +49,10 @@ typedef struct {
u32 adj_index;
} ila_ila2sir_trace_t;
-static ila_entry_t ila_default_entry = {
+static ila_entry_t ila_sir2ila_default_entry = {
.csum_mode = ILA_CSUM_MODE_NO_ACTION,
.type = ILA_TYPE_IID,
+ .dir = ILA_DIR_ILA2SIR, //Will pass the packet with no
};
u8 *
@@ -64,6 +65,18 @@ format_half_ip6_address (u8 * s, va_list * va)
}
+u8 *
+format_ila_direction (u8 * s, va_list * args)
+{
+ ila_direction_t t = va_arg (*args, ila_direction_t);
+#define _(i,n,st) \
+ if (t == ILA_DIR_##i) \
+ return format(s, st);
+ ila_foreach_direction
+#undef _
+ return format (s, "invalid_ila_direction");
+}
+
static u8 *
format_csum_mode (u8 * s, va_list * va)
{
@@ -79,7 +92,7 @@ format_csum_mode (u8 * s, va_list * va)
ila_csum_foreach_type
#undef _
default:
- txt = "(unknown)";
+ txt = "invalid_ila_csum_mode";
break;
}
return format (s, txt);
@@ -94,7 +107,7 @@ format_ila_type (u8 * s, va_list * args)
return format(s, st);
ila_foreach_type
#undef _
- return format (s, "invalid type");
+ return format (s, "invalid_ila_type");
}
static u8 *
@@ -105,27 +118,29 @@ format_ila_entry (u8 * s, va_list * va)
if (!e)
{
- return format (s, "%-15s%=40s%=40s%+16s%+18s", "Type", "SIR Address",
- "ILA Address", "Adjacency Index", "Checksum Mode");
+ return format (s, "%-15s%=40s%=40s%+16s%+18s%+11s", "Type", "SIR Address",
+ "ILA Address", "Adjacency Index", "Checksum Mode", "Direction");
}
else if (vnm)
{
if (e->ila_adj_index == ~0)
{
- return format (s, "%-15U%=40U%=40U%16s%18U",
+ return format (s, "%-15U%=40U%=40U%16s%18U%11U",
format_ila_type, e->type,
format_ip6_address, &e->sir_address,
format_ip6_address, &e->ila_address,
- "n/a", format_csum_mode, e->csum_mode);
+ "n/a", format_csum_mode, e->csum_mode,
+ format_ila_direction, e->dir);
}
else
{
- return format (s, "%-15U%=40U%=40U%16d%18U",
+ return format (s, "%-15U%=40U%=40U%16d%18U%11U",
format_ila_type, e->type,
format_ip6_address, &e->sir_address,
format_ip6_address, &e->ila_address,
- e->ila_adj_index, format_csum_mode, e->csum_mode);
+ e->ila_adj_index, format_csum_mode, e->csum_mode,
+ format_ila_direction, e->dir);
}
}
@@ -145,6 +160,22 @@ format_ila_ila2sir_trace (u8 * s, va_list * args)
}
static uword
+unformat_ila_direction (unformat_input_t * input, va_list * args)
+{
+ ila_direction_t *result = va_arg (*args, ila_direction_t *);
+#define _(i,n,s) \
+ if (unformat(input, s)) \
+ { \
+ *result = ILA_DIR_##i; \
+ return 1;\
+ }
+
+ ila_foreach_direction
+#undef _
+ return 0;
+}
+
+static uword
unformat_ila_type (unformat_input_t * input, va_list * args)
{
ila_type_t *result = va_arg (*args, ila_type_t *);
@@ -228,6 +259,7 @@ ila_ila2sir (vlib_main_t * vm,
ila_entry_t *ie0, *ie1;
ip6_header_t *ip60, *ip61;
ila_adj_data_t *ad0, *ad1;
+ ip6_address_t *sir_address0, *sir_address1;
{
vlib_buffer_t *p2, *p3;
@@ -252,6 +284,8 @@ ila_ila2sir (vlib_main_t * vm,
p1 = vlib_get_buffer (vm, pi1);
ip60 = vlib_buffer_get_current (p0);
ip61 = vlib_buffer_get_current (p1);
+ sir_address0 = &ip60->dst_address;
+ sir_address1 = &ip61->dst_address;
adj0 =
ip_get_adjacency (lm, vnet_buffer (p0)->ip.adj_index[VLIB_TX]);
adj1 =
@@ -279,10 +313,12 @@ ila_ila2sir (vlib_main_t * vm,
tr->adj_index = vnet_buffer (p1)->ip.adj_index[VLIB_TX];
}
- ip60->dst_address.as_u64[0] = ie0->sir_address.as_u64[0];
- ip60->dst_address.as_u64[1] = ie0->sir_address.as_u64[1];
- ip61->dst_address.as_u64[0] = ie1->sir_address.as_u64[0];
- ip61->dst_address.as_u64[1] = ie1->sir_address.as_u64[1];
+ sir_address0 = (ie0->dir != ILA_DIR_SIR2ILA) ? &ie0->sir_address : sir_address0;
+ sir_address1 = (ie1->dir != ILA_DIR_SIR2ILA) ? &ie1->sir_address : sir_address1;
+ ip60->dst_address.as_u64[0] = sir_address0->as_u64[0];
+ ip60->dst_address.as_u64[1] = sir_address0->as_u64[1];
+ ip61->dst_address.as_u64[0] = sir_address1->as_u64[0];
+ ip61->dst_address.as_u64[1] = sir_address1->as_u64[1];
vnet_buffer (p0)->ip.adj_index[VLIB_TX] = ie0->ila_adj_index;
vnet_buffer (p1)->ip.adj_index[VLIB_TX] = ie1->ila_adj_index;
@@ -302,6 +338,7 @@ ila_ila2sir (vlib_main_t * vm,
ila_adj_data_t *ad0;
ila_entry_t *ie0;
ip6_header_t *ip60;
+ ip6_address_t *sir_address0;
pi0 = to_next[0] = from[0];
from += 1;
@@ -311,6 +348,7 @@ ila_ila2sir (vlib_main_t * vm,
p0 = vlib_get_buffer (vm, pi0);
ip60 = vlib_buffer_get_current (p0);
+ sir_address0 = &ip60->dst_address;
adj0 =
ip_get_adjacency (lm, vnet_buffer (p0)->ip.adj_index[VLIB_TX]);
ad0 = (ila_adj_data_t *) & adj0->opaque;
@@ -325,8 +363,9 @@ ila_ila2sir (vlib_main_t * vm,
tr->adj_index = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
}
- ip60->dst_address.as_u64[0] = ie0->sir_address.as_u64[0];
- ip60->dst_address.as_u64[1] = ie0->sir_address.as_u64[1];
+ sir_address0 = (ie0->dir != ILA_DIR_SIR2ILA) ? &ie0->sir_address : sir_address0;
+ ip60->dst_address.as_u64[0] = sir_address0->as_u64[0];
+ ip60->dst_address.as_u64[1] = sir_address0->as_u64[1];
vnet_buffer (p0)->ip.adj_index[VLIB_TX] = ie0->ila_adj_index;
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
@@ -402,8 +441,9 @@ ila_sir2ila (vlib_main_t * vm,
u32 next1 = ILA_SIR2ILA_NEXT_DROP;
BVT (clib_bihash_kv) kv0, value0;
BVT (clib_bihash_kv) kv1, value1;
- ila_entry_t *ie0 = &ila_default_entry;
- ila_entry_t *ie1 = &ila_default_entry;
+ ila_entry_t *ie0 = &ila_sir2ila_default_entry;
+ ila_entry_t *ie1 = &ila_sir2ila_default_entry;
+ ip6_address_t *ila_address0, *ila_address1;
{
vlib_buffer_t *p2, *p3;
@@ -428,6 +468,8 @@ ila_sir2ila (vlib_main_t * vm,
p1 = vlib_get_buffer (vm, pi1);
ip60 = vlib_buffer_get_current (p0);
ip61 = vlib_buffer_get_current (p1);
+ ila_address0 = &ip60->dst_address;
+ ila_address1 = &ip61->dst_address;
kv0.key[0] = ip60->dst_address.as_u64[0];
kv0.key[1] = ip60->dst_address.as_u64[1];
kv0.key[2] = 0;
@@ -435,20 +477,24 @@ ila_sir2ila (vlib_main_t * vm,
kv1.key[1] = ip61->dst_address.as_u64[1];
kv1.key[2] = 0;
- if ((BV (clib_bihash_search)
- (&ilm->id_to_entry_table, &kv0, &value0)) == 0)
- ie0 = &ilm->entries[value0.value];
+ if (PREDICT_TRUE((BV (clib_bihash_search)
+ (&ilm->id_to_entry_table, &kv0, &value0)) == 0)) {
+ ie0 = &ilm->entries[value0.value];
+ ila_address0 = (ie0->dir != ILA_DIR_ILA2SIR) ? &ie0->ila_address : ila_address0;
+ }
if ((BV (clib_bihash_search)
- (&ilm->id_to_entry_table, &kv1, &value1)) == 0)
+ (&ilm->id_to_entry_table, &kv1, &value1)) == 0) {
ie1 = &ilm->entries[value1.value];
+ ila_address1 = (ie1->dir != ILA_DIR_ILA2SIR) ? &ie1->ila_address : ila_address1;
+ }
if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
{
ila_sir2ila_trace_t *tr =
vlib_add_trace (vm, node, p0, sizeof (*tr));
tr->ila_index =
- (ie0 != &ila_default_entry) ? (ie0 - ilm->entries) : ~0;
+ (ie0 != &ila_sir2ila_default_entry) ? (ie0 - ilm->entries) : ~0;
tr->initial_dst = ip60->dst_address;
}
@@ -457,14 +503,14 @@ ila_sir2ila (vlib_main_t * vm,
ila_sir2ila_trace_t *tr =
vlib_add_trace (vm, node, p1, sizeof (*tr));
tr->ila_index =
- (ie1 != &ila_default_entry) ? (ie1 - ilm->entries) : ~0;
+ (ie1 != &ila_sir2ila_default_entry) ? (ie1 - ilm->entries) : ~0;
tr->initial_dst = ip61->dst_address;
}
- ip60->dst_address.as_u64[0] = ie0->ila_address.as_u64[0];
- ip60->dst_address.as_u64[1] = ie0->ila_address.as_u64[1];
- ip61->dst_address.as_u64[0] = ie1->ila_address.as_u64[0];
- ip61->dst_address.as_u64[1] = ie1->ila_address.as_u64[1];
+ ip60->dst_address.as_u64[0] = ila_address0->as_u64[0];
+ ip60->dst_address.as_u64[1] = ila_address0->as_u64[1];
+ ip61->dst_address.as_u64[0] = ila_address1->as_u64[0];
+ ip61->dst_address.as_u64[1] = ila_address1->as_u64[1];
vnet_get_config_data (&cm->config_main,
&p0->current_config_index, &next0, 0);
@@ -485,7 +531,8 @@ ila_sir2ila (vlib_main_t * vm,
ip6_header_t *ip60;
u32 next0 = ILA_SIR2ILA_NEXT_DROP;
BVT (clib_bihash_kv) kv0, value0;
- ila_entry_t *ie0 = &ila_default_entry;
+ ila_entry_t *ie0 = &ila_sir2ila_default_entry;
+ ip6_address_t *ila_address0;
pi0 = to_next[0] = from[0];
from += 1;
@@ -495,26 +542,30 @@ ila_sir2ila (vlib_main_t * vm,
p0 = vlib_get_buffer (vm, pi0);
ip60 = vlib_buffer_get_current (p0);
+ ila_address0 = &ip60->dst_address;
+
kv0.key[0] = ip60->dst_address.as_u64[0];
kv0.key[1] = ip60->dst_address.as_u64[1];
kv0.key[2] = 0;
- if ((BV (clib_bihash_search)
- (&ilm->id_to_entry_table, &kv0, &value0)) == 0)
+ if (PREDICT_TRUE((BV (clib_bihash_search)
+ (&ilm->id_to_entry_table, &kv0, &value0)) == 0)) {
ie0 = &ilm->entries[value0.value];
+ ila_address0 = (ie0->dir != ILA_DIR_ILA2SIR) ? &ie0->ila_address : ila_address0;
+ }
if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
{
ila_sir2ila_trace_t *tr =
vlib_add_trace (vm, node, p0, sizeof (*tr));
tr->ila_index =
- (ie0 != &ila_default_entry) ? (ie0 - ilm->entries) : ~0;
+ (ie0 != &ila_sir2ila_default_entry) ? (ie0 - ilm->entries) : ~0;
tr->initial_dst = ip60->dst_address;
}
//This operation should do everything for any type (except vnid4 obviously)
- ip60->dst_address.as_u64[0] = ie0->ila_address.as_u64[0];
- ip60->dst_address.as_u64[1] = ie0->ila_address.as_u64[1];
+ ip60->dst_address.as_u64[0] = ila_address0->as_u64[0];
+ ip60->dst_address.as_u64[1] = ila_address0->as_u64[1];
vnet_get_config_data (&cm->config_main,
&p0->current_config_index, &next0, 0);
@@ -591,6 +642,7 @@ ila_add_del_entry (ila_add_del_entry_args_t * args)
e->sir_address = args->sir_address;
e->ila_adj_index = args->local_adj_index;
e->csum_mode = args->csum_mode;
+ e->dir = args->dir;
//Construct ILA address
switch (e->type)
@@ -782,6 +834,7 @@ ila_entry_command_fn (vlib_main_t * vm,
args.type = ILA_TYPE_IID;
args.csum_mode = ILA_CSUM_MODE_NO_ACTION;
args.local_adj_index = ~0;
+ args.dir = ILA_DIR_BIDIR;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
@@ -813,6 +866,9 @@ ila_entry_command_fn (vlib_main_t * vm,
if (unformat
(line_input, "next-hop %U", unformat_ip6_address, &next_hop))
next_hop_set = 1;
+ else if (unformat
+ (line_input, "direction %U", unformat_ila_direction, &args.dir))
+ ;
else if (unformat (line_input, "del"))
args.is_del = 1;
else
@@ -853,7 +909,7 @@ VLIB_CLI_COMMAND (ila_entry_command, static) =
{
.path = "ila entry",
.short_help = "ila entry [type <type>] [sir-address <address>] [locator <locator>] [vnid <hex-vnid>]"
- " [adj-index <adj-index>] [next-hop <next-hop>]"
+ " [adj-index <adj-index>] [next-hop <next-hop>] [direction (bidir|sir2ila|ila2sir)]"
" [csum-mode (no-action|neutral-map|transport-adjust)] [del]",
.function = ila_entry_command_fn,
};
diff --git a/plugins/ila-plugin/ila/ila.h b/plugins/ila-plugin/ila/ila.h
index c2650c1d..b800fdd7 100644
--- a/plugins/ila-plugin/ila/ila.h
+++ b/plugins/ila-plugin/ila/ila.h
@@ -47,12 +47,24 @@ typedef enum {
ILA_CSUM_N_TYPES
} ila_csum_mode_t;
+#define ila_foreach_direction \
+_(BIDIR, 0, "bidir") \
+_(SIR2ILA, 1, "sir2ila") \
+_(ILA2SIR, 2, "ila2sir")
+
+typedef enum {
+#define _(i,n,s) ILA_DIR_##i = n,
+ ila_foreach_direction
+#undef _
+} ila_direction_t;
+
typedef struct {
ila_type_t type;
ip6_address_t sir_address;
ip6_address_t ila_address;
u32 ila_adj_index;
ila_csum_mode_t csum_mode;
+ ila_direction_t dir;
} ila_entry_t;
typedef struct {
@@ -79,6 +91,7 @@ typedef struct {
u32 vnid;
u32 local_adj_index;
ila_csum_mode_t csum_mode;
+ ila_direction_t dir;
u8 is_del;
} ila_add_del_entry_args_t;