LB: fix flush flow table issue

Change-Id: Ib0a06ab71aed42eb5bb2ab2edf4844b2167e0610
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
This commit is contained in:
Hongjun Ni
2018-09-18 23:25:02 +08:00
committed by Damjan Marion
parent 742582f415
commit 6a4375e02d
5 changed files with 90 additions and 69 deletions

View 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)
{

View 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;
lb_flush_vip_as(~0, 0);
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;
}
}
}
}
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

View 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;
};

View 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);
}

View 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);