aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/fib
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-02-24 02:11:19 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2018-03-05 18:41:12 +0000
commit53da221b13225695516ec7469ca29d82bb10e594 (patch)
tree10f31c7fd4acd536cef4793b5c542938da7f09dc /src/vnet/fib
parent0e7fe4fddb493350cf78c8126e9cc93d55490c42 (diff)
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 <neale.ranns@cisco.com>
Diffstat (limited to 'src/vnet/fib')
-rw-r--r--src/vnet/fib/fib_entry.h11
-rw-r--r--src/vnet/fib/fib_entry_src.c8
-rw-r--r--src/vnet/fib/fib_entry_src_api.c1
-rw-r--r--src/vnet/fib/fib_entry_src_special.c11
-rw-r--r--src/vnet/fib/fib_table.c2
-rw-r--r--src/vnet/fib/fib_table.h39
-rw-r--r--src/vnet/fib/ip6_fib.c104
-rw-r--r--src/vnet/fib/ip6_fib.h4
8 files changed, 106 insertions, 74 deletions
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
@@ -89,6 +89,10 @@ typedef enum fib_source_t_ {
*/
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
* then the API/CLI. This is on purpose. trust me.
@@ -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", \
@@ -208,6 +213,10 @@ typedef enum fib_entry_attribute_t_ {
*/
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
@@ -29,6 +29,40 @@
#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
*/
@@ -40,6 +74,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
*/
u16 ft_locks[FIB_TABLE_N_LOCKS];
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 <vnet/fib/ip6_fib.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/dpo/ip6_ll_dpo.h>
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);