FD.io VPP  v21.01.1
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 
28 {
29  ASSERT (fib_index <= (1 << 14) - 1);
30  ASSERT (proto <= (1 << 3) - 1);
31  return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 |
32  (proto & 0x7);
33 }
34 
35 always_inline void
37  u32 * fib_index, nat_protocol_t * proto)
38 {
39  if (addr)
40  {
41  addr->as_u32 = key >> 32;
42  }
43  if (port)
44  {
45  *port = (key >> 16) & (u16) ~ 0;
46  }
47  if (fib_index)
48  {
49  *fib_index = key >> 3 & ((1 << 13) - 1);
50  }
51  if (proto)
52  {
53  *proto = key & 0x7;
54  }
55 }
56 
57 always_inline void
59  u32 fib_index, nat_protocol_t proto)
60 {
61  kv->key = calc_nat_key (addr, port, fib_index, proto);
62  kv->value = ~0ULL;
63 }
64 
65 always_inline void
67  u32 fib_index, nat_protocol_t proto, u64 value)
68 {
69  init_nat_k (kv, addr, port, fib_index, proto);
70  kv->value = value;
71 }
72 
73 always_inline void
74 init_nat_i2o_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s)
75 {
76  return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
77  s->nat_proto);
78 }
79 
80 always_inline void
81 init_nat_i2o_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value)
82 {
83  init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
84  s->nat_proto);
85  kv->value = value;
86 }
87 
88 always_inline void
89 init_nat_o2i_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s)
90 {
91  return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
92  s->nat_proto);
93 }
94 
95 always_inline void
96 init_nat_o2i_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value)
97 {
98  init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
99  s->nat_proto);
100  kv->value = value;
101 }
102 
103 static inline uword
106  vlib_frame_t * frame, u32 def_next)
107 {
108  u32 n_left_from, *from;
109 
110  from = vlib_frame_vector_args (frame);
111  n_left_from = frame->n_vectors;
112 
113  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
114  u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
115  vlib_get_buffers (vm, from, b, n_left_from);
116 
117  while (n_left_from >= 2)
118  {
119  u32 next0, next1;
120  u32 arc_next0, arc_next1;
121  vlib_buffer_t *b0, *b1;
122 
123  b0 = *b;
124  b++;
125  b1 = *b;
126  b++;
127 
128  /* Prefetch next iteration. */
129  if (PREDICT_TRUE (n_left_from >= 4))
130  {
131  vlib_buffer_t *p2, *p3;
132 
133  p2 = *b;
134  p3 = *(b + 1);
135 
136  vlib_prefetch_buffer_header (p2, LOAD);
137  vlib_prefetch_buffer_header (p3, LOAD);
138 
141  }
142 
143  next0 = def_next;
144  next1 = def_next;
145 
146  vnet_feature_next (&arc_next0, b0);
147  vnet_feature_next (&arc_next1, b1);
148 
149  vnet_buffer2 (b0)->nat.arc_next = arc_next0;
150  vnet_buffer2 (b1)->nat.arc_next = arc_next1;
151 
152  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
153  {
154  if (b0->flags & VLIB_BUFFER_IS_TRACED)
155  {
156  nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
157  t->next_index = next0;
158  t->arc_next_index = arc_next0;
159  }
160  if (b1->flags & VLIB_BUFFER_IS_TRACED)
161  {
162  nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
163  t->next_index = next1;
164  t->arc_next_index = arc_next1;
165  }
166  }
167 
168  n_left_from -= 2;
169  next[0] = next0;
170  next[1] = next1;
171  next += 2;
172  }
173 
174  while (n_left_from > 0)
175  {
176  u32 next0;
177  u32 arc_next0;
178  vlib_buffer_t *b0;
179 
180  b0 = *b;
181  b++;
182 
183  next0 = def_next;
184  vnet_feature_next (&arc_next0, b0);
185  vnet_buffer2 (b0)->nat.arc_next = arc_next0;
186 
188  && (b0->flags & VLIB_BUFFER_IS_TRACED)))
189  {
190  nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
191  t->next_index = next0;
192  t->arc_next_index = arc_next0;
193  }
194 
195  n_left_from--;
196  next[0] = next0;
197  next++;
198  }
199  vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
200  frame->n_vectors);
201 
202  return frame->n_vectors;
203 }
204 
207  u32 sw_if_index0, u32 ip4_addr)
208 {
210  ip4_address_t *first_int_addr;
211 
212  if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
213  {
214  first_int_addr =
215  ip4_interface_first_address (sm->ip4_main, sw_if_index0,
216  0 /* just want the address */ );
217  rt->cached_sw_if_index = sw_if_index0;
218  if (first_int_addr)
219  rt->cached_ip4_address = first_int_addr->as_u32;
220  else
221  rt->cached_ip4_address = 0;
222  }
223 
224  if (PREDICT_FALSE (ip4_addr == rt->cached_ip4_address))
225  return 1;
226  else
227  return 0;
228 }
229 
230 always_inline void
232 {
234  {
235  if (is_static)
236  u->nstaticsessions++;
237  else
238  u->nsessions++;
239  }
240 }
241 
242 always_inline void
244  u32 thread_index)
245 {
247  snat_user_key_t u_key;
249  thread_index);
250 
251  if (u->nstaticsessions == 0 && u->nsessions == 0)
252  {
253  u_key.addr.as_u32 = u->addr.as_u32;
254  u_key.fib_index = u->fib_index;
255  kv.key = u_key.as_u64;
257  pool_put (tsm->users, u);
258  clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 0);
259  vlib_set_simple_counter (&sm->total_users, thread_index, 0,
260  pool_elts (tsm->users));
261  }
262 }
263 
264 always_inline void
265 nat44_delete_session (snat_main_t * sm, snat_session_t * ses,
266  u32 thread_index)
267 {
269  thread_index);
271  snat_user_t *u;
272  const snat_user_key_t u_key = {
273  .addr = ses->in2out.addr,
274  .fib_index = ses->in2out.fib_index
275  };
276  const u8 u_static = snat_is_session_static (ses);
277 
278  clib_dlist_remove (tsm->list_pool, ses->per_user_index);
279  pool_put_index (tsm->list_pool, ses->per_user_index);
280  if (sm->endpoint_dependent)
281  {
282  clib_dlist_remove (tsm->lru_pool, ses->lru_index);
283  pool_put_index (tsm->lru_pool, ses->lru_index);
284  }
285  pool_put (tsm->sessions, ses);
286  vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
287  pool_elts (tsm->sessions));
288 
289  kv.key = u_key.as_u64;
290  if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
291  {
292  u = pool_elt_at_index (tsm->users, value.value);
293  if (u_static)
294  u->nstaticsessions--;
295  else
296  u->nsessions--;
297 
298  nat44_delete_user_with_no_session (sm, u, thread_index);
299  }
300 }
301 
302 always_inline void
304  snat_session_t * ses, vlib_buffer_t * b,
305  u32 thread_index)
306 {
307  snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
308  u8 tcp_flags = vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags;
309  u32 tcp_ack_number = vnet_buffer (b)->ip.reass.tcp_ack_number;
310  u32 tcp_seq_number = vnet_buffer (b)->ip.reass.tcp_seq_number;
311  if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
312  ses->state = NAT44_SES_RST;
313  if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
314  ses->state = 0;
315  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
316  (ses->state & NAT44_SES_O2I_SYN))
317  ses->state = 0;
318  if (tcp_flags & TCP_FLAG_SYN)
319  ses->state |= NAT44_SES_I2O_SYN;
320  if (tcp_flags & TCP_FLAG_FIN)
321  {
322  ses->i2o_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
323  ses->state |= NAT44_SES_I2O_FIN;
324  }
325  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_O2I_FIN))
326  {
327  if (clib_net_to_host_u32 (tcp_ack_number) > ses->o2i_fin_seq)
328  {
329  ses->state |= NAT44_SES_O2I_FIN_ACK;
330  if (nat44_is_ses_closed (ses))
331  { // if session is now closed, save the timestamp
332  ses->tcp_closed_timestamp = now + sm->timeouts.tcp.transitory;
333  ses->last_lru_update = now;
334  }
335  }
336  }
337 
338  // move the session to proper LRU
339  if (ses->state)
340  {
341  ses->lru_head_index = tsm->tcp_trans_lru_head_index;
342  }
343  else
344  {
345  ses->lru_head_index = tsm->tcp_estab_lru_head_index;
346  }
347  clib_dlist_remove (tsm->lru_pool, ses->lru_index);
348  clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index);
349 }
350 
351 always_inline void
353  snat_session_t * ses, u8 tcp_flags,
354  u32 tcp_ack_number, u32 tcp_seq_number,
355  u32 thread_index)
356 {
357  snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
358  if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
359  ses->state = NAT44_SES_RST;
360  if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
361  ses->state = 0;
362  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
363  (ses->state & NAT44_SES_O2I_SYN))
364  ses->state = 0;
365  if (tcp_flags & TCP_FLAG_SYN)
366  ses->state |= NAT44_SES_O2I_SYN;
367  if (tcp_flags & TCP_FLAG_FIN)
368  {
369  ses->o2i_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
370  ses->state |= NAT44_SES_O2I_FIN;
371  }
372  if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_FIN))
373  {
374  if (clib_net_to_host_u32 (tcp_ack_number) > ses->i2o_fin_seq)
375  ses->state |= NAT44_SES_I2O_FIN_ACK;
376  if (nat44_is_ses_closed (ses))
377  { // if session is now closed, save the timestamp
378  ses->tcp_closed_timestamp = now + sm->timeouts.tcp.transitory;
379  ses->last_lru_update = now;
380  }
381  }
382  // move the session to proper LRU
383  if (ses->state)
384  {
385  ses->lru_head_index = tsm->tcp_trans_lru_head_index;
386  }
387  else
388  {
389  ses->lru_head_index = tsm->tcp_estab_lru_head_index;
390  }
391  clib_dlist_remove (tsm->lru_pool, ses->lru_index);
392  clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index);
393 }
394 
396 nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s)
397 {
398  switch (s->nat_proto)
399  {
400  case NAT_PROTOCOL_ICMP:
401  return sm->timeouts.icmp;
402  case NAT_PROTOCOL_UDP:
403  return sm->timeouts.udp;
404  case NAT_PROTOCOL_TCP:
405  {
406  if (s->state)
407  return sm->timeouts.tcp.transitory;
408  else
409  return sm->timeouts.tcp.established;
410  }
411  default:
412  return sm->timeouts.udp;
413  }
414 
415  return 0;
416 }
417 
418 always_inline void
419 nat44_session_update_counters (snat_session_t * s, f64 now, uword bytes,
420  u32 thread_index)
421 {
422  s->last_heard = now;
423  s->total_pkts++;
424  s->total_bytes += bytes;
425  nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
426  s->ext_host_port, s->nat_proto, s->out2in.fib_index,
427  s->total_pkts, s->total_bytes, thread_index,
428  &s->ha_last_refreshed, now);
429 }
430 
431 /** \brief Per-user LRU list maintenance */
432 always_inline void
433 nat44_session_update_lru (snat_main_t * sm, snat_session_t * s,
434  u32 thread_index)
435 {
436  /* don't update too often - timeout is in magnitude of seconds anyway */
437  if (s->last_heard > s->last_lru_update + 1)
438  {
439  if (!sm->endpoint_dependent)
440  {
441  clib_dlist_remove (sm->per_thread_data[thread_index].list_pool,
442  s->per_user_index);
443  clib_dlist_addtail (sm->per_thread_data[thread_index].list_pool,
444  s->per_user_list_head_index, s->per_user_index);
445  }
446  else
447  {
448  clib_dlist_remove (sm->per_thread_data[thread_index].lru_pool,
449  s->lru_index);
450  clib_dlist_addtail (sm->per_thread_data[thread_index].lru_pool,
451  s->lru_head_index, s->lru_index);
452  }
453  s->last_lru_update = s->last_heard;
454  }
455 }
456 
457 always_inline void
459  ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
460 {
461  kv->key[0] = (u64) r_addr.as_u32 << 32 | l_addr.as_u32;
462  kv->key[1] =
463  (u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto;
464 }
465 
466 always_inline void
468  ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto,
469  u32 thread_index, u32 session_index)
470 {
471  init_ed_k (kv, l_addr, l_port, r_addr, r_port, fib_index, proto);
472  kv->value = (u64) thread_index << 32 | session_index;
473 }
474 
477 {
478  return value->value >> 32;
479 }
480 
483 {
484  return value->value & ~(u32) 0;
485 }
486 
487 always_inline void
489  ip4_address_t * l_addr, ip4_address_t * r_addr, u8 * proto,
490  u32 * fib_index, u16 * l_port, u16 * r_port)
491 {
492  if (l_addr)
493  {
494  l_addr->as_u32 = kv->key[0] & (u32) ~ 0;
495  }
496  if (r_addr)
497  {
498  r_addr->as_u32 = kv->key[0] >> 32;
499  }
500  if (r_port)
501  {
502  *r_port = kv->key[1] >> 48;
503  }
504  if (l_port)
505  {
506  *l_port = (kv->key[1] >> 32) & (u16) ~ 0;
507  }
508  if (fib_index)
509  {
510  *fib_index = (kv->key[1] >> 8) & ((1 << 24) - 1);
511  }
512  if (proto)
513  {
514  *proto = kv->key[1] & (u8) ~ 0;
515  }
516 }
517 
520  u32 thread_index, u32 session_index,
521  nat_protocol_t * nat_proto, u16 * l_port, u16 * r_port,
523 {
524  u8 proto;
525  u16 _l_port, _r_port;
526  ip4_address_t *l_addr, *r_addr;
527 
528  icmp46_header_t *icmp0;
529  icmp_echo_header_t *echo0, *inner_echo0 = 0;
530  ip4_header_t *inner_ip0 = 0;
531  void *l4_header = 0;
532  icmp46_header_t *inner_icmp0;
533 
534  icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
535  echo0 = (icmp_echo_header_t *) (icmp0 + 1);
536 
538  (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
539  {
540  proto = IP_PROTOCOL_ICMP;
541  l_addr = &ip0->src_address;
542  r_addr = &ip0->dst_address;
543  _l_port = vnet_buffer (b)->ip.reass.l4_src_port;
544  _r_port = 0;
545  }
546  else
547  {
548  inner_ip0 = (ip4_header_t *) (echo0 + 1);
549  l4_header = ip4_next_header (inner_ip0);
550  proto = inner_ip0->protocol;
551  r_addr = &inner_ip0->src_address;
552  l_addr = &inner_ip0->dst_address;
553  switch (ip_proto_to_nat_proto (inner_ip0->protocol))
554  {
555  case NAT_PROTOCOL_ICMP:
556  inner_icmp0 = (icmp46_header_t *) l4_header;
557  inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
558  _r_port = 0;
559  _l_port = inner_echo0->identifier;
560  break;
561  case NAT_PROTOCOL_UDP:
562  case NAT_PROTOCOL_TCP:
563  _l_port = ((tcp_udp_header_t *) l4_header)->dst_port;
564  _r_port = ((tcp_udp_header_t *) l4_header)->src_port;
565  break;
566  default:
567  return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
568  }
569  }
570  init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto,
571  thread_index, session_index);
572  if (nat_proto)
573  {
574  *nat_proto = ip_proto_to_nat_proto (proto);
575  }
576  if (l_port)
577  {
578  *l_port = _l_port;
579  }
580  if (r_port)
581  {
582  *r_port = _r_port;
583  }
584  return 0;
585 }
586 
589  u32 thread_index, u32 session_index,
590  nat_protocol_t * nat_proto, u16 * l_port, u16 * r_port,
592 {
593  icmp46_header_t *icmp0;
594  u8 proto;
595  ip4_address_t *l_addr, *r_addr;
596  u16 _l_port, _r_port;
597  icmp_echo_header_t *echo0, *inner_echo0 = 0;
598  ip4_header_t *inner_ip0;
599  void *l4_header = 0;
600  icmp46_header_t *inner_icmp0;
601 
602  icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
603  echo0 = (icmp_echo_header_t *) (icmp0 + 1);
604 
606  (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
607  {
608  proto = IP_PROTOCOL_ICMP;
609  l_addr = &ip0->dst_address;
610  r_addr = &ip0->src_address;
611  _l_port = vnet_buffer (b)->ip.reass.l4_src_port;
612  _r_port = 0;
613  }
614  else
615  {
616  inner_ip0 = (ip4_header_t *) (echo0 + 1);
617  l4_header = ip4_next_header (inner_ip0);
618  proto = inner_ip0->protocol;
619  l_addr = &inner_ip0->src_address;
620  r_addr = &inner_ip0->dst_address;
621  switch (ip_proto_to_nat_proto (inner_ip0->protocol))
622  {
623  case NAT_PROTOCOL_ICMP:
624  inner_icmp0 = (icmp46_header_t *) l4_header;
625  inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
626  _l_port = inner_echo0->identifier;
627  _r_port = 0;
628  break;
629  case NAT_PROTOCOL_UDP:
630  case NAT_PROTOCOL_TCP:
631  _l_port = ((tcp_udp_header_t *) l4_header)->src_port;
632  _r_port = ((tcp_udp_header_t *) l4_header)->dst_port;
633  break;
634  default:
635  return -1;
636  }
637  }
638  init_ed_kv (kv, *l_addr, _l_port, *r_addr, _r_port, rx_fib_index, proto,
639  thread_index, session_index);
640  if (nat_proto)
641  {
642  *nat_proto = ip_proto_to_nat_proto (proto);
643  }
644  if (l_port)
645  {
646  *l_port = _l_port;
647  }
648  if (r_port)
649  {
650  *r_port = _r_port;
651  }
652  return 0;
653 }
654 
655 /**
656  * @brief Check if packet should be translated
657  *
658  * Packets aimed at outside interface and external address with active session
659  * should be translated.
660  *
661  * @param sm NAT main
662  * @param rt NAT runtime data
663  * @param sw_if_index0 index of the inside interface
664  * @param ip0 IPv4 header
665  * @param proto0 NAT protocol
666  * @param rx_fib_index0 RX FIB index
667  *
668  * @returns 0 if packet should be translated otherwise 1
669  */
670 static inline int
672  u32 sw_if_index0, ip4_header_t * ip0, u32 proto0,
673  u32 rx_fib_index0)
674 {
675  if (sm->out2in_dpo)
676  return 0;
677 
679  nat_outside_fib_t *outside_fib;
680  fib_prefix_t pfx = {
682  .fp_len = 32,
683  .fp_addr = {
684  .ip4.as_u32 = ip0->dst_address.as_u32,
685  }
686  ,
687  };
688 
689  /* Don't NAT packet aimed at the intfc address */
690  if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
691  ip0->dst_address.as_u32)))
692  return 1;
693 
694  fei = fib_table_lookup (rx_fib_index0, &pfx);
695  if (FIB_NODE_INDEX_INVALID != fei)
696  {
698  if (sw_if_index == ~0)
699  {
700  vec_foreach (outside_fib, sm->outside_fibs)
701  {
702  fei = fib_table_lookup (outside_fib->fib_index, &pfx);
703  if (FIB_NODE_INDEX_INVALID != fei)
704  {
705  sw_if_index = fib_entry_get_resolving_interface (fei);
706  if (sw_if_index != ~0)
707  break;
708  }
709  }
710  }
711  if (sw_if_index == ~0)
712  return 1;
713 
715  /* *INDENT-OFF* */
716  pool_foreach (i, sm->interfaces) {
717  /* NAT packet aimed at outside interface */
718  if ((nat_interface_is_outside (i)) && (sw_if_index == i->sw_if_index))
719  return 0;
720  }
721  /* *INDENT-ON* */
722  }
723 
724  return 1;
725 }
726 
729 {
730  snat_main_t *sm = &snat_main;
731  u32 rwide;
732  u16 r;
733 
734  rwide = random_u32 (&sm->random_seed);
735  r = rwide & 0xFFFF;
736  if (r >= min && r <= max)
737  return r;
738 
739  return min + (rwide % (max - min + 1));
740 }
741 
742 #endif /* __included_nat_inlines_h__ */
743 
744 /*
745  * fd.io coding-style-patch-verification: ON
746  *
747  * Local Variables:
748  * eval: (c-set-style "gnu")
749  * End:
750  */
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:211
nat_outside_fib_t * outside_fibs
Definition: nat.h:565
dlist_elt_t * lru_pool
Definition: nat.h:459
#define snat_is_session_static(s)
Check if SNAT session is created from static mapping.
Definition: nat.h:786
u32 sessions_per_user_list_head_index
Definition: nat.h:314
static u64 calc_nat_key(ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
The NAT inline functions.
Definition: nat_inlines.h:27
struct nat_timeouts_t::@86 tcp
u32 arc_next_index
Definition: nat.h:100
#define NAT44_SES_I2O_FIN
Definition: nat.h:200
u8 runtime_data[0]
Function dependent node-runtime data.
Definition: node.h:519
nat_timeouts_t timeouts
Definition: nat.h:653
ip4_address_t src_address
Definition: ip4_packet.h:125
#define vnet_buffer2(b)
Definition: buffer.h:481
static u32 nat44_session_get_timeout(snat_main_t *sm, snat_session_t *s)
Definition: nat_inlines.h:396
#define TCP_FLAG_SYN
Definition: fa_node.h:13
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
#define PREDICT_TRUE(x)
Definition: clib.h:122
u32 nsessions
Definition: nat.h:315
static void init_nat_i2o_kv(clib_bihash_kv_8_8_t *kv, snat_session_t *s, u64 value)
Definition: nat_inlines.h:81
unsigned long u64
Definition: types.h:89
static_always_inline int get_icmp_o2i_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index, u32 thread_index, u32 session_index, nat_protocol_t *nat_proto, u16 *l_port, u16 *r_port, clib_bihash_kv_16_8_t *kv)
Definition: nat_inlines.h:588
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:281
u32 nstaticsessions
Definition: nat.h:316
static void init_nat_i2o_k(clib_bihash_kv_8_8_t *kv, snat_session_t *s)
Definition: nat_inlines.h:74
vlib_main_t * vm
Definition: in2out_ed.c:1580
static void nat44_set_tcp_session_state_o2i(snat_main_t *sm, f64 now, snat_session_t *ses, u8 tcp_flags, u32 tcp_ack_number, u32 tcp_seq_number, u32 thread_index)
Definition: nat_inlines.h:352
u32 fib_index
Definition: nat.h:313
#define nat44_is_ses_closed(s)
Check if NAT44 endpoint-dependent TCP session is closed.
Definition: nat.h:846
#define NAT44_SES_O2I_FIN
Definition: nat.h:201
nat_protocol_t
Definition: lib.h:63
static void init_ed_kv(clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port, ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto, u32 thread_index, u32 session_index)
Definition: nat_inlines.h:467
dlist_elt_t * list_pool
Definition: nat.h:456
vhost_vring_addr_t addr
Definition: vhost_user.h:111
u32 established
Definition: lib.h:80
unsigned char u8
Definition: types.h:56
double f64
Definition: types.h:142
static void split_nat_key(u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index, nat_protocol_t *proto)
Definition: nat_inlines.h:36
clib_bihash_8_8_t user_hash
Definition: nat.h:447
u32 cached_sw_if_index
Definition: nat.h:746
u32 next_index
Definition: nat.h:99
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:737
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:671
#define nat_interface_is_outside(i)
Check if NAT interface is outside.
Definition: nat.h:840
u32 max_translations_per_user
Definition: nat.h:646
#define static_always_inline
Definition: clib.h:109
static nat_protocol_t ip_proto_to_nat_proto(u8 ip_proto)
Common NAT inline functions.
Definition: inlines.h:24
ip4_address_t dst_address
Definition: ip4_packet.h:125
static_always_inline u16 snat_random_port(u16 min, u16 max)
Definition: nat_inlines.h:728
#define TCP_FLAG_ACK
Definition: fa_node.h:16
static void nat44_set_tcp_session_state_i2o(snat_main_t *sm, f64 now, snat_session_t *ses, vlib_buffer_t *b, u32 thread_index)
Definition: nat_inlines.h:303
static void init_nat_o2i_kv(clib_bihash_kv_8_8_t *kv, snat_session_t *s, u64 value)
Definition: nat_inlines.h:96
ip4_address_t addr
Definition: nat.h:312
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:207
#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:202
static_always_inline u8 icmp_type_is_error_message(u8 icmp_type)
Definition: inlines.h:55
static void init_nat_o2i_k(clib_bihash_kv_8_8_t *kv, snat_session_t *s)
Definition: nat_inlines.h:89
static void split_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:488
const cJSON *const b
Definition: cJSON.h:255
ip4_main_t * ip4_main
Definition: nat.h:726
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:196
unsigned int u32
Definition: types.h:88
static_always_inline int get_icmp_i2o_ed_key(vlib_buffer_t *b, ip4_header_t *ip0, u32 rx_fib_index, u32 thread_index, u32 session_index, nat_protocol_t *nat_proto, u16 *l_port, u16 *r_port, clib_bihash_kv_16_8_t *kv)
Definition: nat_inlines.h:519
#define VLIB_FRAME_SIZE
Definition: node.h:378
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:206
static void nat44_delete_session(snat_main_t *sm, snat_session_t *ses, u32 thread_index)
Definition: nat_inlines.h:265
u32 transitory
Definition: lib.h:81
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
u32 fib_index
Definition: nat.h:341
vl_api_ip_proto_t proto
Definition: acl_types.api:51
u64 key
the key
Definition: bihash_8_8.h:43
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
u8 out2in_dpo
Definition: nat.h:633
static u32 ed_value_get_session_index(clib_bihash_kv_16_8_t *value)
Definition: nat_inlines.h:482
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
#define PREDICT_FALSE(x)
Definition: clib.h:121
#define always_inline
Definition: ipsec.h:28
#define TCP_FLAG_FIN
Definition: fa_node.h:12
#define NAT44_SES_O2I_SYN
Definition: nat.h:205
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:113
static void init_nat_k(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto)
Definition: nat_inlines.h:58
#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
snat_main_t snat_main
Definition: nat.c:39
u64 value
the value
Definition: bihash_8_8.h:44
snat_user_t * users
Definition: nat.h:450
static void nat44_delete_user_with_no_session(snat_main_t *sm, snat_user_t *u, u32 thread_index)
Definition: nat_inlines.h:243
u32 random_seed
Definition: nat.h:578
u16 n_vectors
Definition: node.h:397
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
Definition: buffer_node.h:339
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
static void nat44_session_update_counters(snat_session_t *s, f64 now, uword bytes, u32 thread_index)
Definition: nat_inlines.h:419
u8 data[]
Packet data.
Definition: buffer.h:181
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
static void init_nat_kv(clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, u32 fib_index, nat_protocol_t proto, u64 value)
Definition: nat_inlines.h:66
8 octet key, 8 octet key value pair
Definition: bihash_8_8.h:41
u32 sw_if_index
Definition: nat.h:414
static uword nat_pre_node_fn_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 def_next)
Definition: nat_inlines.h:104
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
u8 value
Definition: qos.api:54
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:330
#define ASSERT(truth)
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:433
u64 as_u64
Definition: nat.h:113
ip4_address_t addr
Definition: nat.h:110
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
Definition: dlist.h:99
#define NAT44_SES_I2O_SYN
Definition: nat.h:204
typedef key
Definition: ipsec_types.api:86
vlib_simple_counter_main_t total_users
Definition: nat.h:659
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
static void user_session_increment(snat_main_t *sm, snat_user_t *u, u8 is_static)
Definition: nat_inlines.h:231
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1581
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:529
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
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:206
u32 fib_index
Definition: nat.h:111
u16 port
Definition: lb_types.api:73
static void init_ed_k(clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port, ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
Definition: nat_inlines.h:458
u32 udp
Definition: lib.h:84
#define vnet_buffer(b)
Definition: buffer.h:417
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
#define NAT44_SES_I2O_FIN_ACK
Definition: nat.h:202
#define vec_foreach(var, vec)
Vector iterator.
u16 flags
Copy of main node flags.
Definition: node.h:501
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:634
u8 endpoint_dependent
Definition: nat.h:631
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:280
#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:203
vlib_simple_counter_main_t total_sessions
Definition: nat.h:660
snat_session_t * sessions
Definition: nat.h:453
u32 cached_ip4_address
Definition: nat.h:747
static u32 ed_value_get_thread_index(clib_bihash_kv_16_8_t *value)
Definition: nat_inlines.h:476
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
snat_interface_t * interfaces
Definition: nat.h:544
NAT active-passive HA.
u32 icmp
Definition: lib.h:85
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127