ADJ: midchain delegate to performing stacking
this can be used by e.g. tunnels so it doesn't need to be
implemented for each tunnel type.
Change-Id: I0790f89aa49f83421612b35108cce67693285999
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt
index 822ad68..8e56ac3 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -1371,6 +1371,7 @@
adj/adj_nbr.c
adj/adj_glean.c
adj/adj_midchain.c
+ adj/adj_midchain_delegate.c
adj/adj_mcast.c
adj/adj_l2.c
adj/adj_nsh.c
diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c
index 3ca3d60..9d18dbf 100644
--- a/src/vnet/adj/adj.c
+++ b/src/vnet/adj/adj.c
@@ -537,10 +537,32 @@
adj_back_walk_notify (fib_node_t *node,
fib_node_back_walk_ctx_t *ctx)
{
- /*
- * Que pasa. yo soj en el final!
- */
- ASSERT(0);
+ ip_adjacency_t *adj;
+
+ adj = ADJ_FROM_NODE(node);
+
+ switch (adj->lookup_next_index)
+ {
+ case IP_LOOKUP_NEXT_MIDCHAIN:
+ adj_midchain_delegate_restack(adj_get_index(adj));
+ break;
+ case IP_LOOKUP_NEXT_ARP:
+ case IP_LOOKUP_NEXT_REWRITE:
+ case IP_LOOKUP_NEXT_BCAST:
+ case IP_LOOKUP_NEXT_GLEAN:
+ case IP_LOOKUP_NEXT_MCAST:
+ case IP_LOOKUP_NEXT_MCAST_MIDCHAIN:
+ case IP_LOOKUP_NEXT_DROP:
+ case IP_LOOKUP_NEXT_PUNT:
+ case IP_LOOKUP_NEXT_LOCAL:
+ case IP_LOOKUP_NEXT_ICMP_ERROR:
+ case IP_LOOKUP_N_NEXT:
+ /*
+ * Que pasa. yo soj en el final!
+ */
+ ASSERT(0);
+ break;
+ }
return (FIB_NODE_BACK_WALK_CONTINUE);
}
diff --git a/src/vnet/adj/adj_delegate.c b/src/vnet/adj/adj_delegate.c
index 15dcb02..cd5301c 100644
--- a/src/vnet/adj/adj_delegate.c
+++ b/src/vnet/adj/adj_delegate.c
@@ -25,7 +25,7 @@
/**
* The value of the last dynamically allocated delegeate value
*/
-static adj_delegate_type_t ad_max_id = ADJ_DELEGATE_BFD;
+static adj_delegate_type_t ad_max_id = ADJ_DELEGATE_LAST;
static adj_delegate_t *
adj_delegate_find_i (const ip_adjacency_t *adj,
diff --git a/src/vnet/adj/adj_delegate.h b/src/vnet/adj/adj_delegate.h
index 13bf911..f6da245 100644
--- a/src/vnet/adj/adj_delegate.h
+++ b/src/vnet/adj/adj_delegate.h
@@ -36,8 +36,14 @@
* BFD session state
*/
ADJ_DELEGATE_BFD,
+ /**
+ * Stacking of a midchain's nexthop
+ */
+ ADJ_DELEGATE_MIDCHAIN,
} adj_delegate_type_t;
+#define ADJ_DELEGATE_LAST (ADJ_DELEGATE_MIDCHAIN)
+
/**
* Adj delegate. This object is attached to the adjacency.
*/
diff --git a/src/vnet/adj/adj_midchain.h b/src/vnet/adj/adj_midchain.h
index 24fea42..1f5deae 100644
--- a/src/vnet/adj/adj_midchain.h
+++ b/src/vnet/adj/adj_midchain.h
@@ -118,4 +118,25 @@
*/
extern u8* format_adj_midchain(u8* s, va_list *ap);
+/**
+ * @brief
+ * create/attach a midchain delegate and stack it on the prefix passed
+ * @param ai - the index of the adjacency to stack
+ * @param fib_index - The FIB index of the prefix on which to stack
+ * @param pfx - The prefix on which to stack
+ */
+extern void adj_midchain_delegate_stack(adj_index_t ai,
+ u32 fib_index,
+ const fib_prefix_t *pfx);
+
+/**
+ * @brief restack a midchain delegate
+ */
+extern void adj_midchain_delegate_restack(adj_index_t ai);
+
+/**
+ * @brief unstack a midchain delegate (this stacks it on a drop)
+ */
+extern void adj_midchain_delegate_unstack(adj_index_t ai);
+
#endif
diff --git a/src/vnet/adj/adj_midchain_delegate.c b/src/vnet/adj/adj_midchain_delegate.c
new file mode 100644
index 0000000..922283e
--- /dev/null
+++ b/src/vnet/adj/adj_midchain_delegate.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/adj/adj_delegate.h>
+#include <vnet/adj/adj_midchain.h>
+#include <vnet/fib/fib_table.h>
+
+/**
+ * Midchain stacker delegate
+ */
+typedef struct adj_midchain_delegate_t_
+{
+ /**
+ * the Fib Entry we are stacked on
+ */
+ fib_node_index_t amd_fei;
+
+ /**
+ * The sibling entry on the FIB entry
+ */
+ u32 amd_sibling;
+} adj_midchain_delegate_t;
+
+/**
+ * Pool of delegates
+ */
+static adj_midchain_delegate_t *amd_pool;
+
+static inline const adj_midchain_delegate_t*
+adj_midchain_from_const_base (const adj_delegate_t *ad)
+{
+ if (NULL != ad)
+ {
+ return (pool_elt_at_index(amd_pool, ad->ad_index));
+ }
+ return (NULL);
+}
+
+static void
+adj_midchain_delegate_restack_i (adj_index_t ai,
+ adj_midchain_delegate_t *amd)
+{
+ if (vnet_sw_interface_is_admin_up (vnet_get_main (),
+ adj_get_sw_if_index(ai)) &&
+ (FIB_NODE_INDEX_INVALID != amd->amd_fei))
+ {
+ const fib_prefix_t *pfx;
+
+ pfx = fib_entry_get_prefix(amd->amd_fei);
+
+ adj_nbr_midchain_stack_on_fib_entry (
+ ai,
+ amd->amd_fei,
+ fib_forw_chain_type_from_fib_proto(pfx->fp_proto));
+ }
+ else
+ {
+ adj_nbr_midchain_unstack (ai);
+ }
+}
+
+void
+adj_midchain_delegate_restack (adj_index_t ai)
+{
+ adj_midchain_delegate_t *amd;
+ ip_adjacency_t *adj;
+ adj_delegate_t *ad;
+
+ /*
+ * if there's a delegate already use that
+ */
+ adj = adj_get(ai);
+ ad = adj_delegate_get(adj, ADJ_DELEGATE_MIDCHAIN);
+
+ if (NULL != ad)
+ {
+ amd = pool_elt_at_index(amd_pool, ad->ad_index);
+
+ adj_midchain_delegate_restack_i(ai, amd);
+ }
+ /*
+ * else
+ * nothing to stack
+ */
+}
+
+void
+adj_midchain_delegate_stack (adj_index_t ai,
+ u32 fib_index,
+ const fib_prefix_t *pfx)
+{
+ adj_midchain_delegate_t *amd;
+ ip_adjacency_t *adj;
+ adj_delegate_t *ad;
+
+ /*
+ * if there's a delegate already use that
+ */
+ adj = adj_get(ai);
+ ad = adj_delegate_get(adj, ADJ_DELEGATE_MIDCHAIN);
+
+ if (NULL != ad)
+ {
+ amd = pool_elt_at_index(amd_pool, ad->ad_index);
+ }
+ else
+ {
+ pool_get(amd_pool, amd);
+ amd->amd_fei = FIB_NODE_INDEX_INVALID;
+ adj_delegate_add(adj, ADJ_DELEGATE_MIDCHAIN, amd - amd_pool);
+
+ amd->amd_fei = fib_table_entry_special_add(fib_index,
+ pfx,
+ FIB_SOURCE_RR,
+ FIB_ENTRY_FLAG_NONE);
+ amd->amd_sibling = fib_entry_child_add(amd->amd_fei,
+ FIB_NODE_TYPE_ADJ,
+ ai);
+ }
+ adj_midchain_delegate_restack_i(ai, amd);
+}
+
+void
+adj_midchain_delegate_unstack (adj_index_t ai)
+{
+ adj_nbr_midchain_unstack(ai);
+}
+
+static void
+adj_midchain_delegate_adj_deleted (adj_delegate_t *ad)
+{
+ adj_midchain_delegate_t *amd;
+
+ amd = pool_elt_at_index(amd_pool, ad->ad_index);
+
+ fib_entry_child_remove (amd->amd_fei, amd->amd_sibling);
+ fib_table_entry_delete_index (amd->amd_fei, FIB_SOURCE_RR);
+
+ pool_put(amd_pool, amd);
+}
+
+/**
+ * Print a delegate that represents MIDCHAIN tracking
+ */
+static u8 *
+adj_midchain_delegate_fmt (const adj_delegate_t *aed, u8 *s)
+{
+ const adj_midchain_delegate_t *amd = adj_midchain_from_const_base(aed);
+
+ s = format(s, "MIDCHAIN:[fib-entry:%d]", amd->amd_fei);
+
+ return (s);
+}
+
+const static adj_delegate_vft_t adj_delegate_vft = {
+ .adv_format = adj_midchain_delegate_fmt,
+ .adv_adj_deleted = adj_midchain_delegate_adj_deleted,
+};
+
+static clib_error_t *
+adj_midchain_delegate_module_init (vlib_main_t * vm)
+{
+ clib_error_t * error = NULL;
+
+ adj_delegate_register_type (ADJ_DELEGATE_MIDCHAIN, &adj_delegate_vft);
+
+ return (error);
+}
+
+VLIB_INIT_FUNCTION (adj_midchain_delegate_module_init);
+
diff --git a/src/vnet/fib/fib_node.h b/src/vnet/fib/fib_node.h
index e9c45c5..de366f2 100644
--- a/src/vnet/fib/fib_node.h
+++ b/src/vnet/fib/fib_node.h
@@ -39,7 +39,6 @@
FIB_NODE_TYPE_MPLS_TUNNEL,
FIB_NODE_TYPE_LISP_GPE_FWD_ENTRY,
FIB_NODE_TYPE_LISP_ADJ,
- FIB_NODE_TYPE_GRE_TUNNEL,
FIB_NODE_TYPE_VXLAN_TUNNEL,
FIB_NODE_TYPE_MAP_E,
FIB_NODE_TYPE_VXLAN_GPE_TUNNEL,
@@ -69,7 +68,6 @@
[FIB_NODE_TYPE_ADJ] = "adj", \
[FIB_NODE_TYPE_LISP_GPE_FWD_ENTRY] = "lisp-gpe-fwd-entry", \
[FIB_NODE_TYPE_LISP_ADJ] = "lisp-adj", \
- [FIB_NODE_TYPE_GRE_TUNNEL] = "gre-tunnel", \
[FIB_NODE_TYPE_VXLAN_TUNNEL] = "vxlan-tunnel", \
[FIB_NODE_TYPE_MAP_E] = "map-e", \
[FIB_NODE_TYPE_VXLAN_GPE_TUNNEL] = "vxlan-gpe-tunnel", \
diff --git a/src/vnet/gre/gre.h b/src/vnet/gre/gre.h
index 416ab30..a1a03df 100644
--- a/src/vnet/gre/gre.h
+++ b/src/vnet/gre/gre.h
@@ -181,11 +181,6 @@
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
/**
- * Linkage into the FIB object graph
- */
- fib_node_t node;
-
- /**
* The hash table's key stored in separate memory since the tunnel_t
* memory can realloc.
*/
@@ -208,19 +203,6 @@
gre_tunnel_type_t type;
/**
- * The FIB entry sourced by the tunnel for its destination prefix
- */
- fib_node_index_t fib_entry_index;
-
- /**
- * The tunnel is a child of the FIB entry for its desintion. This is
- * so it receives updates when the forwarding information for that entry
- * changes.
- * The tunnels sibling index on the FIB entry's dependency list.
- */
- u32 sibling_index;
-
- /**
* an L2 tunnel always rquires an L2 midchain. cache here for DP.
*/
adj_index_t l2_adj_index;
diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c
index b9bfb79..4f5f528 100644
--- a/src/vnet/gre/interface.c
+++ b/src/vnet/gre/interface.c
@@ -112,14 +112,6 @@
t->key = NULL;
}
-static gre_tunnel_t *
-gre_tunnel_from_fib_node (fib_node_t * node)
-{
- ASSERT (FIB_NODE_TYPE_GRE_TUNNEL == node->fn_type);
- return ((gre_tunnel_t *) (((char *) node) -
- STRUCT_OFFSET_OF (gre_tunnel_t, node)));
-}
-
/**
* gre_tunnel_stack
*
@@ -146,14 +138,11 @@
if ((vnet_hw_interface_get_flags (vnet_get_main (), gt->hw_if_index) &
VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
{
- adj_nbr_midchain_unstack (ai);
+ adj_midchain_delegate_unstack (ai);
}
else
{
- adj_nbr_midchain_stack_on_fib_entry (ai,
- gt->fib_entry_index,
- fib_forw_chain_type_from_fib_proto
- (gt->tunnel_dst.fp_proto));
+ adj_midchain_delegate_stack (ai, gt->outer_fib_index, >->tunnel_dst);
}
}
@@ -182,55 +171,6 @@
}
}
-/**
- * Function definition to backwalk a FIB node
- */
-static fib_node_back_walk_rc_t
-gre_tunnel_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
-{
- gre_tunnel_restack (gre_tunnel_from_fib_node (node));
-
- return (FIB_NODE_BACK_WALK_CONTINUE);
-}
-
-/**
- * Function definition to get a FIB node from its index
- */
-static fib_node_t *
-gre_tunnel_fib_node_get (fib_node_index_t index)
-{
- gre_tunnel_t *gt;
- gre_main_t *gm;
-
- gm = &gre_main;
- gt = pool_elt_at_index (gm->tunnels, index);
-
- return (>->node);
-}
-
-/**
- * Function definition to inform the FIB node that its last lock has gone.
- */
-static void
-gre_tunnel_last_lock_gone (fib_node_t * node)
-{
- /*
- * The MPLS GRE tunnel is a root of the graph. As such
- * it never has children and thus is never locked.
- */
- ASSERT (0);
-}
-
-/*
- * Virtual function table registered by MPLS GRE tunnels
- * for participation in the FIB object graph.
- */
-const static fib_node_vft_t gre_vft = {
- .fnv_get = gre_tunnel_fib_node_get,
- .fnv_last_lock = gre_tunnel_last_lock_gone,
- .fnv_back_walk = gre_tunnel_back_walk,
-};
-
static int
vnet_gre_tunnel_add (vnet_gre_add_del_tunnel_args_t * a,
u32 outer_fib_index, u32 * sw_if_indexp)
@@ -267,7 +207,6 @@
t->dev_instance = t_idx; /* actual */
t->user_instance = u_idx; /* name */
- fib_node_init (&t->node, FIB_NODE_TYPE_GRE_TUNNEL);
t->type = a->tunnel_type;
if (t->type == GRE_TUNNEL_TYPE_ERSPAN)
@@ -357,11 +296,6 @@
}
}
- t->fib_entry_index = fib_table_entry_special_add
- (outer_fib_index, &t->tunnel_dst, FIB_SOURCE_RR, FIB_ENTRY_FLAG_NONE);
- t->sibling_index = fib_entry_child_add
- (t->fib_entry_index, FIB_NODE_TYPE_GRE_TUNNEL, t_idx);
-
if (t->type != GRE_TUNNEL_TYPE_L3)
{
t->l2_adj_index = adj_nbr_add_or_lock
@@ -403,10 +337,10 @@
ethernet_delete_interface (vnm, t->hw_if_index);
if (t->l2_adj_index != ADJ_INDEX_INVALID)
- adj_unlock (t->l2_adj_index);
-
- fib_entry_child_remove (t->fib_entry_index, t->sibling_index);
- fib_table_entry_delete_index (t->fib_entry_index, FIB_SOURCE_RR);
+ {
+ adj_midchain_delegate_unstack (t->l2_adj_index);
+ adj_unlock (t->l2_adj_index);
+ }
ASSERT ((t->type != GRE_TUNNEL_TYPE_ERSPAN) || (t->gre_sn != NULL));
if ((t->type == GRE_TUNNEL_TYPE_ERSPAN) && (t->gre_sn->ref_count-- == 1))
@@ -419,7 +353,6 @@
hash_unset (gm->instance_used, t->user_instance);
gre_tunnel_db_remove (t);
- fib_node_deinit (&t->node);
pool_put (gm->tunnels, t);
if (sw_if_indexp)
@@ -690,9 +623,7 @@
clib_error_t *
gre_interface_init (vlib_main_t * vm)
{
- fib_node_register_type (FIB_NODE_TYPE_GRE_TUNNEL, &gre_vft);
-
- return 0;
+ return (NULL);
}
VLIB_INIT_FUNCTION (gre_interface_init);
diff --git a/src/vnet/ipip/ipip.c b/src/vnet/ipip/ipip.c
index a5e46c4..5d40708 100644
--- a/src/vnet/ipip/ipip.c
+++ b/src/vnet/ipip/ipip.c
@@ -20,6 +20,7 @@
#include <vnet/ipip/ipip.h>
#include <vnet/vnet.h>
#include <vnet/adj/adj_nbr.h>
+#include <vnet/adj/adj_midchain.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/ip/format.h>
@@ -185,15 +186,21 @@
if ((vnet_hw_interface_get_flags (vnet_get_main (), t->hw_if_index) &
VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
{
- adj_nbr_midchain_unstack (ai);
+ adj_midchain_delegate_unstack (ai);
}
else
{
- adj_nbr_midchain_stack_on_fib_entry
- (ai,
- t->p2p.fib_entry_index,
- (t->transport == IPIP_TRANSPORT_IP6) ?
- FIB_FORW_CHAIN_TYPE_UNICAST_IP6 : FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
+ /* *INDENT-OFF* */
+ fib_prefix_t dst = {
+ .fp_len = t->transport == IPIP_TRANSPORT_IP6 ? 128 : 32,
+ .fp_proto = (t->transport == IPIP_TRANSPORT_IP6 ?
+ FIB_PROTOCOL_IP6 :
+ FIB_PROTOCOL_IP4),
+ .fp_addr = t->tunnel_dst
+ };
+ /* *INDENT-ON* */
+
+ adj_midchain_delegate_stack (ai, t->fib_index, &dst);
}
}
@@ -356,82 +363,6 @@
t->key = NULL;
}
-static ipip_tunnel_t *
-ipip_tunnel_from_fib_node (fib_node_t * node)
-{
- ipip_main_t *gm = &ipip_main;
- ASSERT (gm->fib_node_type == node->fn_type);
- return ((ipip_tunnel_t *) (((char *) node) -
- offsetof (ipip_tunnel_t, p2p.node)));
-}
-
-static fib_node_back_walk_rc_t
-ipip_tunnel_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
-{
- ipip_tunnel_restack (ipip_tunnel_from_fib_node (node));
-
- return (FIB_NODE_BACK_WALK_CONTINUE);
-}
-
-static fib_node_t *
-ipip_tunnel_fib_node_get (fib_node_index_t index)
-{
- ipip_tunnel_t *gt;
- ipip_main_t *gm;
-
- gm = &ipip_main;
- gt = pool_elt_at_index (gm->tunnels, index);
-
- return (>->p2p.node);
-}
-
-static void
-ipip_tunnel_last_lock_gone (fib_node_t * node)
-{
- /*
- * The MPLS IPIP tunnel is a root of the graph. As such
- * it never has children and thus is never locked.
- */
- ASSERT (0);
-}
-
-/*
- * Virtual function table registered by IPIP tunnels
- * for participation in the FIB object graph.
- */
-const static fib_node_vft_t ipip_vft = {
- .fnv_get = ipip_tunnel_fib_node_get,
- .fnv_last_lock = ipip_tunnel_last_lock_gone,
- .fnv_back_walk = ipip_tunnel_back_walk,
-};
-
-static void
-ipip_fib_add (ipip_tunnel_t * t)
-{
- ipip_main_t *gm = &ipip_main;
- fib_prefix_t dst = {.fp_len = t->transport == IPIP_TRANSPORT_IP6 ? 128 : 32,
- .fp_proto =
- t->transport ==
- IPIP_TRANSPORT_IP6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4,
- .fp_addr = t->tunnel_dst
- };
-
- t->p2p.fib_entry_index =
- fib_table_entry_special_add (t->fib_index, &dst, FIB_SOURCE_RR,
- FIB_ENTRY_FLAG_NONE);
- t->p2p.sibling_index =
- fib_entry_child_add (t->p2p.fib_entry_index, gm->fib_node_type,
- t->dev_instance);
-}
-
-static void
-ipip_fib_delete (ipip_tunnel_t * t)
-{
- fib_entry_child_remove (t->p2p.fib_entry_index, t->p2p.sibling_index);
- fib_table_entry_delete_index (t->p2p.fib_entry_index, FIB_SOURCE_RR);
- fib_node_deinit (&t->p2p.node);
-}
-
int
ipip_add_tunnel (ipip_transport_t transport,
u32 instance, ip46_address_t * src, ip46_address_t * dst,
@@ -470,7 +401,6 @@
t->dev_instance = t_idx; /* actual */
t->user_instance = u_idx; /* name */
- fib_node_init (&t->p2p.node, gm->fib_node_type);
hw_if_index = vnet_register_interface (vnm, ipip_device_class.index, t_idx,
ipip_hw_interface_class.index,
@@ -507,12 +437,6 @@
ipip_tunnel_db_add (t, &key);
- /*
- * Source the FIB entry for the tunnel's destination and become a
- * child thereof. The tunnel will then get poked when the forwarding
- * for the entry updates, and the tunnel can re-stack accordingly
- */
- ipip_fib_add (t);
if (sw_if_indexp)
*sw_if_indexp = sw_if_index;
@@ -546,7 +470,6 @@
vnet_sw_interface_set_flags (vnm, sw_if_index, 0 /* down */ );
gm->tunnel_index_by_sw_if_index[sw_if_index] = ~0;
vnet_delete_hw_interface (vnm, t->hw_if_index);
- ipip_fib_delete (t);
hash_unset (gm->instance_used, t->user_instance);
ipip_tunnel_db_remove (t);
pool_put (gm->tunnels, t);
@@ -564,7 +487,6 @@
gm->vnet_main = vnet_get_main ();
gm->tunnel_by_key =
hash_create_mem (0, sizeof (ipip_tunnel_key_t), sizeof (uword));
- gm->fib_node_type = fib_node_register_new_type (&ipip_vft);
return 0;
}
diff --git a/src/vnet/ipip/ipip.h b/src/vnet/ipip/ipip.h
index 93930aa..7eecebb 100644
--- a/src/vnet/ipip/ipip.h
+++ b/src/vnet/ipip/ipip.h
@@ -84,25 +84,16 @@
u32 user_instance; /* Instance name being shown to user */
u8 tc_tos;
- union
+ struct
{
- struct
- {
- fib_node_t node;
- fib_node_index_t fib_entry_index;
- u32 sibling_index;
- } p2p;
- struct
- {
- ip6_address_t ip6_prefix;
- ip4_address_t ip4_prefix;
- u8 ip6_prefix_len;
- u8 ip4_prefix_len;
- u8 shift;
- bool security_check;
- u32 ip6_fib_index;
- } sixrd;
- };
+ ip6_address_t ip6_prefix;
+ ip4_address_t ip4_prefix;
+ u8 ip6_prefix_len;
+ u8 ip4_prefix_len;
+ u8 shift;
+ bool security_check;
+ u32 ip6_fib_index;
+ } sixrd;
} ipip_tunnel_t;
typedef struct
@@ -110,7 +101,6 @@
ipip_tunnel_t *tunnels;
uword *tunnel_by_key;
u32 *tunnel_index_by_sw_if_index;
- fib_node_type_t fib_node_type;
/* convenience */
vlib_main_t *vlib_main;