SFF NSH support VXLAN GPE 04/204/19
authorKeith Burns (alagalah) <alagalah@gmail.com>
Wed, 3 Feb 2016 05:45:02 +0000 (21:45 -0800)
committerGerrit Code Review <gerrit@fd.io>
Tue, 9 Feb 2016 13:38:27 +0000 (13:38 +0000)
Change-Id: I23dae9e13f6c2ec7b3326710a40f28984ff6fe1f
Signed-off-by: Keith Burns (alagalah) <alagalah@gmail.com>
vnet/vnet/nsh-vxlan-gpe/decap.c

index 62bb0f8..a8de9bc 100644 (file)
@@ -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: