FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
nat_inlines.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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  * @brief The NAT inline functions
17  */
18 
19 #ifndef __included_nat_inlines_h__
20 #define __included_nat_inlines_h__
21 
22 #include <vnet/fib/ip4_fib.h>
23 #include <nat/nat.h>
24 #include <nat/nat_ha.h>
25 
26 static inline uword
29  vlib_frame_t * frame, u32 def_next)
30 {
31  u32 n_left_from, *from, *to_next;
32  u16 next_index;
33 
34  from = vlib_frame_vector_args (frame);
35  n_left_from = frame->n_vectors;
36  next_index = node->cached_next_index;
37 
38  while (n_left_from > 0)
39  {
40  u32 n_left_to_next;
41 
42  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
43 
44  while (n_left_from >= 4 && n_left_to_next >= 2)
45  {
46  u32 next0, next1;
47  u32 arc_next0, arc_next1;
48  u32 bi0, bi1;
49  vlib_buffer_t *b0, *b1;
50 
51  /* Prefetch next iteration. */
52  {
53  vlib_buffer_t *p2, *p3;
54 
55  p2 = vlib_get_buffer (vm, from[2]);
56  p3 = vlib_get_buffer (vm, from[3]);
57 
58  vlib_prefetch_buffer_header (p2, LOAD);
59  vlib_prefetch_buffer_header (p3, LOAD);
60 
63  }
64 
65  /* speculatively enqueue b0 and b1 to the current next frame */
66  to_next[0] = bi0 = from[0];
67  to_next[1] = bi1 = from[1];
68  from += 2;
69  to_next += 2;
70  n_left_from -= 2;
71  n_left_to_next -= 2;
72 
73  b0 = vlib_get_buffer (vm, bi0);
74  b1 = vlib_get_buffer (vm, bi1);
75 
76  next0 = def_next;
77  next1 = def_next;
78 
79  vnet_feature_next (&arc_next0, b0);
80  vnet_feature_next (&arc_next1, b1);
81 
82  nat_buffer_opaque (b0)->arc_next = arc_next0;
83  nat_buffer_opaque (b1)->arc_next = arc_next1;
84 
86  {
87  if (b0->flags & VLIB_BUFFER_IS_TRACED)
88  {
89  nat_pre_trace_t *t =
90  vlib_add_trace (vm, node, b0, sizeof (*t));
91  t->next_index = next0;
92  }
93  if (b1->flags & VLIB_BUFFER_IS_TRACED)
94  {
95  nat_pre_trace_t *t =
96  vlib_add_trace (vm, node, b0, sizeof (*t));
97  t->next_index = next0;
98  }
99  }
100 
101  /* verify speculative enqueues, maybe switch current next frame */
102  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
103  to_next, n_left_to_next,
104  bi0, bi1, next0, next1);
105  }
106 
107  while (n_left_from > 0 && n_left_to_next > 0)
108  {
109  u32 next0;
110  u32 arc_next0;
111  u32 bi0;
112  vlib_buffer_t *b0;
113 
114  /* speculatively enqueue b0 to the current next frame */
115  bi0 = from[0];
116  to_next[0] = bi0;
117  from += 1;
118  to_next += 1;
119  n_left_from -= 1;
120  n_left_to_next -= 1;
121 
122  b0 = vlib_get_buffer (vm, bi0);
123  next0 = def_next;
124  vnet_feature_next (&arc_next0, b0);
125  nat_buffer_opaque (b0)->arc_next = arc_next0;
126 
128  && (b0->flags & VLIB_BUFFER_IS_TRACED)))
129  {
130  nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
131  t->next_index = next0;
132  }
133 
134  /* verify speculative enqueue, maybe switch current next frame */
135  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
136  to_next, n_left_to_next,
137  bi0, next0);
138  }
139 
140  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
141  }
142 
143  return frame->n_vectors;
144 }
145 
148 {
149  u32 snat_proto = ~0;
150 
151  snat_proto = (ip_proto == IP_PROTOCOL_UDP) ? SNAT_PROTOCOL_UDP : snat_proto;
152  snat_proto = (ip_proto == IP_PROTOCOL_TCP) ? SNAT_PROTOCOL_TCP : snat_proto;
153  snat_proto =
154  (ip_proto == IP_PROTOCOL_ICMP) ? SNAT_PROTOCOL_ICMP : snat_proto;
155  snat_proto =
156  (ip_proto == IP_PROTOCOL_ICMP6) ? SNAT_PROTOCOL_ICMP : snat_proto;
157 
158  return snat_proto;
159 }
160 
163 {
164  u8 ip_proto = ~0;
165 
166  ip_proto = (snat_proto == SNAT_PROTOCOL_UDP) ? IP_PROTOCOL_UDP : ip_proto;
167  ip_proto = (snat_proto == SNAT_PROTOCOL_TCP) ? IP_PROTOCOL_TCP : ip_proto;
168  ip_proto = (snat_proto == SNAT_PROTOCOL_ICMP) ? IP_PROTOCOL_ICMP : ip_proto;
169 
170  return ip_proto;
171 }
172 
175 {
176  switch (icmp_type)
177  {
178  case ICMP4_destination_unreachable:
179  case ICMP4_time_exceeded:
180  case ICMP4_parameter_problem:
181  case ICMP4_source_quench:
182  case ICMP4_redirect:
183  case ICMP4_alternate_host_address:
184  return 1;
185  }
186  return 0;
187 }
188 
191  u32 sw_if_index0, u32 ip4_addr)
192 {
194  ip4_address_t *first_int_addr;
195 
196  if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
197  {
198  first_int_addr =
199  ip4_interface_first_address (sm->ip4_main, sw_if_index0,
200  0 /* just want the address */ );
201  rt->cached_sw_if_index = sw_if_index0;
202  if (first_int_addr)
203  rt->cached_ip4_address = first_int_addr->as_u32;
204  else
205  rt->cached_ip4_address = 0;
206  }
207 
208  if (PREDICT_FALSE (ip4_addr == rt->cached_ip4_address))
209  return 1;
210  else
211  return 0;
212 }
213 
216 {
217  if (pool_elts (sm->per_thread_data[thread_index].sessions) >=
218  sm->max_translations)
219  return 1;
220 
221  return 0;
222 }
223 
224 always_inline void
227  u32 next)
228 {
229  u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
230 
231  from = bi_vector;
232  n_left_from = vec_len (bi_vector);
233  next_index = node->cached_next_index;
234  while (n_left_from > 0)
235  {
236  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
237  while (n_left_from > 0 && n_left_to_next > 0)
238  {
239  u32 bi0 = to_next[0] = from[0];
240  from += 1;
241  n_left_from -= 1;
242  to_next += 1;
243  n_left_to_next -= 1;
244  vlib_buffer_t *p0 = vlib_get_buffer (vm, bi0);
245  if (error)
246  p0->error = *error;
247  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
248  n_left_to_next, bi0, next);
249  }
250  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
251  }
252 }
253 
254 always_inline void
256 {
258  {
259  if (is_static)
260  u->nstaticsessions++;
261  else
262  u->nsessions++;
263  }
264 }
265 
266 always_inline void
268  u32 thread_index)
269 {
271  snat_user_key_t u_key;
273  thread_index);
274 
275  if (u->nstaticsessions == 0 && u->nsessions == 0)
276  {
277  u_key.addr.as_u32 = u->addr.as_u32;
278  u_key.fib_index = u->fib_index;
279  kv.key = u_key.as_u64;
281  pool_put (tsm->users, u);
282  clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 0);
283  vlib_set_simple_counter (&sm->total_users, thread_index, 0,
284  pool_elts (tsm->users));
285  }
286 }
287 
288 always_inline void
289 nat44_delete_session (snat_main_t * sm, snat_session_t * ses,
290  u32 thread_index)
291 {
293  thread_index);
295  snat_user_t *u;
296  const snat_user_key_t u_key = {
297  .addr = ses->in2out.addr,
298  .fib_index = ses->in2out.fib_index
299  };
300  const u8 u_static = snat_is_session_static (ses);
301 
302  clib_dlist_remove (tsm->list_pool, ses->per_user_index);
303  pool_put_index (tsm->list_pool, ses->per_user_index);
304  pool_put (tsm->sessions, ses);
305  vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
306  pool_elts (tsm->sessions));
307 
308  kv.key = u_key.as_u64;
309  if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
310  {
311  u = pool_elt_at_index (tsm->users, value.value);
312  if (u_static)
313  u->nstaticsessions--;
314  else
315  u->nsessions--;
316 
317  nat44_delete_user_with_no_session (sm, u, thread_index);
318  }
319 }
320 
321 /** \brief Set TCP session state.
322  @return 1 if session was closed, otherwise 0
323 */
324 always_inline int
325 nat44_set_tcp_session_state_i2o (snat_main_t * sm, snat_session_t * ses,
326  vlib_buffer_t * b, u32 thread_index)
327 {
328  u8 tcp_flags = vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags;
329  u32 tcp_ack_number = vnet_buffer (b)->ip.reass.tcp_ack_number;
330  u32 tcp_seq_number = vnet_buffer (b)->ip.reass.tcp_seq_number;
331  if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
332  ses->state = NAT44_SES_RST;
333  if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
334  ses->state = 0;
335  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
336  (ses->state & NAT44_SES_O2I_SYN))
337  ses->state = 0;
338  if (tcp_flags & TCP_FLAG_SYN)
339  ses->state |= NAT44_SES_I2O_SYN;
340  if (tcp_flags & TCP_FLAG_FIN)
341  {
342  ses->i2o_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
343  ses->state |= NAT44_SES_I2O_FIN;
344  }
345  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_O2I_FIN))
346  {
347  if (clib_net_to_host_u32 (tcp_ack_number) > ses->o2i_fin_seq)
348  ses->state |= NAT44_SES_O2I_FIN_ACK;
349  }
350  if (nat44_is_ses_closed (ses)
351  && !(ses->flags & SNAT_SESSION_FLAG_OUTPUT_FEATURE))
352  {
353  nat_free_session_data (sm, ses, thread_index, 0);
354  nat44_delete_session (sm, ses, thread_index);
355  return 1;
356  }
357  return 0;
358 }
359 
360 always_inline int
361 nat44_set_tcp_session_state_o2i (snat_main_t * sm, snat_session_t * ses,
362  u8 tcp_flags, u32 tcp_ack_number,
363  u32 tcp_seq_number, u32 thread_index)
364 {
365  if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
366  ses->state = NAT44_SES_RST;
367  if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
368  ses->state = 0;
369  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
370  (ses->state & NAT44_SES_O2I_SYN))
371  ses->state = 0;
372  if (tcp_flags & TCP_FLAG_SYN)
373  ses->state |= NAT44_SES_O2I_SYN;
374  if (tcp_flags & TCP_FLAG_FIN)
375  {
376  ses->o2i_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
377  ses->state |= NAT44_SES_O2I_FIN;
378  }
379  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_FIN))
380  {
381  if (clib_net_to_host_u32 (tcp_ack_number) > ses->i2o_fin_seq)
382  ses->state |= NAT44_SES_I2O_FIN_ACK;
383  }
384  if (nat44_is_ses_closed (ses))
385  {
386  nat_free_session_data (sm, ses, thread_index, 0);
387  nat44_delete_session (sm, ses, thread_index);
388  return 1;
389  }
390  return 0;
391 }
392 
394 nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s)
395 {
396  switch (s->in2out.protocol)
397  {
398  case SNAT_PROTOCOL_ICMP:
399  return sm->icmp_timeout;
400  case SNAT_PROTOCOL_UDP:
401  return sm->udp_timeout;
402  case SNAT_PROTOCOL_TCP:
403  {
404  if (s->state)
405  return sm->tcp_transitory_timeout;
406  else
407  return sm->tcp_established_timeout;
408  }
409  default:
410  return sm->udp_timeout;
411  }
412 
413  return 0;
414 }
415 
416 always_inline void
417 nat44_session_update_counters (snat_session_t * s, f64 now, uword bytes,
418  u32 thread_index)
419 {
420  s->last_heard = now;
421  s->total_pkts++;
422  s->total_bytes += bytes;
423  nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
424  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
425  s->total_pkts, s->total_bytes, thread_index,
426  &s->ha_last_refreshed, now);
427 }
428 
429 /** \brief Per-user LRU list maintenance */
430 always_inline void
431 nat44_session_update_lru (snat_main_t * sm, snat_session_t * s,
432  u32 thread_index)
433 {
434  clib_dlist_remove (sm->per_thread_data[thread_index].list_pool,
435  s->per_user_index);
436  clib_dlist_addtail (sm->per_thread_data[thread_index].list_pool,
437  s->per_user_list_head_index, s->per_user_index);
438 }
439 
440 always_inline void
442  ip4_address_t * r_addr, u8 proto, u32 fib_index, u16 l_port,
443  u16 r_port)
444 {
446 
447  key->l_addr.as_u32 = l_addr->as_u32;
448  key->r_addr.as_u32 = r_addr->as_u32;
449  key->fib_index = fib_index;
450  key->proto = proto;
451  key->l_port = l_port;
452  key->r_port = r_port;
453 
454  kv->value = ~0ULL;
455 }
456 
457 always_inline void
459  u32 fib_index, u16 port)
460 {
462 
463  key.addr.as_u32 = addr->as_u32;
464  key.port = port;
465  key.protocol = proto;
466  key.fib_index = fib_index;
467 
468  kv->key = key.as_u64;
469  kv->value = ~0ULL;
470 }
471 
474  nat_ed_ses_key_t * p_key0)
475 {
476  icmp46_header_t *icmp0;
477  nat_ed_ses_key_t key0;
478  icmp_echo_header_t *echo0, *inner_echo0 = 0;
479  ip4_header_t *inner_ip0 = 0;
480  void *l4_header = 0;
481  icmp46_header_t *inner_icmp0;
482 
483  icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
484  echo0 = (icmp_echo_header_t *) (icmp0 + 1);
485 
487  (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
488  {
489  key0.proto = IP_PROTOCOL_ICMP;
490  key0.l_addr = ip0->src_address;
491  key0.r_addr = ip0->dst_address;
492  key0.l_port = vnet_buffer (b)->ip.reass.l4_src_port; // TODO should this be src or dst?
493  key0.r_port = 0;
494  }
495  else
496  {
497  inner_ip0 = (ip4_header_t *) (echo0 + 1);
498  l4_header = ip4_next_header (inner_ip0);
499  key0.proto = inner_ip0->protocol;
500  key0.r_addr = inner_ip0->src_address;
501  key0.l_addr = inner_ip0->dst_address;
502  switch (ip_proto_to_snat_proto (inner_ip0->protocol))
503  {
504  case SNAT_PROTOCOL_ICMP:
505  inner_icmp0 = (icmp46_header_t *) l4_header;
506  inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
507  key0.r_port = 0;
508  key0.l_port = inner_echo0->identifier;
509  break;
510  case SNAT_PROTOCOL_UDP:
511  case SNAT_PROTOCOL_TCP:
512  key0.l_port = ((tcp_udp_header_t *) l4_header)->dst_port;
513  key0.r_port = ((tcp_udp_header_t *) l4_header)->src_port;
514  break;
515  default:
516  return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
517  }
518  }
519  *p_key0 = key0;
520  return 0;
521 }
522 
523 
526  nat_ed_ses_key_t * p_key0)
527 {
528  icmp46_header_t *icmp0;
529  nat_ed_ses_key_t key0;
530  icmp_echo_header_t *echo0, *inner_echo0 = 0;
531  ip4_header_t *inner_ip0;
532  void *l4_header = 0;
533  icmp46_header_t *inner_icmp0;
534 
535  icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
536  echo0 = (icmp_echo_header_t *) (icmp0 + 1);
537 
539  (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
540  {
541  key0.proto = IP_PROTOCOL_ICMP;
542  key0.l_addr = ip0->dst_address;
543  key0.r_addr = ip0->src_address;
544  key0.l_port = vnet_buffer (b)->ip.reass.l4_src_port; // TODO should this be src or dst?
545  key0.r_port = 0;
546  }
547  else
548  {
549  inner_ip0 = (ip4_header_t *) (echo0 + 1);
550  l4_header = ip4_next_header (inner_ip0);
551  key0.proto = inner_ip0->protocol;
552  key0.l_addr = inner_ip0->src_address;
553  key0.r_addr = inner_ip0->dst_address;
554  switch (ip_proto_to_snat_proto (inner_ip0->protocol))
555  {
556  case SNAT_PROTOCOL_ICMP:
557  inner_icmp0 = (icmp46_header_t *) l4_header;
558  inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
559  key0.l_port = inner_echo0->identifier;
560  key0.r_port = 0;
561  break;
562  case SNAT_PROTOCOL_UDP:
563  case SNAT_PROTOCOL_TCP:
564  key0.l_port = ((tcp_udp_header_t *) l4_header)->src_port;
565  key0.r_port = ((tcp_udp_header_t *) l4_header)->dst_port;
566  break;
567  default:
568  return -1;
569  }
570  }
571  *p_key0 = key0;
572  return 0;
573 }
574 
575 always_inline void
577 {
578  u8 *data;
579  u8 opt_len, opts_len, kind;
580  u16 mss;
581 
582  if (!(sm->mss_clamping && tcp_syn (tcp)))
583  return;
584 
585  opts_len = (tcp_doff (tcp) << 2) - sizeof (tcp_header_t);
586  data = (u8 *) (tcp + 1);
587  for (; opts_len > 0; opts_len -= opt_len, data += opt_len)
588  {
589  kind = data[0];
590 
591  if (kind == TCP_OPTION_EOL)
592  break;
593  else if (kind == TCP_OPTION_NOOP)
594  {
595  opt_len = 1;
596  continue;
597  }
598  else
599  {
600  if (opts_len < 2)
601  return;
602  opt_len = data[1];
603 
604  if (opt_len < 2 || opt_len > opts_len)
605  return;
606  }
607 
608  if (kind == TCP_OPTION_MSS)
609  {
610  mss = *(u16 *) (data + 2);
611  if (clib_net_to_host_u16 (mss) > sm->mss_clamping)
612  {
613  *sum =
614  ip_csum_update (*sum, mss, sm->mss_value_net, ip4_header_t,
615  length);
616  clib_memcpy_fast (data + 2, &sm->mss_value_net, 2);
617  }
618  return;
619  }
620  }
621 }
622 
623 /**
624  * @brief Check if packet should be translated
625  *
626  * Packets aimed at outside interface and external address with active session
627  * should be translated.
628  *
629  * @param sm NAT main
630  * @param rt NAT runtime data
631  * @param sw_if_index0 index of the inside interface
632  * @param ip0 IPv4 header
633  * @param proto0 NAT protocol
634  * @param rx_fib_index0 RX FIB index
635  *
636  * @returns 0 if packet should be translated otherwise 1
637  */
638 static inline int
640  u32 sw_if_index0, ip4_header_t * ip0, u32 proto0,
641  u32 rx_fib_index0)
642 {
643  if (sm->out2in_dpo)
644  return 0;
645 
647  nat_outside_fib_t *outside_fib;
648  fib_prefix_t pfx = {
650  .fp_len = 32,
651  .fp_addr = {
652  .ip4.as_u32 = ip0->dst_address.as_u32,
653  }
654  ,
655  };
656 
657  /* Don't NAT packet aimed at the intfc address */
658  if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
659  ip0->dst_address.as_u32)))
660  return 1;
661 
662  fei = fib_table_lookup (rx_fib_index0, &pfx);
663  if (FIB_NODE_INDEX_INVALID != fei)
664  {
666  if (sw_if_index == ~0)
667  {
668  vec_foreach (outside_fib, sm->outside_fibs)
669  {
670  fei = fib_table_lookup (outside_fib->fib_index, &pfx);
671  if (FIB_NODE_INDEX_INVALID != fei)
672  {
673  sw_if_index = fib_entry_get_resolving_interface (fei);
674  if (sw_if_index != ~0)
675  break;
676  }
677  }
678  }
679  if (sw_if_index == ~0)
680  return 1;
681 
683  /* *INDENT-OFF* */
684  pool_foreach (i, sm->interfaces, ({
685  /* NAT packet aimed at outside interface */
686  if ((nat_interface_is_outside (i)) && (sw_if_index == i->sw_if_index))
687  return 0;
688  }));
689  /* *INDENT-ON* */
690  }
691 
692  return 1;
693 }
694 
695 #endif /* __included_nat_inlines_h__ */
696 
697 /*
698  * fd.io coding-style-patch-verification: ON
699  *
700  * Local Variables:
701  * eval: (c-set-style "gnu")
702  * End:
703  */
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
nat_outside_fib_t * outside_fibs
Definition: nat.h:598
#define nat_buffer_opaque(b)
Definition: nat.h:71
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
Definition: nat.h:765
u32 sessions_per_user_list_head_index
Definition: nat.h:349
End of options.
Definition: tcp_packet.h:104
u8 proto
Definition: acl_types.api:47
#define NAT44_SES_I2O_FIN
Definition: nat.h:272
u32 icmp_timeout
Definition: nat.h:677
u8 runtime_data[0]
Function dependent node-runtime data.
Definition: node.h:523
ip4_address_t src_address
Definition: ip4_packet.h:170
static u32 nat44_session_get_timeout(snat_main_t *sm, snat_session_t *s)
Definition: nat_inlines.h:394
#define TCP_FLAG_SYN
Definition: fa_node.h:13
u32 nsessions
Definition: nat.h:350
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
Definition: ip4_forward.c:279
static void make_sm_kv(clib_bihash_kv_8_8_t *kv, ip4_address_t *addr, u8 proto, u32 fib_index, u16 port)
Definition: nat_inlines.h:458
#define tcp_doff(_th)
Definition: tcp_packet.h:78
void nat_free_session_data(snat_main_t *sm, snat_session_t *s, u32 thread_index, u8 is_ha)
Free NAT44 session data (lookup keys, external addrres port)
Definition: nat.c:194
u8 data[0]
Packet data.
Definition: buffer.h:181
u32 nstaticsessions
Definition: nat.h:351
u16 vlib_error_t
Definition: error.h:43
int i
uword ip_csum_t
Definition: ip_packet.h:244
u32 fib_index
Definition: nat.h:348
#define nat44_is_ses_closed(s)
Check if NAT44 endpoint-dependent TCP session is closed.
Definition: nat.h:819
#define NAT44_SES_O2I_FIN
Definition: nat.h:273
No operation.
Definition: tcp_packet.h:105
dlist_elt_t * list_pool
Definition: nat.h:512
struct _tcp_header tcp_header_t
vhost_vring_addr_t addr
Definition: vhost_user.h:147
unsigned char u8
Definition: types.h:56
u16 l_port
Definition: nat.h:108
double f64
Definition: types.h:142
clib_bihash_8_8_t user_hash
Definition: nat.h:503
u32 cached_sw_if_index
Definition: nat.h:713
u32 next_index
Definition: nat.h:68
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.
Definition: nat_ha.c:734
static int snat_not_translate_fast(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, ip4_header_t *ip0, u32 proto0, u32 rx_fib_index0)
Check if packet should be translated.
Definition: nat_inlines.h:639
u32 max_translations_per_user
Definition: nat.h:669
Limit MSS.
Definition: tcp_packet.h:106
#define static_always_inline
Definition: clib.h:99
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
u16 r_port
Definition: nat.h:109
ip4_address_t dst_address
Definition: ip4_packet.h:170
#define TCP_FLAG_ACK
Definition: fa_node.h:16
ip4_address_t addr
Definition: nat.h:347
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
#define SNAT_SESSION_FLAG_OUTPUT_FEATURE
Definition: nat.h:288
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Aggregate type for a prefix.
Definition: fib_types.h:203
ip4_main_t * ip4_main
Definition: nat.h:700
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:241
unsigned int u32
Definition: types.h:88
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.
Definition: fib_table.c:68
#define NAT44_SES_RST
Definition: nat.h:278
static u8 maximum_sessions_exceeded(snat_main_t *sm, u32 thread_index)
Definition: nat_inlines.h:215
static void nat44_delete_session(snat_main_t *sm, snat_session_t *ses, u32 thread_index)
Definition: nat_inlines.h:289
static_always_inline int get_icmp_i2o_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, nat_ed_ses_key_t *p_key0)
Definition: nat_inlines.h:473
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
u32 max_translations
Definition: nat.h:666
static void mss_clamping(snat_main_t *sm, tcp_header_t *tcp, ip_csum_t *sum)
Definition: nat_inlines.h:576
static int nat44_set_tcp_session_state_i2o(snat_main_t *sm, snat_session_t *ses, vlib_buffer_t *b, u32 thread_index)
Set TCP session state.
Definition: nat_inlines.h:325
u32 fib_index
Definition: nat.h:107
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
u32 fib_index
Definition: nat.h:370
u16 mss_value_net
Definition: nat.h:683
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
Definition: nat_inlines.h:174
u64 key
the key
Definition: bihash_8_8.h:35
u16 mss_clamping
Definition: nat.h:682
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
Definition: dlist.h:43
unsigned short u16
Definition: types.h:57
u16 protocol
Definition: nat.h:92
u8 out2in_dpo
Definition: nat.h:662
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
u32 udp_timeout
Definition: nat.h:676
#define PREDICT_FALSE(x)
Definition: clib.h:111
#define always_inline
Definition: ipsec.h:28
#define TCP_FLAG_FIN
Definition: fa_node.h:12
#define NAT44_SES_O2I_SYN
Definition: nat.h:277
static void vlib_set_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 value)
Set a simple counter.
Definition: counter.h:94
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
#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.
Definition: buffer_node.h:218
#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).
Definition: node_funcs.h:338
vlib_main_t * vm
Definition: in2out_ed.c:1810
#define TCP_FLAG_RST
Definition: fa_node.h:14
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1458
u64 value
the value
Definition: bihash_8_8.h:36
snat_user_t * users
Definition: nat.h:506
static void nat44_delete_user_with_no_session(snat_main_t *sm, snat_user_t *u, u32 thread_index)
Definition: nat_inlines.h:267
static u8 snat_proto_to_ip_proto(snat_protocol_t snat_proto)
Definition: nat_inlines.h:162
u16 n_vectors
Definition: node.h:397
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
ip4_address_t l_addr
Definition: nat.h:105
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
static void nat44_session_update_counters(snat_session_t *s, f64 now, uword bytes, u32 thread_index)
Definition: nat_inlines.h:417
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
8 octet key, 8 octet key value pair
Definition: bihash_8_8.h:33
ip4_address_t addr
Definition: nat.h:90
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:456
static int nat44_set_tcp_session_state_o2i(snat_main_t *sm, snat_session_t *ses, u8 tcp_flags, u32 tcp_ack_number, u32 tcp_seq_number, u32 thread_index)
Definition: nat_inlines.h:361
static uword nat_pre_node_fn_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 def_next)
The NAT inline functions.
Definition: nat_inlines.h:27
static void make_ed_kv(clib_bihash_kv_16_8_t *kv, ip4_address_t *l_addr, ip4_address_t *r_addr, u8 proto, u32 fib_index, u16 l_port, u16 r_port)
Definition: nat_inlines.h:441
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
u32 tcp_transitory_timeout
Definition: nat.h:678
ip4_address_t r_addr
Definition: nat.h:106
ip_proto
Definition: ip_types.api:64
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:515
u8 value
Definition: qos.api:54
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:316
#define tcp_syn(_th)
Definition: tcp_packet.h:80
u8 data[128]
Definition: ipsec_types.api:87
static void nat44_session_update_lru(snat_main_t *sm, snat_session_t *s, u32 thread_index)
Per-user LRU list maintenance.
Definition: nat_inlines.h:431
u64 as_u64
Definition: nat.h:140
ip4_address_t addr
Definition: nat.h:137
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
Definition: dlist.h:99
#define NAT44_SES_I2O_SYN
Definition: nat.h:276
static_always_inline int get_icmp_o2i_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, nat_ed_ses_key_t *p_key0)
Definition: nat_inlines.h:525
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
typedef key
Definition: ipsec_types.api:83
vlib_simple_counter_main_t total_users
Definition: nat.h:686
static u32 ip_proto_to_snat_proto(u8 ip_proto)
Definition: nat_inlines.h:147
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
static void user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static)
Definition: nat_inlines.h:255
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
snat_main_per_thread_data_t * per_thread_data
Definition: nat.h:568
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
snat_protocol_t
Definition: nat.h:189
#define ip_csum_update(sum, old, new, type, field)
Definition: ip_packet.h:294
static u8 is_interface_addr(snat_main_t *sm, vlib_node_runtime_t *node, u32 sw_if_index0, u32 ip4_addr)
Definition: nat_inlines.h:190
u32 fib_index
Definition: nat.h:138
u16 port
Definition: lb_types.api:72
#define vnet_buffer(b)
Definition: buffer.h:408
#define NAT44_SES_I2O_FIN_ACK
Definition: nat.h:274
#define vec_foreach(var, vec)
Vector iterator.
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1811
u16 flags
Copy of main node flags.
Definition: node.h:509
static void nat_send_all_to_node(vlib_main_t *vm, u32 *bi_vector, vlib_node_runtime_t *node, vlib_error_t *error, u32 next)
Definition: nat_inlines.h:225
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:302
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
#define NAT44_SES_O2I_FIN_ACK
Definition: nat.h:275
vlib_simple_counter_main_t total_sessions
Definition: nat.h:687
snat_session_t * sessions
Definition: nat.h:509
u32 cached_ip4_address
Definition: nat.h:714
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
snat_interface_t * interfaces
Definition: nat.h:580
NAT active-passive HA.
u16 fib_index
Definition: nat.h:92
u32 tcp_established_timeout
Definition: nat.h:679
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128