diff options
-rw-r--r-- | vnet/vnet/nsh-vxlan-gpe/decap.c | 130 |
1 files changed, 115 insertions, 15 deletions
diff --git a/vnet/vnet/nsh-vxlan-gpe/decap.c b/vnet/vnet/nsh-vxlan-gpe/decap.c index 62bb0f81dc7..a8de9bc3af1 100644 --- a/vnet/vnet/nsh-vxlan-gpe/decap.c +++ b/vnet/vnet/nsh-vxlan-gpe/decap.c @@ -166,11 +166,44 @@ nsh_vxlan_gpe_input (vlib_main_t * vm, /* Required to make the l2 tag push / pop code work on l2 subifs */ vnet_update_l2_len (b0); - /* - * ip[46] lookup in the configured FIB - * nsh-vxlan-gpe-encap, here's the encap tunnel sw_if_index - */ - vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->decap_fib_index; + if (next0 == NSH_VXLAN_GPE_INPUT_NEXT_NSH_VXLAN_GPE_ENCAP) + { + /* + * Functioning as SFF (ie "half NSH tunnel mode") + * If ingress (we are in decap.c) with NSH header, and 'decap next nsh-vxlan-gpe' then "NSH switch" + * 1. Take DST, remap to SRC, remap other keys in place + * 2. Look up new t0 as per above + * 3. Set sw_if_index[VLIB_TX] to be t0->sw_if_index + */ + uword * next_p0; + nsh_vxlan_gpe_tunnel_t * next_t0; + nsh_vxlan_gpe_tunnel_key_t next_key0; + + next_key0.src = iuvn0->ip4.dst_address.as_u32; + next_key0.vni = iuvn0->vxlan.vni_res; + next_key0.spi_si = iuvn0->nsh.spi_si; + next_key0.pad = 0; + + next_p0 = hash_get_mem (ngm->nsh_vxlan_gpe_tunnel_by_key, &next_key0); + + if (next_p0 == 0) + { + error0 = NSH_VXLAN_GPE_ERROR_NO_SUCH_TUNNEL; + goto trace0; + } + next_t0 = pool_elt_at_index (ngm->tunnels, next_p0[0]); + vnet_buffer(b0)->sw_if_index[VLIB_TX] = next_t0->sw_if_index; + + } + else + { + /* + * ip[46] lookup in the configured FIB + * nsh-vxlan-gpe-encap, here's the encap tunnel sw_if_index + */ + vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->decap_fib_index; + } + trace0: b0->error = error0 ? node->errors[error0] : 0; @@ -215,10 +248,44 @@ nsh_vxlan_gpe_input (vlib_main_t * vm, /* Required to make the l2 tag push / pop code work on l2 subifs */ vnet_update_l2_len (b1); - /* - * ip[46] lookup in the configured FIB - * nsh-vxlan-gpe-encap, here's the encap tunnel sw_if_index - */ + if (next1 == NSH_VXLAN_GPE_INPUT_NEXT_NSH_VXLAN_GPE_ENCAP) + { + /* + * Functioning as SFF (ie "half NSH tunnel mode") + * If ingress (we are in decap.c) with NSH header, and 'decap next nsh-vxlan-gpe' then "NSH switch" + * 1. Take DST, remap to SRC, remap other keys in place + * 2. Look up new t0 as per above + * 3. Set sw_if_index[VLIB_TX] to be t0->sw_if_index + */ + uword * next_p1; + nsh_vxlan_gpe_tunnel_t * next_t1; + nsh_vxlan_gpe_tunnel_key_t next_key1; + + next_key1.src = iuvn0->ip4.dst_address.as_u32; + next_key1.vni = iuvn0->vxlan.vni_res; + next_key1.spi_si = iuvn0->nsh.spi_si; + next_key1.pad = 0; + + next_p1 = hash_get_mem (ngm->nsh_vxlan_gpe_tunnel_by_key, &next_key1); + + if (next_p1 == 0) + { + error1 = NSH_VXLAN_GPE_ERROR_NO_SUCH_TUNNEL; + goto trace1; + } + next_t1 = pool_elt_at_index (ngm->tunnels, next_p1[0]); + vnet_buffer(b1)->sw_if_index[VLIB_TX] = next_t1->sw_if_index; + + } + else + { + /* + * ip[46] lookup in the configured FIB + * nsh-vxlan-gpe-encap, here's the encap tunnel sw_if_index + */ + vnet_buffer(b1)->sw_if_index[VLIB_TX] = t1->decap_fib_index; + } + vnet_buffer(b1)->sw_if_index[VLIB_TX] = t1->decap_fib_index; pkts_decapsulated += 2; @@ -283,7 +350,7 @@ nsh_vxlan_gpe_input (vlib_main_t * vm, || (key0.as_u64[1] != last_key.as_u64[1]))) { p0 = hash_get_mem (ngm->nsh_vxlan_gpe_tunnel_by_key, &key0); - + if (p0 == 0) { error0 = NSH_VXLAN_GPE_ERROR_NO_SUCH_TUNNEL; @@ -304,11 +371,44 @@ nsh_vxlan_gpe_input (vlib_main_t * vm, /* Required to make the l2 tag push / pop code work on l2 subifs */ vnet_update_l2_len (b0); - /* - * ip[46] lookup in the configured FIB - * nsh-vxlan-gpe-encap, here's the encap tunnel sw_if_index - */ - vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->decap_fib_index; + if (next0 == NSH_VXLAN_GPE_INPUT_NEXT_NSH_VXLAN_GPE_ENCAP) + { + /* + * Functioning as SFF (ie "half NSH tunnel mode") + * If ingress (we are in decap.c) with NSH header, and 'decap next nsh-vxlan-gpe' then "NSH switch" + * 1. Take DST, remap to SRC, remap other keys in place + * 2. Look up new t0 as per above + * 3. Set sw_if_index[VLIB_TX] to be t0->sw_if_index + */ + uword * next_p0; + nsh_vxlan_gpe_tunnel_t * next_t0; + nsh_vxlan_gpe_tunnel_key_t next_key0; + + next_key0.src = iuvn0->ip4.dst_address.as_u32; + next_key0.vni = iuvn0->vxlan.vni_res; + next_key0.spi_si = iuvn0->nsh.spi_si; + next_key0.pad = 0; + + next_p0 = hash_get_mem (ngm->nsh_vxlan_gpe_tunnel_by_key, &next_key0); + + if (next_p0 == 0) + { + error0 = NSH_VXLAN_GPE_ERROR_NO_SUCH_TUNNEL; + goto trace00; + } + next_t0 = pool_elt_at_index (ngm->tunnels, next_p0[0]); + vnet_buffer(b0)->sw_if_index[VLIB_TX] = next_t0->sw_if_index; + + } + else + { + /* + * ip[46] lookup in the configured FIB + * nsh-vxlan-gpe-encap, here's the encap tunnel sw_if_index + */ + vnet_buffer(b0)->sw_if_index[VLIB_TX] = t0->decap_fib_index; + } + pkts_decapsulated ++; trace00: |