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>
This commit is contained in:

committed by
Damjan Marion

parent
af3f0783b0
commit
4c3ba81709
@ -1371,6 +1371,7 @@ list(APPEND VNET_SOURCES
|
||||
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
|
||||
|
@ -537,10 +537,32 @@ static fib_node_back_walk_rc_t
|
||||
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);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ static adj_delegate_vft_t *ad_vfts;
|
||||
/**
|
||||
* 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,
|
||||
|
@ -36,8 +36,14 @@ typedef enum adj_delegate_type_t_ {
|
||||
* 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.
|
||||
*/
|
||||
|
@ -118,4 +118,25 @@ extern void adj_midchain_module_init(void);
|
||||
*/
|
||||
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
|
||||
|
183
src/vnet/adj/adj_midchain_delegate.c
Normal file
183
src/vnet/adj/adj_midchain_delegate.c
Normal file
@ -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);
|
||||
|
@ -39,7 +39,6 @@ typedef enum fib_node_type_t_ {
|
||||
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 @@ typedef enum fib_node_type_t_ {
|
||||
[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", \
|
||||
|
@ -180,11 +180,6 @@ typedef struct
|
||||
*/
|
||||
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.
|
||||
@ -207,19 +202,6 @@ typedef struct
|
||||
u32 sw_if_index;
|
||||
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.
|
||||
*/
|
||||
|
@ -112,14 +112,6 @@ gre_tunnel_db_remove (gre_tunnel_t * t)
|
||||
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 @@ gre_tunnel_stack (adj_index_t ai)
|
||||
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 @@ gre_tunnel_restack (gre_tunnel_t * gt)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ vnet_gre_tunnel_add (vnet_gre_add_del_tunnel_args_t * a,
|
||||
|
||||
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 @@ vnet_gre_tunnel_add (vnet_gre_add_del_tunnel_args_t * a,
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ vnet_gre_tunnel_delete (vnet_gre_add_del_tunnel_args_t * a,
|
||||
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 @@ vnet_gre_tunnel_delete (vnet_gre_add_del_tunnel_args_t * a,
|
||||
|
||||
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 @@ VLIB_CLI_COMMAND (show_gre_tunnel_command, static) = {
|
||||
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);
|
||||
|
@ -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 @@ ipip_tunnel_stack (adj_index_t ai)
|
||||
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 @@ ipip_tunnel_db_remove (ipip_tunnel_t * t)
|
||||
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 @@ ipip_add_tunnel (ipip_transport_t transport,
|
||||
|
||||
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_add_tunnel (ipip_transport_t transport,
|
||||
|
||||
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 @@ ipip_del_tunnel (u32 sw_if_index)
|
||||
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 @@ ipip_init (vlib_main_t * vm)
|
||||
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;
|
||||
}
|
||||
|
@ -84,25 +84,16 @@ typedef struct
|
||||
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 @@ typedef struct
|
||||
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;
|
||||
|
Reference in New Issue
Block a user