aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2016-06-17 13:59:10 +0200
committerDave Barach <openvpp@barachs.net>2016-06-19 13:26:11 +0000
commit2459e4c5f577907ea060957bc0699a72a1f8e1be (patch)
tree02668088c85da27400f8c318cd4a401774752e4b
parent808b2db9648b444dec906d27050afd9af6138f90 (diff)
Fix use of lookup_next_index in LISP src/dst FIB
Adjacencies in LISP src/dst FIB store the index of the LISP output interface (next node after lookup) in the lookup_next_index. Since the values of interface node indexes are not constrained, they can collide with the 'special' adjacencies IP_LOOKUP_NEXT_LOCAL and IP_LOOKUP_NEXT_DROP. As a result, at allocation time, LISP ajacencies may be automatically shared with the previous two, predefined adjacencies and all LISP specific state stored in the rewrite area is lost. This fixes the problem by 'hijacking' the explicit_fib_index instead of the lookup_next_index field. Change-Id: I3c59121dcf0851decf5c08004143d1201dbd1ece Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--vnet/vnet/lisp-gpe/ip_forward.c82
-rw-r--r--vnet/vnet/lisp-gpe/lisp_gpe.c9
2 files changed, 79 insertions, 12 deletions
diff --git a/vnet/vnet/lisp-gpe/ip_forward.c b/vnet/vnet/lisp-gpe/ip_forward.c
index 38a274e3e3c..fcb453c6486 100644
--- a/vnet/vnet/lisp-gpe/ip_forward.c
+++ b/vnet/vnet/lisp-gpe/ip_forward.c
@@ -245,6 +245,12 @@ ip4_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
/* dst adj should point to lisp gpe lookup */
dst_adj.lookup_next_index = lgm->ip4_lookup_next_lgpe_ip4_lookup;
+ /* make sure we have different signatures for adj in different tables
+ * but with the same lookup_next_index */
+ dst_adj.explicit_fib_index = table_id;
+
+ dst_adj.n_adj = 1;
+
memset(&a, 0, sizeof(a));
a.flags = IP4_ROUTE_FLAG_TABLE_ID;
a.table_index_or_table_id = table_id; /* vrf */
@@ -262,6 +268,14 @@ ip4_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
dst_address_length);
ASSERT(p != 0);
+
+ /* make sure insertion succeeded */
+ if (CLIB_DEBUG)
+ {
+ dst_adjp = ip_get_adjacency (lgm->lm4, p[0]);
+ ASSERT(dst_adjp->rewrite_header.sw_if_index
+ == dst_adj.rewrite_header.sw_if_index);
+ }
}
}
else
@@ -277,6 +291,12 @@ ip4_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
dst_adjp = ip_get_adjacency (lgm->lm4, p[0]);
+ /* make sure adj signature is unique, i.e., fill in mcast_group_index
+ * and saved_lookup_next index with data that makes this adj unique.
+ * All these fields are (and should stay that way) unused by LISP. */
+ add_adj->mcast_group_index = table_id;
+ add_adj->saved_lookup_next_index = dst_adjp->rewrite_header.sw_if_index;
+
/* add/del src prefix to src fib */
memset(&a, 0, sizeof(a));
a.flags = IP4_ROUTE_FLAG_TABLE_ID;
@@ -290,6 +310,18 @@ ip4_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
a.dst_address = src;
ip4_sd_fib_add_del_src_route (lgm, &a);
+ /* make sure insertion succeeded */
+ if (CLIB_DEBUG)
+ {
+ uword * sai;
+ ip_adjacency_t * src_adjp;
+ sai = ip4_sd_get_src_route (lgm, dst_adjp->rewrite_header.sw_if_index,
+ &src, src_address_length);
+ src_adjp = ip_get_adjacency(lgm->lm4, sai[0]);
+ ASSERT(src_adjp->rewrite_header.node_index
+ == add_adj->rewrite_header.node_index);
+ }
+
/* if a delete, check if there are elements left in the src fib */
if (!is_add)
{
@@ -559,6 +591,10 @@ ip6_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
/* dst adj should point to lisp gpe ip lookup */
dst_adj.lookup_next_index = lgm->ip6_lookup_next_lgpe_ip6_lookup;
+ /* make sure we have different signatures for adj in different tables
+ * but with the same lookup_next_index */
+ dst_adj.explicit_fib_index = table_id;
+
memset(&a, 0, sizeof(a));
a.flags = IP6_ROUTE_FLAG_TABLE_ID;
a.table_index_or_table_id = table_id; /* vrf */
@@ -576,6 +612,14 @@ ip6_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
dst_address_length);
ASSERT(adj_index != 0);
+
+ /* make sure insertion succeeded */
+ if (CLIB_DEBUG)
+ {
+ dst_adjp = ip_get_adjacency (lgm->lm6, adj_index);
+ ASSERT(dst_adjp->rewrite_header.sw_if_index
+ == dst_adj.rewrite_header.sw_if_index);
+ }
}
}
else
@@ -591,6 +635,12 @@ ip6_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
dst_adjp = ip_get_adjacency (lgm->lm6, adj_index);
+ /* make sure adj signature is unique, i.e., fill in mcast_group_index
+ * and saved_lookup_next index with data that makes this adj unique.
+ * All these fields are (and should stay that way) unused by LISP. */
+ add_adj->mcast_group_index = table_id;
+ add_adj->saved_lookup_next_index = dst_adjp->rewrite_header.sw_if_index;
+
/* add/del src prefix to src fib */
memset(&a, 0, sizeof(a));
a.flags = IP6_ROUTE_FLAG_TABLE_ID;
@@ -604,6 +654,18 @@ ip6_sd_fib_add_del_route (lisp_gpe_main_t * lgm, ip_prefix_t * dst_prefix,
a.dst_address = src;
ip6_sd_fib_add_del_src_route (lgm, &a);
+ /* make sure insertion succeeded */
+ if (CLIB_DEBUG)
+ {
+ u32 sai;
+ ip_adjacency_t * src_adjp;
+ sai = ip6_sd_get_src_route (lgm, dst_adjp->rewrite_header.sw_if_index,
+ &src, src_address_length);
+ src_adjp = ip_get_adjacency(lgm->lm6, sai);
+ ASSERT(src_adjp->rewrite_header.node_index
+ == add_adj->rewrite_header.node_index);
+ }
+
/* if a delete, check if there are elements left in the src fib */
if (!is_add)
{
@@ -825,8 +887,8 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
src_adj0 = ip_get_adjacency (lgm->lm4, src_adj_index0);
src_adj1 = ip_get_adjacency (lgm->lm4, src_adj_index1);
- next0 = src_adj0->lookup_next_index;
- next1 = src_adj1->lookup_next_index;
+ next0 = src_adj0->explicit_fib_index;
+ next1 = src_adj1->explicit_fib_index;
/* prepare buffer for lisp-gpe output node */
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
@@ -842,7 +904,7 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
&ip0->src_address, &src_adj_index0);
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
src_adj0 = ip_get_adjacency (lgm->lm4, src_adj_index0);
- next0 = src_adj0->lookup_next_index;
+ next0 = src_adj0->explicit_fib_index;
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
src_adj0->rewrite_header.sw_if_index;
}
@@ -852,7 +914,7 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
&ip1->src_address, &src_adj_index1);
vnet_buffer(b1)->ip.adj_index[VLIB_TX] = src_adj_index1;
src_adj1 = ip_get_adjacency (lgm->lm4, src_adj_index1);
- next1 = src_adj1->lookup_next_index;
+ next1 = src_adj1->explicit_fib_index;
vnet_buffer (b1)->sw_if_index[VLIB_TX] =
src_adj1->rewrite_header.sw_if_index;
}
@@ -894,7 +956,7 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
&src_adj_index0);
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
src_adj0 = ip_get_adjacency (lgm->lm4, src_adj_index0);
- next0 = src_adj0->lookup_next_index;
+ next0 = src_adj0->explicit_fib_index;
/* prepare packet for lisp-gpe output node */
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
@@ -1041,8 +1103,8 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
src_adj0 = ip_get_adjacency (lgm->lm6, src_adj_index0);
src_adj1 = ip_get_adjacency (lgm->lm6, src_adj_index1);
- next0 = src_adj0->lookup_next_index;
- next1 = src_adj1->lookup_next_index;
+ next0 = src_adj0->explicit_fib_index;
+ next1 = src_adj1->explicit_fib_index;
/* prepare buffer for lisp-gpe output node */
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
@@ -1058,7 +1120,7 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
&ip0->src_address);
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
src_adj0 = ip_get_adjacency (lgm->lm6, src_adj_index0);
- next0 = src_adj0->lookup_next_index;
+ next0 = src_adj0->explicit_fib_index;
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
src_adj0->rewrite_header.sw_if_index;
}
@@ -1068,7 +1130,7 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
&ip1->src_address);
vnet_buffer(b1)->ip.adj_index[VLIB_TX] = src_adj_index1;
src_adj1 = ip_get_adjacency (lgm->lm6, src_adj_index1);
- next1 = src_adj1->lookup_next_index;
+ next1 = src_adj1->explicit_fib_index;
vnet_buffer (b1)->sw_if_index[VLIB_TX] =
src_adj1->rewrite_header.sw_if_index;
}
@@ -1111,7 +1173,7 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
src_adj0 = ip_get_adjacency (lgm->lm6, src_adj_index0);
- next0 = src_adj0->lookup_next_index;
+ next0 = src_adj0->explicit_fib_index;
/* prepare packet for lisp-gpe output node */
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.c b/vnet/vnet/lisp-gpe/lisp_gpe.c
index 35e16bbcf7c..f594e927ea8 100644
--- a/vnet/vnet/lisp-gpe/lisp_gpe.c
+++ b/vnet/vnet/lisp-gpe/lisp_gpe.c
@@ -243,7 +243,11 @@ vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
/* setup adjacency for eid */
memset (&adj, 0, sizeof(adj));
adj.n_adj = 1;
- adj.explicit_fib_index = ~0;
+
+ /* fill in lookup_next_index with a 'legal' value to avoid problems */
+ adj.lookup_next_index = (ip_ver == IP4) ?
+ lgm->ip4_lookup_next_lgpe_ip4_lookup :
+ lgm->ip6_lookup_next_lgpe_ip6_lookup;
if (a->is_add)
{
@@ -261,7 +265,8 @@ vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
ASSERT(lookup_next_index != 0);
ASSERT(lgpe_sw_if_index != 0);
- adj.lookup_next_index = lookup_next_index[0];
+ /* hijack explicit fib index to store lisp interface node index */
+ adj.explicit_fib_index = lookup_next_index[0];
adj.rewrite_header.node_index = tun_index;
adj.rewrite_header.sw_if_index = lgpe_sw_if_index[0];
}