LB: fix flush flow table issue
Change-Id: Ib0a06ab71aed42eb5bb2ab2edf4844b2167e0610 Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
This commit is contained in:

committed by
Damjan Marion

parent
742582f415
commit
6a4375e02d
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user