diff options
-rw-r--r-- | plugins/ila-plugin/ila/ila.c | 124 | ||||
-rw-r--r-- | plugins/ila-plugin/ila/ila.h | 13 |
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; |