FD.io VPP  v17.07-30-g839fa73
Vector Packet Processing
nat64.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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
17  * @brief NAT64 implementation
18  */
19 
20 #include <snat/nat64.h>
21 #include <snat/nat64_db.h>
22 #include <vnet/fib/ip4_fib.h>
23 
24 
26 
27 /* *INDENT-OFF* */
28 
29 /* Hook up input features */
30 VNET_FEATURE_INIT (nat64_in2out, static) = {
31  .arc_name = "ip6-unicast",
32  .node_name = "nat64-in2out",
33  .runs_before = VNET_FEATURES ("ip6-lookup"),
34 };
35 VNET_FEATURE_INIT (nat64_out2in, static) = {
36  .arc_name = "ip4-unicast",
37  .node_name = "nat64-out2in",
38  .runs_before = VNET_FEATURES ("ip4-lookup"),
39 };
40 
41 static u8 well_known_prefix[] = {
42  0x00, 0x64, 0xff, 0x9b,
43  0x00, 0x00, 0x00, 0x00,
44  0x00, 0x00, 0x00, 0x00,
45  0x00, 0x00, 0x00, 0x00
46 };
47 
48 /* *INDENT-ON* */
49 
52 {
53  nat64_main_t *nm = &nat64_main;
54  clib_error_t *error = 0;
56 
57  nm->is_disabled = 0;
58 
59  if (tm->n_vlib_mains > 1)
60  {
61  nm->is_disabled = 1;
62  goto error;
63  }
64 
65  if (nat64_db_init (&nm->db))
66  {
67  error = clib_error_return (0, "NAT64 DB init failed");
68  goto error;
69  }
70 
71  /* set session timeouts to default values */
77 
78 error:
79  return error;
80 }
81 
82 int
84 {
85  nat64_main_t *nm = &nat64_main;
86  snat_address_t *a = 0;
87  snat_interface_t *interface;
88  int i;
89 
90  /* Check if address already exists */
91  for (i = 0; i < vec_len (nm->addr_pool); i++)
92  {
93  if (nm->addr_pool[i].addr.as_u32 == addr->as_u32)
94  {
95  a = nm->addr_pool + i;
96  break;
97  }
98  }
99 
100  if (is_add)
101  {
102  if (a)
103  return VNET_API_ERROR_VALUE_EXIST;
104 
105  vec_add2 (nm->addr_pool, a, 1);
106  a->addr = *addr;
107  a->fib_index = 0;
108  if (vrf_id != ~0)
109  a->fib_index =
111 #define _(N, i, n, s) \
112  clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535);
114 #undef _
115  }
116  else
117  {
118  if (!a)
119  return VNET_API_ERROR_NO_SUCH_ENTRY;
120 
121 #define _(N, id, n, s) \
122  clib_bitmap_free (a->busy_##n##_port_bitmap);
124 #undef _
125  vec_del1 (nm->addr_pool, i);
126  }
127 
128  /* Add/del external address to FIB */
129  /* *INDENT-OFF* */
130  pool_foreach (interface, nm->interfaces,
131  ({
132  if (interface->is_inside)
133  continue;
134 
135  snat_add_del_addr_to_fib (addr, 32, interface->sw_if_index, is_add);
136  break;
137  }));
138  /* *INDENT-ON* */
139 
140  return 0;
141 }
142 
143 void
145 {
146  nat64_main_t *nm = &nat64_main;
147  snat_address_t *a = 0;
148 
149  /* *INDENT-OFF* */
150  vec_foreach (a, nm->addr_pool)
151  {
152  if (fn (a, ctx))
153  break;
154  };
155  /* *INDENT-ON* */
156 }
157 
158 int
159 nat64_add_del_interface (u32 sw_if_index, u8 is_inside, u8 is_add)
160 {
161  nat64_main_t *nm = &nat64_main;
162  snat_interface_t *interface = 0, *i;
163  snat_address_t *ap;
164  const char *feature_name, *arc_name;
165 
166  /* Check if address already exists */
167  /* *INDENT-OFF* */
168  pool_foreach (i, nm->interfaces,
169  ({
170  if (i->sw_if_index == sw_if_index)
171  {
172  interface = i;
173  break;
174  }
175  }));
176  /* *INDENT-ON* */
177 
178  if (is_add)
179  {
180  if (interface)
181  return VNET_API_ERROR_VALUE_EXIST;
182 
183  pool_get (nm->interfaces, interface);
184  interface->sw_if_index = sw_if_index;
185  interface->is_inside = is_inside;
186 
187  }
188  else
189  {
190  if (!interface)
191  return VNET_API_ERROR_NO_SUCH_ENTRY;
192 
193  pool_put (nm->interfaces, interface);
194  }
195 
196  if (!is_inside)
197  {
198  /* *INDENT-OFF* */
199  vec_foreach (ap, nm->addr_pool)
200  snat_add_del_addr_to_fib(&ap->addr, 32, sw_if_index, is_add);
201  /* *INDENT-ON* */
202  }
203 
204  arc_name = is_inside ? "ip6-unicast" : "ip4-unicast";
205  feature_name = is_inside ? "nat64-in2out" : "nat64-out2in";
206 
207  return vnet_feature_enable_disable (arc_name, feature_name, sw_if_index,
208  is_add, 0, 0);
209 }
210 
211 void
213 {
214  nat64_main_t *nm = &nat64_main;
215  snat_interface_t *i = 0;
216 
217  /* *INDENT-OFF* */
218  pool_foreach (i, nm->interfaces,
219  ({
220  if (fn (i, ctx))
221  break;
222  }));
223  /* *INDENT-ON* */
224 }
225 
226 int
228  ip4_address_t * addr, u16 * port)
229 {
230  nat64_main_t *nm = &nat64_main;
231  snat_main_t *sm = &snat_main;
232  int i;
233  snat_address_t *a, *ga = 0;
234  u32 portnum;
235 
236  for (i = 0; i < vec_len (nm->addr_pool); i++)
237  {
238  a = nm->addr_pool + i;
239  switch (proto)
240  {
241 #define _(N, j, n, s) \
242  case SNAT_PROTOCOL_##N: \
243  if (a->busy_##n##_ports < (65535-1024)) \
244  { \
245  if (a->fib_index == fib_index) \
246  { \
247  while (1) \
248  { \
249  portnum = random_u32 (&sm->random_seed); \
250  portnum &= 0xFFFF; \
251  if (portnum < 1024) \
252  continue; \
253  if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \
254  portnum)) \
255  continue; \
256  clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \
257  portnum, 1); \
258  a->busy_##n##_ports++; \
259  *port = portnum; \
260  addr->as_u32 = a->addr.as_u32; \
261  return 0; \
262  } \
263  } \
264  else if (a->fib_index == 0) \
265  ga = a; \
266  } \
267  break;
269 #undef _
270  default:
271  clib_warning ("unknown protocol");
272  return 1;
273  }
274  }
275 
276  if (ga)
277  {
278  switch (proto)
279  {
280 #define _(N, j, n, s) \
281  case SNAT_PROTOCOL_##N: \
282  while (1) \
283  { \
284  portnum = random_u32 (&sm->random_seed); \
285  portnum &= 0xFFFF; \
286  if (portnum < 1024) \
287  continue; \
288  if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \
289  portnum)) \
290  continue; \
291  clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \
292  portnum, 1); \
293  a->busy_##n##_ports++; \
294  *port = portnum; \
295  addr->as_u32 = a->addr.as_u32; \
296  return 0; \
297  }
298  break;
300 #undef _
301  default:
302  clib_warning ("unknown protocol");
303  return 1;
304  }
305  }
306 
307  /* Totally out of translations to use... */
308  //TODO: IPFix
309  return 1;
310 }
311 
312 void
314  snat_protocol_t proto)
315 {
316  nat64_main_t *nm = &nat64_main;
317  int i;
318  snat_address_t *a;
319 
320  for (i = 0; i < vec_len (nm->addr_pool); i++)
321  {
322  a = nm->addr_pool + i;
323  if (addr->as_u32 != a->addr.as_u32)
324  continue;
325  switch (proto)
326  {
327 #define _(N, j, n, s) \
328  case SNAT_PROTOCOL_##N: \
329  ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \
330  port) == 1); \
331  clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, port, 0); \
332  a->busy_##n##_ports--; \
333  break;
335 #undef _
336  default:
337  clib_warning ("unknown protocol");
338  return;
339  }
340  break;
341  }
342 }
343 
344 int
346  ip4_address_t * out_addr, u16 in_port,
347  u16 out_port, u8 proto, u32 vrf_id, u8 is_add)
348 {
349  nat64_main_t *nm = &nat64_main;
350  nat64_db_bib_entry_t *bibe;
351  u32 fib_index =
354  ip46_address_t addr;
355  int i;
356  snat_address_t *a;
357 
358  addr.as_u64[0] = in_addr->as_u64[0];
359  addr.as_u64[1] = in_addr->as_u64[1];
360  bibe =
361  nat64_db_bib_entry_find (&nm->db, &addr, clib_host_to_net_u16 (in_port),
362  p, fib_index, 1);
363 
364  if (is_add)
365  {
366  if (bibe)
367  return VNET_API_ERROR_VALUE_EXIST;
368 
369  for (i = 0; i < vec_len (nm->addr_pool); i++)
370  {
371  a = nm->addr_pool + i;
372  if (out_addr->as_u32 != a->addr.as_u32)
373  continue;
374  switch (p)
375  {
376 #define _(N, j, n, s) \
377  case SNAT_PROTOCOL_##N: \
378  if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \
379  out_port)) \
380  return VNET_API_ERROR_INVALID_VALUE; \
381  clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \
382  out_port, 1); \
383  if (out_port > 1024) \
384  a->busy_##n##_ports++; \
385  break;
387 #undef _
388  default:
389  clib_warning ("unknown protocol");
390  return VNET_API_ERROR_INVALID_VALUE_2;
391  }
392  break;
393  }
394  bibe =
395  nat64_db_bib_entry_create (&nm->db, in_addr, out_addr,
396  clib_host_to_net_u16 (in_port),
397  clib_host_to_net_u16 (out_port), fib_index,
398  p, 1);
399  if (!bibe)
400  return VNET_API_ERROR_UNSPECIFIED;
401  }
402  else
403  {
404  if (!bibe)
405  return VNET_API_ERROR_NO_SUCH_ENTRY;
406 
407  nat64_free_out_addr_and_port (out_addr, out_port, p);
408  nat64_db_bib_entry_free (&nm->db, bibe);
409  }
410 
411  return 0;
412 }
413 
414 int
416 {
417  nat64_main_t *nm = &nat64_main;
418 
419  if (timeout == 0)
421  else if (timeout < SNAT_UDP_TIMEOUT_MIN)
422  return VNET_API_ERROR_INVALID_VALUE;
423  else
424  nm->udp_timeout = timeout;
425 
426  return 0;
427 }
428 
429 u32
431 {
432  nat64_main_t *nm = &nat64_main;
433 
434  return nm->udp_timeout;
435 }
436 
437 int
439 {
440  nat64_main_t *nm = &nat64_main;
441 
442  if (timeout == 0)
444  else
445  nm->icmp_timeout = timeout;
446 
447  return 0;
448 }
449 
450 u32
452 {
453  nat64_main_t *nm = &nat64_main;
454 
455  return nm->icmp_timeout;
456 }
457 
458 int
459 nat64_set_tcp_timeouts (u32 trans, u32 est, u32 incoming_syn)
460 {
461  nat64_main_t *nm = &nat64_main;
462 
463  if (trans == 0)
465  else
466  nm->tcp_trans_timeout = trans;
467 
468  if (est == 0)
470  else
471  nm->tcp_est_timeout = est;
472 
473  if (incoming_syn == 0)
475  else
476  nm->tcp_incoming_syn_timeout = incoming_syn;
477 
478  return 0;
479 }
480 
481 u32
483 {
484  nat64_main_t *nm = &nat64_main;
485 
486  return nm->tcp_trans_timeout;
487 }
488 
489 u32
491 {
492  nat64_main_t *nm = &nat64_main;
493 
494  return nm->tcp_est_timeout;
495 }
496 
497 u32
499 {
500  nat64_main_t *nm = &nat64_main;
501 
502  return nm->tcp_incoming_syn_timeout;
503 }
504 
505 void
506 nat64_session_reset_timeout (nat64_db_st_entry_t * ste, vlib_main_t * vm)
507 {
508  nat64_main_t *nm = &nat64_main;
509  u32 now = (u32) vlib_time_now (vm);
510 
511  switch (ste->proto)
512  {
513  case SNAT_PROTOCOL_ICMP:
514  ste->expire = now + nm->icmp_timeout;
515  return;
516  case SNAT_PROTOCOL_TCP:
517  {
518  switch (ste->tcp_state)
519  {
520  case NAT64_TCP_STATE_V4_INIT:
521  case NAT64_TCP_STATE_V6_INIT:
522  case NAT64_TCP_STATE_V4_FIN_RCV:
523  case NAT64_TCP_STATE_V6_FIN_RCV:
524  case NAT64_TCP_STATE_V6_FIN_V4_FIN_RCV:
525  case NAT64_TCP_STATE_TRANS:
526  ste->expire = now + nm->tcp_trans_timeout;
527  return;
528  case NAT64_TCP_STATE_ESTABLISHED:
529  ste->expire = now + nm->tcp_est_timeout;
530  return;
531  default:
532  return;
533  }
534  }
535  case SNAT_PROTOCOL_UDP:
536  ste->expire = now + nm->udp_timeout;
537  return;
538  default:
539  return;
540  }
541 }
542 
543 void
544 nat64_tcp_session_set_state (nat64_db_st_entry_t * ste, tcp_header_t * tcp,
545  u8 is_ip6)
546 {
547  switch (ste->tcp_state)
548  {
549  case NAT64_TCP_STATE_CLOSED:
550  {
551  if (tcp->flags & TCP_FLAG_SYN)
552  {
553  if (is_ip6)
554  ste->tcp_state = NAT64_TCP_STATE_V6_INIT;
555  else
556  ste->tcp_state = NAT64_TCP_STATE_V4_INIT;
557  }
558  return;
559  }
560  case NAT64_TCP_STATE_V4_INIT:
561  {
562  if (is_ip6 && (tcp->flags & TCP_FLAG_SYN))
563  ste->tcp_state = NAT64_TCP_STATE_ESTABLISHED;
564  return;
565  }
566  case NAT64_TCP_STATE_V6_INIT:
567  {
568  if (!is_ip6 && (tcp->flags & TCP_FLAG_SYN))
569  ste->tcp_state = NAT64_TCP_STATE_ESTABLISHED;
570  return;
571  }
572  case NAT64_TCP_STATE_ESTABLISHED:
573  {
574  if (tcp->flags & TCP_FLAG_FIN)
575  {
576  if (is_ip6)
577  ste->tcp_state = NAT64_TCP_STATE_V6_FIN_RCV;
578  else
579  ste->tcp_state = NAT64_TCP_STATE_V4_FIN_RCV;
580  }
581  else if (tcp->flags & TCP_FLAG_RST)
582  {
583  ste->tcp_state = NAT64_TCP_STATE_TRANS;
584  }
585  return;
586  }
587  case NAT64_TCP_STATE_V4_FIN_RCV:
588  {
589  if (is_ip6 && (tcp->flags & TCP_FLAG_FIN))
590  ste->tcp_state = NAT64_TCP_STATE_V6_FIN_V4_FIN_RCV;
591  return;
592  }
593  case NAT64_TCP_STATE_V6_FIN_RCV:
594  {
595  if (!is_ip6 && (tcp->flags & TCP_FLAG_FIN))
596  ste->tcp_state = NAT64_TCP_STATE_V6_FIN_V4_FIN_RCV;
597  return;
598  }
599  case NAT64_TCP_STATE_TRANS:
600  {
601  if (!(tcp->flags & TCP_FLAG_RST))
602  ste->tcp_state = NAT64_TCP_STATE_ESTABLISHED;
603  return;
604  }
605  default:
606  return;
607  }
608 }
609 
610 int
611 nat64_add_del_prefix (ip6_address_t * prefix, u8 plen, u32 vrf_id, u8 is_add)
612 {
613  nat64_main_t *nm = &nat64_main;
614  nat64_prefix_t *p = 0;
615  int i;
616 
617  /* Verify prefix length */
618  if (plen != 32 && plen != 40 && plen != 48 && plen != 56 && plen != 64
619  && plen != 96)
620  return VNET_API_ERROR_INVALID_VALUE;
621 
622  /* Check if tenant already have prefix */
623  for (i = 0; i < vec_len (nm->pref64); i++)
624  {
625  if (nm->pref64[i].vrf_id == vrf_id)
626  {
627  p = nm->pref64 + i;
628  break;
629  }
630  }
631 
632  if (is_add)
633  {
634  if (!p)
635  {
636  vec_add2 (nm->pref64, p, 1);
637  p->fib_index =
639  p->vrf_id = vrf_id;
640  }
641 
642  p->prefix.as_u64[0] = prefix->as_u64[0];
643  p->prefix.as_u64[1] = prefix->as_u64[1];
644  p->plen = plen;
645  }
646  else
647  {
648  if (!p)
649  return VNET_API_ERROR_NO_SUCH_ENTRY;
650 
651  vec_del1 (nm->pref64, i);
652  }
653 
654  return 0;
655 }
656 
657 void
659 {
660  nat64_main_t *nm = &nat64_main;
661  nat64_prefix_t *p = 0;
662 
663  /* *INDENT-OFF* */
664  vec_foreach (p, nm->pref64)
665  {
666  if (fn (p, ctx))
667  break;
668  };
669  /* *INDENT-ON* */
670 }
671 
672 void
674 {
675  nat64_main_t *nm = &nat64_main;
676  nat64_prefix_t *p, *gp = 0, *prefix = 0;
677 
678  /* *INDENT-OFF* */
679  vec_foreach (p, nm->pref64)
680  {
681  if (p->fib_index == fib_index)
682  {
683  prefix = p;
684  break;
685  }
686 
687  if (p->fib_index == 0)
688  gp = p;
689  };
690  /* *INDENT-ON* */
691 
692  if (!prefix)
693  prefix = gp;
694 
695  if (prefix)
696  {
697  memset (ip6, 0, 16);
698  memcpy (ip6, &p->prefix, p->plen);
699  switch (p->plen)
700  {
701  case 32:
702  ip6->as_u32[1] = ip4->as_u32;
703  break;
704  case 40:
705  ip6->as_u8[5] = ip4->as_u8[0];
706  ip6->as_u8[6] = ip4->as_u8[1];
707  ip6->as_u8[7] = ip4->as_u8[2];
708  ip6->as_u8[9] = ip4->as_u8[3];
709  break;
710  case 48:
711  ip6->as_u8[6] = ip4->as_u8[0];
712  ip6->as_u8[7] = ip4->as_u8[1];
713  ip6->as_u8[9] = ip4->as_u8[2];
714  ip6->as_u8[10] = ip4->as_u8[3];
715  break;
716  case 56:
717  ip6->as_u8[7] = ip4->as_u8[0];
718  ip6->as_u8[9] = ip4->as_u8[1];
719  ip6->as_u8[10] = ip4->as_u8[2];
720  ip6->as_u8[11] = ip4->as_u8[3];
721  break;
722  case 64:
723  ip6->as_u8[9] = ip4->as_u8[0];
724  ip6->as_u8[10] = ip4->as_u8[1];
725  ip6->as_u8[11] = ip4->as_u8[2];
726  ip6->as_u8[12] = ip4->as_u8[3];
727  break;
728  case 96:
729  ip6->as_u32[3] = ip4->as_u32;
730  break;
731  default:
732  clib_warning ("invalid prefix length");
733  break;
734  }
735  }
736  else
737  {
738  memcpy (ip6, well_known_prefix, 16);
739  ip6->as_u32[3] = ip4->as_u32;
740  }
741 }
742 
743 void
745 {
746  nat64_main_t *nm = &nat64_main;
747  nat64_prefix_t *p, *gp = 0;
748  u8 plen = 0;
749 
750  /* *INDENT-OFF* */
751  vec_foreach (p, nm->pref64)
752  {
753  if (p->fib_index == fib_index)
754  {
755  plen = p->plen;
756  break;
757  }
758 
759  if (p->vrf_id == 0)
760  gp = p;
761  };
762  /* *INDENT-ON* */
763 
764  if (!plen)
765  {
766  if (gp)
767  plen = gp->plen;
768  else
769  plen = 96;
770  }
771 
772  switch (plen)
773  {
774  case 32:
775  ip4->as_u32 = ip6->as_u32[1];
776  break;
777  case 40:
778  ip4->as_u8[0] = ip6->as_u8[5];
779  ip4->as_u8[1] = ip6->as_u8[6];
780  ip4->as_u8[2] = ip6->as_u8[7];
781  ip4->as_u8[3] = ip6->as_u8[9];
782  break;
783  case 48:
784  ip4->as_u8[0] = ip6->as_u8[6];
785  ip4->as_u8[1] = ip6->as_u8[7];
786  ip4->as_u8[2] = ip6->as_u8[9];
787  ip4->as_u8[3] = ip6->as_u8[10];
788  break;
789  case 56:
790  ip4->as_u8[0] = ip6->as_u8[7];
791  ip4->as_u8[1] = ip6->as_u8[9];
792  ip4->as_u8[2] = ip6->as_u8[10];
793  ip4->as_u8[3] = ip6->as_u8[11];
794  break;
795  case 64:
796  ip4->as_u8[0] = ip6->as_u8[9];
797  ip4->as_u8[1] = ip6->as_u8[10];
798  ip4->as_u8[2] = ip6->as_u8[11];
799  ip4->as_u8[3] = ip6->as_u8[12];
800  break;
801  case 96:
802  ip4->as_u32 = ip6->as_u32[3];
803  break;
804  default:
805  clib_warning ("invalid prefix length");
806  break;
807  }
808 
809  clib_warning ("%U %U plen %u", format_ip6_address, ip6, format_ip4_address,
810  ip4, plen);
811 }
812 
813 /**
814  * @brief The 'nat64-expire-walk' process's main loop.
815  *
816  * Check expire time for NAT64 sessions.
817  */
818 static uword
820  vlib_frame_t * f)
821 {
822  nat64_main_t *nm = &nat64_main;
823 
824  while (!nm->is_disabled)
825  {
828  u32 now = (u32) vlib_time_now (vm);
829 
830  nad64_db_st_free_expired (&nm->db, now);
831  }
832 
833  return 0;
834 }
835 
837 
838 /* *INDENT-OFF* */
839 VLIB_REGISTER_NODE (nat64_expire_walk_node, static) = {
840  .function = nat64_expire_walk_fn,
841  .type = VLIB_NODE_TYPE_PROCESS,
842  .name = "nat64-expire-walk",
843 };
844 /* *INDENT-ON* */
845 
846 /*
847  * fd.io coding-style-patch-verification: ON
848  *
849  * Local Variables:
850  * eval: (c-set-style "gnu")
851  * End:
852  */
u32 nat64_get_icmp_timeout(void)
Get ICMP session timeout.
Definition: nat64.c:451
u32 icmp_timeout
Definition: nat64.h:66
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
int nat64_set_udp_timeout(u32 timeout)
Set UDP session timeout.
Definition: nat64.c:415
int nat64_alloc_out_addr_and_port(u32 fib_index, snat_protocol_t proto, ip4_address_t *addr, u16 *port)
Alloce IPv4 address and port pair from NAT64 pool.
Definition: nat64.c:227
#define SNAT_UDP_TIMEOUT
Definition: snat.h:32
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...
Definition: node_funcs.h:699
a
Definition: bitmap.h:516
ip6_address_t prefix
Definition: nat64.h:44
snat_address_t * addr_pool
Address pool vector.
Definition: nat64.h:56
#define TCP_FLAG_SYN
Definition: fa_node.h:8
void nat64_extract_ip4(ip6_address_t *ip6, ip4_address_t *ip4, u32 fib_index)
Extract IPv4 address from the IPv4-embedded IPv6 addresses.
Definition: nat64.c:744
nat64_db_bib_entry_t * nat64_db_bib_entry_create(nat64_db_t *db, ip6_address_t *in_addr, ip4_address_t *out_addr, u16 in_port, u16 out_port, u32 fib_index, snat_protocol_t proto, u8 is_static)
Create new NAT64 BIB entry.
Definition: nat64_db.c:45
u8 as_u8[16]
Definition: ip6_packet.h:48
u64 as_u64[2]
Definition: ip6_packet.h:51
int nat64_add_del_interface(u32 sw_if_index, u8 is_inside, u8 is_add)
Enable/disable NAT64 feature on the interface.
Definition: nat64.c:159
#define NULL
Definition: clib.h:55
u8 is_disabled
Definition: nat64.h:71
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:192
int nat64_add_del_pool_addr(ip4_address_t *addr, u32 vrf_id, u8 is_add)
Add/delete address to NAT64 pool.
Definition: nat64.c:83
struct _vlib_node_registration vlib_node_registration_t
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:561
u32 tcp_trans_timeout
Definition: nat64.h:67
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
struct _tcp_header tcp_header_t
int nat64_set_tcp_timeouts(u32 trans, u32 est, u32 incoming_syn)
Set TCP session timeouts.
Definition: nat64.c:459
format_function_t format_ip4_address
Definition: format.h:79
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
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...
Definition: node_funcs.h:542
nat64_db_bib_entry_t * nat64_db_bib_entry_find(nat64_db_t *db, ip46_address_t *addr, u16 port, snat_protocol_t proto, u32 fib_index, u8 is_ip6)
Find NAT64 BIB entry.
Definition: nat64_db.c:171
int nat64_set_icmp_timeout(u32 timeout)
Set ICMP session timeout.
Definition: nat64.c:438
#define SNAT_ICMP_TIMEOUT
Definition: snat.h:37
#define clib_error_return(e, args...)
Definition: error.h:99
u32 tcp_est_timeout
Definition: nat64.h:68
void nat64_tcp_session_set_state(nat64_db_st_entry_t *ste, tcp_header_t *tcp, u8 is_ip6)
Set NAT64 TCP session state.
Definition: nat64.c:544
snat_interface_t * interfaces
Interface pool.
Definition: nat64.h:53
u32 tcp_incoming_syn_timeout
Definition: nat64.h:69
nat64_db_t db
BIB and session DB.
Definition: nat64.h:62
u32 fib_index
Definition: nat64.h:47
u32 udp_timeout
Definition: nat64.h:65
#define SNAT_TCP_TRANSITORY_TIMEOUT
Definition: snat.h:34
nat64_prefix_t * pref64
Pref64 vector.
Definition: nat64.h:59
void nat64_session_reset_timeout(nat64_db_st_entry_t *ste, vlib_main_t *vm)
Reset NAT64 session timeout.
Definition: nat64.c:506
void nad64_db_st_free_expired(nat64_db_t *db, u32 now)
Free expired session entries in session tables.
Definition: nat64_db.c:487
#define SNAT_UDP_TIMEOUT_MIN
Definition: snat.h:33
u32 nat64_get_udp_timeout(void)
Get UDP session timeout.
Definition: nat64.c:430
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
snat_main_t snat_main
Definition: jvpp_snat.h:39
void nat64_db_bib_entry_free(nat64_db_t *db, nat64_db_bib_entry_t *bibe)
Free NAT64 BIB entry.
Definition: nat64_db.c:105
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:805
static uword nat64_expire_walk_fn(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
The &#39;nat64-expire-walk&#39; process&#39;s main loop.
Definition: nat64.c:819
#define TCP_FLAG_FIN
Definition: fa_node.h:7
void nat64_compose_ip6(ip6_address_t *ip6, ip4_address_t *ip4, u32 fib_index)
Compose IPv4-embedded IPv6 addresses.
Definition: nat64.c:673
#define TCP_FLAG_RST
Definition: fa_node.h:9
static u8 well_known_prefix[]
Definition: nat64.c:41
u32 as_u32[4]
Definition: ip6_packet.h:50
u32 nat64_get_tcp_est_timeout(void)
Get TCP established timeout.
Definition: nat64.c:490
void nat64_pool_addr_walk(nat64_pool_addr_walk_fn_t fn, void *ctx)
Walk NAT64 pool.
Definition: nat64.c:144
format_function_t format_ip6_address
Definition: format.h:95
int nat64_add_del_prefix(ip6_address_t *prefix, u8 plen, u32 vrf_id, u8 is_add)
Add/delete NAT64 prefix.
Definition: nat64.c:611
#define clib_warning(format, args...)
Definition: error.h:59
nat64_main_t nat64_main
Definition: nat64.c:25
u32 vrf_id
Definition: nat64.h:46
snat_protocol_t
Definition: snat.h:98
unsigned int u32
Definition: types.h:88
u32 nat64_get_tcp_incoming_syn_timeout(void)
Get TCP incoming SYN timeout.
Definition: nat64.c:498
void snat_add_del_addr_to_fib(ip4_address_t *addr, u8 p_len, u32 sw_if_index, int is_add)
Add/del NAT address to FIB.
Definition: snat.c:96
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1041
ip4_address_t addr
Definition: snat.h:158
#define VNET_FEATURES(...)
Definition: feature.h:368
void nat64_prefix_walk(nat64_prefix_walk_fn_t fn, void *ctx)
Walk NAT64 prefixes.
Definition: nat64.c:658
u64 uword
Definition: types.h:112
#define SNAT_TCP_INCOMING_SYN
Definition: snat.h:36
void nat64_interfaces_walk(nat64_interface_walk_fn_t fn, void *ctx)
Walk NAT64 interfaces.
Definition: nat64.c:212
clib_error_t * nat64_init(vlib_main_t *vm)
Initialize NAT64.
Definition: nat64.c:51
NAT64 global declarations.
static vlib_node_registration_t nat64_expire_walk_node
(constructor) VLIB_REGISTER_NODE (nat64_expire_walk_node)
Definition: nat64.c:836
unsigned short u16
Definition: types.h:57
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static u32 ip_proto_to_snat_proto(u8 ip_proto)
Definition: snat.h:389
NAT64 DB.
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:144
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define vec_foreach(var, vec)
Vector iterator.
vhost_vring_addr_t addr
Definition: vhost-user.h:82
int nat64_db_init(nat64_db_t *db)
Initialize NAT64 DB.
Definition: nat64_db.c:22
VNET_FEATURE_INIT(nat64_in2out, static)
void nat64_free_out_addr_and_port(ip4_address_t *addr, u16 port, snat_protocol_t proto)
Free IPv4 address and port pair from NAT64 pool.
Definition: nat64.c:313
int nat64_add_del_static_bib_entry(ip6_address_t *in_addr, ip4_address_t *out_addr, u16 in_port, u16 out_port, u8 proto, u32 vrf_id, u8 is_add)
Add/delete static NAT64 BIB entry.
Definition: nat64.c:345
int(* nat64_prefix_walk_fn_t)(nat64_prefix_t *pref64, void *ctx)
Call back function when walking addresses in NAT64 prefixes, non-zero return value stop walk...
Definition: nat64.h:282
#define SNAT_TCP_ESTABLISHED_TIMEOUT
Definition: snat.h:35
u32 fib_index
Definition: snat.h:159
u32 nat64_get_tcp_trans_timeout(void)
Get TCP transitory timeout.
Definition: nat64.c:482
int(* nat64_interface_walk_fn_t)(snat_interface_t *i, void *ctx)
Call back function when walking interfaces with NAT64 feature, non-zero return value stop walk...
Definition: nat64.h:120
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:225
int(* nat64_pool_addr_walk_fn_t)(snat_address_t *addr, void *ctx)
Call back function when walking addresses in NAT64 pool, non-zero return value stop walk...
Definition: nat64.h:95