diff options
author | Pierre Pfister <ppfister@cisco.com> | 2016-07-27 17:46:11 +0100 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-07-28 12:19:21 +0000 |
commit | 4c3f39353d0307a35180e597c0b0454439e848e9 (patch) | |
tree | 191befe11b7a42c07e812e7dcecf1f9c5c3c4ab9 /vnet/vnet/ip/lookup.c | |
parent | 6cc6f9175c46d9a98db43f47da35119e2b59aa00 (diff) |
Add IP adjacency registration function
Given that it is possible and easy to add dynamic
IP adjacencies, it might be helpful to have an explicit
call to do so.
This way, additional information such as how to display
the adjacency can be provided at the same time.
Change-Id: I5c735ae45ed763560352f637e3462f2931dc97d9
Signed-off-by: Pierre Pfister <ppfister@cisco.com>
Diffstat (limited to 'vnet/vnet/ip/lookup.c')
-rw-r--r-- | vnet/vnet/ip/lookup.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/vnet/vnet/ip/lookup.c b/vnet/vnet/ip/lookup.c index 2d9e01f24b9..126783a23d4 100644 --- a/vnet/vnet/ip/lookup.c +++ b/vnet/vnet/ip/lookup.c @@ -134,6 +134,34 @@ ip_unshare_adjacency(ip_lookup_main_t * lm, u32 adj_index) } } +int ip_register_adjacency(vlib_main_t *vm, + u8 is_ip4, + ip_adj_register_t *reg) +{ + ip_lookup_main_t *lm = (is_ip4)?&ip4_main.lookup_main:&ip6_main.lookup_main; + vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) ((is_ip4)?"ip4-lookup":"ip6-lookup")); + vlib_node_t *next_node = vlib_get_node_by_name(vm, (u8 *) reg->node_name); + *reg->next_index = vlib_node_add_next (vm, node->index, next_node->index); + vec_validate(lm->registered_adjacencies, *reg->next_index); + lm->registered_adjacencies[*reg->next_index] = *reg; + return 0; +} + +int ip_init_registered_adjacencies(u8 is_ip4) +{ + vlib_main_t *vm = vlib_get_main(); + ip_lookup_main_t *lm = (is_ip4)?&ip4_main.lookup_main:&ip6_main.lookup_main; + ip_adj_register_t *reg = lm->registered_adjacencies; + lm->registered_adjacencies = 0; //Init vector + int rv; + while (reg) { + if((rv = ip_register_adjacency(vm, is_ip4, reg))) + return rv; + reg = reg->next; + } + return 0; +} + /* Create new block of given number of contiguous adjacencies. */ ip_adjacency_t * ip_add_adjacency (ip_lookup_main_t * lm, @@ -915,6 +943,8 @@ void ip_lookup_init (ip_lookup_main_t * lm, u32 is_ip6) lm->builtin_protocol_by_ip_protocol[IP_PROTOCOL_UDP] = IP_BUILTIN_PROTOCOL_UDP; lm->builtin_protocol_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 : IP_PROTOCOL_ICMP] = IP_BUILTIN_PROTOCOL_ICMP; } + + ip_init_registered_adjacencies(!is_ip6); } u8 * format_ip_flow_hash_config (u8 * s, va_list * args) @@ -930,13 +960,22 @@ u8 * format_ip_flow_hash_config (u8 * s, va_list * args) u8 * format_ip_lookup_next (u8 * s, va_list * args) { - ip_lookup_next_t n = va_arg (*args, ip_lookup_next_t); + ip_lookup_main_t * lm = va_arg (*args, ip_lookup_main_t *); + ip_lookup_next_t n = va_arg (*args, u32); + ip_adj_register_t *reg; + char * t = 0; switch (n) { default: - s = format (s, "unknown %d", n); + vec_validate(lm->registered_adjacencies, n); + reg = vec_elt_at_index(lm->registered_adjacencies, n); + if (reg->node_name) { + s = format (s, "%s:", reg->node_name); + } else { + s = format (s, "unknown %d", n); + } return s; case IP_LOOKUP_NEXT_MISS: t = "miss"; break; @@ -977,6 +1016,7 @@ u8 * format_ip_adjacency (u8 * s, va_list * args) ip_lookup_main_t * lm = va_arg (*args, ip_lookup_main_t *); u32 adj_index = va_arg (*args, u32); ip_adjacency_t * adj = ip_get_adjacency (lm, adj_index); + ip_adj_register_t *reg; switch (adj->lookup_next_index) { @@ -987,7 +1027,7 @@ u8 * format_ip_adjacency (u8 * s, va_list * args) break; default: - s = format (s, "%U", format_ip_lookup_next, adj->lookup_next_index); + s = format (s, "%U", format_ip_lookup_next, lm, adj->lookup_next_index); if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) s = format (s, " %U", format_vnet_sw_interface_name, @@ -1009,11 +1049,19 @@ u8 * format_ip_adjacency (u8 * s, va_list * args) case IP_LOOKUP_NEXT_CLASSIFY: s = format (s, " table %d", adj->classify.table_index); - + break; case IP_LOOKUP_NEXT_INDIRECT: s = format (s, " via %U", format_ip46_address, &adj->indirect.next_hop, IP46_TYPE_ANY); + break; default: + //Fallback to registered format functions + vec_validate(lm->registered_adjacencies, adj->lookup_next_index); + reg = vec_elt_at_index(lm->registered_adjacencies, adj->lookup_next_index); + if (reg->fn) { + s = format(s, " "); + s = reg->fn(s, lm, adj); + } break; } break; |