nat.h revision 9a6dc8a9
1/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/**
16 * @file NAT plugin global declarations
17 */
18#ifndef __included_nat_h__
19#define __included_nat_h__
20
21#include <vnet/vnet.h>
22#include <vnet/ip/ip.h>
23#include <vnet/ethernet/ethernet.h>
24#include <vnet/ip/icmp46_packet.h>
25#include <vnet/api_errno.h>
26#include <vppinfra/elog.h>
27#include <vppinfra/bihash_8_8.h>
28#include <vppinfra/bihash_16_8.h>
29#include <vppinfra/dlist.h>
30#include <vppinfra/error.h>
31#include <vlibapi/api.h>
32#include <vlib/log.h>
33
34/* default session timeouts */
35#define SNAT_UDP_TIMEOUT 300
36#define SNAT_TCP_TRANSITORY_TIMEOUT 240
37#define SNAT_TCP_ESTABLISHED_TIMEOUT 7440
38#define SNAT_ICMP_TIMEOUT 60
39
40/* number of worker handoff frame queue elements */
41#define NAT_FQ_NELTS 64
42
43/* NAT buffer flags */
44#define SNAT_FLAG_HAIRPINNING (1 << 0)
45
46typedef struct
47{
48  u32 arc_next;
49} nat_buffer_opaque_t;
50
51typedef enum
52{
53  NAT_NEXT_DROP,
54  NAT_NEXT_ICMP_ERROR,
55  NAT_NEXT_IN2OUT_PRE,
56  NAT_NEXT_OUT2IN_PRE,
57  NAT_NEXT_IN2OUT_ED_FAST_PATH,
58  NAT_NEXT_IN2OUT_ED_SLOW_PATH,
59  NAT_NEXT_IN2OUT_ED_OUTPUT_SLOW_PATH,
60  NAT_NEXT_IN2OUT_ED_REASS,
61  NAT_NEXT_IN2OUT_ED_OUTPUT_REASS,
62  NAT_NEXT_OUT2IN_ED_FAST_PATH,
63  NAT_NEXT_OUT2IN_ED_SLOW_PATH,
64  NAT_NEXT_OUT2IN_ED_REASS,
65  NAT_N_NEXT,
66} nat_next_t;
67
68typedef struct
69{
70  u32 next_index;
71} nat_pre_trace_t;
72
73#define nat_buffer_opaque(b) \
74  ((nat_buffer_opaque_t *)((vnet_buffer_opaque2_t *)b->opaque2)->__unused2)
75
76/*
77STATIC_ASSERT (sizeof (nat_buffer_opaque_t) <=
78               STRUCT_SIZE_OF (vnet_buffer_opaque_t, unused),
79               "Custom meta-data too large for vnet_buffer_opaque_t");
80
81#define nat_buffer_opaque(b) \
82  ((nat_buffer_opaque_t *)((u8 *)((b)->opaque) + \
83    STRUCT_OFFSET_OF (vnet_buffer_opaque_t, unused)))*/
84
85/* session key (4-tuple) */
86typedef struct
87{
88  union
89  {
90    struct
91    {
92      ip4_address_t addr;
93      u16 port;
94      u16 protocol:3, fib_index:13;
95    };
96    u64 as_u64;
97  };
98} snat_session_key_t;
99
100/* endpoint-dependent session key (6-tuple) */
101typedef struct
102{
103  union
104  {
105    struct
106    {
107      ip4_address_t l_addr;
108      ip4_address_t r_addr;
109      u32 proto:8, fib_index:24;
110      u16 l_port;
111      u16 r_port;
112    };
113    u64 as_u64[2];
114  };
115} nat_ed_ses_key_t;
116
117/* deterministic session outside key */
118typedef struct
119{
120  union
121  {
122    struct
123    {
124      ip4_address_t ext_host_addr;
125      u16 ext_host_port;
126      u16 out_port;
127    };
128    u64 as_u64;
129  };
130} snat_det_out_key_t;
131
132/* user (internal host) key */
133typedef struct
134{
135  union
136  {
137    struct
138    {
139      ip4_address_t addr;
140      u32 fib_index;
141    };
142    u64 as_u64;
143  };
144} snat_user_key_t;
145
146typedef struct
147{
148  u32 sw_if_index;
149  u32 next_index;
150  u8 cached;
151} nat44_reass_trace_t;
152
153/* NAT API Configuration flags */
154#define foreach_nat_config_flag \
155  _(0x01, IS_TWICE_NAT)         \
156  _(0x02, IS_SELF_TWICE_NAT)    \
157  _(0x04, IS_OUT2IN_ONLY)       \
158  _(0x08, IS_ADDR_ONLY)         \
159  _(0x10, IS_OUTSIDE)           \
160  _(0x20, IS_INSIDE)            \
161  _(0x40, IS_STATIC)            \
162  _(0x80, IS_EXT_HOST_VALID)    \
163
164typedef enum nat_config_flags_t_
165{
166#define _(n,f) NAT_API_##f = n,
167  foreach_nat_config_flag
168#undef _
169} nat_config_flags_t;
170
171/* External address and port allocation modes */
172#define foreach_nat_addr_and_port_alloc_alg \
173  _(0, DEFAULT, "default")         \
174  _(1, MAPE, "map-e")              \
175  _(2, RANGE, "port-range")
176
177typedef enum
178{
179#define _(v, N, s) NAT_ADDR_AND_PORT_ALLOC_ALG_##N = v,
180  foreach_nat_addr_and_port_alloc_alg
181#undef _
182} nat_addr_and_port_alloc_alg_t;
183
184
185/* Supported L4 protocols */
186#define foreach_snat_protocol \
187  _(UDP, 0, udp, "udp")       \
188  _(TCP, 1, tcp, "tcp")       \
189  _(ICMP, 2, icmp, "icmp")
190
191typedef enum
192{
193#define _(N, i, n, s) SNAT_PROTOCOL_##N = i,
194  foreach_snat_protocol
195#undef _
196} snat_protocol_t;
197
198
199/* Session state */
200#define foreach_snat_session_state          \
201  _(0, UNKNOWN, "unknown")                 \
202  _(1, UDP_ACTIVE, "udp-active")           \
203  _(2, TCP_SYN_SENT, "tcp-syn-sent")       \
204  _(3, TCP_ESTABLISHED, "tcp-established") \
205  _(4, TCP_FIN_WAIT, "tcp-fin-wait")       \
206  _(5, TCP_CLOSE_WAIT, "tcp-close-wait")   \
207  _(6, TCP_CLOSING, "tcp-closing")         \
208  _(7, TCP_LAST_ACK, "tcp-last-ack")       \
209  _(8, TCP_CLOSED, "tcp-closed")           \
210  _(9, ICMP_ACTIVE, "icmp-active")
211
212typedef enum
213{
214#define _(v, N, s) SNAT_SESSION_##N = v,
215  foreach_snat_session_state
216#undef _
217} snat_session_state_t;
218
219#define foreach_nat_in2out_ed_error                     \
220_(UNSUPPORTED_PROTOCOL, "unsupported protocol")         \
221_(IN2OUT_PACKETS, "good in2out packets processed")      \
222_(OUT_OF_PORTS, "out of ports")                         \
223_(BAD_ICMP_TYPE, "unsupported ICMP type")               \
224_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded")   \
225_(DROP_FRAGMENT, "drop fragment")                       \
226_(MAX_REASS, "maximum reassemblies exceeded")           \
227_(MAX_FRAG, "maximum fragments per reassembly exceeded")\
228_(NON_SYN, "non-SYN packet try to create session")      \
229_(TCP_PACKETS, "TCP packets")                           \
230_(UDP_PACKETS, "UDP packets")                           \
231_(ICMP_PACKETS, "ICMP packets")                         \
232_(OTHER_PACKETS, "other protocol packets")              \
233_(FRAGMENTS, "fragments")                               \
234_(CACHED_FRAGMENTS, "cached fragments")                 \
235_(PROCESSED_FRAGMENTS, "processed fragments")
236
237typedef enum
238{
239#define _(sym,str) NAT_IN2OUT_ED_ERROR_##sym,
240  foreach_nat_in2out_ed_error
241#undef _
242    NAT_IN2OUT_ED_N_ERROR,
243} nat_in2out_ed_error_t;
244
245#define foreach_nat_out2in_ed_error                     \
246_(UNSUPPORTED_PROTOCOL, "unsupported protocol")         \
247_(OUT2IN_PACKETS, "good out2in packets processed")      \
248_(OUT_OF_PORTS, "out of ports")                         \
249_(BAD_ICMP_TYPE, "unsupported ICMP type")               \
250_(NO_TRANSLATION, "no translation")                     \
251_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded")   \
252_(DROP_FRAGMENT, "drop fragment")                       \
253_(MAX_REASS, "maximum reassemblies exceeded")           \
254_(MAX_FRAG, "maximum fragments per reassembly exceeded")\
255_(NON_SYN, "non-SYN packet try to create session")      \
256_(TCP_PACKETS, "TCP packets")                           \
257_(UDP_PACKETS, "UDP packets")                           \
258_(ICMP_PACKETS, "ICMP packets")                         \
259_(OTHER_PACKETS, "other protocol packets")              \
260_(FRAGMENTS, "fragments")                               \
261_(CACHED_FRAGMENTS, "cached fragments")                 \
262_(PROCESSED_FRAGMENTS, "processed fragments")
263
264typedef enum
265{
266#define _(sym,str) NAT_OUT2IN_ED_ERROR_##sym,
267  foreach_nat_out2in_ed_error
268#undef _
269    NAT_OUT2IN_ED_N_ERROR,
270} nat_out2in_ed_error_t;
271
272
273/* Endpoint dependent TCP session state */
274#define NAT44_SES_I2O_FIN 1
275#define NAT44_SES_O2I_FIN 2
276#define NAT44_SES_I2O_FIN_ACK 4
277#define NAT44_SES_O2I_FIN_ACK 8
278#define NAT44_SES_I2O_SYN 16
279#define NAT44_SES_O2I_SYN 32
280#define NAT44_SES_RST     64
281
282/* Session flags */
283#define SNAT_SESSION_FLAG_STATIC_MAPPING       1
284#define SNAT_SESSION_FLAG_UNKNOWN_PROTO        2
285#define SNAT_SESSION_FLAG_LOAD_BALANCING       4
286#define SNAT_SESSION_FLAG_TWICE_NAT            8
287#define SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT   16
288#define SNAT_SESSION_FLAG_FWD_BYPASS           32
289#define SNAT_SESSION_FLAG_AFFINITY             64
290#define SNAT_SESSION_FLAG_OUTPUT_FEATURE       128
291
292/* NAT interface flags */
293#define NAT_INTERFACE_FLAG_IS_INSIDE 1
294#define NAT_INTERFACE_FLAG_IS_OUTSIDE 2
295
296/* Static mapping flags */
297#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY    1
298#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY  2
299#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT 4
300#define NAT_STATIC_MAPPING_FLAG_LB           8
301
302/* *INDENT-OFF* */
303typedef CLIB_PACKED(struct
304{
305  /* Outside network key */
306  snat_session_key_t out2in;
307
308  /* Inside network key */
309  snat_session_key_t in2out;
310
311  /* Flags */
312  u32 flags;
313
314  /* Per-user translations */
315  u32 per_user_index;
316  u32 per_user_list_head_index;
317
318  /* Last heard timer */
319  f64 last_heard;
320
321  /* Last HA refresh */
322  f64 ha_last_refreshed;
323
324  /* Counters */
325  u64 total_bytes;
326  u32 total_pkts;
327
328  /* External host address and port */
329  ip4_address_t ext_host_addr;
330  u16 ext_host_port;
331
332  /* External host address and port after translation */
333  ip4_address_t ext_host_nat_addr;
334  u16 ext_host_nat_port;
335
336  /* TCP session state */
337  u8 state;
338  u32 i2o_fin_seq;
339  u32 o2i_fin_seq;
340
341  /* user index */
342  u32 user_index;
343}) snat_session_t;
344/* *INDENT-ON* */
345
346
347typedef struct
348{
349  ip4_address_t addr;
350  u32 fib_index;
351  u32 sessions_per_user_list_head_index;
352  u32 nsessions;
353  u32 nstaticsessions;
354} snat_user_t;
355
356typedef struct
357{
358  ip4_address_t addr;
359  u32 fib_index;
360/* *INDENT-OFF* */
361#define _(N, i, n, s) \
362  u16 busy_##n##_ports; \
363  u16 * busy_##n##_ports_per_thread; \
364  uword * busy_##n##_port_bitmap;
365  foreach_snat_protocol
366#undef _
367/* *INDENT-ON* */
368} snat_address_t;
369
370typedef struct
371{
372  u32 fib_index;
373  u32 refcount;
374} nat_outside_fib_t;
375
376typedef struct
377{
378  /* Inside network port */
379  u16 in_port;
380  /* Outside network address and port */
381  snat_det_out_key_t out;
382  /* Session state */
383  u8 state;
384  /* Expire timeout */
385  u32 expire;
386} snat_det_session_t;
387
388typedef struct
389{
390  /* inside IP address range */
391  ip4_address_t in_addr;
392  u8 in_plen;
393  /* outside IP address range */
394  ip4_address_t out_addr;
395  u8 out_plen;
396  /* inside IP addresses / outside IP addresses */
397  u32 sharing_ratio;
398  /* number of ports available to internal host */
399  u16 ports_per_host;
400  /* session counter */
401  u32 ses_num;
402  /* vector of sessions */
403  snat_det_session_t *sessions;
404} snat_det_map_t;
405
406typedef struct
407{
408  /* backend IP address */
409  ip4_address_t addr;
410  /* backend port number */
411  u16 port;
412  /* probability of the backend to be randomly matched */
413  u8 probability;
414  u8 prefix;
415  /* backend FIB table */
416  u32 vrf_id;
417  u32 fib_index;
418} nat44_lb_addr_port_t;
419
420typedef enum
421{
422  /* twice-nat disabled */
423  TWICE_NAT_DISABLED,
424  /* twice-nat enabled */
425  TWICE_NAT,
426  /* twice-nat only when src IP equals dst IP after translation */
427  TWICE_NAT_SELF,
428} twice_nat_type_t;
429
430typedef enum
431{
432  /* no load-balancing */
433  NO_LB_NAT,
434  /* load-balancing */
435  LB_NAT,
436  /* load-balancing with affinity */
437  AFFINITY_LB_NAT,
438} lb_nat_type_t;
439
440typedef struct
441{
442  /* local IP address */
443  ip4_address_t local_addr;
444  /* external IP address */
445  ip4_address_t external_addr;
446  /* local port */
447  u16 local_port;
448  /* external port */
449  u16 external_port;
450  /* is twice-nat */
451  twice_nat_type_t twice_nat;
452  /* local FIB table */
453  u32 vrf_id;
454  u32 fib_index;
455  /* protocol */
456  snat_protocol_t proto;
457  /* 0 = disabled, otherwise client IP affinity sticky time in seconds */
458  u32 affinity;
459  /* worker threads used by backends/local host */
460  u32 *workers;
461  /* opaque string tag */
462  u8 *tag;
463  /* backends for load-balancing mode */
464  nat44_lb_addr_port_t *locals;
465  /* affinity per service lis */
466  u32 affinity_per_service_list_head_index;
467  /* flags */
468  u32 flags;
469} snat_static_mapping_t;
470
471typedef struct
472{
473  u32 sw_if_index;
474  u8 flags;
475} snat_interface_t;
476
477typedef struct
478{
479  ip4_address_t l_addr;
480  u16 l_port;
481  u16 e_port;
482  u32 sw_if_index;
483  u32 vrf_id;
484  snat_protocol_t proto;
485  u32 flags;
486  int addr_only;
487  int twice_nat;
488  int is_add;
489  int out2in_only;
490  int identity_nat;
491  u8 *tag;
492} snat_static_map_resolve_t;
493
494typedef struct
495{
496  /* Main lookup tables */
497  clib_bihash_8_8_t out2in;
498  clib_bihash_8_8_t in2out;
499
500  /* Endpoint dependent sessions lookup tables */
501  clib_bihash_16_8_t out2in_ed;
502  clib_bihash_16_8_t in2out_ed;
503
504  /* Find-a-user => src address lookup */
505  clib_bihash_8_8_t user_hash;
506
507  /* User pool */
508  snat_user_t *users;
509
510  /* Session pool */
511  snat_session_t *sessions;
512
513  /* Pool of doubly-linked list elements */
514  dlist_elt_t *list_pool;
515
516  /* NAT thread index */
517  u32 snat_thread_index;
518
519  /* real thread index */
520  u32 thread_index;
521} snat_main_per_thread_data_t;
522
523struct snat_main_s;
524
525/* ICMP session match function */
526typedef u32 (snat_icmp_match_function_t) (struct snat_main_s * sm,
527					  vlib_node_runtime_t * node,
528					  u32 thread_index,
529					  vlib_buffer_t * b0,
530					  ip4_header_t * ip0, u8 * p_proto,
531					  snat_session_key_t * p_value,
532					  u8 * p_dont_translate, void *d,
533					  void *e);
534
535/* Return worker thread index for given packet */
536typedef u32 (snat_get_worker_function_t) (ip4_header_t * ip,
537					  u32 rx_fib_index, u8 is_output);
538
539/* NAT address and port allacotaion function */
540typedef int (nat_alloc_out_addr_and_port_function_t) (snat_address_t *
541						      addresses,
542						      u32 fib_index,
543						      u32 thread_index,
544						      snat_session_key_t * k,
545						      u16 port_per_thread,
546						      u32 snat_thread_index);
547
548typedef struct snat_main_s
549{
550  /* ICMP session match functions */
551  snat_icmp_match_function_t *icmp_match_in2out_cb;
552  snat_icmp_match_function_t *icmp_match_out2in_cb;
553
554  /* Thread settings */
555  u32 num_workers;
556  u32 first_worker_index;
557  u32 *workers;
558  snat_get_worker_function_t *worker_in2out_cb;
559  snat_get_worker_function_t *worker_out2in_cb;
560  u16 port_per_thread;
561  u32 num_snat_thread;
562
563  /* Per thread data */
564  snat_main_per_thread_data_t *per_thread_data;
565
566  /* Find a static mapping by local */
567  clib_bihash_8_8_t static_mapping_by_local;
568
569  /* Find a static mapping by external */
570  clib_bihash_8_8_t static_mapping_by_external;
571
572  /* Static mapping pool */
573  snat_static_mapping_t *static_mappings;
574
575  /* Interface pool */
576  snat_interface_t *interfaces;
577  snat_interface_t *output_feature_interfaces;
578
579  /* Vector of outside addresses */
580  snat_address_t *addresses;
581  /* Address and port allocation function */
582  nat_alloc_out_addr_and_port_function_t *alloc_addr_and_port;
583  /* Address and port allocation type */
584  nat_addr_and_port_alloc_alg_t addr_and_port_alloc_alg;
585  /* Port set parameters (MAP-E) */
586  u8 psid_offset;
587  u8 psid_length;
588  u16 psid;
589  /* Port range parameters */
590  u16 start_port;
591  u16 end_port;
592
593  /* vector of outside fibs */
594  nat_outside_fib_t *outside_fibs;
595
596  /* Vector of twice NAT addresses for extenal hosts */
597  snat_address_t *twice_nat_addresses;
598
599  /* sw_if_indices whose intfc addresses should be auto-added */
600  u32 *auto_add_sw_if_indices;
601  u32 *auto_add_sw_if_indices_twice_nat;
602
603  /* vector of interface address static mappings to resolve. */
604  snat_static_map_resolve_t *to_resolve;
605
606  /* Randomize port allocation order */
607  u32 random_seed;
608
609  /* Worker handoff frame-queue index */
610  u32 fq_in2out_index;
611  u32 fq_in2out_output_index;
612  u32 fq_out2in_index;
613
614  /* node indexes */
615  u32 error_node_index;
616
617  /* handoff fq nodes  */
618  u32 handoff_out2in_index;
619  u32 handoff_in2out_index;
620  u32 handoff_in2out_output_index;
621
622  /* respect feature arc nodes */
623  u32 pre_out2in_node_index;
624  u32 pre_in2out_node_index;
625
626  u32 in2out_node_index;
627  u32 in2out_output_node_index;
628  u32 in2out_fast_node_index;
629  u32 in2out_slowpath_node_index;
630  u32 in2out_slowpath_output_node_index;
631  u32 in2out_reass_node_index;
632  u32 ed_in2out_node_index;
633  u32 ed_in2out_slowpath_node_index;
634  u32 ed_in2out_reass_node_index;
635  u32 out2in_node_index;
636  u32 out2in_fast_node_index;
637  u32 out2in_reass_node_index;
638  u32 ed_out2in_node_index;
639  u32 ed_out2in_slowpath_node_index;
640  u32 ed_out2in_reass_node_index;
641  u32 det_in2out_node_index;
642  u32 det_out2in_node_index;
643
644  u32 hairpinning_node_index;
645  u32 hairpin_dst_node_index;
646  u32 hairpin_src_node_index;
647  u32 ed_hairpinning_node_index;
648  u32 ed_hairpin_dst_node_index;
649  u32 ed_hairpin_src_node_index;
650
651
652  /* Deterministic NAT mappings */
653  snat_det_map_t *det_maps;
654
655  /* If forwarding is enabled */
656  u8 forwarding_enabled;
657
658  /* Config parameters */
659  u8 static_mapping_only;
660  u8 static_mapping_connection_tracking;
661  u8 deterministic;
662  u8 out2in_dpo;
663  u8 endpoint_dependent;
664  u32 translation_buckets;
665  u32 translation_memory_size;
666  u32 max_translations;
667  u32 user_buckets;
668  u32 user_memory_size;
669  u32 max_translations_per_user;
670  u32 outside_vrf_id;
671  u32 outside_fib_index;
672  u32 inside_vrf_id;
673  u32 inside_fib_index;
674
675  /* values of various timeouts */
676  u32 udp_timeout;
677  u32 tcp_established_timeout;
678  u32 tcp_transitory_timeout;
679  u32 icmp_timeout;
680
681  /* TCP MSS clamping */
682  u16 mss_clamping;
683  u16 mss_value_net;
684
685  /* counters/gauges */
686  vlib_simple_counter_main_t total_users;
687  vlib_simple_counter_main_t total_sessions;
688
689  /* API message ID base */
690  u16 msg_id_base;
691
692  /* log class */
693  vlib_log_class_t log_class;
694  /* logging level */
695  u8 log_level;
696
697  /* convenience */
698  vlib_main_t *vlib_main;
699  vnet_main_t *vnet_main;
700  ip4_main_t *ip4_main;
701  ip_lookup_main_t *ip4_lookup_main;
702  api_main_t *api_main;
703} snat_main_t;
704
705typedef struct
706{
707  u32 thread_index;
708  f64 now;
709} nat44_is_idle_session_ctx_t;
710
711typedef struct
712{
713  u32 cached_sw_if_index;
714  u32 cached_ip4_address;
715} snat_runtime_t;
716
717extern snat_main_t snat_main;
718
719// nat pre ed next_node feature classification
720extern vlib_node_registration_t nat_default_node;
721extern vlib_node_registration_t nat_pre_in2out_node;
722extern vlib_node_registration_t nat_pre_out2in_node;
723
724extern vlib_node_registration_t snat_in2out_node;
725extern vlib_node_registration_t snat_in2out_output_node;
726extern vlib_node_registration_t snat_out2in_node;
727extern vlib_node_registration_t snat_in2out_fast_node;
728extern vlib_node_registration_t snat_out2in_fast_node;
729extern vlib_node_registration_t snat_in2out_worker_handoff_node;
730extern vlib_node_registration_t snat_in2out_output_worker_handoff_node;
731extern vlib_node_registration_t snat_out2in_worker_handoff_node;
732extern vlib_node_registration_t snat_det_in2out_node;
733extern vlib_node_registration_t snat_det_out2in_node;
734extern vlib_node_registration_t snat_hairpin_dst_node;
735extern vlib_node_registration_t snat_hairpin_src_node;
736extern vlib_node_registration_t nat44_ed_in2out_node;
737extern vlib_node_registration_t nat44_ed_in2out_output_node;
738extern vlib_node_registration_t nat44_ed_out2in_node;
739extern vlib_node_registration_t nat44_ed_hairpin_dst_node;
740extern vlib_node_registration_t nat44_ed_hairpin_src_node;
741extern vlib_node_registration_t nat44_ed_in2out_worker_handoff_node;
742extern vlib_node_registration_t nat44_ed_in2out_output_worker_handoff_node;
743extern vlib_node_registration_t nat44_ed_out2in_worker_handoff_node;
744
745/* format functions */
746format_function_t format_snat_user;
747format_function_t format_snat_static_mapping;
748format_function_t format_snat_static_map_to_resolve;
749format_function_t format_snat_session;
750format_function_t format_det_map_ses;
751format_function_t format_snat_key;
752format_function_t format_static_mapping_key;
753format_function_t format_snat_protocol;
754format_function_t format_nat_addr_and_port_alloc_alg;
755format_function_t format_nat44_reass_trace;
756/* unformat functions */
757unformat_function_t unformat_snat_protocol;
758
759/** \brief Check if SNAT session is created from static mapping.
760    @param s SNAT session
761    @return 1 if SNAT session is created from static mapping otherwise 0
762*/
763#define snat_is_session_static(s) (s->flags & SNAT_SESSION_FLAG_STATIC_MAPPING)
764
765/** \brief Check if SNAT session for unknown protocol.
766    @param s SNAT session
767    @return 1 if SNAT session for unknown protocol otherwise 0
768*/
769#define snat_is_unk_proto_session(s) (s->flags & SNAT_SESSION_FLAG_UNKNOWN_PROTO)
770
771/** \brief Check if NAT session is twice NAT.
772    @param s NAT session
773    @return 1 if NAT session is twice NAT
774*/
775#define is_twice_nat_session(s) (s->flags & SNAT_SESSION_FLAG_TWICE_NAT)
776
777/** \brief Check if NAT session is load-balancing.
778    @param s NAT session
779    @return 1 if NAT session is load-balancing
780*/
781#define is_lb_session(s) (s->flags & SNAT_SESSION_FLAG_LOAD_BALANCING)
782
783/** \brief Check if NAT session is forwarding bypass.
784    @param s NAT session
785    @return 1 if NAT session is load-balancing
786*/
787#define is_fwd_bypass_session(s) (s->flags & SNAT_SESSION_FLAG_FWD_BYPASS)
788
789/** \brief Check if NAT session is endpoint dependent.
790    @param s NAT session
791    @return 1 if NAT session is endpoint dependent
792*/
793#define is_ed_session(s) (s->flags & SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT)
794
795/** \brief Check if NAT session has affinity record.
796    @param s NAT session
797    @return 1 if NAT session has affinity record
798*/
799#define is_affinity_sessions(s) (s->flags & SNAT_SESSION_FLAG_AFFINITY)
800
801/** \brief Check if NAT interface is inside.
802    @param i NAT interfce
803    @return 1 if inside interface
804*/
805#define nat_interface_is_inside(i) i->flags & NAT_INTERFACE_FLAG_IS_INSIDE
806
807/** \brief Check if NAT interface is outside.
808    @param i NAT interfce
809    @return 1 if outside interface
810*/
811#define nat_interface_is_outside(i) i->flags & NAT_INTERFACE_FLAG_IS_OUTSIDE
812
813/** \brief Check if NAT44 endpoint-dependent TCP session is closed.
814    @param s NAT session
815    @return 1 if session is closed
816*/
817#define nat44_is_ses_closed(s) s->state == 0xf
818
819/** \brief Check if NAT static mapping is address only (1:1NAT).
820    @param sm NAT static mapping
821    @return 1 if 1:1NAT, 0 if 1:1NAPT
822*/
823#define is_addr_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_ADDR_ONLY)
824
825/** \brief Check if NAT static mapping match only out2in direction.
826    @param sm NAT static mapping
827    @return 1 if rule match only out2in direction
828*/
829#define is_out2in_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY)
830
831/** \brief Check if NAT static mapping is identity NAT.
832    @param sm NAT static mapping
833    @return 1 if identity NAT
834*/
835#define is_identity_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT)
836
837/** \brief Check if NAT static mapping is load-balancing.
838    @param sm NAT static mapping
839    @return 1 if load-balancing
840*/
841#define is_lb_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_LB)
842
843/** \brief Check if client initiating TCP connection (received SYN from client)
844    @param t TCP header
845    @return 1 if client initiating TCP connection
846*/
847#define tcp_is_init(t) ((t->flags & TCP_FLAG_SYN) && !(t->flags & TCP_FLAG_ACK))
848
849/* logging */
850#define nat_log_err(...) \
851  vlib_log(VLIB_LOG_LEVEL_ERR, snat_main.log_class, __VA_ARGS__)
852#define nat_log_warn(...) \
853  vlib_log(VLIB_LOG_LEVEL_WARNING, snat_main.log_class, __VA_ARGS__)
854#define nat_log_notice(...) \
855  vlib_log(VLIB_LOG_LEVEL_NOTICE, snat_main.log_class, __VA_ARGS__)
856#define nat_log_info(...) \
857  vlib_log(VLIB_LOG_LEVEL_INFO, snat_main.log_class, __VA_ARGS__)
858#define nat_log_debug(...)\
859  vlib_log(VLIB_LOG_LEVEL_DEBUG, snat_main.log_class, __VA_ARGS__)
860
861/* NAT API Logging Levels */
862#define foreach_nat_log_level \
863  _(0x00, LOG_NONE)           \
864  _(0x01, LOG_ERROR)          \
865  _(0x02, LOG_WARNING)        \
866  _(0x03, LOG_NOTICE)         \
867  _(0x04, LOG_INFO)           \
868  _(0x05, LOG_DEBUG)
869
870typedef enum nat_log_level_t_
871{
872#define _(n,f) SNAT_##f = n,
873  foreach_nat_log_level
874#undef _
875} nat_log_level_t;
876
877#define nat_elog(_level, _str)                    \
878do                                                \
879  {                                               \
880    snat_main_t *sm = &snat_main;                 \
881    if (PREDICT_FALSE (sm->log_level >= _level))  \
882      {                                           \
883        ELOG_TYPE_DECLARE (e) =                   \
884          {                                       \
885            .format = "nat-msg " _str,            \
886            .format_args = "",                    \
887          };                                      \
888        ELOG_DATA (&sm->vlib_main->elog_main, e); \
889      }                                           \
890  } while (0);
891
892#define nat_elog_addr(_level, _str, _addr)               \
893do                                                       \
894  {                                                      \
895    if (PREDICT_FALSE (sm->log_level >= _level))         \
896      {                                                  \
897        ELOG_TYPE_DECLARE (e) =                          \
898          {                                              \
899            .format = "nat-msg " _str " %d.%d.%d.%d",    \
900            .format_args = "i1i1i1i1",                   \
901          };                                             \
902        CLIB_PACKED(struct                               \
903          {                                              \
904            u8 oct1;                                     \
905            u8 oct2;                                     \
906            u8 oct3;                                     \
907            u8 oct4;                                     \
908          }) *ed;                                        \
909        ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
910        ed->oct4 = _addr >> 24;                          \
911        ed->oct3 = _addr >> 16;                          \
912        ed->oct2 = _addr >> 8;                           \
913        ed->oct1 = _addr;                                \
914    }                                                    \
915  } while (0);
916
917#define nat_elog_debug_handoff(_str, _tid, _fib, _src, _dst)                \
918do                                                                          \
919  {                                                                         \
920  if (PREDICT_FALSE (sm->log_level >= SNAT_LOG_DEBUG))                      \
921    {                                                                       \
922      ELOG_TYPE_DECLARE (e) =                                               \
923        {                                                                   \
924          .format = "nat-msg " _str " ip src: %d.%d.%d.%d dst: %d.%d.%d.%d" \
925                                    " tid from: %d to: %d fib: %d",         \
926        .format_args = "i1i1i1i1i1i1i1i1i4i4i4",                            \
927      };                                                                    \
928      CLIB_PACKED(struct                                                    \
929        {                                                                   \
930          u8 src_oct1;                                                      \
931          u8 src_oct2;                                                      \
932          u8 src_oct3;                                                      \
933          u8 src_oct4;                                                      \
934          u8 dst_oct1;                                                      \
935          u8 dst_oct2;                                                      \
936          u8 dst_oct3;                                                      \
937          u8 dst_oct4;                                                      \
938          u32 ftid;                                                         \
939          u32 ttid;                                                         \
940          u32 fib;                                                          \
941        }) *ed;                                                             \
942      ed = ELOG_DATA (&vlib_global_main.elog_main, e);                      \
943      ed->src_oct1 = _src >> 24;                                            \
944      ed->src_oct2 = _src >> 16;                                            \
945      ed->src_oct3 = _src >> 8;                                             \
946      ed->src_oct4 = _src;                                                  \
947      ed->dst_oct1 = _dst >> 24;                                            \
948      ed->dst_oct2 = _dst >> 16;                                            \
949      ed->dst_oct3 = _dst >> 8;                                             \
950      ed->dst_oct4 = _dst;                                                  \
951      ed->ftid = vlib_get_thread_index ();                                  \
952      ed->ttid = _tid;                                                      \
953      ed->fib = _fib;                                                       \
954    }                                                                       \
955  } while (0);
956
957#define nat_elog_debug_handoff_v2(_str, _prt, _fib, _src, _dst)              \
958do                                                                           \
959  {                                                                          \
960  if (PREDICT_FALSE (sm->log_level >= SNAT_LOG_DEBUG))                       \
961    {                                                                        \
962      ELOG_TYPE_DECLARE (e) =                                                \
963        {                                                                    \
964          .format = "nat-msg " _str " ip_src:%d.%d.%d.%d ip_dst:%d.%d.%d.%d" \
965                                    " tid:%d prt:%d fib:%d",                 \
966        .format_args = "i1i1i1i1i1i1i1i1i4i4i4",                             \
967      };                                                                     \
968      CLIB_PACKED(struct                                                     \
969        {                                                                    \
970          u8 src_oct1;                                                       \
971          u8 src_oct2;                                                       \
972          u8 src_oct3;                                                       \
973          u8 src_oct4;                                                       \
974          u8 dst_oct1;                                                       \
975          u8 dst_oct2;                                                       \
976          u8 dst_oct3;                                                       \
977          u8 dst_oct4;                                                       \
978          u32 tid;                                                           \
979          u32 prt;                                                           \
980          u32 fib;                                                           \
981        }) *ed;                                                              \
982      ed = ELOG_DATA (&vlib_global_main.elog_main, e);                       \
983      ed->src_oct1 = _src >> 24;                                             \
984      ed->src_oct2 = _src >> 16;                                             \
985      ed->src_oct3 = _src >> 8;                                              \
986      ed->src_oct4 = _src;                                                   \
987      ed->dst_oct1 = _dst >> 24;                                             \
988      ed->dst_oct2 = _dst >> 16;                                             \
989      ed->dst_oct3 = _dst >> 8;                                              \
990      ed->dst_oct4 = _dst;                                                   \
991      ed->tid = vlib_get_thread_index ();                                    \
992      ed->prt = _prt;                                                        \
993      ed->fib = _fib;                                                        \
994    }                                                                        \
995  } while (0);
996
997#define nat_elog_X1(_level, _fmt, _arg, _val1)         \
998do                                                     \
999  {                                                    \
1000    snat_main_t *sm = &snat_main;                      \
1001    if (PREDICT_FALSE (sm->log_level >= _level))       \
1002      {                                                \
1003        ELOG_TYPE_DECLARE (e) =                        \
1004          {                                            \
1005            .format = "nat-msg " _fmt,                 \
1006            .format_args = _arg,                       \
1007          };                                           \
1008        CLIB_PACKED(struct                             \
1009          {                                            \
1010            typeof (_val1) val1;                       \
1011          }) *ed;                                      \
1012        ed = ELOG_DATA (&sm->vlib_main->elog_main, e); \
1013        ed->val1 = _val1;                              \
1014      }                                                \
1015  } while (0);
1016
1017#define nat_elog_notice(nat_elog_str) \
1018  nat_elog(SNAT_LOG_INFO, "[notice] " nat_elog_str)
1019#define nat_elog_warn(nat_elog_str) \
1020  nat_elog(SNAT_LOG_WARNING, "[warning] " nat_elog_str)
1021#define nat_elog_err(nat_elog_str) \
1022  nat_elog(SNAT_LOG_ERROR, "[error] " nat_elog_str)
1023#define nat_elog_debug(nat_elog_str) \
1024  nat_elog(SNAT_LOG_DEBUG, "[debug] " nat_elog_str)
1025#define nat_elog_info(nat_elog_str) \
1026  nat_elog(SNAT_LOG_INFO, "[info] " nat_elog_str)
1027
1028#define nat_elog_notice_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
1029  nat_elog_X1(SNAT_LOG_NOTICE, "[notice] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
1030#define nat_elog_warn_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
1031  nat_elog_X1(SNAT_LOG_WARNING, "[warning] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
1032#define nat_elog_err_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
1033  nat_elog_X1(SNAT_LOG_ERROR, "[error] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
1034#define nat_elog_debug_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
1035  nat_elog_X1(SNAT_LOG_DEBUG, "[debug] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
1036#define nat_elog_info_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
1037  nat_elog_X1(SNAT_LOG_INFO, "[info] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
1038
1039/* ICMP session match functions */
1040u32 icmp_match_in2out_fast (snat_main_t * sm, vlib_node_runtime_t * node,
1041			    u32 thread_index, vlib_buffer_t * b0,
1042			    ip4_header_t * ip0, u8 * p_proto,
1043			    snat_session_key_t * p_value,
1044			    u8 * p_dont_translate, void *d, void *e);
1045u32 icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node,
1046			    u32 thread_index, vlib_buffer_t * b0,
1047			    ip4_header_t * ip0, u8 * p_proto,
1048			    snat_session_key_t * p_value,
1049			    u8 * p_dont_translate, void *d, void *e);
1050u32 icmp_match_out2in_fast (snat_main_t * sm, vlib_node_runtime_t * node,
1051			    u32 thread_index, vlib_buffer_t * b0,
1052			    ip4_header_t * ip0, u8 * p_proto,
1053			    snat_session_key_t * p_value,
1054			    u8 * p_dont_translate, void *d, void *e);
1055u32 icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node,
1056			    u32 thread_index, vlib_buffer_t * b0,
1057			    ip4_header_t * ip0, u8 * p_proto,
1058			    snat_session_key_t * p_value,
1059			    u8 * p_dont_translate, void *d, void *e);
1060
1061/* ICMP deterministic NAT session match functions */
1062u32 icmp_match_out2in_det (snat_main_t * sm, vlib_node_runtime_t * node,
1063			   u32 thread_index, vlib_buffer_t * b0,
1064			   ip4_header_t * ip0, u8 * p_proto,
1065			   snat_session_key_t * p_value,
1066			   u8 * p_dont_translate, void *d, void *e);
1067u32 icmp_match_in2out_det (snat_main_t * sm, vlib_node_runtime_t * node,
1068			   u32 thread_index, vlib_buffer_t * b0,
1069			   ip4_header_t * ip0, u8 * p_proto,
1070			   snat_session_key_t * p_value,
1071			   u8 * p_dont_translate, void *d, void *e);
1072
1073/* ICMP endpoint-dependent session match functions */
1074u32 icmp_match_out2in_ed (snat_main_t * sm, vlib_node_runtime_t * node,
1075			  u32 thread_index, vlib_buffer_t * b0,
1076			  ip4_header_t * ip0, u8 * p_proto,
1077			  snat_session_key_t * p_value,
1078			  u8 * p_dont_translate, void *d, void *e);
1079u32 icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
1080			  u32 thread_index, vlib_buffer_t * b0,
1081			  ip4_header_t * ip0, u8 * p_proto,
1082			  snat_session_key_t * p_value,
1083			  u8 * p_dont_translate, void *d, void *e);
1084
1085u32 icmp_in2out (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
1086		 icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
1087		 vlib_node_runtime_t * node, u32 next0, u32 thread_index,
1088		 void *d, void *e);
1089
1090u32 icmp_out2in (snat_main_t * sm, vlib_buffer_t * b0, ip4_header_t * ip0,
1091		 icmp46_header_t * icmp0, u32 sw_if_index0, u32 rx_fib_index0,
1092		 vlib_node_runtime_t * node, u32 next0, u32 thread_index,
1093		 void *d, void *e);
1094
1095/* hairpinning functions */
1096u32 snat_icmp_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
1097			   ip4_header_t * ip0, icmp46_header_t * icmp0,
1098			   int is_ed);
1099void nat_hairpinning_sm_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
1100				       ip4_header_t * ip);
1101void nat44_ed_hairpinning_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
1102					 ip4_header_t * ip);
1103int snat_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
1104		      ip4_header_t * ip0, udp_header_t * udp0,
1105		      tcp_header_t * tcp0, u32 proto0, int is_ed);
1106void nat44_reass_hairpinning (snat_main_t * sm, vlib_buffer_t * b0,
1107			      ip4_header_t * ip0, u16 sport, u16 dport,
1108			      u32 proto0, int is_ed);
1109
1110/* Call back functions for clib_bihash_add_or_overwrite_stale */
1111int nat44_i2o_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg);
1112int nat44_o2i_ed_is_idle_session_cb (clib_bihash_kv_16_8_t * kv, void *arg);
1113int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
1114int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
1115
1116/**
1117 * @brief Increment IPv4 address
1118 */
1119void increment_v4_address (ip4_address_t * a);
1120
1121/**
1122 * @brief Add external address to NAT44 pool
1123 *
1124 * @param addr      IPv4 address
1125 * @param vrf_id    VRF id of tenant, ~0 means independent of VRF
1126 * @param twice_nat 1 if twice NAT address
1127 *
1128 * @return 0 on success, non-zero value otherwise
1129 */
1130int snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id,
1131		      u8 twice_nat);
1132
1133/**
1134 * @brief Delete external address from NAT44 pool
1135 *
1136 * @param addr      IPv4 address
1137 * @param delete_sm 1 if delete static mapping using address
1138 * @param twice_nat 1 if twice NAT address
1139 *
1140 * @return 0 on success, non-zero value otherwise
1141 */
1142int snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
1143		      u8 twice_nat);
1144
1145/**
1146 * @brief Add/delete external address to FIB DPO (out2in DPO mode)
1147 *
1148 * @param addr   IPv4 address
1149 * @param is_add 1 = add, 0 = delete
1150 *
1151 * @return 0 on success, non-zero value otherwise
1152 */
1153void nat44_add_del_address_dpo (ip4_address_t addr, u8 is_add);
1154
1155/**
1156 * @brief Add/delete NAT44 static mapping
1157 *
1158 * @param l_addr       local IPv4 address
1159 * @param e_addr       external IPv4 address
1160 * @param l_port       local port number
1161 * @param e_port       external port number
1162 * @param vrf_id       local VRF ID
1163 * @param addr_only    1 = 1:1NAT, 0 = 1:1NAPT
1164 * @param sw_if_index  use interface address as external IPv4 address
1165 * @param proto        L4 protocol
1166 * @param is_add       1 = add, 0 = delete
1167 * @param twice_nat    twice-nat mode
1168 * @param out2in_only  if 1 rule match only out2in direction
1169 * @param tag          opaque string tag
1170 * @param identity_nat identity NAT
1171 *
1172 * @return 0 on success, non-zero value otherwise
1173 */
1174int snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
1175			     u16 l_port, u16 e_port, u32 vrf_id,
1176			     int addr_only, u32 sw_if_index,
1177			     snat_protocol_t proto, int is_add,
1178			     twice_nat_type_t twice_nat, u8 out2in_only,
1179			     u8 * tag, u8 identity_nat);
1180
1181/**
1182 * @brief Add/delete static mapping with load-balancing (multiple backends)
1183 *
1184 * @param e_addr      external IPv4 address
1185 * @param e_port      external port number
1186 * @param proto       L4 protocol
1187 * @param locals      list of local backends
1188 * @param is_add      1 = add, 0 = delete
1189 * @param twice_nat   twice-nat mode
1190 * @param out2in_only if 1 rule match only out2in direction
1191 * @param tag         opaque string tag
1192 * @param affinity    0 = disabled, otherwise client IP affinity sticky time
1193 *
1194 * @return 0 on success, non-zero value otherwise
1195 */
1196int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
1197				     snat_protocol_t proto,
1198				     nat44_lb_addr_port_t * locals, u8 is_add,
1199				     twice_nat_type_t twice_nat,
1200				     u8 out2in_only, u8 * tag, u32 affinity);
1201
1202int nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
1203					   ip4_address_t l_addr, u16 l_port,
1204					   snat_protocol_t proto, u32 vrf_id,
1205					   u8 probability, u8 is_add);
1206
1207clib_error_t *snat_api_init (vlib_main_t * vm, snat_main_t * sm);
1208
1209/**
1210 * @brief Set NAT plugin workers
1211 *
1212 * @param bitmap NAT workers bitmap
1213 *
1214 * @return 0 on success, non-zero value otherwise
1215 */
1216int snat_set_workers (uword * bitmap);
1217
1218/**
1219 * @brief Enable/disable NAT44 feature on the interface
1220 *
1221 * @param sw_if_index software index of the interface
1222 * @param is_inside   1 = inside, 0 = outside
1223 * @param is_del      1 = delete, 0 = add
1224 *
1225 * @return 0 on success, non-zero value otherwise
1226 */
1227int snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del);
1228
1229/**
1230 * @brief Enable/disable NAT44 output feature on the interface (postrouting NAT)
1231 *
1232 * @param sw_if_index software index of the interface
1233 * @param is_inside   1 = inside, 0 = outside
1234 * @param is_del      1 = delete, 0 = add
1235 *
1236 * @return 0 on success, non-zero value otherwise
1237 */
1238int snat_interface_add_del_output_feature (u32 sw_if_index, u8 is_inside,
1239					   int is_del);
1240
1241/**
1242 * @brief Add/delete NAT44 pool address from specific interfce
1243 *
1244 * @param sw_if_index software index of the interface
1245 * @param is_del      1 = delete, 0 = add
1246 * @param twice_nat   1 = twice NAT address for extenal hosts
1247 *
1248 * @return 0 on success, non-zero value otherwise
1249 */
1250int snat_add_interface_address (snat_main_t * sm, u32 sw_if_index, int is_del,
1251				u8 twice_nat);
1252
1253/**
1254 * @brief Delete NAT44 session
1255 *
1256 * @param addr   IPv4 address
1257 * @param port   L4 port number
1258 * @param proto  L4 protocol
1259 * @param vrf_id VRF ID
1260 * @param is_in  1 = inside network address and port pair, 0 = outside
1261 *
1262 * @return 0 on success, non-zero value otherwise
1263 */
1264int nat44_del_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
1265		       snat_protocol_t proto, u32 vrf_id, int is_in);
1266
1267/**
1268 * @brief Delete NAT44 endpoint-dependent session
1269 *
1270 * @param addr   IPv4 address
1271 * @param port   L4 port number
1272 * @param proto  L4 protocol
1273 * @param vrf_id VRF ID
1274 * @param is_in  1 = inside network address and port pair, 0 = outside
1275 *
1276 * @return 0 on success, non-zero value otherwise
1277 */
1278int nat44_del_ed_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
1279			  ip4_address_t * eh_addr, u16 eh_port, u8 proto,
1280			  u32 vrf_id, int is_in);
1281
1282/**
1283 * @brief Free NAT44 session data (lookup keys, external addrres port)
1284 *
1285 * @param s            NAT session
1286 * @param thread_index thread index
1287 * @param is_ha        is HA event
1288 */
1289void nat_free_session_data (snat_main_t * sm, snat_session_t * s,
1290			    u32 thread_index, u8 is_ha);
1291
1292/**
1293 * @brief Find or create NAT user
1294 *
1295 * @param addr         IPv4 address
1296 * @param fib_index    FIB table index
1297 * @param thread_index thread index
1298 *
1299 * @return NAT user data structure on success otherwise zero value
1300 */
1301snat_user_t *nat_user_get_or_create (snat_main_t * sm, ip4_address_t * addr,
1302				     u32 fib_index, u32 thread_index);
1303
1304/**
1305 * @brief Allocate new NAT session or recycle last used
1306 *
1307 * @param u            NAT user
1308 * @param thread_index thread index
1309 *
1310 * @return session data structure on success otherwise zero value
1311 */
1312snat_session_t *nat_session_alloc_or_recycle (snat_main_t * sm,
1313					      snat_user_t * u,
1314					      u32 thread_index, f64 now);
1315
1316/**
1317 * @brief Allocate NAT endpoint-dependent session
1318 *
1319 * @param u            NAT user
1320 * @param thread_index thread index
1321 *
1322 * @return session data structure on success otherwise zero value
1323 */
1324snat_session_t *nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u,
1325				      u32 thread_index, f64 now);
1326
1327/**
1328 * @brief Set address and port assignment algorithm for MAP-E CE
1329 *
1330 * @param psid        Port Set Identifier value
1331 * @param psid_offset number of offset bits
1332 * @param psid_length length of PSID
1333 */
1334void nat_set_alloc_addr_and_port_mape (u16 psid, u16 psid_offset,
1335				       u16 psid_length);
1336
1337/**
1338 * @brief Set address and port assignment algorithm for port range
1339 *
1340 * @param start_port beginning of the port range
1341 * @param end_port   end of the port range
1342 */
1343void nat_set_alloc_addr_and_port_range (u16 start_port, u16 end_port);
1344
1345/**
1346 * @brief Set address and port assignment algorithm to default/standard
1347 */
1348void nat_set_alloc_addr_and_port_default (void);
1349
1350/**
1351 * @brief Free outside address and port pair
1352 *
1353 * @param addresses    vector of outside addresses
1354 * @param thread_index thread index
1355 * @param k            address, port and protocol
1356 */
1357void snat_free_outside_address_and_port (snat_address_t * addresses,
1358					 u32 thread_index,
1359					 snat_session_key_t * k);
1360
1361/**
1362 * @brief Alloc outside address and port
1363 *
1364 * @param addresses         vector of outside addresses
1365 * @param fib_index         FIB table index
1366 * @param thread_index      thread index
1367 * @param k                 allocated address and port pair
1368 * @param port_per_thread   number of ports per threead
1369 * @param snat_thread_index NAT thread index
1370 *
1371 * @return 0 on success, non-zero value otherwise
1372 */
1373int snat_alloc_outside_address_and_port (snat_address_t * addresses,
1374					 u32 fib_index,
1375					 u32 thread_index,
1376					 snat_session_key_t * k,
1377					 u16 port_per_thread,
1378					 u32 snat_thread_index);
1379
1380/**
1381 * @brief Match NAT44 static mapping.
1382 *
1383 * @param match         address and port to match
1384 * @param mapping       external/local address and port of the matched mapping
1385 * @param by_external   if 0 match by local address otherwise match by external
1386 *                      address
1387 * @param is_addr_only  1 if matched mapping is address only
1388 * @param twice_nat     matched mapping is twice NAT type
1389 * @param lb            1 if matched mapping is load-balanced
1390 * @param ext_host_addr external host address
1391 *
1392 * @returns 0 if match found otherwise 1.
1393 */
1394int snat_static_mapping_match (snat_main_t * sm,
1395			       snat_session_key_t match,
1396			       snat_session_key_t * mapping,
1397			       u8 by_external,
1398			       u8 * is_addr_only,
1399			       twice_nat_type_t * twice_nat,
1400			       lb_nat_type_t * lb,
1401			       ip4_address_t * ext_host_addr,
1402			       u8 * is_identity_nat);
1403
1404/**
1405 * @brief Add/del NAT address to FIB.
1406 *
1407 * Add the external NAT address to the FIB as receive entries. This ensures
1408 * that VPP will reply to ARP for this address and we don't need to enable
1409 * proxy ARP on the outside interface.
1410 *
1411 * @param addr        IPv4 address
1412 * @param plen        address prefix length
1413 * @param sw_if_index software index of the outside interface
1414 * @param is_add      0 = delete, 1 = add.
1415 */
1416void snat_add_del_addr_to_fib (ip4_address_t * addr,
1417			       u8 p_len, u32 sw_if_index, int is_add);
1418
1419/*
1420 * Why is this here? Because we don't need to touch this layer to
1421 * simply reply to an icmp. We need to change id to a unique
1422 * value to NAT an echo request/reply.
1423 */
1424
1425typedef struct
1426{
1427  u16 identifier;
1428  u16 sequence;
1429} icmp_echo_header_t;
1430
1431typedef struct
1432{
1433  u16 src_port, dst_port;
1434} tcp_udp_header_t;
1435
1436#endif /* __included_nat_h__ */
1437
1438/*
1439 * fd.io coding-style-patch-verification: ON
1440 *
1441 * Local Variables:
1442 * eval: (c-set-style "gnu")
1443 * End:
1444 */
1445