LB: fix flush flow table issue 61/14861/7
authorHongjun Ni <hongjun.ni@intel.com>
Tue, 18 Sep 2018 15:25:02 +0000 (23:25 +0800)
committerDamjan Marion <dmarion@me.com>
Mon, 24 Sep 2018 08:04:37 +0000 (08:04 +0000)
Change-Id: Ib0a06ab71aed42eb5bb2ab2edf4844b2167e0610
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
src/plugins/lb/api.c
src/plugins/lb/cli.c
src/plugins/lb/lb.api
src/plugins/lb/lb.c
src/plugins/lb/lb.h

index 5194c2e..c392123 100644 (file)
@@ -239,11 +239,54 @@ static void *vl_api_lb_add_del_as_t_print
   FINISH;
 }
 
+static void
+vl_api_lb_flush_vip_t_handler
+(vl_api_lb_flush_vip_t * mp)
+{
+  lb_main_t *lbm = &lb_main;
+  int rv = 0;
+  ip46_address_t vip_prefix;
+  u8 vip_plen;
+  u32 vip_index;
+  vl_api_lb_flush_vip_reply_t * rmp;
+
+  if (mp->port == 0)
+    {
+      mp->protocol = ~0;
+    }
+
+  memcpy (&(vip_prefix.ip6), mp->ip_prefix, sizeof(vip_prefix.ip6));
+
+  vip_plen = mp->prefix_length;
+
+  rv = lb_vip_find_index(&vip_prefix, vip_plen, mp->protocol,
+                         (u16)mp->port, &vip_index);
+
+  rv = lb_flush_vip_as(vip_index, ~0);
+
+ REPLY_MACRO (VL_API_LB_FLUSH_VIP_REPLY);
+}
+
+static void *vl_api_lb_flush_vip_t_print
+(vl_api_lb_flush_vip_t *mp, void * handle)
+{
+  u8 * s;
+  s = format (0, "SCRIPT: lb_add_del_vip ");
+  s = format (s, "%U ", format_ip46_prefix,
+              (ip46_address_t *)mp->ip_prefix, mp->prefix_length, IP46_TYPE_ANY);
+
+  s = format (s, "protocol %u ", mp->protocol);
+  s = format (s, "port %u ", mp->port);
+
+  FINISH;
+}
+
 /* List of message types that this plugin understands */
 #define foreach_lb_plugin_api_msg            \
 _(LB_CONF, lb_conf)                          \
 _(LB_ADD_DEL_VIP, lb_add_del_vip)            \
-_(LB_ADD_DEL_AS, lb_add_del_as)
+_(LB_ADD_DEL_AS, lb_add_del_as)              \
+_(LB_FLUSH_VIP, lb_flush_vip)
 
 static clib_error_t * lb_api_init (vlib_main_t * vm)
 {
index 6e1b7c1..a12a633 100644 (file)
@@ -497,32 +497,13 @@ VLIB_CLI_COMMAND (lb_set_interface_nat6_command, static) = {
   .short_help = "lb set interface nat6 in <intfc> [del]",
 };
 
-int
-lb_flush_vip (u32 vip_index)
+static clib_error_t *
+lb_flowtable_flush_command_fn (vlib_main_t * vm,
+              unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  u32 thread_index;
-  vlib_thread_main_t *tm = vlib_get_thread_main();
-  lb_main_t *lbm = &lb_main;
-
-  for(thread_index = 0; thread_index < tm->n_vlib_mains; thread_index++ ) {
-    lb_hash_t *h = lbm->per_cpu[thread_index].sticky_ht;
-    if (h != NULL) {
-        u32 i;
-        lb_hash_bucket_t *b;
-
-        lb_hash_foreach_entry(h, b, i) {
-          if (b->vip[i] == vip_index)
-            {
-              vlib_refcount_add(&lbm->as_refcount, thread_index, b->value[i], -1);
-              vlib_refcount_add(&lbm->as_refcount, thread_index, 0, 1);
-              b->vip[i] = ~0;
-              b->value[i] = ~0;
-            }
-        }
-    }
-  }
+  lb_flush_vip_as(~0, 0);
 
-  return 0;
+  return NULL;
 }
 
 static clib_error_t *
@@ -574,7 +555,7 @@ lb_flush_vip_command_fn (vlib_main_t * vm,
     goto done;
   }
 
-  if ((ret = lb_flush_vip(vip_index)))
+  if ((ret = lb_flush_vip_as(vip_index, ~0)))
     {
       error = clib_error_return (0, "lb_flush_vip error %d", ret);
     }
@@ -596,37 +577,10 @@ VLIB_CLI_COMMAND (lb_flush_vip_command, static) =
 {
   .path = "lb flush vip",
   .short_help = "lb flush vip <prefix> "
-      "[protocol (tcp|udp) port <n>] exec []",
+      "[protocol (tcp|udp) port <n>]",
   .function = lb_flush_vip_command_fn,
 };
 
-static clib_error_t *
-lb_flowtable_flush_command_fn (vlib_main_t * vm,
-              unformat_input_t * input, vlib_cli_command_t * cmd)
-{
-  u32 thread_index;
-  vlib_thread_main_t *tm = vlib_get_thread_main();
-  lb_main_t *lbm = &lb_main;
-
-  for(thread_index = 0; thread_index < tm->n_vlib_mains; thread_index++ ) {
-    lb_hash_t *h = lbm->per_cpu[thread_index].sticky_ht;
-    if (h != NULL) {
-        u32 i;
-        lb_hash_bucket_t *b;
-
-        lb_hash_foreach_entry(h, b, i) {
-            vlib_refcount_add(&lbm->as_refcount, thread_index, b->value[i], -1);
-            vlib_refcount_add(&lbm->as_refcount, thread_index, 0, 1);
-        }
-
-        lb_hash_free(h);
-        lbm->per_cpu[thread_index].sticky_ht = 0;
-    }
-  }
-
-  return NULL;
-}
-
 /*
  * flush all lb flowtables
  * This is indented for debug and unit-tests purposes only
index 545d6b1..d36f857 100644 (file)
@@ -75,3 +75,19 @@ autoreply define lb_add_del_as {
   u8 is_flush;
 };
 
+/** \brief Flush a given vip
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param ip_prefix - IP address (IPv4 in lower order 32 bits).
+    @param prefix_length - IP prefix length (96 + 'IPv4 prefix length' for IPv4).
+    @param protocol - tcp or udp.
+    @param port - destination port.
+*/
+autoreply define lb_flush_vip {
+  u32 client_index;
+  u32 context;
+  u8 ip_prefix[16];
+  u8 prefix_length;
+  u8 protocol;
+  u16 port;
+};
index 601b297..1936c19 100644 (file)
@@ -766,8 +766,9 @@ lb_flush_vip_as (u32 vip_index, u32 as_index)
         lb_hash_bucket_t *b;
 
         lb_hash_foreach_entry(h, b, i) {
-          if ((b->vip[i] == vip_index)
-              || (b->value[i] == as_index))
+          if ((vip_index == ~0)
+              || ((b->vip[i] == vip_index) && (as_index == ~0))
+              || ((b->vip[i] == vip_index) && (b->value[i] == as_index)))
             {
               vlib_refcount_add(&lbm->as_refcount, thread_index, b->value[i], -1);
               vlib_refcount_add(&lbm->as_refcount, thread_index, 0, 1);
@@ -775,18 +776,24 @@ lb_flush_vip_as (u32 vip_index, u32 as_index)
               b->value[i] = ~0;
             }
         }
+        if (vip_index == ~0)
+          {
+            lb_hash_free(h);
+            lbm->per_cpu[thread_index].sticky_ht = 0;
+          }
+      }
     }
-  }
 
   return 0;
 }
 
 int lb_vip_del_ass_withlock(u32 vip_index, ip46_address_t *addresses, u32 n,
-                            u32 *as_index)
+                            u8 flush)
 {
   lb_main_t *lbm = &lb_main;
   u32 now = (u32) vlib_time_now(vlib_get_main());
   u32 *ip = 0;
+  u32 as_index = 0;
 
   lb_vip_t *vip;
   if (!(vip = lb_vip_get_by_index(vip_index))) {
@@ -795,7 +802,7 @@ int lb_vip_del_ass_withlock(u32 vip_index, ip46_address_t *addresses, u32 n,
 
   u32 *indexes = NULL;
   while (n--) {
-    if (lb_as_find_index_vip(vip, &addresses[n], as_index)) {
+    if (lb_as_find_index_vip(vip, &addresses[n], &as_index)) {
       vec_free(indexes);
       return VNET_API_ERROR_NO_SUCH_ENTRY;
     }
@@ -809,7 +816,7 @@ int lb_vip_del_ass_withlock(u32 vip_index, ip46_address_t *addresses, u32 n,
       }
     }
 
-    vec_add1(indexes, *as_index);
+    vec_add1(indexes, as_index);
 next:
   continue;
   }
@@ -821,6 +828,12 @@ next:
     vec_foreach(ip, indexes) {
       lbm->ass[*ip].flags &= ~LB_AS_FLAGS_USED;
       lbm->ass[*ip].last_used = now;
+
+      if(flush)
+        {
+          /* flush flow table for deleted ASs*/
+          lb_flush_vip_as(vip_index, *ip);
+        }
     }
 
     //Recompute flows
@@ -833,17 +846,10 @@ next:
 
 int lb_vip_del_ass(u32 vip_index, ip46_address_t *addresses, u32 n, u8 flush)
 {
-  u32 as_index = 0;
   lb_get_writer_lock();
-  int ret = lb_vip_del_ass_withlock(vip_index, addresses, n, &as_index);
+  int ret = lb_vip_del_ass_withlock(vip_index, addresses, n, flush);
   lb_put_writer_lock();
 
-  if(flush)
-    {
-      /* flush flow table per as of per-port-vip */
-      ret = lb_flush_vip_as(vip_index, as_index);
-    }
-
   return ret;
 }
 
@@ -1203,12 +1209,13 @@ int lb_vip_del(u32 vip_index)
     ip46_address_t *ass = 0;
     lb_as_t *as;
     u32 *as_index;
+
     pool_foreach(as_index, vip->as_indexes, {
         as = &lbm->ass[*as_index];
         vec_add1(ass, as->address);
     });
     if (vec_len(ass))
-      lb_vip_del_ass_withlock(vip_index, ass, vec_len(ass), as_index);
+      lb_vip_del_ass_withlock(vip_index, ass, vec_len(ass), 0);
     vec_free(ass);
   }
 
index c77a1b6..d09ac63 100644 (file)
@@ -607,6 +607,7 @@ int lb_vip_find_index(ip46_address_t *prefix, u8 plen, u8 protocol,
 
 int lb_vip_add_ass(u32 vip_index, ip46_address_t *addresses, u32 n);
 int lb_vip_del_ass(u32 vip_index, ip46_address_t *addresses, u32 n, u8 flush);
+int lb_flush_vip_as (u32 vip_index, u32 as_index);
 
 u32 lb_hash_time_now(vlib_main_t * vm);