- if (is_input_v4) {
- ip4_header_t *ip40;
- ip40 = vlib_buffer_get_current (p0);
- len0 = clib_net_to_host_u16(ip40->length);
- key0[0] = (u64) ip40->src_address.as_u32;
- key0[1] = (u64) ip40->dst_address.as_u32;
- key0[2] = 0;
- key0[3] = 0;
- key0[4] = ((u64)((udp_header_t *)(ip40 + 1))->src_port << 32) |
- ((u64)((udp_header_t *)(ip40 + 1))->dst_port << 16);
-
- hash0 = lb_hash_hash(key0);
- } else {
- ip6_header_t *ip60;
- ip60 = vlib_buffer_get_current (p0);
- len0 = clib_net_to_host_u16(ip60->payload_length) + sizeof(ip6_header_t);
- key0[0] = ip60->src_address.as_u64[0];
- key0[1] = ip60->src_address.as_u64[1];
- key0[2] = ip60->dst_address.as_u64[0];
- key0[3] = ip60->dst_address.as_u64[1];
- key0[4] = ((u64)((udp_header_t *)(ip60 + 1))->src_port << 32) |
- ((u64)((udp_header_t *)(ip60 + 1))->dst_port << 16);
-
- hash0 = lb_hash_hash(key0);
- }
-
- //NOTE: This is an ugly trick to not include the VIP index in the hash calculation
- //but actually use it in the key determination.
- key0[4] |= ((vip0 - lbm->vips));
-
- lb_hash_get(sticky_ht, key0, hash0, lb_time, &available_index0, &value0);
- if (PREDICT_TRUE(value0 != ~0)) {
- //Found an existing entry
- as0 = &lbm->ass[value0];
- } else if (PREDICT_TRUE(available_index0 != ~0)) {
- //There is an available slot for a new flow
- as0 = &lbm->ass[vip0->new_flow_table[hash0 & vip0->new_flow_table_mask].as_index];
- if (PREDICT_FALSE(as0 == lbm->ass)) { //Special first element
- error0 = LB_ERROR_NO_SERVER;
- } else {
- vlib_increment_simple_counter(&lbm->vip_counters[LB_VIP_COUNTER_TRACKED_SESSION],
- cpu_index, vip0 - lbm->vips, 1);
- }
-
- //TODO: There are race conditions with as0 and vip0 manipulation.
- //Configuration may be changed, vectors resized, etc...
-
- //Dereference previously used
- vlib_refcount_add(&lbm->as_refcount, cpu_index, lb_hash_available_value(sticky_ht, available_index0), -1);
- vlib_refcount_add(&lbm->as_refcount, cpu_index, as0 - lbm->ass, 1);
-
- //Add sticky entry
- //Note that when there is no AS configured, an entry is configured anyway.
- //But no configured AS is not something that should happen
- lb_hash_put(sticky_ht, key0, as0 - lbm->ass, available_index0, lb_time);
- } else {
- //Could not store new entry in the table
- as0 = &lbm->ass[vip0->new_flow_table[hash0 & vip0->new_flow_table_mask].as_index];
- vlib_increment_simple_counter(&lbm->vip_counters[LB_VIP_COUNTER_UNTRACKED_PACKET],
- cpu_index, vip0 - lbm->vips, 1);
- }
+ if (is_input_v4)
+ {
+ ip4_header_t *ip40;
+ ip40 = vlib_buffer_get_current (p0);
+ len0 = clib_net_to_host_u16(ip40->length);
+ }
+ else
+ {
+ ip6_header_t *ip60;
+ ip60 = vlib_buffer_get_current (p0);
+ len0 = clib_net_to_host_u16(ip60->payload_length) + sizeof(ip6_header_t);
+ }
+
+ lb_hash_get(sticky_ht, hash0, vnet_buffer (p0)->ip.adj_index[VLIB_TX],
+ lb_time, &available_index0, &asindex0);
+
+ if (PREDICT_TRUE(asindex0 != ~0))
+ {
+ //Found an existing entry
+ counter = LB_VIP_COUNTER_NEXT_PACKET;
+ }
+ else if (PREDICT_TRUE(available_index0 != ~0))
+ {
+ //There is an available slot for a new flow
+ asindex0 = vip0->new_flow_table[hash0 & vip0->new_flow_table_mask].as_index;
+ counter = LB_VIP_COUNTER_FIRST_PACKET;
+ counter = (asindex0 == 0)?LB_VIP_COUNTER_NO_SERVER:counter;
+
+ //TODO: There are race conditions with as0 and vip0 manipulation.
+ //Configuration may be changed, vectors resized, etc...
+
+ //Dereference previously used
+ vlib_refcount_add(&lbm->as_refcount, cpu_index,
+ lb_hash_available_value(sticky_ht, hash0, available_index0), -1);
+ vlib_refcount_add(&lbm->as_refcount, cpu_index,
+ asindex0, 1);
+
+ //Add sticky entry
+ //Note that when there is no AS configured, an entry is configured anyway.
+ //But no configured AS is not something that should happen
+ lb_hash_put(sticky_ht, hash0, asindex0,
+ vnet_buffer (p0)->ip.adj_index[VLIB_TX],
+ available_index0, lb_time);
+ }
+ else
+ {
+ //Could not store new entry in the table
+ asindex0 = vip0->new_flow_table[hash0 & vip0->new_flow_table_mask].as_index;
+ counter = LB_VIP_COUNTER_UNTRACKED_PACKET;
+ }
+
+ vlib_increment_simple_counter(&lbm->vip_counters[counter],
+ cpu_index,
+ vnet_buffer (p0)->ip.adj_index[VLIB_TX],
+ 1);