22 #define foreach_lb_error \ 24 _(PROTO_NOT_SUPPORTED, "protocol not supported") 28 #define _(sym,str) LB_ERROR_##sym, 36 #define _(sym,string) string, 73 s =
format (s,
"lb vip[%d]: This VIP was freed since capture\n");
82 s =
format (s,
"lb as[%d]: This AS was freed since capture\n");
104 s =
format (s,
"lb vip[%d]: This VIP was freed since capture\n");
113 s =
format (s,
"lb as[%d]: This AS was freed since capture\n");
120 s =
format (s,
"lb nat: rx_sw_if_index = %d, next_index = %d",
178 u32 *hash,
u32 *vip_idx,
u8 per_port_vip)
200 || ip40->
protocol == IP_PROTOCOL_UDP))
211 key.
port = (
u16)(ports & 0xFFFF);
222 || ip60->
protocol == IP_PROTOCOL_UDP))
236 key.
port = (
u16)(ports & 0xFFFF);
250 *vip_idx = value.
value;
263 u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
273 u32 next_vip_idx0 = ~0;
278 &next_vip_idx0, per_port_vip);
281 while (n_left_from > 0)
284 while (n_left_from > 0 && n_left_to_next > 0)
291 u32 available_index0;
293 u32 hash0 = nexthash0;
294 u32 vip_index0 = next_vip_idx0;
302 &nexthash0, &next_vip_idx0,
318 pi0 = to_next[0] = from[0];
332 len0 = clib_net_to_host_u16 (ip40->
length);
344 &available_index0, &asindex0);
349 counter = LB_VIP_COUNTER_NEXT_PACKET;
356 counter = LB_VIP_COUNTER_FIRST_PACKET;
357 counter = (asindex0 == 0) ? LB_VIP_COUNTER_NO_SERVER : counter;
374 available_index0, lb_time);
381 counter = LB_VIP_COUNTER_UNTRACKED_PACKET;
407 ip40->
length = clib_host_to_net_u16 (
423 clib_host_to_net_u32 (0x6 << 28);
432 clib_host_to_net_u16 (0x0800) :
433 clib_host_to_net_u16 (0x86DD);
440 u32 old_dst, new_dst;
445 new_dst = lbm->
ass[asindex0].
address.ip4.as_u32;
489 if (ip40->
protocol == IP_PROTOCOL_UDP)
507 ip6_address_t old_dst;
526 csum, lbm->
ass[asindex0].
address.ip6.as_u64[0]);
528 csum, lbm->
ass[asindex0].
address.ip6.as_u64[1]);
551 vm, node, next_index, to_next, n_left_to_next, pi0, next0);
570 s =
format (s,
"lb vip[%d]: This VIP was freed since capture\n");
588 u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
594 while (n_left_from > 0)
598 while (n_left_from > 0 && n_left_to_next > 0)
621 pi0 = to_next[0] = from[0];
689 if (clib_bihash_search_8_8 (mapping_hash, &kv4, &value))
694 *index = value.
value;
714 m_key6.
addr.as_u64[0] = match->
addr.as_u64[0];
715 m_key6.
addr.as_u64[1] = match->
addr.as_u64[1];
724 if (clib_bihash_search_24_8 (mapping_hash, &kv6, &value))
729 *index = value.
value;
737 u32 n_left_from, *from, *to_next;
739 u32 pkts_processed = 0;
741 u32 stats_node_index;
750 while (n_left_from > 0)
756 while (n_left_from > 0 && n_left_to_next > 0)
763 u16 old_port0, new_port0;
787 u32 old_addr0, new_addr0;
809 new_addr0 = sm40->
src_ip.ip4.as_u32;
822 old_port0 = tcp0->src_port;
823 tcp0->src_port = new_port0;
825 csum = tcp0->checksum;
850 ip6_address_t old_addr0, new_addr0;
873 new_addr0.as_u64[0] = sm60->
src_ip.as_u64[0];
874 new_addr0.as_u64[1] = sm60->
src_ip.as_u64[1];
884 old_port0 = tcp0->src_port;
885 tcp0->src_port = new_port0;
887 csum = tcp0->checksum;
924 n_left_to_next, bi0, next0);
931 LB_NAT_IN2OUT_ERROR_IN2OUT_PACKETS,
1038 .vector_size =
sizeof(
u32),
1051 .vector_size =
sizeof(
u32),
1064 .vector_size =
sizeof(
u32),
1077 .vector_size =
sizeof(
u32),
1089 .name =
"lb6-gre6-port",
1090 .vector_size =
sizeof(
u32),
1102 .name =
"lb6-gre4-port",
1103 .vector_size =
sizeof(
u32),
1115 .name =
"lb4-gre6-port",
1116 .vector_size =
sizeof(
u32),
1128 .name =
"lb4-gre4-port",
1129 .vector_size =
sizeof(
u32),
1141 .name =
"lb4-l3dsr-port",
1142 .vector_size =
sizeof(
u32),
1154 .name =
"lb4-l3dsr",
1155 .vector_size =
sizeof(
u32),
1167 .name =
"lb6-nat6-port",
1168 .vector_size =
sizeof(
u32),
1180 .name =
"lb4-nat4-port",
1181 .vector_size =
sizeof(
u32),
1207 .name =
"lb4-nodeport",
1208 .vector_size =
sizeof(
u32),
1223 .name =
"lb6-nodeport",
1224 .vector_size =
sizeof(
u32),
1238 .arc_name =
"ip4-unicast",
1239 .node_name =
"lb-nat4-in2out",
1246 .name =
"lb-nat4-in2out",
1247 .vector_size =
sizeof(
u32),
1261 .arc_name =
"ip6-unicast",
1262 .node_name =
"lb-nat6-in2out",
1269 .name =
"lb-nat6-in2out",
1270 .vector_size =
sizeof(
u32),
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
format_function_t format_lb_vip
u32 lb_hash_time_now(vlib_main_t *vm)
static u32 lb_ip_proto_to_nat_proto(u8 ip_proto)
vlib_node_registration_t lb6_gre6_node
(constructor) VLIB_REGISTER_NODE (lb6_gre6_node)
vlib_node_registration_t lb6_gre6_port_node
(constructor) VLIB_REGISTER_NODE (lb6_gre6_port_node)
vlib_node_registration_t lb4_gre4_node
(constructor) VLIB_REGISTER_NODE (lb4_gre4_node)
static uword lb6_gre4_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword lb6_nat6_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 per_cpu_sticky_buckets
Number of buckets in the per-cpu sticky hash table.
static uword lb_nat6_in2out_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vl_api_ip_port_and_mask_t dst_port
lb_hash_t * lb_get_sticky_table(u32 thread_index)
static_always_inline lb_hash_t * lb_hash_alloc(u32 buckets, u32 timeout)
vlib_node_registration_t lb4_nat4_port_node
(constructor) VLIB_REGISTER_NODE (lb4_nat4_port_node)
static uword lb4_nat4_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
static uword lb_nat_in2out_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 is_nat4)
static_always_inline u32 lb_hash_available_value(lb_hash_t *h, u32 hash, u32 available_index)
struct _tcp_header tcp_header_t
lb_hash_t * sticky_ht
Each CPU has its own sticky flow hash table.
static uword lb6_gre6_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
ip46_address_t address
Destination address used to tunnel traffic towards that application server.
u8 * format_lb_trace(u8 *s, va_list *args)
vlib_node_registration_t lb6_nat6_port_node
(constructor) VLIB_REGISTER_NODE (lb6_nat6_port_node)
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
#define lb_hash_nbuckets(h)
#define static_always_inline
int lb_nat44_mapping_match(lb_main_t *lbm, lb_snat4_key_t *match, u32 *index)
Match NAT44 static mapping.
static char * lb_error_strings[]
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
u32 flow_timeout
Flow timeout in seconds.
vlib_refcount_t as_refcount
Each AS has an associated reference counter.
lb_vip_encap_args_t encap_args
static uword lb_nodeport_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_input_v4)
static uword lb4_gre4_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void * ip4_next_header(ip4_header_t *i)
format_function_t format_lb_as
lb_vip_t * vips
Pool of all Virtual IPs.
ip4_address_t ip4_src_address
Source address used for IPv4 encapsulated traffic.
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vlib_node_registration_t lb4_l3dsr_node
(constructor) VLIB_REGISTER_NODE (lb4_l3dsr_node)
u32 value[LBHASH_ENTRY_PER_BUCKET]
static uword lb6_gre6_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword lb_nat4_in2out_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword lb4_gre6_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u16 src_port
Network byte order for vip + port case, src_port = port; for node ip + node_port, src_port = node_por...
vlib_node_registration_t lb4_nodeport_node
(constructor) VLIB_REGISTER_NODE (lb4_nodeport_node)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vlib_node_registration_t lb6_gre4_port_node
(constructor) VLIB_REGISTER_NODE (lb6_gre4_port_node)
vlib_node_registration_t lb4_gre4_port_node
(constructor) VLIB_REGISTER_NODE (lb4_gre4_port_node)
static_always_inline void lb_hash_prefetch_bucket(lb_hash_t *ht, u32 hash)
clib_bihash_8_8_t mapping_by_as4
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
static_always_inline void vlib_refcount_add(vlib_refcount_t *r, u32 thread_index, u32 counter_index, i32 v)
ip46_address_t src_ip
for vip + port case, src_ip = vip; for node ip + node_port, src_ip = node_ip
#define lb_hash_foreach_entry(h, bucket, i)
static uword lb4_gre6_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define VLIB_REGISTER_NODE(x,...)
static uword lb4_l3dsr_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define CLIB_PREFETCH(addr, size, type)
sll srl srl sll sra u16x4 i
#define clib_warning(format, args...)
u8 * format_nodeport_lb_trace(u8 *s, va_list *args)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
8 octet key, 8 octet key value pair
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
vlib_node_registration_t lb4_l3dsr_port_node
(constructor) VLIB_REGISTER_NODE (lb4_l3dsr_port_node)
static void * ip6_next_header(ip6_header_t *i)
static_always_inline void lb_hash_free(lb_hash_t *h)
lb_as_t * ass
Pool of ASs.
uword * vip_index_by_nodeport
vlib_main_t vlib_node_runtime_t * node
static uword lb6_nodeport_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vlib_node_registration_t lb6_nodeport_node
(constructor) VLIB_REGISTER_NODE (lb6_nodeport_node)
vlib_node_registration_t lb4_gre6_node
(constructor) VLIB_REGISTER_NODE (lb4_gre6_node)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
int lb_nat66_mapping_match(lb_main_t *lbm, lb_snat6_key_t *match, u32 *index)
Match NAT66 static mapping.
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
static ip_csum_t ip_csum_sub_even(ip_csum_t c, ip_csum_t x)
u32 new_flow_table_mask
New flows table length - 1 (length MUST be a power of 2)
vlib_node_registration_t lb_nat4_in2out_node
(constructor) VLIB_REGISTER_NODE (lb_nat4_in2out_node)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
lb_per_cpu_t * per_cpu
Some global data is per-cpu.
#define VNET_FEATURES(...)
vlib_simple_counter_main_t vip_counters[LB_N_VIP_COUNTERS]
Per VIP counter.
vlib_node_registration_t lb4_gre6_port_node
(constructor) VLIB_REGISTER_NODE (lb4_gre6_port_node)
ip6_address_t ip6_src_address
Source address used in IPv6 encapsulated traffic.
u64 lb_node_get_other_ports6(ip6_header_t *ip60)
static uword lb4_gre4_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
index_t dpoi_index
the index of objects of that type
static_always_inline void lb_node_get_hash(lb_main_t *lbm, vlib_buffer_t *p, u8 is_input_v4, u32 *hash, u32 *vip_idx, u8 per_port_vip)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
vlib_node_registration_t lb_nat6_in2out_node
(constructor) VLIB_REGISTER_NODE (lb_nat6_in2out_node)
lb_snat_mapping_t * snat_mappings
#define ip_csum_update(sum, old, new, type, field)
static uword lb4_l3dsr_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define hash_get_mem(h, key)
clib_bihash_8_8_t vip_index_per_port
static_always_inline u32 lb_hash_hash(u64 k0, u64 k1, u64 k2, u64 k3, u64 k4)
dpo_id_t dpo
The next DPO in the graph to follow.
u16 flags
Copy of main node flags.
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
u16 dpoi_next_node
The next VLIB node to follow.
clib_bihash_24_8_t mapping_by_as6
lb_new_flow_entry_t * new_flow_table
Vector mapping (flow-hash & new_connect_table_mask) to AS index.
#define VLIB_NODE_FLAG_TRACE
static uword lb6_gre4_port_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static_always_inline uword lb_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_input_v4, lb_encap_type_t encap_type, u8 per_port_vip)
static uword lb4_nodeport_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Load balancing service is provided per VIP+protocol+port.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static_always_inline void lb_hash_get(lb_hash_t *ht, u32 hash, u32 vip, u32 time_now, u32 *available_index, u32 *found_value)
static u16 ip4_header_checksum(ip4_header_t *i)
u8 * format_lb_nat_trace(u8 *s, va_list *args)
static u16 ip_csum_fold(ip_csum_t c)
u64 lb_node_get_other_ports4(ip4_header_t *ip40)
static ip_csum_t ip_csum_add_even(ip_csum_t c, ip_csum_t x)
VNET_FEATURE_INIT(lb_nat4_in2out_node_fn, static)
vlib_node_registration_t lb6_gre4_node
(constructor) VLIB_REGISTER_NODE (lb6_gre4_node)
static_always_inline void lb_hash_put(lb_hash_t *h, u32 hash, u32 value, u32 vip, u32 available_index, u32 time_now)