#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
#include <vnet/api_errno.h>
-#include <vnet/udp/udp.h>
+#include <vnet/udp/udp_local.h>
#include <vppinfra/lock.h>
//GC runs at most once every so many seconds
//After so many seconds. It is assumed that inter-core race condition will not occur.
#define LB_CONCURRENCY_TIMEOUT 10
+// FIB source for adding routes
+static fib_source_t lb_fib_src;
+
lb_main_t lb_main;
#define lb_get_writer_lock() clib_spinlock_lock (&lb_main.writer_lock)
lb_as_t *as;
u32 *as_index;
- pool_foreach(as_index, vip->as_indexes, {
+ pool_foreach (as_index, vip->as_indexes) {
as = &lbm->ass[*as_index];
s = format(s, "%U %U %u buckets %Lu flows dpo:%u %s\n",
format_white_space, indent,
vlib_refcount_get(&lbm->as_refcount, as - lbm->ass),
as->dpo.dpoi_index,
(as->flags & LB_AS_FLAGS_USED)?"used":" removed");
- });
+ }
vec_free(count);
return s;
vip->last_garbage_collection = now;
lb_as_t *as;
u32 *as_index;
- pool_foreach(as_index, vip->as_indexes, {
+ pool_foreach (as_index, vip->as_indexes) {
as = &lbm->ass[*as_index];
if (!(as->flags & LB_AS_FLAGS_USED) && //Not used
clib_u32_loop_gt(now, as->last_used + LB_CONCURRENCY_TIMEOUT) &&
pool_put(vip->as_indexes, as_index);
pool_put(lbm->ass, as);
}
- });
+ }
}
void lb_garbage_collection()
lb_get_writer_lock();
lb_vip_t *vip;
u32 *to_be_removed_vips = 0, *i;
- pool_foreach(vip, lbm->vips, {
+ pool_foreach (vip, lbm->vips) {
lb_vip_garbage_collection(vip);
if (!(vip->flags & LB_VIP_FLAGS_USED) &&
(pool_elts(vip->as_indexes) == 0)) {
vec_add1(to_be_removed_vips, vip - lbm->vips);
}
- });
+ }
vec_foreach(i, to_be_removed_vips) {
vip = &lbm->vips[*i];
//Check if some AS is configured or not
i = 0;
- pool_foreach(as_index, vip->as_indexes, {
+ pool_foreach (as_index, vip->as_indexes) {
as = &lbm->ass[*as_index];
if (as->flags & LB_AS_FLAGS_USED) { //Not used anymore
i = 1;
goto out; //Not sure 'break' works in this macro-loop
}
- });
+ }
out:
if (i == 0) {
vec_alloc(sort_arr, pool_elts(vip->as_indexes));
i = 0;
- pool_foreach(as_index, vip->as_indexes, {
+ pool_foreach (as_index, vip->as_indexes) {
as = &lbm->ass[*as_index];
if (!(as->flags & LB_AS_FLAGS_USED)) //Not used anymore
continue;
sort_arr[i].as_index = as - lbm->ass;
i++;
- });
+ }
_vec_len(sort_arr) = i;
vec_sort_with_function(sort_arr, lb_pseudorand_compare);
/* This must be called with the lock owned */
CLIB_SPINLOCK_ASSERT_LOCKED (&lbm->writer_lock);
ip46_prefix_normalize(prefix, plen);
- pool_foreach(vip, lbm->vips, {
+ pool_foreach (vip, lbm->vips) {
if ((vip->flags & LB_AS_FLAGS_USED) &&
vip->plen == plen &&
vip->prefix.as_u64[0] == prefix->as_u64[0] &&
return 0;
}
}
- });
+ }
return VNET_API_ERROR_NO_SUCH_ENTRY;
}
CLIB_SPINLOCK_ASSERT_LOCKED (&lbm->writer_lock);
lb_as_t *as;
u32 *asi;
- pool_foreach(asi, vip->as_indexes, {
+ pool_foreach (asi, vip->as_indexes) {
as = &lbm->ass[*asi];
if (as->vip_index == (vip - lbm->vips) &&
as->address.as_u64[0] == address->as_u64[0] &&
*as_index = as - lbm->ass;
return 0;
}
- });
+ }
return -1;
}
if (!lb_vip_port_find_diff_port(&(vip->prefix), vip->plen,
vip->protocol, vip->port, &vip_idx))
{
+ lb_vip_t *exists_vip = lb_vip_get_by_index(vip_idx);
+ *vip_prefix_index = exists_vip ? exists_vip->vip_prefix_index : ~0;
return;
}
dpo_set(&dpo, dpo_type, proto, *vip_prefix_index);
fib_table_entry_special_dpo_add(0,
&pfx,
- FIB_SOURCE_PLUGIN_HI,
+ lb_fib_src,
FIB_ENTRY_FLAG_EXCLUSIVE,
&dpo);
dpo_reset(&dpo);
pfx.fp_len = vip->plen;
pfx.fp_proto = FIB_PROTOCOL_IP6;
}
- fib_table_entry_special_remove(0, &pfx, FIB_SOURCE_PLUGIN_HI);
+ fib_table_entry_special_remove(0, &pfx, lb_fib_src);
}
int lb_vip_add(lb_vip_add_args_t args, u32 *vip_index)
lb_as_t *as;
u32 *as_index;
- pool_foreach(as_index, vip->as_indexes, {
+ 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), 0);
vec_free(ass);
#define _(a,b,c) lbm->vip_counters[c].name = b;
lb_foreach_vip_counter
#undef _
+
+ lb_fib_src = fib_source_allocate("lb",
+ FIB_SOURCE_PRIORITY_HI,
+ FIB_SOURCE_BH_SIMPLE);
+
return NULL;
}