FD.io VPP  v19.08.3-2-gbabecb413
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
28  vlib_node_runtime_t * node,
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 
174 icmp_is_error_message (icmp46_header_t * icmp)
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
226  vlib_node_runtime_t * node, vlib_error_t * error,
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  tcp_header_t * tcp, u32 thread_index)
327 {
328  if ((ses->state == 0) && (tcp->flags & TCP_FLAG_RST))
329  ses->state = NAT44_SES_RST;
330  if ((ses->state == NAT44_SES_RST) && !(tcp->flags & TCP_FLAG_RST))
331  ses->state = 0;
332  if ((tcp->flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
333  (ses->state & NAT44_SES_O2I_SYN))
334  ses->state = 0;
335  if (tcp->flags & TCP_FLAG_SYN)
336  ses->state |= NAT44_SES_I2O_SYN;
337  if (tcp->flags & TCP_FLAG_FIN)
338  {
339  ses->i2o_fin_seq = clib_net_to_host_u32 (tcp->seq_number);
340  ses->state |= NAT44_SES_I2O_FIN;
341  }
342  if ((tcp->flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_O2I_FIN))
343  {
344  if (clib_net_to_host_u32 (tcp->ack_number) > ses->o2i_fin_seq)
345  ses->state |= NAT44_SES_O2I_FIN_ACK;
346  }
347  if (nat44_is_ses_closed (ses)
348  && !(ses->flags & SNAT_SESSION_FLAG_OUTPUT_FEATURE))
349  {
350  nat_free_session_data (sm, ses, thread_index, 0);
351  nat44_delete_session (sm, ses, thread_index);
352  return 1;
353  }
354  return 0;
355 }
356 
357 always_inline int
358 nat44_set_tcp_session_state_o2i (snat_main_t * sm, snat_session_t * ses,
359  tcp_header_t * tcp, u32 thread_index)
360 {
361  if ((ses->state == 0) && (tcp->flags & TCP_FLAG_RST))
362  ses->state = NAT44_SES_RST;
363  if ((ses->state == NAT44_SES_RST) && !(tcp->flags & TCP_FLAG_RST))
364  ses->state = 0;
365  if ((tcp->flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
366  (ses->state & NAT44_SES_O2I_SYN))
367  ses->state = 0;
368  if (tcp->flags & TCP_FLAG_SYN)
369  ses->state |= NAT44_SES_O2I_SYN;
370  if (tcp->flags & TCP_FLAG_FIN)
371  {
372  ses->o2i_fin_seq = clib_net_to_host_u32 (tcp->seq_number);
373  ses->state |= NAT44_SES_O2I_FIN;
374  }
375  if ((tcp->flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_FIN))
376  {
377  if (clib_net_to_host_u32 (tcp->ack_number) > ses->i2o_fin_seq)
378  ses->state |= NAT44_SES_I2O_FIN_ACK;
379  }
380  if (nat44_is_ses_closed (ses))
381  {
382  nat_free_session_data (sm, ses, thread_index, 0);
383  nat44_delete_session (sm, ses, thread_index);
384  return 1;
385  }
386  return 0;
387 }
388 
390 nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s)
391 {
392  switch (s->in2out.protocol)
393  {
394  case SNAT_PROTOCOL_ICMP:
395  return sm->icmp_timeout;
396  case SNAT_PROTOCOL_UDP:
397  return sm->udp_timeout;
398  case SNAT_PROTOCOL_TCP:
399  {
400  if (s->state)
401  return sm->tcp_transitory_timeout;
402  else
403  return sm->tcp_established_timeout;
404  }
405  default:
406  return sm->udp_timeout;
407  }
408 
409  return 0;
410 }
411 
412 always_inline void
413 nat44_session_update_counters (snat_session_t * s, f64 now, uword bytes,
414  u32 thread_index)
415 {
416  s->last_heard = now;
417  s->total_pkts++;
418  s->total_bytes += bytes;
419  nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
420  s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
421  s->total_pkts, s->total_bytes, thread_index,
422  &s->ha_last_refreshed, now);
423 }
424 
425 /** \brief Per-user LRU list maintenance */
426 always_inline void
427 nat44_session_update_lru (snat_main_t * sm, snat_session_t * s,
428  u32 thread_index)
429 {
430  clib_dlist_remove (sm->per_thread_data[thread_index].list_pool,
431  s->per_user_index);
432  clib_dlist_addtail (sm->per_thread_data[thread_index].list_pool,
433  s->per_user_list_head_index, s->per_user_index);
434 }
435 
436 always_inline void
438  ip4_address_t * r_addr, u8 proto, u32 fib_index, u16 l_port,
439  u16 r_port)
440 {
442 
443  key->l_addr.as_u32 = l_addr->as_u32;
444  key->r_addr.as_u32 = r_addr->as_u32;
445  key->fib_index = fib_index;
446  key->proto = proto;
447  key->l_port = l_port;
448  key->r_port = r_port;
449 
450  kv->value = ~0ULL;
451 }
452 
453 always_inline void
455  u32 fib_index, u16 port)
456 {
458 
459  key.addr.as_u32 = addr->as_u32;
460  key.port = port;
461  key.protocol = proto;
462  key.fib_index = fib_index;
463 
464  kv->key = key.as_u64;
465  kv->value = ~0ULL;
466 }
467 
470 {
471  icmp46_header_t *icmp0;
472  nat_ed_ses_key_t key0;
473  icmp_echo_header_t *echo0, *inner_echo0 = 0;
474  ip4_header_t *inner_ip0 = 0;
475  void *l4_header = 0;
476  icmp46_header_t *inner_icmp0;
477 
478  icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
479  echo0 = (icmp_echo_header_t *) (icmp0 + 1);
480 
481  if (!icmp_is_error_message (icmp0))
482  {
483  key0.proto = IP_PROTOCOL_ICMP;
484  key0.l_addr = ip0->src_address;
485  key0.r_addr = ip0->dst_address;
486  key0.l_port = echo0->identifier;
487  key0.r_port = 0;
488  }
489  else
490  {
491  inner_ip0 = (ip4_header_t *) (echo0 + 1);
492  l4_header = ip4_next_header (inner_ip0);
493  key0.proto = inner_ip0->protocol;
494  key0.r_addr = inner_ip0->src_address;
495  key0.l_addr = inner_ip0->dst_address;
496  switch (ip_proto_to_snat_proto (inner_ip0->protocol))
497  {
498  case SNAT_PROTOCOL_ICMP:
499  inner_icmp0 = (icmp46_header_t *) l4_header;
500  inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
501  key0.r_port = 0;
502  key0.l_port = inner_echo0->identifier;
503  break;
504  case SNAT_PROTOCOL_UDP:
505  case SNAT_PROTOCOL_TCP:
506  key0.l_port = ((tcp_udp_header_t *) l4_header)->dst_port;
507  key0.r_port = ((tcp_udp_header_t *) l4_header)->src_port;
508  break;
509  default:
510  return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
511  }
512  }
513  *p_key0 = key0;
514  return 0;
515 }
516 
517 
520 {
521  icmp46_header_t *icmp0;
522  nat_ed_ses_key_t key0;
523  icmp_echo_header_t *echo0, *inner_echo0 = 0;
524  ip4_header_t *inner_ip0;
525  void *l4_header = 0;
526  icmp46_header_t *inner_icmp0;
527 
528  icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
529  echo0 = (icmp_echo_header_t *) (icmp0 + 1);
530 
531  if (!icmp_is_error_message (icmp0))
532  {
533  key0.proto = IP_PROTOCOL_ICMP;
534  key0.l_addr = ip0->dst_address;
535  key0.r_addr = ip0->src_address;
536  key0.l_port = echo0->identifier;
537  key0.r_port = 0;
538  }
539  else
540  {
541  inner_ip0 = (ip4_header_t *) (echo0 + 1);
542  l4_header = ip4_next_header (inner_ip0);
543  key0.proto = inner_ip0->protocol;
544  key0.l_addr = inner_ip0->src_address;
545  key0.r_addr = inner_ip0->dst_address;
546  switch (ip_proto_to_snat_proto (inner_ip0->protocol))
547  {
548  case SNAT_PROTOCOL_ICMP:
549  inner_icmp0 = (icmp46_header_t *) l4_header;
550  inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
551  key0.l_port = inner_echo0->identifier;
552  key0.r_port = 0;
553  break;
554  case SNAT_PROTOCOL_UDP:
555  case SNAT_PROTOCOL_TCP:
556  key0.l_port = ((tcp_udp_header_t *) l4_header)->src_port;
557  key0.r_port = ((tcp_udp_header_t *) l4_header)->dst_port;
558  break;
559  default:
560  return -1;
561  }
562  }
563  *p_key0 = key0;
564  return 0;
565 }
566 
567 always_inline void
569 {
570  u8 *data;
571  u8 opt_len, opts_len, kind;
572  u16 mss;
573 
574  if (!(sm->mss_clamping && tcp_syn (tcp)))
575  return;
576 
577  opts_len = (tcp_doff (tcp) << 2) - sizeof (tcp_header_t);
578  data = (u8 *) (tcp + 1);
579  for (; opts_len > 0; opts_len -= opt_len, data += opt_len)
580  {
581  kind = data[0];
582 
583  if (kind == TCP_OPTION_EOL)
584  break;
585  else if (kind == TCP_OPTION_NOOP)
586  {
587  opt_len = 1;
588  continue;
589  }
590  else
591  {
592  if (opts_len < 2)
593  return;
594  opt_len = data[1];
595 
596  if (opt_len < 2 || opt_len > opts_len)
597  return;
598  }
599 
600  if (kind == TCP_OPTION_MSS)
601  {
602  mss = *(u16 *) (data + 2);
603  if (clib_net_to_host_u16 (mss) > sm->mss_clamping)
604  {
605  *sum =
606  ip_csum_update (*sum, mss, sm->mss_value_net, ip4_header_t,
607  length);
608  clib_memcpy_fast (data + 2, &sm->mss_value_net, 2);
609  }
610  return;
611  }
612  }
613 }
614 
615 /**
616  * @brief Check if packet should be translated
617  *
618  * Packets aimed at outside interface and external address with active session
619  * should be translated.
620  *
621  * @param sm NAT main
622  * @param rt NAT runtime data
623  * @param sw_if_index0 index of the inside interface
624  * @param ip0 IPv4 header
625  * @param proto0 NAT protocol
626  * @param rx_fib_index0 RX FIB index
627  *
628  * @returns 0 if packet should be translated otherwise 1
629  */
630 static inline int
632  u32 sw_if_index0, ip4_header_t * ip0, u32 proto0,
633  u32 rx_fib_index0)
634 {
635  if (sm->out2in_dpo)
636  return 0;
637 
639  nat_outside_fib_t *outside_fib;
640  fib_prefix_t pfx = {
642  .fp_len = 32,
643  .fp_addr = {
644  .ip4.as_u32 = ip0->dst_address.as_u32,
645  }
646  ,
647  };
648 
649  /* Don't NAT packet aimed at the intfc address */
650  if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
651  ip0->dst_address.as_u32)))
652  return 1;
653 
654  fei = fib_table_lookup (rx_fib_index0, &pfx);
655  if (FIB_NODE_INDEX_INVALID != fei)
656  {
658  if (sw_if_index == ~0)
659  {
660  vec_foreach (outside_fib, sm->outside_fibs)
661  {
662  fei = fib_table_lookup (outside_fib->fib_index, &pfx);
663  if (FIB_NODE_INDEX_INVALID != fei)
664  {
665  sw_if_index = fib_entry_get_resolving_interface (fei);
666  if (sw_if_index != ~0)
667  break;
668  }
669  }
670  }
671  if (sw_if_index == ~0)
672  return 1;
673 
675  /* *INDENT-OFF* */
676  pool_foreach (i, sm->interfaces, ({
677  /* NAT packet aimed at outside interface */
678  if ((nat_interface_is_outside (i)) && (sw_if_index == i->sw_if_index))
679  return 0;
680  }));
681  /* *INDENT-ON* */
682  }
683 
684  return 1;
685 }
686 
687 #endif /* __included_nat_inlines_h__ */
688 
689 /*
690  * fd.io coding-style-patch-verification: ON
691  *
692  * Local Variables:
693  * eval: (c-set-style "gnu")
694  * End:
695  */
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:594
#define nat_buffer_opaque(b)
Definition: nat.h:73
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
Definition: nat.h:763
u32 sessions_per_user_list_head_index
Definition: nat.h:351
End of options.
Definition: tcp_packet.h:104
#define NAT44_SES_I2O_FIN
Definition: nat.h:274
u32 icmp_timeout
Definition: nat.h:679
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:390
#define TCP_FLAG_SYN
Definition: fa_node.h:13
static_always_inline int get_icmp_i2o_ed_key(ip4_header_t *ip0, nat_ed_ses_key_t *p_key0)
Definition: nat_inlines.h:469
u32 nsessions
Definition: nat.h:352
static_always_inline u8 icmp_is_error_message(icmp46_header_t *icmp)
Definition: nat_inlines.h:174
#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:278
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:454
#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:189
u32 nstaticsessions
Definition: nat.h:353
u16 vlib_error_t
Definition: error.h:43
int i
uword ip_csum_t
Definition: ip_packet.h:219
u8 data[128]
Definition: ipsec.api:251
u32 fib_index
Definition: nat.h:350
#define nat44_is_ses_closed(s)
Check if NAT44 endpoint-dependent TCP session is closed.
Definition: nat.h:817
#define NAT44_SES_O2I_FIN
Definition: nat.h:275
No operation.
Definition: tcp_packet.h:105
dlist_elt_t * list_pool
Definition: nat.h:514
struct _tcp_header tcp_header_t
vhost_vring_addr_t addr
Definition: vhost_user.h:147
unsigned char u8
Definition: types.h:56
static int nat44_set_tcp_session_state_o2i(snat_main_t *sm, snat_session_t *ses, tcp_header_t *tcp, u32 thread_index)
Definition: nat_inlines.h:358
u16 l_port
Definition: nat.h:110
double f64
Definition: types.h:142
clib_bihash_8_8_t user_hash
Definition: nat.h:505
u32 cached_sw_if_index
Definition: nat.h:713
u32 next_index
Definition: nat.h:70
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:631
u32 max_translations_per_user
Definition: nat.h:669
Limit MSS.
Definition: tcp_packet.h:106
#define static_always_inline
Definition: clib.h:100
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
static_always_inline int get_icmp_o2i_ed_key(ip4_header_t *ip0, nat_ed_ses_key_t *p_key0)
Definition: nat_inlines.h:519
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
u16 r_port
Definition: nat.h:111
#define always_inline
Definition: clib.h:99
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:349
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
#define SNAT_SESSION_FLAG_OUTPUT_FEATURE
Definition: nat.h:290
#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:66
#define NAT44_SES_RST
Definition: nat.h:280
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
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:568
u32 fib_index
Definition: nat.h:109
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
u32 fib_index
Definition: nat.h:372
u16 mss_value_net
Definition: nat.h:683
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:94
u8 out2in_dpo
Definition: nat.h:662
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
u32 udp_timeout
Definition: nat.h:676
#define PREDICT_FALSE(x)
Definition: clib.h:112
#define TCP_FLAG_FIN
Definition: fa_node.h:12
u16 port
Definition: punt.api:40
#define NAT44_SES_O2I_SYN
Definition: nat.h:279
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
#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:1466
u64 value
the value
Definition: bihash_8_8.h:36
snat_user_t * users
Definition: nat.h:508
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
vlib_main_t * vm
Definition: buffer.c:323
ip4_address_t l_addr
Definition: nat.h:107
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:413
u8 data[]
Packet data.
Definition: buffer.h:181
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:92
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 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:437
u32 tcp_transitory_timeout
Definition: nat.h:678
ip4_address_t r_addr
Definition: nat.h:108
static int nat44_set_tcp_session_state_i2o(snat_main_t *sm, snat_session_t *ses, tcp_header_t *tcp, u32 thread_index)
Set TCP session state.
Definition: nat_inlines.h:325
ip_proto
Definition: ip_types.api:63
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:53
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:311
#define tcp_syn(_th)
Definition: tcp_packet.h:80
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:427
u64 as_u64
Definition: nat.h:142
ip4_address_t addr
Definition: nat.h:139
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
Definition: dlist.h:99
#define NAT44_SES_I2O_SYN
Definition: nat.h:278
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
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:564
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:191
typedef key
Definition: ipsec.api:247
#define ip_csum_update(sum, old, new, type, field)
Definition: ip_packet.h:269
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:140
#define NAT44_SES_I2O_FIN_ACK
Definition: nat.h:276
#define vec_foreach(var, vec)
Vector iterator.
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:277
vlib_simple_counter_main_t total_sessions
Definition: nat.h:687
snat_session_t * sessions
Definition: nat.h:511
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:576
NAT active-passive HA.
u16 fib_index
Definition: nat.h:94
vl_api_fib_path_nh_proto_t proto
Definition: fib_types.api:125
u32 tcp_established_timeout
Definition: nat.h:677
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128