Saves memory at no appreciable performance cost.
before:
DBGvpp# sh fib mem
FIB memory
Name Size in-use /allocated totals
Entry 80 7 / 150 560/12000
after:
DBGvpp# sh fib mem
FIB memory
Name Size in-use /allocated totals
Entry 72 7 / 7 504/504
Change-Id: Ic5d3920ceb57b54260dc9af2078c26484335fef1
Signed-off-by: Neale Ranns <nranns@cisco.com>
13 files changed:
static fib_entry_t*
fib_entry_from_fib_node (fib_node_t *node)
{
static fib_entry_t*
fib_entry_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_ENTRY == node->fn_type);
ASSERT(FIB_NODE_TYPE_ENTRY == node->fn_type);
return ((fib_entry_t*)node);
}
return ((fib_entry_t*)node);
}
fib_node_init (fib_node_t *node,
fib_node_type_t type)
{
fib_node_init (fib_node_t *node,
fib_node_type_t type)
{
- * The node's type. make sure we are dynamic/down casting correctly
+ * The node's type. used to retrieve the VFT.
- node->fn_vft = &fn_vfts[type];
node->fn_children = FIB_NODE_INDEX_INVALID;
}
node->fn_children = FIB_NODE_INDEX_INVALID;
}
if (0 == node->fn_locks)
{
if (0 == node->fn_locks)
{
- node->fn_vft->fnv_last_lock(node);
+ fn_vfts[node->fn_type].fnv_last_lock(node);
*/
FIB_NODE_TYPE_TEST,
FIB_NODE_TYPE_LAST = FIB_NODE_TYPE_TEST,
*/
FIB_NODE_TYPE_TEST,
FIB_NODE_TYPE_LAST = FIB_NODE_TYPE_TEST,
+} __attribute__ ((packed)) fib_node_type_t;
#define FIB_NODE_TYPE_MAX (FIB_NODE_TYPE_LAST + 1)
#define FIB_NODE_TYPE_MAX (FIB_NODE_TYPE_LAST + 1)
* Objects in the FIB form a graph.
*/
typedef struct fib_node_t_ {
* Objects in the FIB form a graph.
*/
typedef struct fib_node_t_ {
/**
* The node's type. make sure we are dynamic/down casting correctly
*/
fib_node_type_t fn_type;
/**
* The node's type. make sure we are dynamic/down casting correctly
*/
fib_node_type_t fn_type;
+
+ /**
+ * Some pad space the concrete/derived type is free to use
+ */
+ u16 fn_pad;
/**
* The node's VFT.
* we could store the type here instead, and lookup the VFT using that. But
* I like this better,
*/
/**
* The node's VFT.
* we could store the type here instead, and lookup the VFT using that. But
* I like this better,
*/
- const fib_node_vft_t *fn_vft;
+// const fib_node_vft_t *fn_vft;
/**
* Vector of nodes that depend upon/use/share this node
/**
* Vector of nodes that depend upon/use/share this node
u32 fn_locks;
} fib_node_t;
u32 fn_locks;
} fib_node_t;
+STATIC_ASSERT(sizeof(fib_node_t) == 12, "FIB node type is growing");
+
/**
* @brief
* Register the function table for a given type
/**
* @brief
* Register the function table for a given type
static fib_path_t*
fib_path_from_fib_node (fib_node_t *node)
{
static fib_path_t*
fib_path_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_PATH == node->fn_type);
ASSERT(FIB_NODE_TYPE_PATH == node->fn_type);
return ((fib_path_t*)node);
}
return ((fib_path_t*)node);
}
static fib_path_list_t*
fib_path_list_from_fib_node (fib_node_t *node)
{
static fib_path_list_t*
fib_path_list_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_PATH_LIST == node->fn_type);
ASSERT(FIB_NODE_TYPE_PATH_LIST == node->fn_type);
return ((fib_path_list_t*)node);
}
return ((fib_path_list_t*)node);
}
static geneve_tunnel_t *
geneve_tunnel_from_fib_node (fib_node_t * node)
{
static geneve_tunnel_t *
geneve_tunnel_from_fib_node (fib_node_t * node)
{
ASSERT (FIB_NODE_TYPE_GENEVE_TUNNEL == node->fn_type);
ASSERT (FIB_NODE_TYPE_GENEVE_TUNNEL == node->fn_type);
return ((geneve_tunnel_t *) (((char *) node) -
STRUCT_OFFSET_OF (geneve_tunnel_t, node)));
}
return ((geneve_tunnel_t *) (((char *) node) -
STRUCT_OFFSET_OF (geneve_tunnel_t, node)));
}
static gre_tunnel_t *
gre_tunnel_from_fib_node (fib_node_t *node)
{
static gre_tunnel_t *
gre_tunnel_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_GRE_TUNNEL == node->fn_type);
ASSERT(FIB_NODE_TYPE_GRE_TUNNEL == node->fn_type);
return ((gre_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(gre_tunnel_t, node)));
}
return ((gre_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(gre_tunnel_t, node)));
}
static map_main_pre_resolved_t *
map_from_fib_node (fib_node_t * node)
{
static map_main_pre_resolved_t *
map_from_fib_node (fib_node_t * node)
{
ASSERT (FIB_NODE_TYPE_MAP_E == node->fn_type);
ASSERT (FIB_NODE_TYPE_MAP_E == node->fn_type);
return ((map_main_pre_resolved_t *)
(((char *) node) -
STRUCT_OFFSET_OF (map_main_pre_resolved_t, node)));
return ((map_main_pre_resolved_t *)
(((char *) node) -
STRUCT_OFFSET_OF (map_main_pre_resolved_t, node)));
static mfib_entry_t*
mfib_entry_from_fib_node (fib_node_t *node)
{
static mfib_entry_t*
mfib_entry_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_MFIB_ENTRY == node->fn_type);
ASSERT(FIB_NODE_TYPE_MFIB_ENTRY == node->fn_type);
return ((mfib_entry_t*)node);
}
return ((mfib_entry_t*)node);
}
static mpls_tunnel_t *
mpls_tunnel_from_fib_node (fib_node_t *node)
{
static mpls_tunnel_t *
mpls_tunnel_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_MPLS_TUNNEL == node->fn_type);
ASSERT(FIB_NODE_TYPE_MPLS_TUNNEL == node->fn_type);
return ((mpls_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(mpls_tunnel_t, mt_node)));
}
return ((mpls_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(mpls_tunnel_t, mt_node)));
}
static udp_encap_t *
udp_encap_from_fib_node (fib_node_t * node)
{
static udp_encap_t *
udp_encap_from_fib_node (fib_node_t * node)
{
ASSERT (FIB_NODE_TYPE_UDP_ENCAP == node->fn_type);
ASSERT (FIB_NODE_TYPE_UDP_ENCAP == node->fn_type);
return ((udp_encap_t *) (((char *) node) -
STRUCT_OFFSET_OF (udp_encap_t, ue_fib_node)));
}
return ((udp_encap_t *) (((char *) node) -
STRUCT_OFFSET_OF (udp_encap_t, ue_fib_node)));
}
static vxlan_gpe_tunnel_t *
vxlan_gpe_tunnel_from_fib_node (fib_node_t *node)
{
static vxlan_gpe_tunnel_t *
vxlan_gpe_tunnel_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_VXLAN_GPE_TUNNEL == node->fn_type);
ASSERT(FIB_NODE_TYPE_VXLAN_GPE_TUNNEL == node->fn_type);
return ((vxlan_gpe_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(vxlan_gpe_tunnel_t, node)));
}
return ((vxlan_gpe_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(vxlan_gpe_tunnel_t, node)));
}
static vxlan_tunnel_t *
vxlan_tunnel_from_fib_node (fib_node_t *node)
{
static vxlan_tunnel_t *
vxlan_tunnel_from_fib_node (fib_node_t *node)
{
ASSERT(FIB_NODE_TYPE_VXLAN_TUNNEL == node->fn_type);
ASSERT(FIB_NODE_TYPE_VXLAN_TUNNEL == node->fn_type);
return ((vxlan_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(vxlan_tunnel_t, node)));
}
return ((vxlan_tunnel_t*) (((char*)node) -
STRUCT_OFFSET_OF(vxlan_tunnel_t, node)));
}