X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Flb%2Flb.c;h=b1e0b237478b24366ae06c129c8ad9e0a851c5c4;hb=7b2e9fb1a;hp=1936c1983ee7876c85cc3c3ee43cea14c986f89c;hpb=6a4375e02d8dd4ebcc2f79ee9f6abbafdd2f674c;p=vpp.git diff --git a/src/plugins/lb/lb.c b/src/plugins/lb/lb.c index 1936c1983ee..b1e0b237478 100644 --- a/src/plugins/lb/lb.c +++ b/src/plugins/lb/lb.c @@ -18,6 +18,7 @@ #include #include #include +#include //GC runs at most once every so many seconds #define LB_GARBAGE_RUN 60 @@ -27,8 +28,8 @@ lb_main_t lb_main; -#define lb_get_writer_lock() do {} while(__sync_lock_test_and_set (lb_main.writer_lock, 1)) -#define lb_put_writer_lock() lb_main.writer_lock[0] = 0 +#define lb_get_writer_lock() clib_spinlock_lock (&lb_main.writer_lock) +#define lb_put_writer_lock() clib_spinlock_unlock (&lb_main.writer_lock) static void lb_as_stack (lb_as_t *as); @@ -289,7 +290,7 @@ static void lb_vip_garbage_collection(lb_vip_t *vip) lb_snat6_key_t m_key6; clib_bihash_kv_24_8_t kv6, value6; lb_snat_mapping_t *m = 0; - ASSERT (lbm->writer_lock[0]); + CLIB_SPINLOCK_ASSERT_LOCKED (&lbm->writer_lock); u32 now = (u32) vlib_time_now(vlib_get_main()); if (!clib_u32_loop_gt(now, vip->last_garbage_collection + LB_GARBAGE_RUN)) @@ -384,7 +385,7 @@ static void lb_vip_update_new_flow_table(lb_vip_t *vip) lb_as_t *as; lb_pseudorand_t *pr, *sort_arr = 0; - ASSERT (lbm->writer_lock[0]); //We must have the lock + CLIB_SPINLOCK_ASSERT_LOCKED (&lbm->writer_lock); // We must have the lock //Check if some AS is configured or not i = 0; @@ -442,7 +443,7 @@ out: //Let's create a new flow table vec_validate(new_flow_table, vip->new_flow_table_mask); for (i=0; ilast; pr->last = (pr->last + pr->skip) & vip->new_flow_table_mask; - if (new_flow_table[last].as_index == ~0) { + if (new_flow_table[last].as_index == 0) { new_flow_table[last].as_index = pr->as_index; break; } @@ -496,7 +497,8 @@ int lb_vip_port_find_index(ip46_address_t *prefix, u8 plen, { lb_main_t *lbm = &lb_main; lb_vip_t *vip; - ASSERT (lbm->writer_lock[0]); //This must be called with the lock owned + /* 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, { if ((vip->flags & LB_AS_FLAGS_USED) && @@ -560,7 +562,8 @@ int lb_vip_find_index(ip46_address_t *prefix, u8 plen, u8 protocol, static int lb_as_find_index_vip(lb_vip_t *vip, ip46_address_t *address, u32 *as_index) { lb_main_t *lbm = &lb_main; - ASSERT (lbm->writer_lock[0]); //This must be called with the lock owned + /* This must be called with the lock owned */ + CLIB_SPINLOCK_ASSERT_LOCKED (&lbm->writer_lock); lb_as_t *as; u32 *asi; pool_foreach(asi, vip->as_indexes, { @@ -676,7 +679,7 @@ next: { /* Add SNAT static mapping */ pool_get (lbm->snat_mappings, m); - memset (m, 0, sizeof (*m)); + clib_memset (m, 0, sizeof (*m)); if (lb_vip_is_nat4_port(vip)) { lb_snat4_key_t m_key4; clib_bihash_kv_8_8_t kv4; @@ -773,7 +776,7 @@ lb_flush_vip_as (u32 vip_index, u32 as_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; + b->value[i] = 0; } } if (vip_index == ~0) @@ -857,7 +860,7 @@ static int lb_vip_prefix_index_alloc (lb_main_t *lbm) { /* - * Check for dynamically allocaetd instance number. + * Check for dynamically allocated instance number. */ u32 bit; @@ -984,10 +987,15 @@ static int lb_vip_del_port_filter(lb_main_t *lbm, lb_vip_t *vip) key.vip_prefix_index = vip->vip_prefix_index; key.protocol = vip->protocol; key.port = clib_host_to_net_u16(vip->port); + key.rsv = 0; kv.key = key.as_u64; - if(clib_bihash_search_8_8(&lbm->vip_index_per_port, &kv, &value) == 0) - m = pool_elt_at_index (lbm->vips, value.value); + if(clib_bihash_search_8_8(&lbm->vip_index_per_port, &kv, &value) != 0) + { + clib_warning("looking up vip_index_per_port failed."); + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + m = pool_elt_at_index (lbm->vips, value.value); ASSERT (m); kv.value = m - lbm->vips; @@ -1190,10 +1198,11 @@ int lb_vip_del(u32 vip_index) { lb_main_t *lbm = &lb_main; lb_vip_t *vip; + int rv = 0; /* Does not remove default vip, i.e. vip_index = 0 */ if (vip_index == 0) - return 0; + return VNET_API_ERROR_INVALID_VALUE; lb_get_writer_lock(); if (!(vip = lb_vip_get_by_index(vip_index))) { @@ -1225,20 +1234,20 @@ int lb_vip_del(u32 vip_index) //Delete per-port vip filtering entry if (vip->port != 0) { - lb_vip_del_port_filter(lbm, vip); + rv = lb_vip_del_port_filter(lbm, vip); } //Set the VIP as unused vip->flags &= ~LB_VIP_FLAGS_USED; lb_put_writer_lock(); - return 0; + return rv; } /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, - .description = "Load Balancer", + .description = "Load Balancer (LB)", }; /* *INDENT-ON* */ @@ -1369,6 +1378,7 @@ lb_init (vlib_main_t * vm) //Allocate and init default VIP. lbm->vips = 0; pool_get(lbm->vips, default_vip); + default_vip->new_flow_table_mask = 0; default_vip->prefix.ip6.as_u64[0] = 0xffffffffffffffffL; default_vip->prefix.ip6.as_u64[1] = 0xffffffffffffffffL; default_vip->protocol = ~0; @@ -1377,8 +1387,7 @@ lb_init (vlib_main_t * vm) lbm->per_cpu = 0; vec_validate(lbm->per_cpu, tm->n_vlib_mains - 1); - lbm->writer_lock = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES); - lbm->writer_lock[0] = 0; + clib_spinlock_init (&lbm->writer_lock); lbm->per_cpu_sticky_buckets = LB_DEFAULT_PER_CPU_STICKY_BUCKETS; lbm->flow_timeout = LB_DEFAULT_FLOW_TIMEOUT; lbm->ip4_src_address.as_u32 = 0xffffffff; @@ -1412,6 +1421,12 @@ lb_init (vlib_main_t * vm) default_as->address.ip6.as_u64[0] = 0xffffffffffffffffL; default_as->address.ip6.as_u64[1] = 0xffffffffffffffffL; + /* Generate a valid flow table for default VIP */ + default_vip->as_indexes = NULL; + lb_get_writer_lock(); + lb_vip_update_new_flow_table(default_vip); + lb_put_writer_lock(); + lbm->vip_index_by_nodeport = hash_create_mem (0, sizeof(u16), sizeof (uword));