aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/lb/api.c45
-rw-r--r--src/plugins/lb/cli.c60
-rw-r--r--src/plugins/lb/lb.api16
-rw-r--r--src/plugins/lb/lb.c37
-rw-r--r--src/plugins/lb/lb.h1
5 files changed, 90 insertions, 69 deletions
diff --git a/src/plugins/lb/api.c b/src/plugins/lb/api.c
index 5194c2e88ec..c392123c792 100644
--- a/src/plugins/lb/api.c
+++ b/src/plugins/lb/api.c
@@ -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)
{
diff --git a/src/plugins/lb/cli.c b/src/plugins/lb/cli.c
index 6e1b7c1b1ee..a12a63354cc 100644
--- a/src/plugins/lb/cli.c
+++ b/src/plugins/lb/cli.c
@@ -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
diff --git a/src/plugins/lb/lb.api b/src/plugins/lb/lb.api
index 545d6b18c3e..d36f857f5de 100644
--- a/src/plugins/lb/lb.api
+++ b/src/plugins/lb/lb.api
@@ -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;
+};
diff --git a/src/plugins/lb/lb.c b/src/plugins/lb/lb.c
index 601b297ffe8..1936c1983ee 100644
--- a/src/plugins/lb/lb.c
+++ b/src/plugins/lb/lb.c
@@ -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);
}
diff --git a/src/plugins/lb/lb.h b/src/plugins/lb/lb.h
index c77a1b6e294..d09ac632be6 100644
--- a/src/plugins/lb/lb.h
+++ b/src/plugins/lb/lb.h
@@ -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);