fib: fix crash when create vxlan/vxlan-gpe/geneve/gtpu tunnel. 03/37303/4
authorHuawei LI <lihuawei_zzu@163.com>
Thu, 29 Sep 2022 03:28:12 +0000 (11:28 +0800)
committerNeale Ranns <neale@graphiant.com>
Tue, 11 Oct 2022 03:37:36 +0000 (03:37 +0000)
Fix vpp crash when create vxlan/vxlan-gpe/geneve/gtpu tunnel
with 0.0.0.0 dst ip in debug build. The ASSERT should be move
out of fib_prefix_from_ip46_addr, which may be called when
create vxlan/vxlan-gpe/geneve/gtpu tunnel with 0.0.0.0 dst ip.

How to reproduce:
1. build debug vpp and run vpp
2. create vxlan t src 192.168.0.2 dst 0.0.0.0 vni 1 instance 1
   create vxlan-gpe tunnel local 192.168.0.2 remote 0.0.0.0 vni 1
   create geneve tunnel local 192.168.0.2 remote 0.0.0.0 vni 1
   create gtpu tunnel src 192.168.0.2 dst 0.0.0.0 teid 1

Type: fix

Change-Id: I19972f6af588f4ff7fd17de1b16b9301e43d596f
Signed-off-by: Huawei LI <lihuawei_zzu@163.com>
src/plugins/geneve/geneve.c
src/plugins/gtpu/gtpu.c
src/vnet/fib/fib_path.c
src/vnet/fib/fib_types.c
src/vnet/fib/fib_types.h
src/vnet/vxlan-gpe/vxlan_gpe.c
src/vnet/vxlan/vxlan.c

index bc0ad58..2bdd162 100644 (file)
@@ -470,7 +470,8 @@ int vnet_geneve_add_del_tunnel
       fib_prefix_t tun_remote_pfx;
       vnet_flood_class_t flood_class = VNET_FLOOD_CLASS_TUNNEL_NORMAL;
 
-      fib_prefix_from_ip46_addr (&t->remote, &tun_remote_pfx);
+      fib_protocol_t fp = fib_ip_proto (is_ip6);
+      fib_prefix_from_ip46_addr (fp, &t->remote, &tun_remote_pfx);
       if (!ip46_address_is_multicast (&t->remote))
        {
          /* Unicast tunnel -
@@ -494,8 +495,6 @@ int vnet_geneve_add_del_tunnel
           * with different VNIs, create the output fib adjecency only if
           * it does not already exist
           */
-         fib_protocol_t fp = fib_ip_proto (is_ip6);
-
          if (vtep_addr_ref (&vxm->vtep_table,
                             t->encap_fib_index, &t->remote) == 1)
            {
index 086a4b5..d3a2f05 100644 (file)
@@ -473,7 +473,8 @@ int vnet_gtpu_add_mod_del_tunnel
       fib_prefix_t tun_dst_pfx;
       vnet_flood_class_t flood_class = VNET_FLOOD_CLASS_TUNNEL_NORMAL;
 
-      fib_prefix_from_ip46_addr (&t->dst, &tun_dst_pfx);
+      fib_protocol_t fp = fib_ip_proto (is_ip6);
+      fib_prefix_from_ip46_addr (fp, &t->dst, &tun_dst_pfx);
       if (!ip46_address_is_multicast (&t->dst))
        {
          /* Unicast tunnel -
@@ -497,8 +498,6 @@ int vnet_gtpu_add_mod_del_tunnel
           * with different VNIs, create the output adjacency only if
           * it does not already exist
           */
-         fib_protocol_t fp = fib_ip_proto (is_ip6);
-
          if (vtep_addr_ref (&gtm->vtep_table,
                             t->encap_fib_index, &t->dst) == 1)
            {
index db78587..8d160d9 100644 (file)
@@ -1998,7 +1998,11 @@ fib_path_resolve (fib_node_index_t path_index)
        }
        else
        {
-           fib_prefix_from_ip46_addr(&path->recursive.fp_nh.fp_ip, &pfx);
+           ASSERT(!ip46_address_is_zero(&path->recursive.fp_nh.fp_ip));
+
+           fib_protocol_t fp = (ip46_address_is_ip4(&path->recursive.fp_nh.fp_ip) ?
+                                        FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
+           fib_prefix_from_ip46_addr(fp, &path->recursive.fp_nh.fp_ip, &pfx);
        }
 
         fib_table_lock(path->recursive.fp_tbl_id,
index 7eeb79f..5c5fd0b 100644 (file)
@@ -78,16 +78,15 @@ format_fib_mpls_label (u8 *s, va_list *ap)
 }
 
 void
-fib_prefix_from_ip46_addr (const ip46_address_t *addr,
+fib_prefix_from_ip46_addr (fib_protocol_t fproto,
+                          const ip46_address_t *addr,
                           fib_prefix_t *pfx)
 {
-    ASSERT(!ip46_address_is_zero(addr));
+    ASSERT(FIB_PROTOCOL_MPLS != fproto);
 
-    pfx->fp_proto = ((ip46_address_is_ip4(addr) ?
-                     FIB_PROTOCOL_IP4 :
-                     FIB_PROTOCOL_IP6));
-    pfx->fp_len = ((ip46_address_is_ip4(addr) ?
-                   32 : 128));
+    pfx->fp_proto = fproto;
+    pfx->fp_len = ((FIB_PROTOCOL_IP4 == fproto) ?
+                   32 : 128);
     pfx->fp_addr = *addr;
     pfx->___fp___pad = 0;
 }
index dbd4e97..49a4b39 100644 (file)
@@ -276,8 +276,9 @@ extern void fib_prefix_normalize(const fib_prefix_t *p,
 /**
  * \brief Host prefix from ip
  */
-extern void fib_prefix_from_ip46_addr (const ip46_address_t *addr,
-                          fib_prefix_t *pfx);
+extern void fib_prefix_from_ip46_addr (fib_protocol_t fproto,
+                                      const ip46_address_t *addr,
+                                      fib_prefix_t *pfx);
 
 extern u8 * format_fib_prefix(u8 * s, va_list * args);
 extern u8 * format_fib_forw_chain_type(u8 * s, va_list * args);
index a926847..5919e0f 100644 (file)
@@ -594,7 +594,8 @@ int vnet_vxlan_gpe_add_del_tunnel
       fib_prefix_t tun_remote_pfx;
       vnet_flood_class_t flood_class = VNET_FLOOD_CLASS_TUNNEL_NORMAL;
 
-      fib_prefix_from_ip46_addr (&t->remote, &tun_remote_pfx);
+      fib_protocol_t fp = fib_ip_proto (is_ip6);
+      fib_prefix_from_ip46_addr (fp, &t->remote, &tun_remote_pfx);
       if (!ip46_address_is_multicast (&t->remote))
        {
          /* Unicast tunnel -
@@ -618,8 +619,6 @@ int vnet_vxlan_gpe_add_del_tunnel
           * with different VNIs, create the output fib adjacency only if
           * it does not already exist
           */
-         fib_protocol_t fp = fib_ip_proto (is_ip6);
-
          if (vtep_addr_ref (&ngm->vtep_table,
                             t->encap_fib_index, &t->remote) == 1)
            {
index f670ee9..1871e5d 100644 (file)
@@ -537,7 +537,8 @@ int vnet_vxlan_add_del_tunnel
       fib_prefix_t tun_dst_pfx;
       vnet_flood_class_t flood_class = VNET_FLOOD_CLASS_TUNNEL_NORMAL;
 
-      fib_prefix_from_ip46_addr (&t->dst, &tun_dst_pfx);
+      fib_protocol_t fp = fib_ip_proto (is_ip6);
+      fib_prefix_from_ip46_addr (fp, &t->dst, &tun_dst_pfx);
       if (!ip46_address_is_multicast (&t->dst))
        {
          /* Unicast tunnel -
@@ -561,8 +562,6 @@ int vnet_vxlan_add_del_tunnel
           * with different VNIs, create the output fib adjacency only if
           * it does not already exist
           */
-         fib_protocol_t fp = fib_ip_proto (is_ip6);
-
          if (vtep_addr_ref (&vxm->vtep_table,
                             t->encap_fib_index, &t->dst) == 1)
            {