diff options
author | Florin Coras <fcoras@cisco.com> | 2016-06-17 13:59:10 +0200 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-06-19 13:26:11 +0000 |
commit | 2459e4c5f577907ea060957bc0699a72a1f8e1be (patch) | |
tree | 02668088c85da27400f8c318cd4a401774752e4b | |
parent | 808b2db9648b444dec906d27050afd9af6138f90 (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.c | 82 | ||||
-rw-r--r-- | vnet/vnet/lisp-gpe/lisp_gpe.c | 9 |
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]; } |