|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
28 #define NAT_HA_RETRIES 3
30 #define foreach_nat_ha_counter \
31 _(RECV_ADD, "add-event-recv", 0) \
32 _(RECV_DEL, "del-event-recv", 1) \
33 _(RECV_REFRESH, "refresh-event-recv", 2) \
34 _(SEND_ADD, "add-event-send", 3) \
35 _(SEND_DEL, "del-event-send", 4) \
36 _(SEND_REFRESH, "refresh-event-send", 5) \
37 _(RECV_ACK, "ack-recv", 6) \
38 _(SEND_ACK, "ack-send", 7) \
39 _(RETRY_COUNT, "retry-count", 8) \
40 _(MISSED_COUNT, "missed-count", 9)
43 #define NAT_HA_VERSION 0x01
46 #define NAT_HA_FLAG_ACK 0x01
94 #define _(N, s, v) NAT_HA_COUNTER_##N = v,
182 nat44_ei_session_t *s;
192 .ip4.as_u32 = eh_addr->
as_u32,
199 *out_addr, out_port,
proto))
211 s->out2in.addr.as_u32 = out_addr->
as_u32;
212 s->out2in.port = out_port;
213 s->nat_proto =
proto;
216 s->ext_host_addr.as_u32 = eh_addr->
as_u32;
217 s->ext_host_port = eh_port;
235 s->out2in.fib_index = outside_fib->
fib_index;
243 if (clib_bihash_add_del_8_8 (&
nm->
out2in, &kv, 1))
246 s->in2out.addr.as_u32 = in_addr->
as_u32;
247 s->in2out.port = in_port;
248 s->in2out.fib_index = fib_index;
250 if (clib_bihash_add_del_8_8 (&
nm->
in2out, &kv, 1))
261 nat44_ei_session_t *s;
282 nat44_ei_session_t *s;
292 s->total_pkts = total_pkts;
293 s->total_bytes = total_bytes;
322 u8 is_resync,
u32 vlib_thread_index)
363 clib_net_to_host_u32 (seq));
376 u32 i, *del, *to_delete = 0;
401 [NAT_HA_COUNTER_MISSED_COUNT],
419 b->
flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
420 b->
flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
486 ha->counters[v].name = s; \
487 ha->counters[v].stat_segment_name = "/nat44-ei/ha/" s; \
488 vlib_validate_simple_counter (&ha->counters[v], 0); \
489 vlib_zero_simple_counter (&ha->counters[v], 0);
541 u32 session_refresh_interval)
556 u32 * session_refresh_interval)
576 in_addr.
as_u32 =
event->in_addr;
577 out_addr.
as_u32 =
event->out_addr;
578 eh_addr.
as_u32 =
event->eh_addr;
579 ehn_addr.
as_u32 =
event->ehn_addr;
580 fib_index = clib_net_to_host_u32 (event->
fib_index);
598 out_addr.
as_u32 =
event->out_addr;
599 eh_addr.
as_u32 =
event->eh_addr;
600 fib_index = clib_net_to_host_u32 (event->
fib_index);
611 u32 fib_index, total_pkts;
617 out_addr.
as_u32 =
event->out_addr;
618 eh_addr.
as_u32 =
event->eh_addr;
619 fib_index = clib_net_to_host_u32 (event->
fib_index);
620 total_pkts = clib_net_to_host_u32 (event->
total_pkts);
621 total_bytes = clib_net_to_host_u64 (event->
total_bytes);
624 event->
protocol, fib_index, total_pkts, total_bytes,
662 b->
flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
663 b->
flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
671 ip->ip_version_and_header_length = 0x45;
673 ip->protocol = IP_PROTOCOL_UDP;
674 ip->flags_and_fragment_offset =
689 h->sequence_number = clib_host_to_net_u32 (sequence_number);
698 u32 vlib_thread_index)
777 offset +=
sizeof (*event);
785 &ha->
counters[NAT_HA_COUNTER_SEND_ADD], vlib_thread_index, 0, 1);
789 &ha->
counters[NAT_HA_COUNTER_SEND_DEL], vlib_thread_index, 0, 1);
793 &ha->
counters[NAT_HA_COUNTER_SEND_REFRESH], vlib_thread_index, 0,
819 #define skip_if_disabled() \
821 nat_ha_main_t *ha = &nat_ha_main; \
822 if (PREDICT_TRUE (!ha->dst_port)) \
845 event.flags = clib_host_to_net_u16 (
flags);
846 event.in_addr = in_addr->
as_u32;
847 event.in_port = in_port;
848 event.out_addr = out_addr->
as_u32;
849 event.out_port = out_port;
850 event.eh_addr = eh_addr->
as_u32;
851 event.eh_port = eh_port;
852 event.ehn_addr = ehn_addr->
as_u32;
853 event.ehn_port = ehn_port;
854 event.fib_index = clib_host_to_net_u32 (fib_index);
855 event.protocol =
proto;
869 event.out_addr = out_addr->
as_u32;
870 event.out_port = out_port;
871 event.eh_addr = eh_addr->
as_u32;
872 event.eh_port = eh_port;
873 event.fib_index = clib_host_to_net_u32 (fib_index);
874 event.protocol =
proto;
891 *last_refreshed =
now;
894 event.out_addr = out_addr->
as_u32;
895 event.out_port = out_port;
896 event.eh_addr = eh_addr->
as_u32;
897 event.eh_port = eh_port;
898 event.fib_index = clib_host_to_net_u32 (fib_index);
899 event.protocol =
proto;
900 event.total_pkts = clib_host_to_net_u32 (total_pkts);
901 event.total_bytes = clib_host_to_net_u64 (total_bytes);
933 .state = VLIB_NODE_STATE_INTERRUPT,
934 .name =
"nat44-ei-ha-worker",
945 uword *event_data = 0;
951 nat_elog_info (
nm,
"nat44-ei-ha-process: bogus kickoff event received");
976 .name =
"nat44-ei-ha-process",
1015 #define foreach_nat_ha_error \
1016 _(PROCESSED, "pkts-processed") \
1017 _(BAD_VERSION, "bad-version")
1021 #define _(sym, str) NAT_HA_ERROR_##sym,
1028 #define _(sym, str) str,
1041 u32 pkts_processed = 0;
1058 u32 bi0, next0, src_addr0, dst_addr0;;
1062 u16 event_count0, src_port0, dst_port0, old_len0;
1072 n_left_to_next -= 1;
1085 b0->
error =
node->errors[NAT_HA_ERROR_BAD_VERSION];
1089 event_count0 = clib_net_to_host_u16 (h0->
count);
1094 b0->
error =
node->errors[NAT_HA_ERROR_PROCESSED];
1101 while (event_count0)
1112 b0->
current_length =
sizeof (*ip0) +
sizeof (*udp0) +
sizeof (*h0);
1124 ip0->
ttl = host_config_ttl;
1141 [NAT_HA_COUNTER_SEND_ACK],
1146 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
1156 to_next, n_left_to_next,
1166 return frame->n_vectors;
1172 .name =
"nat44-ei-ha",
1173 .vector_size =
sizeof (
u32),
1192 #define foreach_nat_ha_handoff_error \
1193 _(CONGESTION_DROP, "congestion drop") \
1194 _(SAME_WORKER, "same worker") \
1195 _(DO_HANDOFF, "do handoff")
1199 #define _(sym,str) NAT_HA_HANDOFF_ERROR_##sym,
1206 #define _(sym,string) string,
1234 u32 do_handoff = 0, same_worker = 0;
1241 ti = thread_indices;
1256 && (
b[0]->
flags & VLIB_BUFFER_IS_TRACED)))
1269 thread_indices,
frame->n_vectors, 1);
1273 NAT_HA_HANDOFF_ERROR_CONGESTION_DROP,
1274 frame->n_vectors - n_enq);
1276 NAT_HA_HANDOFF_ERROR_SAME_WORKER, same_worker);
1278 NAT_HA_HANDOFF_ERROR_DO_HANDOFF, do_handoff);
1279 return frame->n_vectors;
1292 .name =
"nat44-ei-ha-handoff",
1293 .vector_size =
sizeof (
u32),
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u8 ttl
TTL to use for host generated packets.
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
nat44_ei_main_per_thread_data_t * tnm
nat_ha_resync_event_cb_t event_callback
static u32 nat_value_get_thread_index(clib_bihash_kv_8_8_t *value)
u32 ha_handoff_node_index
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
#define IP4_HEADER_FLAG_DONT_FRAGMENT
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
static_always_inline u32 vlib_buffer_enqueue_to_thread(vlib_main_t *vm, vlib_node_runtime_t *node, u32 frame_queue_index, u32 *buffer_indices, u16 *thread_indices, u32 n_packets, int drop_on_congestion)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
void nat44_ei_free_session_data_v2(nat44_ei_main_t *nm, nat44_ei_session_t *s, u32 thread_index, u8 is_ha)
static int nat_ha_resend_queue_add(vlib_main_t *vm, u32 seq, u8 *data, u8 data_len, u8 is_resync, u32 vlib_thread_index)
#define nat_elog_warn(_pm, nat_elog_str)
#define foreach_nat_ha_counter
#define clib_memcpy(d, s, n)
#define foreach_nat_ha_error
nat44_ei_hairpin_src_next_t next_index
nat_ha_resend_entry_t * resend_queue
ip4_main_t ip4_main
Global ip4 main structure.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
void nat44_ei_delete_session(nat44_ei_main_t *nm, nat44_ei_session_t *ses, u32 thread_index)
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
void nat_ha_get_listener(ip4_address_t *addr, u16 *port, u32 *path_mtu)
Get HA listener/local configuration.
void nat_ha_flush(u8 is_resync)
Flush the current HA data (for testing)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void nat_ha_sref(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 total_pkts, u64 total_bytes, u32 thread_index, f64 *last_refreshed, f64 now)
Create session refresh HA event.
static_always_inline void nat_ha_ack_recv(u32 seq, u32 thread_index)
vlib_get_buffers(vm, from, b, n_left_from)
@ VLIB_NODE_TYPE_INTERNAL
ip4_address_t dst_ip_address
vlib_main_t vlib_node_runtime_t * node
#define FIB_NODE_INDEX_INVALID
static uword nat_ha_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static uword nat_ha_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define NAT44_EI_SESSION_FLAG_STATIC_MAPPING
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
#define clib_atomic_fetch_sub(a, b)
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
NAT port/address allocation lib.
static void init_nat_i2o_kv(clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s, u32 thread_index, u32 session_index)
static uword nat_ha_handoff_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
nat44_ei_address_t * addresses
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
void nat_ha_disable()
Disable NAT HA.
static_always_inline void nat44_ei_ha_sadd(ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, ip4_address_t *ehn_addr, u16 ehn_port, u8 proto, u32 fib_index, u16 flags, u32 thread_index)
nat_ha_main_t nat_ha_main
nat44_ei_session_t * sessions
u32 vlib_frame_queue_main_init(u32 node_index, u32 frame_queue_nelts)
vlib_node_registration_t nat_ha_handoff_node
(constructor) VLIB_REGISTER_NODE (nat_ha_handoff_node)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type,...
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
#define nat44_ei_is_session_static(sp)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void nat_ha_header_create(vlib_buffer_t *b, u32 *offset, u32 thread_index)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define nat_elog_info_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
nat_ha_per_thread_data_t * per_thread_data
static u32 nat_value_get_session_index(clib_bihash_kv_8_8_t *value)
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
nat44_ei_main_t nat44_ei_main
static char * nat_ha_error_strings[]
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
int nat44_ei_set_outside_address_and_port(nat44_ei_address_t *addresses, u32 thread_index, ip4_address_t addr, u16 port, nat_protocol_t protocol)
vlib_node_registration_t nat_ha_node
(constructor) VLIB_REGISTER_NODE (nat_ha_node)
u32 state_sync_next_event_offset
#define VLIB_NODE_FLAG_TRACE
struct clib_bihash_value offset
template key/value backing page structure
struct ip4_main_t::@372 host_config
Template information for VPP generated packets.
static_always_inline void nat_ha_event_add(nat_ha_event_t *event, u8 do_flush, u32 session_thread_index, u8 is_resync)
static_always_inline uword vlib_get_thread_index(void)
vlib_buffer_t * state_sync_buffer
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static void nat_ha_send(vlib_frame_t *f, vlib_buffer_t *b, u8 is_resync, u32 vlib_thread_index)
#define static_always_inline
struct nat_ha_main_s nat_ha_main_t
u32 fib_node_index_t
A typedef of a node index.
void nat_ha_sdel(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 session_thread_index)
Create session delete HA event.
#define vec_foreach_index(var, v)
Iterate over vector indices.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
nat44_ei_session_t * nat44_ei_session_alloc_or_recycle(nat44_ei_main_t *nm, nat44_ei_user_t *u, u32 thread_index, f64 now)
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
sll srl srl sll sra u16x4 i
nat44_ei_main_per_thread_data_t * per_thread_data
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
static_always_inline void nat_ha_recv_del(nat_ha_event_t *event, u32 thread_index)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
static void init_nat_o2i_kv(clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s, u32 thread_index, u32 session_index)
struct _vlib_node_registration vlib_node_registration_t
u16 current_length
Nbytes between current data and the end of this buffer.
void nat_ha_set_node_indexes(nat_ha_main_t *ha, vlib_main_t *vm)
nat44_ei_user_t * nat44_ei_user_get_or_create(nat44_ei_main_t *nm, ip4_address_t *addr, u32 fib_index, u32 thread_index)
#define clib_atomic_fetch_add(a, b)
#define nat_elog_notice_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
static_always_inline void nat_ha_recv_add(nat_ha_event_t *event, f64 now, u32 thread_index)
#define nat_elog_debug_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
#define vec_free(V)
Free vector's memory (no header).
u32 ha_process_node_index
vlib_simple_counter_main_t counters[NAT_HA_N_COUNTERS]
#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.
template key/value backing page structure
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
static void nat_ha_resend_scan(vlib_main_t *vm, u32 thread_index)
#define nat_elog_info(_pm, nat_elog_str)
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
static void nat44_ei_user_session_increment(nat44_ei_main_t *nm, nat44_ei_user_t *u, u8 is_static)
description fragment has unexpected format
vlib_put_next_frame(vm, node, next_index, 0)
static_always_inline void nat44_ei_ha_sdel(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 thread_index)
#define skip_if_disabled()
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
static uword nat_ha_worker_fn(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static_always_inline void nat44_ei_ha_sref(ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index, u32 total_pkts, u64 total_bytes, u32 thread_index)
#define vec_foreach(var, vec)
Vector iterator.
8 octet key, 8 octet key value pair
static vlib_main_t * vlib_get_main_by_index(u32 thread_index)
fib_protocol_t fp_proto
protocol type
vlib_frame_t * state_sync_frame
void nat_ha_enable()
Enable NAT HA.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define ip_csum_update(sum, old, new, type, field)
static u32 vlib_get_n_threads()
void(* nat_ha_resync_event_cb_t)(u32 client_index, u32 pid, u32 missed_count)
#define foreach_nat_ha_handoff_error
A collection of simple counters.
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static vlib_main_t * vlib_get_main(void)
vlib_node_registration_t nat_ha_process_node
(constructor) VLIB_REGISTER_NODE (nat_ha_process_node)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vnet_interface_output_runtime_t * rt
int nat_ha_set_failover(vlib_main_t *vm, ip4_address_t *addr, u16 port, u32 session_refresh_interval)
Set HA failover (remote settings)
static u16 ip4_header_checksum(ip4_header_t *i)
int nat_ha_resync(u32 client_index, u32 pid, nat_ha_resync_event_cb_t event_callback)
Resync HA (resend existing sessions to new failover)
static_always_inline void nat_ha_event_process(nat_ha_event_t *event, f64 now, u32 thread_index)
static_always_inline u8 plugin_enabled()
int nat_ha_set_listener(vlib_main_t *vm, ip4_address_t *addr, u16 port, u32 path_mtu)
Set HA listener (local settings)
static void nat_ha_resync_fin(void)
static_always_inline void nat_ha_recv_refresh(nat_ha_event_t *event, f64 now, u32 thread_index)
static f64 vlib_time_now(vlib_main_t *vm)
void nat_ha_init(vlib_main_t *vm, u32 num_workers, u32 num_threads)
Initialize NAT HA.
void nat_ha_sadd(ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr, u16 out_port, ip4_address_t *eh_addr, u16 eh_port, ip4_address_t *ehn_addr, u16 ehn_port, u8 proto, u32 fib_index, u16 flags, u32 thread_index, u8 is_resync)
Create session add HA event.
#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 u16 ip_csum_fold(ip_csum_t c)
void nat_ha_get_failover(ip4_address_t *addr, u16 *port, u32 *session_refresh_interval)
Get HA failover/remote settings.
static void init_nat_k(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto)
nat44_ei_outside_fib_t * outside_fibs
ip4_address_t src_ip_address
Aggregate type for a prefix.
vl_api_fib_path_type_t type
void nat_ha_get_resync_status(u8 *in_resync, u32 *resync_ack_missed)
Get resync status.
static u8 * format_nat_ha_handoff_trace(u8 *s, va_list *args)
#define vec_del1(v, i)
Delete the element at index I.
static void * ip4_next_header(ip4_header_t *i)
static u8 * format_nat_ha_trace(u8 *s, va_list *args)
static char * nat_ha_handoff_error_strings[]
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
vlib_node_registration_t nat_ha_worker_node
(constructor) VLIB_REGISTER_NODE (nat_ha_worker_node)
VLIB buffer representation.
u32 session_refresh_interval
#define VLIB_REGISTER_NODE(x,...)
vl_api_wireguard_peer_flags_t flags