summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/ip/lookup.h
diff options
context:
space:
mode:
authorDave Barach <dbarach@cisco.com>2016-03-15 10:21:54 +0100
committerDamjan Marion <damarion@cisco.com>2016-03-18 12:59:51 +0100
commitdbf19ca7f9b93a843503f9204afd0815f3ef8332 (patch)
tree61c37d487be23bbc98a3e8e7d5733231cded4149 /vnet/vnet/ip/lookup.h
parent4ea4ecdda9dbc01f9776b63d3a91397b34e46f13 (diff)
Make adjacencies shareable
Change-Id: I620871ca715b751d2e487f37341b7118797c9176 Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'vnet/vnet/ip/lookup.h')
-rw-r--r--vnet/vnet/ip/lookup.h50
1 files changed, 49 insertions, 1 deletions
diff --git a/vnet/vnet/ip/lookup.h b/vnet/vnet/ip/lookup.h
index ccce88935eb..02ab20d11d9 100644
--- a/vnet/vnet/ip/lookup.h
+++ b/vnet/vnet/ip/lookup.h
@@ -106,9 +106,12 @@ _(reverse, IP_FLOW_HASH_REVERSE_SRC_DST)
/* IP unicast adjacency. */
typedef struct {
+ CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
/* Handle for this adjacency in adjacency heap. */
u32 heap_handle;
+ STRUCT_MARK(signature_start);
+
/* Interface address index for this local/arp adjacency. */
u32 if_address_index;
@@ -131,9 +134,51 @@ typedef struct {
/* Highest possible perf subgraph arc interposition, e.g. for ip6 ioam */
u16 saved_lookup_next_index;
- vnet_declare_rewrite (VLIB_BUFFER_PRE_DATA_SIZE - 5*sizeof(u32));
+ STRUCT_MARK(signature_end);
+
+ /* Number of FIB entries sharing this adjacency */
+ u32 share_count;
+ /* Use this adjacency instead */
+ u32 next_adj_with_signature;
+
+ CLIB_CACHE_LINE_ALIGN_MARK(cacheline1);
+
+ /* Rewrite in second/third cache lines */
+ vnet_declare_rewrite (VLIB_BUFFER_PRE_DATA_SIZE);
} ip_adjacency_t;
+static inline uword
+vnet_ip_adjacency_signature (ip_adjacency_t * adj)
+{
+ uword signature = 0xfeedfaceULL;
+
+ /* Skip heap handle, sum everything up to but not including share_count */
+ signature = hash_memory64
+ (STRUCT_MARK_PTR(adj, signature_start),
+ STRUCT_OFFSET_OF(ip_adjacency_t, signature_end)
+ - STRUCT_OFFSET_OF(ip_adjacency_t, signature_start),
+ signature);
+
+ /* and the rewrite */
+ signature = hash_memory64 (&adj->rewrite_header, VLIB_BUFFER_PRE_DATA_SIZE,
+ signature);
+ return signature;
+}
+
+static inline int
+vnet_ip_adjacency_share_compare (ip_adjacency_t * a1, ip_adjacency_t *a2)
+{
+ if (memcmp (STRUCT_MARK_PTR(a1, signature_start),
+ STRUCT_MARK_PTR(a2, signature_start),
+ STRUCT_OFFSET_OF(ip_adjacency_t, signature_end)
+ - STRUCT_OFFSET_OF(ip_adjacency_t, signature_start)))
+ return 0;
+ if (memcmp (&a1->rewrite_header, &a2->rewrite_header,
+ VLIB_BUFFER_PRE_DATA_SIZE))
+ return 0;
+ return 1;
+}
+
/* Index into adjacency table. */
typedef u32 ip_adjacency_index_t;
@@ -261,6 +306,9 @@ typedef struct ip_lookup_main_t {
/* Indexed by heap_handle from ip_adjacency_t. */
ip_multipath_adjacency_t * multipath_adjacencies;
+ /* Adjacency by signature hash */
+ uword * adj_index_by_signature;
+
/* Temporary vectors for looking up next hops in hash. */
ip_multipath_next_hop_t * next_hop_hash_lookup_key;
ip_multipath_next_hop_t * next_hop_hash_lookup_key_normalized;