summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vnet/vnet/lisp-gpe/ip_forward.c196
-rw-r--r--vnet/vnet/lisp-gpe/lisp_gpe.c6
2 files changed, 127 insertions, 75 deletions
diff --git a/vnet/vnet/lisp-gpe/ip_forward.c b/vnet/vnet/lisp-gpe/ip_forward.c
index a8d53ee3588..607687305c5 100644
--- a/vnet/vnet/lisp-gpe/ip_forward.c
+++ b/vnet/vnet/lisp-gpe/ip_forward.c
@@ -745,17 +745,24 @@ ip4_src_fib_lookup_one (lisp_gpe_main_t * lgm, u32 src_fib_index0,
ip4_fib_mtrie_leaf_t leaf0, leaf1;
ip4_fib_mtrie_t * mtrie0;
- mtrie0 = &vec_elt_at_index(lgm->ip4_src_fibs, src_fib_index0)->mtrie;
-
- leaf0 = leaf1 = IP4_FIB_MTRIE_LEAF_ROOT;
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 0);
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 1);
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 2);
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 3);
-
- /* Handle default route. */
- leaf0 = (leaf0 == IP4_FIB_MTRIE_LEAF_EMPTY ? mtrie0->default_leaf : leaf0);
- src_adj_index0[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
+ /* if default route not hit in ip4 lookup */
+ if (PREDICT_TRUE(src_fib_index0 != (u32 ) ~0))
+ {
+ mtrie0 = &vec_elt_at_index(lgm->ip4_src_fibs, src_fib_index0)->mtrie;
+
+ leaf0 = leaf1 = IP4_FIB_MTRIE_LEAF_ROOT;
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 0);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 1);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 2);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 3);
+
+ /* Handle default route. */
+ leaf0 = (leaf0 == IP4_FIB_MTRIE_LEAF_EMPTY) ?
+ mtrie0->default_leaf : leaf0;
+ src_adj_index0[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
+ }
+ else
+ src_adj_index0[0] = ~0;
}
always_inline void
@@ -767,28 +774,39 @@ ip4_src_fib_lookup_two (lisp_gpe_main_t * lgm, u32 src_fib_index0,
ip4_fib_mtrie_leaf_t leaf0, leaf1;
ip4_fib_mtrie_t * mtrie0, * mtrie1;
- mtrie0 = &vec_elt_at_index(lgm->ip4_src_fibs, src_fib_index0)->mtrie;
- mtrie1 = &vec_elt_at_index(lgm->ip4_src_fibs, src_fib_index1)->mtrie;
+ /* if default route not hit in ip4 lookup */
+ if (PREDICT_TRUE(src_fib_index0 != (u32 ) ~0 && src_fib_index1 != (u32 ) ~0))
+ {
+ mtrie0 = &vec_elt_at_index(lgm->ip4_src_fibs, src_fib_index0)->mtrie;
+ mtrie1 = &vec_elt_at_index(lgm->ip4_src_fibs, src_fib_index1)->mtrie;
- leaf0 = leaf1 = IP4_FIB_MTRIE_LEAF_ROOT;
+ leaf0 = leaf1 = IP4_FIB_MTRIE_LEAF_ROOT;
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 0);
- leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 0);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 0);
+ leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 0);
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 1);
- leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 1);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 1);
+ leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 1);
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 2);
- leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 2);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 2);
+ leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 2);
- leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 3);
- leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 3);
+ leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, addr0, 3);
+ leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, addr1, 3);
- /* Handle default route. */
- leaf0 = (leaf0 == IP4_FIB_MTRIE_LEAF_EMPTY ? mtrie0->default_leaf : leaf0);
- leaf1 = (leaf1 == IP4_FIB_MTRIE_LEAF_EMPTY ? mtrie1->default_leaf : leaf1);
- src_adj_index0[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
- src_adj_index1[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf1);
+ /* Handle default route. */
+ leaf0 = (leaf0 == IP4_FIB_MTRIE_LEAF_EMPTY) ?
+ mtrie0->default_leaf : leaf0;
+ leaf1 = (leaf1 == IP4_FIB_MTRIE_LEAF_EMPTY) ?
+ mtrie1->default_leaf : leaf1;
+ src_adj_index0[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
+ src_adj_index1[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf1);
+ }
+ else
+ {
+ ip4_src_fib_lookup_one (lgm, src_fib_index0, addr0, src_adj_index0);
+ ip4_src_fib_lookup_one (lgm, src_fib_index1, addr1, src_adj_index1);
+ }
}
always_inline uword
@@ -860,14 +878,14 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
src_fib_index1 = dst_adj1->rewrite_header.sw_if_index;
- /* if default route not hit in ip4 lookup */
- if (PREDICT_TRUE(src_fib_index0 != (u32) ~0
- && src_fib_index1 != (u32) ~0))
- {
- ip4_src_fib_lookup_two (lgm, src_fib_index0, src_fib_index1,
- &ip0->src_address, &ip1->src_address,
- &src_adj_index0, &src_adj_index1);
+ ip4_src_fib_lookup_two (lgm, src_fib_index0, src_fib_index1,
+ &ip0->src_address, &ip1->src_address,
+ &src_adj_index0, &src_adj_index1);
+ /* if a source fib exists */
+ if (PREDICT_TRUE((u32) ~0 != src_adj_index0
+ && (u32) ~0 != src_adj_index1))
+ {
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
vnet_buffer(b1)->ip.adj_index[VLIB_TX] = src_adj_index1;
@@ -885,10 +903,8 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
- if (src_fib_index0 != (u32) ~0)
+ if ((u32) ~0 != src_adj_index0)
{
- ip4_src_fib_lookup_one (lgm, src_fib_index0,
- &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->explicit_fib_index;
@@ -898,13 +914,10 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
else
{
next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
- vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP;
}
- if (src_fib_index1 != (u32) ~0)
+ if ((u32) ~0 != src_adj_index1)
{
- ip4_src_fib_lookup_one (lgm, src_fib_index1,
- &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->explicit_fib_index;
@@ -914,10 +927,15 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
else
{
next1 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
- vnet_buffer (b1)->lisp.overlay_afi = LISP_AFI_IP;
}
}
+ /* mark the packets for CP lookup if needed*/
+ if (PREDICT_FALSE(LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
+ vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP;
+ if (PREDICT_FALSE(LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next1))
+ vnet_buffer (b1)->lisp.overlay_afi = LISP_AFI_IP;
+
vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
n_left_to_next, bi0, bi1, next0,
next1);
@@ -946,12 +964,13 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
dst_adj0 = ip_get_adjacency (lgm->lm4, dst_adj_index0);
src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
- /* if default route not hit in ip4 lookup */
- if (PREDICT_TRUE(src_fib_index0 != (u32 ) ~0))
+ /* do src lookup */
+ ip4_src_fib_lookup_one (lgm, src_fib_index0, &ip0->src_address,
+ &src_adj_index0);
+
+ /* if a source fib exists */
+ if (PREDICT_TRUE((u32) ~0 != src_adj_index0))
{
- /* do src lookup */
- ip4_src_fib_lookup_one (lgm, src_fib_index0, &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->explicit_fib_index;
@@ -963,9 +982,11 @@ lgpe_ip4_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
else
{
next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
- vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP;
}
+ if (PREDICT_FALSE(LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
+ vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP;
+
vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
n_left_to_next, bi0, next0);
}
@@ -1021,6 +1042,36 @@ ip6_src_fib_lookup (lisp_gpe_main_t * lgm, u32 src_fib_index,
return 0;
}
+always_inline void
+ip6_src_fib_lookup_one (lisp_gpe_main_t * lgm, u32 src_fib_index0,
+ ip6_address_t * addr0, u32 * src_adj_index0)
+{
+ /* if default route not hit in ip6 lookup */
+ if (PREDICT_TRUE(src_fib_index0 != (u32 ) ~0))
+ src_adj_index0[0] = ip6_src_fib_lookup (lgm, src_fib_index0, addr0);
+ else
+ src_adj_index0[0] = ~0;
+}
+
+always_inline void
+ip6_src_fib_lookup_two (lisp_gpe_main_t * lgm, u32 src_fib_index0,
+ u32 src_fib_index1, ip6_address_t * addr0,
+ ip6_address_t * addr1, u32 * src_adj_index0,
+ u32 * src_adj_index1)
+{
+ /* if default route not hit in ip6 lookup */
+ if (PREDICT_TRUE(src_fib_index0 != (u32 ) ~0 && src_fib_index1 != (u32 ) ~0))
+ {
+ src_adj_index0[0] = ip6_src_fib_lookup(lgm, src_fib_index0, addr0);
+ src_adj_index1[0] = ip6_src_fib_lookup(lgm, src_fib_index1, addr1);
+ }
+ else
+ {
+ ip6_src_fib_lookup_one (lgm, src_fib_index0, addr0, src_adj_index0);
+ ip6_src_fib_lookup_one (lgm, src_fib_index1, addr1, src_adj_index1);
+ }
+}
+
always_inline uword
lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
@@ -1090,16 +1141,14 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
src_fib_index1 = dst_adj1->rewrite_header.sw_if_index;
- /* if default route not hit in ip6 lookup */
- if (PREDICT_TRUE(src_fib_index0 != (u32) ~0
- && src_fib_index1 != (u32) ~0))
- {
- /* do src lookup */
- src_adj_index0 = ip6_src_fib_lookup (lgm, src_fib_index0,
- &ip0->src_address);
- src_adj_index1 = ip6_src_fib_lookup (lgm, src_fib_index1,
- &ip1->src_address);
+ ip6_src_fib_lookup_two (lgm, src_fib_index0, src_fib_index1,
+ &ip0->src_address, &ip1->src_address,
+ &src_adj_index0, &src_adj_index1);
+ /* if a source fib exists */
+ if (PREDICT_TRUE((u32) ~0 != src_adj_index0
+ && (u32) ~0 != src_adj_index1))
+ {
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
vnet_buffer(b1)->ip.adj_index[VLIB_TX] = src_adj_index1;
@@ -1117,10 +1166,8 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
- if (src_fib_index0 != (u32) ~0)
+ if (src_adj_index0 != (u32) ~0)
{
- src_adj_index0 = ip6_src_fib_lookup (lgm, src_fib_index0,
- &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->explicit_fib_index;
@@ -1130,13 +1177,10 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
else
{
next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
- vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP6;
}
- if (src_fib_index1 != (u32) ~0)
+ if (src_adj_index1 != (u32) ~0)
{
- src_adj_index1 = ip6_src_fib_lookup (lgm, src_fib_index1,
- &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->explicit_fib_index;
@@ -1146,10 +1190,15 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
else
{
next1 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
- vnet_buffer (b1)->lisp.overlay_afi = LISP_AFI_IP6;
}
}
+ /* mark the packets for CP lookup if needed*/
+ if (PREDICT_FALSE(LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
+ vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP;
+ if (PREDICT_FALSE(LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next1))
+ vnet_buffer (b1)->lisp.overlay_afi = LISP_AFI_IP;
+
vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next,
n_left_to_next, bi0, bi1, next0,
next1);
@@ -1178,13 +1227,13 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
dst_adj0 = ip_get_adjacency (lgm->lm6, dst_adj_index0);
src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
- /* if default route not hit in ip6 lookup */
- if (PREDICT_TRUE(src_fib_index0 != (u32 ) ~0))
- {
- /* do src lookup */
- src_adj_index0 = ip6_src_fib_lookup (lgm, src_fib_index0,
- &ip0->src_address);
+ /* do src lookup */
+ ip6_src_fib_lookup_one (lgm, src_fib_index0, &ip0->src_address,
+ &src_adj_index0);
+ /* if a source fib exists */
+ if (PREDICT_TRUE(src_adj_index0 != (u32 ) ~0))
+ {
vnet_buffer(b0)->ip.adj_index[VLIB_TX] = src_adj_index0;
src_adj0 = ip_get_adjacency (lgm->lm6, src_adj_index0);
next0 = src_adj0->explicit_fib_index;
@@ -1196,9 +1245,12 @@ lgpe_ip6_lookup (vlib_main_t * vm, vlib_node_runtime_t * node,
else
{
next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
- vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP6;
}
+ /* mark the packets for CP lookup if needed*/
+ if (PREDICT_FALSE(LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
+ vnet_buffer (b0)->lisp.overlay_afi = LISP_AFI_IP;
+
vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next,
n_left_to_next, bi0, next0);
}
diff --git a/vnet/vnet/lisp-gpe/lisp_gpe.c b/vnet/vnet/lisp-gpe/lisp_gpe.c
index ae3a5e0f7fd..e5d3500fb06 100644
--- a/vnet/vnet/lisp-gpe/lisp_gpe.c
+++ b/vnet/vnet/lisp-gpe/lisp_gpe.c
@@ -236,6 +236,7 @@ build_ip_adjacency (lisp_gpe_main_t * lgm, ip_adjacency_t * adj, u32 table_id,
{
adj->rewrite_header.sw_if_index = ~0;
adj->rewrite_header.next_index = ~0;
+ adj->if_address_index = tun_index;
switch (action)
{
@@ -276,7 +277,7 @@ add_del_ip_fwd_entry (lisp_gpe_main_t * lgm,
ip_ver = ip_prefix_version(rmt_pref);
/* add/del tunnel to tunnels pool and prepares rewrite */
- if (!a->is_negative)
+ if (0 != a->locator_pairs)
{
rv = add_del_ip_tunnel (a, 0 /* is_l2 */, &tun_index);
if (rv)
@@ -310,8 +311,7 @@ add_del_ip_fwd_entry (lisp_gpe_main_t * lgm,
adjp = ip_get_adjacency ((ip_ver == IP4) ? lgm->lm4 : lgm->lm6,
adj_index);
- ASSERT(adjp != 0);
- ASSERT(adjp->if_address_index == tun_index);
+ ASSERT(adjp != 0 && adjp->if_address_index == tun_index);
}
return rv;