From 53da221b13225695516ec7469ca29d82bb10e594 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Sat, 24 Feb 2018 02:11:19 -0800 Subject: IP6 link-local table - IPv6 link local table is a per-SW interface array of IPv6 unicast FIBs - the per-interface ocst is sizeof(fib_table_t) which is small, w.r.t. the cost of an interface - FE80::/10 in the 'global' table points to a DPO that performs a lookup in the input interface's LL fib. Change-Id: Ice834b25ebeeacb2e929d7c864d7ec8c09918cbe Signed-off-by: Neale Ranns --- src/vnet/fib/fib_entry.h | 11 ++++ src/vnet/fib/fib_entry_src.c | 8 +-- src/vnet/fib/fib_entry_src_api.c | 1 + src/vnet/fib/fib_entry_src_special.c | 11 ++++ src/vnet/fib/fib_table.c | 2 +- src/vnet/fib/fib_table.h | 39 +++++++++++++ src/vnet/fib/ip6_fib.c | 104 +++++++++++++---------------------- src/vnet/fib/ip6_fib.h | 4 +- 8 files changed, 106 insertions(+), 74 deletions(-) (limited to 'src/vnet/fib') diff --git a/src/vnet/fib/fib_entry.h b/src/vnet/fib/fib_entry.h index d905a839c48..3fde97add32 100644 --- a/src/vnet/fib/fib_entry.h +++ b/src/vnet/fib/fib_entry.h @@ -88,6 +88,10 @@ typedef enum fib_source_t_ { * IPv6 Proxy ND */ FIB_SOURCE_IP6_ND_PROXY, + /** + * IPv6 ND (seen in the link-local tables) + */ + FIB_SOURCE_IP6_ND, /** * Adjacency source. * routes created as a result of ARP/ND entries. This is lower priority @@ -151,6 +155,7 @@ STATIC_ASSERT (sizeof(fib_source_t) == 1, [FIB_SOURCE_CLASSIFY] = "classify", \ [FIB_SOURCE_DHCP] = "DHCP", \ [FIB_SOURCE_IP6_ND_PROXY] = "IPv6-proxy-nd", \ + [FIB_SOURCE_IP6_ND] = "IPv6-nd", \ [FIB_SOURCE_RR] = "recursive-resolution", \ [FIB_SOURCE_AE] = "attached_export", \ [FIB_SOURCE_MPLS] = "mpls", \ @@ -207,6 +212,10 @@ typedef enum fib_entry_attribute_t_ { * To be used with caution */ FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT, + /** + * The prefix/address exempted from attached export + */ + FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT, /** * This FIB entry imposes its source information on all prefixes * that is covers @@ -227,6 +236,7 @@ typedef enum fib_entry_attribute_t_ { [FIB_ENTRY_ATTRIBUTE_LOCAL] = "local", \ [FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT] = "uRPF-exempt", \ [FIB_ENTRY_ATTRIBUTE_MULTICAST] = "multicast", \ + [FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT] = "no-attached-export", \ [FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT] = "covered-inherit", \ } @@ -243,6 +253,7 @@ typedef enum fib_entry_flag_t_ { FIB_ENTRY_FLAG_EXCLUSIVE = (1 << FIB_ENTRY_ATTRIBUTE_EXCLUSIVE), FIB_ENTRY_FLAG_LOCAL = (1 << FIB_ENTRY_ATTRIBUTE_LOCAL), FIB_ENTRY_FLAG_IMPORT = (1 << FIB_ENTRY_ATTRIBUTE_IMPORT), + FIB_ENTRY_FLAG_NO_ATTACHED_EXPORT = (1 << FIB_ENTRY_ATTRIBUTE_NO_ATTACHED_EXPORT), FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT = (1 << FIB_ENTRY_ATTRIBUTE_URPF_EXEMPT), FIB_ENTRY_FLAG_MULTICAST = (1 << FIB_ENTRY_ATTRIBUTE_MULTICAST), FIB_ENTRY_FLAG_COVERED_INHERIT = (1 << FIB_ENTRY_ATTRIBUTE_COVERED_INHERIT), diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c index 616d77e8b0a..6dc0c73a305 100644 --- a/src/vnet/fib/fib_entry_src.c +++ b/src/vnet/fib/fib_entry_src.c @@ -1352,10 +1352,7 @@ fib_route_attached_cross_table (const fib_entry_t *fib_entry, } /* - * fib_route_attached_cross_table - * - * Return true the the route is attached via an interface that - * is not in the same table as the route + * Return true if the path is attached */ static inline int fib_path_is_attached (const fib_route_path_t *rpath) @@ -1419,7 +1416,8 @@ fib_entry_flags_update (const fib_entry_t *fib_entry, esrc->fes_entry_flags |= FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT; } } - if (fib_route_attached_cross_table(fib_entry, rpath)) + if (fib_route_attached_cross_table(fib_entry, rpath) && + !(esrc->fes_entry_flags & FIB_ENTRY_FLAG_NO_ATTACHED_EXPORT)) { esrc->fes_entry_flags |= FIB_ENTRY_FLAG_IMPORT; } diff --git a/src/vnet/fib/fib_entry_src_api.c b/src/vnet/fib/fib_entry_src_api.c index 1cdcfbde850..4558d65d523 100644 --- a/src/vnet/fib/fib_entry_src_api.c +++ b/src/vnet/fib/fib_entry_src_api.c @@ -167,5 +167,6 @@ fib_entry_src_api_register (void) fib_entry_src_register(FIB_SOURCE_CLI, &api_src_vft); fib_entry_src_register(FIB_SOURCE_DHCP, &api_src_vft); fib_entry_src_register(FIB_SOURCE_IP6_ND_PROXY, &api_src_vft); + fib_entry_src_register(FIB_SOURCE_IP6_ND, &api_src_vft); fib_entry_src_register(FIB_SOURCE_SR, &api_src_vft); } diff --git a/src/vnet/fib/fib_entry_src_special.c b/src/vnet/fib/fib_entry_src_special.c index a2899161c8f..c976da9327a 100644 --- a/src/vnet/fib/fib_entry_src_special.c +++ b/src/vnet/fib/fib_entry_src_special.c @@ -52,11 +52,22 @@ fib_entry_src_special_add (fib_entry_src_t *src, dpo); } +static void +fib_entry_src_special_path_swap (fib_entry_src_t *src, + const fib_entry_t *entry, + fib_path_list_flags_t pl_flags, + const fib_route_path_t *rpaths) +{ + src->fes_pl = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | pl_flags), + rpaths); +} + const static fib_entry_src_vft_t special_src_vft = { .fesv_init = fib_entry_src_special_init, .fesv_deinit = fib_entry_src_special_deinit, .fesv_add = fib_entry_src_special_add, .fesv_remove = fib_entry_src_special_remove, + .fesv_path_swap = fib_entry_src_special_path_swap, }; void diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c index c20bb255ddf..e9173484dec 100644 --- a/src/vnet/fib/fib_table.c +++ b/src/vnet/fib/fib_table.c @@ -1129,7 +1129,7 @@ fib_table_create_and_lock (fib_protocol_t proto, fi = ip4_fib_table_create_and_lock(src); break; case FIB_PROTOCOL_IP6: - fi = ip6_fib_table_create_and_lock(src); + fi = ip6_fib_table_create_and_lock(src, FIB_TABLE_FLAG_NONE, NULL); break; case FIB_PROTOCOL_MPLS: fi = mpls_fib_table_create_and_lock(src); diff --git a/src/vnet/fib/fib_table.h b/src/vnet/fib/fib_table.h index 14ac7054059..ddc00e537c2 100644 --- a/src/vnet/fib/fib_table.h +++ b/src/vnet/fib/fib_table.h @@ -28,6 +28,40 @@ #define FIB_TABLE_N_LOCKS (FIB_SOURCE_MAX+1) #define FIB_TABLE_TOTAL_LOCKS FIB_SOURCE_MAX +/** + * Flags for the source data + */ +typedef enum fib_table_attribute_t_ { + /** + * Marker. Add new values after this one. + */ + FIB_TABLE_ATTRIBUTE_FIRST, + /** + * the table is for IP6 link local addresses + */ + FIB_TABLE_ATTRIBUTE_IP6_LL = FIB_TABLE_ATTRIBUTE_FIRST, + /** + * Marker. add new entries before this one. + */ + FIB_TABLE_ATTRIBUTE_LAST = FIB_TABLE_ATTRIBUTE_IP6_LL, +} fib_table_attribute_t; + +#define FIB_TABLE_ATTRIBUTE_MAX (FIB_TABLE_ATTRIBUTE_LAST+1) + +#define FIB_TABLE_ATTRIBUTES { \ + [FIB_TABLE_ATTRIBUTE_IP6_LL] = "ip6-ll", \ +} + +#define FOR_EACH_FIB_TABLE_ATTRIBUTE(_item) \ + for (_item = FIB_TABLE_ATTRIBUTE_FIRST; \ + _item < FIB_TABLE_ATTRIBUTE_MAX; \ + _item++) + +typedef enum fib_table_flags_t_ { + FIB_TABLE_FLAG_NONE = 0, + FIB_TABLE_FLAG_IP6_LL = (1 << FIB_TABLE_ATTRIBUTE_IP6_LL), +} __attribute__ ((packed)) fib_table_flags_t; + /** * @brief * A protocol Independent FIB table @@ -39,6 +73,11 @@ typedef struct fib_table_t_ */ fib_protocol_t ft_proto; + /** + * Table flags + */ + fib_table_flags_t ft_flags; + /** * per-source number of locks on the table */ diff --git a/src/vnet/fib/ip6_fib.c b/src/vnet/fib/ip6_fib.c index 9f58e4b6a9e..fa9eb112986 100644 --- a/src/vnet/fib/ip6_fib.c +++ b/src/vnet/fib/ip6_fib.c @@ -15,6 +15,7 @@ #include #include +#include static void vnet_ip6_fib_init (u32 fib_index) @@ -38,20 +39,23 @@ vnet_ip6_fib_init (u32 fib_index) FIB_ENTRY_FLAG_DROP); /* - * all link local for us + * all link local via the link local lookup DPO */ pfx.fp_addr.ip6.as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL); pfx.fp_addr.ip6.as_u64[1] = 0; pfx.fp_len = 10; - fib_table_entry_special_add(fib_index, - &pfx, - FIB_SOURCE_SPECIAL, - FIB_ENTRY_FLAG_LOCAL); + fib_table_entry_special_dpo_add(fib_index, + &pfx, + FIB_SOURCE_SPECIAL, + FIB_ENTRY_FLAG_NONE, + ip6_ll_dpo_get()); } static u32 create_fib_with_table_id (u32 table_id, - fib_source_t src) + fib_source_t src, + fib_table_flags_t flags, + u8 *desc) { fib_table_t *fib_table; ip6_fib_t *v6_fib; @@ -76,6 +80,8 @@ create_fib_with_table_id (u32 table_id, v6_fib->table_id = table_id; fib_table->ft_flow_hash_config = IP_FLOW_HASH_DEFAULT; + fib_table->ft_flags = flags; + fib_table->ft_desc = desc; vnet_ip6_fib_init(fib_table->ft_index); fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6, src); @@ -91,95 +97,57 @@ ip6_fib_table_find_or_create_and_lock (u32 table_id, p = hash_get (ip6_main.fib_index_by_table_id, table_id); if (NULL == p) - return create_fib_with_table_id(table_id, src); - + return create_fib_with_table_id(table_id, src, + FIB_TABLE_FLAG_NONE, + NULL); + fib_table_lock(p[0], FIB_PROTOCOL_IP6, src); return (p[0]); } u32 -ip6_fib_table_create_and_lock (fib_source_t src) +ip6_fib_table_create_and_lock (fib_source_t src, + fib_table_flags_t flags, + u8 *desc) { - return (create_fib_with_table_id(~0, src)); + return (create_fib_with_table_id(~0, src, flags, desc)); } void ip6_fib_table_destroy (u32 fib_index) { + /* + * all link local first ... + */ fib_prefix_t pfx = { .fp_proto = FIB_PROTOCOL_IP6, - .fp_len = 0, + .fp_len = 10, .fp_addr = { .ip6 = { - { 0, 0, }, + .as_u8 = { + [0] = 0xFE, + [1] = 0x80, + }, }, } }; + fib_table_entry_delete(fib_index, + &pfx, + FIB_SOURCE_SPECIAL); /* - * the default route. + * ... then the default route. */ + pfx.fp_addr.ip6.as_u64[0] = 0; + pfx.fp_len = 00; fib_table_entry_special_remove(fib_index, &pfx, FIB_SOURCE_DEFAULT_ROUTE); - - /* - * ff02::1:ff00:0/104 - */ - ip6_set_solicited_node_multicast_address(&pfx.fp_addr.ip6, 0); - pfx.fp_len = 104; - fib_table_entry_special_remove(fib_index, - &pfx, - FIB_SOURCE_SPECIAL); - - /* - * all-routers multicast address - */ - ip6_set_reserved_multicast_address (&pfx.fp_addr.ip6, - IP6_MULTICAST_SCOPE_link_local, - IP6_MULTICAST_GROUP_ID_all_routers); - pfx.fp_len = 128; - fib_table_entry_special_remove(fib_index, - &pfx, - FIB_SOURCE_SPECIAL); - - /* - * all-nodes multicast address - */ - ip6_set_reserved_multicast_address (&pfx.fp_addr.ip6, - IP6_MULTICAST_SCOPE_link_local, - IP6_MULTICAST_GROUP_ID_all_hosts); - pfx.fp_len = 128; - fib_table_entry_special_remove(fib_index, - &pfx, - FIB_SOURCE_SPECIAL); - - /* - * all-mldv2 multicast address - */ - ip6_set_reserved_multicast_address (&pfx.fp_addr.ip6, - IP6_MULTICAST_SCOPE_link_local, - IP6_MULTICAST_GROUP_ID_mldv2_routers); - pfx.fp_len = 128; - fib_table_entry_special_remove(fib_index, - &pfx, - FIB_SOURCE_SPECIAL); - - /* - * all link local - */ - pfx.fp_addr.ip6.as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL); - pfx.fp_addr.ip6.as_u64[1] = 0; - pfx.fp_len = 10; - fib_table_entry_special_remove(fib_index, - &pfx, - FIB_SOURCE_SPECIAL); - fib_table_t *fib_table = fib_table_get(fib_index, FIB_PROTOCOL_IP6); fib_source_t source; - + /* * validate no more routes. */ @@ -691,6 +659,8 @@ ip6_show_fib (vlib_main_t * vm, continue; if (fib_index != ~0 && fib_index != (int)fib->index) continue; + if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL) + continue; s = format(s, "%U, fib_index:%d, flow hash:[%U] locks:[", format_fib_table_name, fib->index, diff --git a/src/vnet/fib/ip6_fib.h b/src/vnet/fib/ip6_fib.h index dcd6c301bec..10ae75ce6f9 100644 --- a/src/vnet/fib/ip6_fib.h +++ b/src/vnet/fib/ip6_fib.h @@ -156,7 +156,9 @@ ip6_src_lookup_for_packet (ip6_main_t * im, */ extern u32 ip6_fib_table_find_or_create_and_lock(u32 table_id, fib_source_t src); -extern u32 ip6_fib_table_create_and_lock(fib_source_t src); +extern u32 ip6_fib_table_create_and_lock(fib_source_t src, + fib_table_flags_t flags, + u8* desc); extern u8 *format_ip6_fib_table_memory(u8 * s, va_list * args); -- cgit 1.2.3-korg