cnat: allow max_u16 translation backends 40/29440/5
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>
Tue, 13 Oct 2020 15:26:47 +0000 (17:26 +0200)
committerBeno�t Ganne <bganne@cisco.com>
Wed, 21 Oct 2020 12:44:40 +0000 (12:44 +0000)
Type: fix

Allow for 65536 backends for a translation.
- use u32 instead of u8
- filter out back_walk with more than
FIB_PATH_LIST_POPULAR backends
- we're still limited by u16 lb_n_buckets
in src/vnet/dpo/load_balance.h

Change-Id: Ib37b958e59b25ef5ef9f92b82008d626860faddd
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
src/plugins/cnat/cnat.api
src/plugins/cnat/cnat_api.c
src/plugins/cnat/cnat_translation.c
src/plugins/cnat/cnat_translation.h

index a9507c9..7bf6be8 100644 (file)
@@ -53,7 +53,7 @@ typedef cnat_translation
   vl_api_ip_proto_t ip_proto;
   u8 is_real_ip;
   u8 flags;
-  u8 n_paths;
+  u32 n_paths;
   vl_api_cnat_endpoint_tuple_t paths[n_paths];
 };
 
index f692451..338cb59 100644 (file)
@@ -88,16 +88,17 @@ vl_api_cnat_translation_update_t_handler (vl_api_cnat_translation_update_t
   u32 id = ~0;
   u8 flags;
   int rv = 0;
-  u8 pi;
+  u32 pi, n_paths;
 
   rv = ip_proto_decode (mp->translation.ip_proto, &ip_proto);
 
   if (rv)
     goto done;
 
-  vec_validate (paths, mp->translation.n_paths - 1);
+  n_paths = clib_net_to_host_u32 (mp->translation.n_paths);
+  vec_validate (paths, n_paths - 1);
 
-  for (pi = 0; pi < mp->translation.n_paths; pi++)
+  for (pi = 0; pi < n_paths; pi++)
     {
       path = &paths[pi];
       cnat_endpoint_tuple_decode (&mp->translation.paths[pi], path);
@@ -146,7 +147,7 @@ cnat_translation_send_details (u32 cti, void *args)
   vl_api_cnat_endpoint_tuple_t *path;
   size_t msg_size;
   cnat_translation_t *ct;
-  u8 n_paths;
+  u32 n_paths;
 
   ctx = args;
   ct = cnat_translation_get (cti);
@@ -158,8 +159,8 @@ cnat_translation_send_details (u32 cti, void *args)
 
   /* fill in the message */
   mp->context = ctx->context;
-  mp->translation.n_paths = n_paths;
-  mp->translation.id = htonl (cti);
+  mp->translation.n_paths = clib_host_to_net_u32 (n_paths);
+  mp->translation.id = clib_host_to_net_u32 (cti);
   cnat_endpoint_encode (&ct->ct_vip, &mp->translation.vip);
   mp->translation.ip_proto = ip_proto_encode (ct->ct_proto);
 
index 4833df9..263ec05 100644 (file)
@@ -180,7 +180,7 @@ cnat_translation_stack (cnat_translation_t * ct)
   fib_protocol_t fproto;
   cnat_ep_trk_t *trk;
   dpo_proto_t dproto;
-  u8 ep_idx = 0;
+  u32 ep_idx = 0;
   index_t lbi;
 
   fproto = ip_address_family_to_fib_proto (ct->ct_vip.ce_ip.version);
@@ -198,6 +198,7 @@ cnat_translation_stack (cnat_translation_t * ct)
 
   dpo_set (&ct->ct_lb, DPO_LOAD_BALANCE, dproto, lbi);
   dpo_stack (cnat_client_dpo, dproto, &ct->ct_lb, &ct->ct_lb);
+  ct->flags |= CNAT_TRANSLATION_STACKED;
 }
 
 int
@@ -277,6 +278,7 @@ cnat_translation_update (cnat_endpoint_t * vip,
   }
 
   vec_reset_length (ct->ct_paths);
+  ct->flags &= ~CNAT_TRANSLATION_STACKED;
 
   u64 path_idx = 0;
   vec_foreach (path, paths)
@@ -457,6 +459,12 @@ cnat_translation_back_walk_notify (fib_node_t * node,
    */
   cnat_translation_t *ct = cnat_translation_get_from_node (node);
 
+  /* If we have more than FIB_PATH_LIST_POPULAR paths
+   * we might get called during path tracking
+   * (cnat_tracker_track) */
+  if (!(ct->flags & CNAT_TRANSLATION_STACKED))
+    return (FIB_NODE_BACK_WALK_CONTINUE);
+
   cnat_translation_stack (ct);
 
   return (FIB_NODE_BACK_WALK_CONTINUE);
@@ -601,9 +609,12 @@ cnat_if_addr_add_del_backend_cb (addr_resolution_t * ar,
       ip_address_copy (&ep->ce_ip, address);
       ep->ce_flags |= CNAT_EP_FLAG_RESOLVED;
     }
+
+  ct->flags &= ~CNAT_TRANSLATION_STACKED;
   cnat_tracker_track (ar->cti, trk);
 
   cnat_translation_stack (ct);
+  ct->flags |= CNAT_TRANSLATION_STACKED;
 }
 
 static void
index cfcbf5b..a4ae1ec 100644 (file)
@@ -58,7 +58,12 @@ typedef struct cnat_ep_trk_t_
 
 typedef enum cnat_translation_flag_t_
 {
+  /* Do allocate a source port */
   CNAT_TRANSLATION_FLAG_ALLOCATE_PORT = (1 << 0),
+  /* Has this translation been satcked ?
+   * this allow not being called twice when
+   * with more then FIB_PATH_LIST_POPULAR backends  */
+  CNAT_TRANSLATION_STACKED = (1 << 1),
 } cnat_translation_flag_t;
 
 typedef enum