FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
ip6_map_t.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #include "map.h"
16 
17 #include <vnet/ip/ip4_to_ip6.h>
18 #include <vnet/ip/ip6_to_ip4.h>
19 #include <vnet/ip/ip_frag.h>
20 
21 typedef enum
22 {
29 
30 typedef enum
31 {
37 
38 typedef enum
39 {
45 
46 typedef enum
47 {
53 
54 typedef struct
55 {
59 
60 static int
62 {
63  icmp6_to_icmp_ctx_t *ctx = arg;
64  u32 ip4_sadr;
65 
66  // Security check
67  // Note that this prevents an intermediate IPv6 router from answering
68  // the request.
69  ip4_sadr = map_get_ip4 (&ip6->src_address, ctx->d->flags);
70  if (ip6->src_address.as_u64[0] !=
71  map_get_pfx_net (ctx->d, ip4_sadr, ctx->sender_port)
72  || ip6->src_address.as_u64[1] != map_get_sfx_net (ctx->d, ip4_sadr,
73  ctx->sender_port))
74  return -1;
75 
76  ip4->dst_address.as_u32 =
78  ip4->src_address.as_u32 = ip4_sadr;
79 
80  return 0;
81 }
82 
83 static int
85  void *arg)
86 {
87  icmp6_to_icmp_ctx_t *ctx = arg;
88  u32 inner_ip4_dadr;
89 
90  //Security check of inner packet
91  inner_ip4_dadr = map_get_ip4 (&ip6->dst_address, ctx->d->flags);
92  if (ip6->dst_address.as_u64[0] !=
93  map_get_pfx_net (ctx->d, inner_ip4_dadr, ctx->sender_port)
94  || ip6->dst_address.as_u64[1] != map_get_sfx_net (ctx->d,
95  inner_ip4_dadr,
96  ctx->sender_port))
97  return -1;
98 
99  ip4->dst_address.as_u32 = inner_ip4_dadr;
100  ip4->src_address.as_u32 =
102 
103  return 0;
104 }
105 
106 static uword
109 {
110  u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
111  vlib_node_runtime_t *error_node =
113  from = vlib_frame_vector_args (frame);
114  n_left_from = frame->n_vectors;
115  next_index = node->cached_next_index;
117  u32 thread_index = vm->thread_index;
118 
119  while (n_left_from > 0)
120  {
121  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
122 
123  while (n_left_from > 0 && n_left_to_next > 0)
124  {
125  u32 pi0;
126  vlib_buffer_t *p0;
127  u8 error0;
128  ip6_mapt_icmp_next_t next0;
129  map_domain_t *d0;
130  u16 len0;
131  icmp6_to_icmp_ctx_t ctx0;
132  ip6_header_t *ip60;
133 
134  pi0 = to_next[0] = from[0];
135  from += 1;
136  n_left_from -= 1;
137  to_next += 1;
138  n_left_to_next -= 1;
139  error0 = MAP_ERROR_NONE;
141 
142  p0 = vlib_get_buffer (vm, pi0);
143  ip60 = vlib_buffer_get_current (p0);
144  len0 = clib_net_to_host_u16 (ip60->payload_length);
145  d0 =
147  vnet_buffer (p0)->map_t.map_domain_index);
148  ctx0.d = d0;
149  ctx0.sender_port = 0;
150  if (!ip6_get_port
151  (vm, p0, ip60, p0->current_length, NULL, &ctx0.sender_port,
152  NULL, NULL, NULL, NULL))
153  {
154  // In case of 1:1 mapping, we don't care about the port
155  if (!(d0->ea_bits_len == 0 && d0->rules))
156  {
157  error0 = MAP_ERROR_ICMP;
158  goto err0;
159  }
160  }
161 
162  if (icmp6_to_icmp (vm, p0, ip6_to_ip4_set_icmp_cb, &ctx0,
164  {
165  error0 = MAP_ERROR_ICMP;
166  goto err0;
167  }
168 
169  if (vnet_buffer (p0)->map_t.mtu < p0->current_length)
170  {
171  // Send to fragmentation node if necessary
172  vnet_buffer (p0)->ip_frag.mtu = vnet_buffer (p0)->map_t.mtu;
173  vnet_buffer (p0)->ip_frag.next_index = IP_FRAG_NEXT_IP4_LOOKUP;
175  }
176  err0:
177  if (PREDICT_TRUE (error0 == MAP_ERROR_NONE))
178  {
180  thread_index,
181  vnet_buffer (p0)->
182  map_t.map_domain_index, 1,
183  len0);
184  }
185  else
186  {
187  next0 = IP6_MAPT_ICMP_NEXT_DROP;
188  }
189 
190  p0->error = error_node->errors[error0];
191  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
192  to_next, n_left_to_next, pi0,
193  next0);
194  }
195  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
196  }
197  return frame->n_vectors;
198 }
199 
200 /*
201  * Translate IPv6 fragmented packet to IPv4.
202  */
203 always_inline int
205 {
206  ip6_header_t *ip6;
207  ip6_frag_hdr_t *frag;
208  ip4_header_t *ip4;
209  u16 frag_id;
210  u8 frag_more;
211  u16 frag_offset;
212  u8 l4_protocol;
213  u16 l4_offset;
214 
215  ip6 = vlib_buffer_get_current (p);
216 
217  if (ip6_parse
218  (vm, p, ip6, p->current_length, &l4_protocol, &l4_offset, &frag_offset))
219  return -1;
220 
221  frag = (ip6_frag_hdr_t *) u8_ptr_add (ip6, frag_offset);
222  ip4 = (ip4_header_t *) u8_ptr_add (ip6, l4_offset - sizeof (*ip4));
223  vlib_buffer_advance (p, l4_offset - sizeof (*ip4));
224 
225  frag_id = frag_id_6to4 (frag->identification);
226  frag_more = ip6_frag_hdr_more (frag);
227  frag_offset = ip6_frag_hdr_offset (frag);
228 
229  ip4->dst_address.as_u32 = vnet_buffer (p)->map_t.v6.daddr;
230  ip4->src_address.as_u32 = vnet_buffer (p)->map_t.v6.saddr;
231 
235  ip4->length =
237  sizeof (*ip4) - l4_offset + sizeof (*ip6));
238  ip4->fragment_id = frag_id;
240  clib_host_to_net_u16 (frag_offset |
241  (frag_more ? IP4_HEADER_FLAG_MORE_FRAGMENTS : 0));
242  ip4->ttl = ip6->hop_limit;
243  ip4->protocol =
244  (l4_protocol == IP_PROTOCOL_ICMP6) ? IP_PROTOCOL_ICMP : l4_protocol;
245  ip4->checksum = ip4_header_checksum (ip4);
246 
247  return 0;
248 }
249 
250 static uword
253 {
254  u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
255  from = vlib_frame_vector_args (frame);
256  n_left_from = frame->n_vectors;
257  next_index = node->cached_next_index;
258  vlib_node_runtime_t *error_node =
260 
261  while (n_left_from > 0)
262  {
263  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
264 
265  while (n_left_from > 0 && n_left_to_next > 0)
266  {
267  u32 pi0;
268  vlib_buffer_t *p0;
269  u32 next0;
270 
271  pi0 = to_next[0] = from[0];
272  from += 1;
273  n_left_from -= 1;
274  to_next += 1;
275  n_left_to_next -= 1;
276 
278  p0 = vlib_get_buffer (vm, pi0);
279 
280  if (map_ip6_to_ip4_fragmented (vm, p0))
281  {
282  p0->error = error_node->errors[MAP_ERROR_FRAGMENT_DROPPED];
284  }
285  else
286  {
287  if (vnet_buffer (p0)->map_t.mtu < p0->current_length)
288  {
289  // Send to fragmentation node if necessary
290  vnet_buffer (p0)->ip_frag.mtu = vnet_buffer (p0)->map_t.mtu;
291  vnet_buffer (p0)->ip_frag.next_index =
294  }
295  }
296 
297  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
298  to_next, n_left_to_next, pi0,
299  next0);
300  }
301  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
302  }
303  return frame->n_vectors;
304 }
305 
306 /*
307  * Translate IPv6 UDP/TCP packet to IPv4.
308  */
309 always_inline int
311  bool udp_checksum)
312 {
313  map_main_t *mm = &map_main;
314  ip6_header_t *ip6;
315  u16 *checksum;
316  ip_csum_t csum = 0;
317  ip4_header_t *ip4;
318  u16 fragment_id;
319  u16 flags;
320  u16 frag_offset;
321  u8 l4_protocol;
322  u16 l4_offset;
323  ip6_address_t old_src, old_dst;
324 
325  ip6 = vlib_buffer_get_current (p);
326 
327  if (ip6_parse
328  (vm, p, ip6, p->current_length, &l4_protocol, &l4_offset, &frag_offset))
329  return -1;
330 
331  if (l4_protocol == IP_PROTOCOL_TCP)
332  {
333  tcp_header_t *tcp = ip6_next_header (ip6);
334  if (mm->tcp_mss > 0)
335  {
336  csum = tcp->checksum;
337  map_mss_clamping (tcp, &csum, mm->tcp_mss);
338  tcp->checksum = ip_csum_fold (csum);
339  }
340  checksum = &tcp->checksum;
341  }
342  else
343  {
344  udp_header_t *udp = ip6_next_header (ip6);
345  checksum = &udp->checksum;
346  }
347 
348  old_src.as_u64[0] = ip6->src_address.as_u64[0];
349  old_src.as_u64[1] = ip6->src_address.as_u64[1];
350  old_dst.as_u64[0] = ip6->dst_address.as_u64[0];
351  old_dst.as_u64[1] = ip6->dst_address.as_u64[1];
352 
353  ip4 = (ip4_header_t *) u8_ptr_add (ip6, l4_offset - sizeof (*ip4));
354 
355  vlib_buffer_advance (p, l4_offset - sizeof (*ip4));
356 
357  if (PREDICT_FALSE (frag_offset))
358  {
359  // Only the first fragment
360  ip6_frag_hdr_t *hdr = (ip6_frag_hdr_t *) u8_ptr_add (ip6, frag_offset);
361  fragment_id = frag_id_6to4 (hdr->identification);
362  flags = clib_host_to_net_u16 (IP4_HEADER_FLAG_MORE_FRAGMENTS);
363  }
364  else
365  {
366  fragment_id = 0;
367  flags = 0;
368  }
369 
370  ip4->dst_address.as_u32 = vnet_buffer (p)->map_t.v6.daddr;
371  ip4->src_address.as_u32 = vnet_buffer (p)->map_t.v6.saddr;
372 
376  ip4->length =
378  sizeof (*ip4) + sizeof (*ip6) - l4_offset);
379  ip4->fragment_id = fragment_id;
381  ip4->ttl = ip6->hop_limit;
382  ip4->protocol = l4_protocol;
383  ip4->checksum = ip4_header_checksum (ip4);
384 
385  // UDP checksum is optional over IPv4
386  if (!udp_checksum && l4_protocol == IP_PROTOCOL_UDP)
387  {
388  *checksum = 0;
389  }
390  else
391  {
392  csum = ip_csum_sub_even (*checksum, old_src.as_u64[0]);
393  csum = ip_csum_sub_even (csum, old_src.as_u64[1]);
394  csum = ip_csum_sub_even (csum, old_dst.as_u64[0]);
395  csum = ip_csum_sub_even (csum, old_dst.as_u64[1]);
396  csum = ip_csum_add_even (csum, ip4->dst_address.as_u32);
397  csum = ip_csum_add_even (csum, ip4->src_address.as_u32);
398  *checksum = ip_csum_fold (csum);
399  }
400 
401  return 0;
402 }
403 
404 static uword
407 {
408  u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
409  vlib_node_runtime_t *error_node =
411 
412  from = vlib_frame_vector_args (frame);
413  n_left_from = frame->n_vectors;
414  next_index = node->cached_next_index;
415  while (n_left_from > 0)
416  {
417  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
418 
419  while (n_left_from > 0 && n_left_to_next > 0)
420  {
421  u32 pi0;
422  vlib_buffer_t *p0;
424 
425  pi0 = to_next[0] = from[0];
426  from += 1;
427  n_left_from -= 1;
428  to_next += 1;
429  n_left_to_next -= 1;
431 
432  p0 = vlib_get_buffer (vm, pi0);
433 
434  if (map_ip6_to_ip4_tcp_udp (vm, p0, true))
435  {
436  p0->error = error_node->errors[MAP_ERROR_UNKNOWN];
438  }
439  else
440  {
441  if (vnet_buffer (p0)->map_t.mtu < p0->current_length)
442  {
443  // Send to fragmentation node if necessary
444  vnet_buffer (p0)->ip_frag.mtu = vnet_buffer (p0)->map_t.mtu;
445  vnet_buffer (p0)->ip_frag.next_index =
448  }
449  }
450 
451  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
452  to_next, n_left_to_next, pi0,
453  next0);
454  }
455  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
456  }
457  return frame->n_vectors;
458 }
459 
460 static uword
462 {
463  u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
464  vlib_node_runtime_t *error_node =
467  u32 thread_index = vm->thread_index;
468 
469  from = vlib_frame_vector_args (frame);
470  n_left_from = frame->n_vectors;
471  next_index = node->cached_next_index;
472  while (n_left_from > 0)
473  {
474  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
475 
476  while (n_left_from > 0 && n_left_to_next > 0)
477  {
478  u32 pi0;
479  vlib_buffer_t *p0;
480  ip6_header_t *ip60;
481  u8 error0;
482  u32 l4_len0;
483  i32 map_port0;
484  map_domain_t *d0;
485  ip6_frag_hdr_t *frag0;
486  ip6_mapt_next_t next0 = 0;
487  u32 saddr;
488 
489  pi0 = to_next[0] = from[0];
490  from += 1;
491  n_left_from -= 1;
492  to_next += 1;
493  n_left_to_next -= 1;
494  error0 = MAP_ERROR_NONE;
495  p0 = vlib_get_buffer (vm, pi0);
496  u16 l4_src_port = vnet_buffer (p0)->ip.reass.l4_src_port;
497 
498  ip60 = vlib_buffer_get_current (p0);
499 
500  d0 =
502  &vnet_buffer (p0)->map_t.map_domain_index,
503  &error0);
504  if (!d0)
505  { /* Guess it wasn't for us */
506  vnet_feature_next (&next0, p0);
507  goto exit;
508  }
509 
510  saddr = map_get_ip4 (&ip60->src_address, d0->ip6_src_len);
511  vnet_buffer (p0)->map_t.v6.saddr = saddr;
512  vnet_buffer (p0)->map_t.v6.daddr =
514  vnet_buffer (p0)->map_t.mtu = d0->mtu ? d0->mtu : ~0;
515 
516  if (PREDICT_FALSE
517  (ip6_parse (vm, p0, ip60, p0->current_length,
518  &(vnet_buffer (p0)->map_t.v6.l4_protocol),
519  &(vnet_buffer (p0)->map_t.v6.l4_offset),
520  &(vnet_buffer (p0)->map_t.v6.frag_offset))))
521  {
522  error0 =
523  error0 == MAP_ERROR_NONE ? MAP_ERROR_MALFORMED : error0;
524  }
525 
526  map_port0 = -1;
527  l4_len0 =
528  (u32) clib_net_to_host_u16 (ip60->payload_length) +
529  sizeof (*ip60) - vnet_buffer (p0)->map_t.v6.l4_offset;
530  frag0 =
531  (ip6_frag_hdr_t *) u8_ptr_add (ip60,
532  vnet_buffer (p0)->map_t.v6.
533  frag_offset);
534 
535  if (PREDICT_FALSE
536  (vnet_buffer (p0)->map_t.v6.frag_offset
537  && ip6_frag_hdr_offset (frag0)))
538  {
539  map_port0 = l4_src_port;
541  }
542  else
543  if (PREDICT_TRUE
544  (vnet_buffer (p0)->map_t.v6.l4_protocol == IP_PROTOCOL_TCP))
545  {
546  error0 =
547  l4_len0 <
548  sizeof (tcp_header_t) ? MAP_ERROR_MALFORMED : error0;
549  vnet_buffer (p0)->map_t.checksum_offset =
550  vnet_buffer (p0)->map_t.v6.l4_offset + 16;
552  map_port0 = l4_src_port;
553  }
554  else
555  if (PREDICT_TRUE
556  (vnet_buffer (p0)->map_t.v6.l4_protocol == IP_PROTOCOL_UDP))
557  {
558  error0 =
559  l4_len0 <
560  sizeof (udp_header_t) ? MAP_ERROR_MALFORMED : error0;
561  vnet_buffer (p0)->map_t.checksum_offset =
562  vnet_buffer (p0)->map_t.v6.l4_offset + 6;
564  map_port0 = l4_src_port;
565  }
566  else if (vnet_buffer (p0)->map_t.v6.l4_protocol ==
567  IP_PROTOCOL_ICMP6)
568  {
569  error0 =
570  l4_len0 <
571  sizeof (icmp46_header_t) ? MAP_ERROR_MALFORMED : error0;
572  next0 = IP6_MAPT_NEXT_MAPT_ICMP;
573  if (((icmp46_header_t *)
574  u8_ptr_add (ip60,
575  vnet_buffer (p0)->map_t.v6.l4_offset))->code ==
576  ICMP6_echo_reply
577  || ((icmp46_header_t *)
578  u8_ptr_add (ip60,
579  vnet_buffer (p0)->map_t.v6.l4_offset))->
580  code == ICMP6_echo_request)
581  map_port0 = l4_src_port;
582  }
583  else
584  {
585  // TODO: In case of 1:1 mapping, it might be possible to
586  // do something with those packets.
587  error0 = MAP_ERROR_BAD_PROTOCOL;
588  }
589 
590  if (PREDICT_FALSE (map_port0 != -1) &&
591  (ip60->src_address.as_u64[0] !=
592  map_get_pfx_net (d0, vnet_buffer (p0)->map_t.v6.saddr,
593  map_port0)
594  || ip60->src_address.as_u64[1] != map_get_sfx_net (d0,
596  (p0)->map_t.
597  v6.saddr,
598  map_port0)))
599  {
600  // Security check when map_port0 is not zero (non-first
601  // fragment, UDP or TCP)
602  error0 =
603  error0 == MAP_ERROR_NONE ? MAP_ERROR_SEC_CHECK : error0;
604  }
605 
606  if (PREDICT_TRUE
607  (error0 == MAP_ERROR_NONE && next0 != IP6_MAPT_NEXT_MAPT_ICMP))
608  {
610  thread_index,
611  vnet_buffer (p0)->map_t.
612  map_domain_index, 1,
613  clib_net_to_host_u16 (ip60->
614  payload_length));
615  }
616 
617  next0 = (error0 != MAP_ERROR_NONE) ? IP6_MAPT_NEXT_DROP : next0;
618  p0->error = error_node->errors[error0];
619  if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
620  {
621  map_add_trace (vm, node, p0,
622  vnet_buffer (p0)->map_t.map_domain_index,
623  map_port0);
624  }
625  exit:
626  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
627  to_next, n_left_to_next, pi0,
628  next0);
629  }
630  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
631  }
632  return frame->n_vectors;
633 }
634 
635 static char *map_t_error_strings[] = {
636 #define _(sym, string) string,
638 #undef _
639 };
640 
641 /* *INDENT-OFF* */
643  .function = ip6_map_t_fragmented,
644  .name = "ip6-map-t-fragmented",
645  .vector_size = sizeof (u32),
646  .format_trace = format_map_trace,
648 
649  .n_errors = MAP_N_ERROR,
650  .error_strings = map_t_error_strings,
651 
652  .n_next_nodes = IP6_MAPT_FRAGMENTED_N_NEXT,
653  .next_nodes =
654  {
655  [IP6_MAPT_FRAGMENTED_NEXT_IP4_LOOKUP] = "ip4-lookup",
657  [IP6_MAPT_FRAGMENTED_NEXT_DROP] = "error-drop",
658  },
659 };
660 /* *INDENT-ON* */
661 
662 /* *INDENT-OFF* */
664  .function = ip6_map_t_icmp,
665  .name = "ip6-map-t-icmp",
666  .vector_size = sizeof (u32),
667  .format_trace = format_map_trace,
669 
670  .n_errors = MAP_N_ERROR,
671  .error_strings = map_t_error_strings,
672 
673  .n_next_nodes = IP6_MAPT_ICMP_N_NEXT,
674  .next_nodes =
675  {
676  [IP6_MAPT_ICMP_NEXT_IP4_LOOKUP] = "ip4-lookup",
678  [IP6_MAPT_ICMP_NEXT_DROP] = "error-drop",
679  },
680 };
681 /* *INDENT-ON* */
682 
683 /* *INDENT-OFF* */
685  .function = ip6_map_t_tcp_udp,
686  .name = "ip6-map-t-tcp-udp",
687  .vector_size = sizeof (u32),
688  .format_trace = format_map_trace,
690 
691  .n_errors = MAP_N_ERROR,
692  .error_strings = map_t_error_strings,
693 
694  .n_next_nodes = IP6_MAPT_TCP_UDP_N_NEXT,
695  .next_nodes =
696  {
697  [IP6_MAPT_TCP_UDP_NEXT_IP4_LOOKUP] = "ip4-lookup",
699  [IP6_MAPT_TCP_UDP_NEXT_DROP] = "error-drop",
700  },
701 };
702 /* *INDENT-ON* */
703 
704 /* *INDENT-OFF* */
705 VNET_FEATURE_INIT (ip6_map_t_feature, static) = {
706  .arc_name = "ip6-unicast",
707  .node_name = "ip6-map-t",
708  .runs_before = VNET_FEATURES ("ip6-flow-classify"),
709  .runs_after = VNET_FEATURES ("ip6-sv-reassembly-feature"),
710 };
711 
713  .function = ip6_map_t,
714  .name = "ip6-map-t",
715  .vector_size = sizeof(u32),
716  .format_trace = format_map_trace,
718 
719  .n_errors = MAP_N_ERROR,
720  .error_strings = map_t_error_strings,
721 
722  .n_next_nodes = IP6_MAPT_N_NEXT,
723  .next_nodes =
724  {
725  [IP6_MAPT_NEXT_MAPT_TCP_UDP] = "ip6-map-t-tcp-udp",
726  [IP6_MAPT_NEXT_MAPT_ICMP] = "ip6-map-t-icmp",
727  [IP6_MAPT_NEXT_MAPT_FRAGMENTED] = "ip6-map-t-fragmented",
728  [IP6_MAPT_NEXT_DROP] = "error-drop",
729  },
730 };
731 /* *INDENT-ON* */
732 
733 /*
734  * fd.io coding-style-patch-verification: ON
735  *
736  * Local Variables:
737  * eval: (c-set-style "gnu")
738  * End:
739  */
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
static void map_add_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, u32 map_domain_index, u16 port)
Definition: map.h:247
map_domain_t * d
Definition: ip6_map_t.c:56
static uword ip6_map_t_tcp_udp(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_map_t.c:405
map_domain_flags_e flags
Definition: map.h:83
map_main_t map_main
Definition: map.c:27
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:220
u16 udp_checksum(udp_header_t *uh, u32 udp_len, void *ih, u8 version)
Definition: packets.c:114
ip6_mapt_next_t
Definition: ip6_map_t.c:21
ip4_address_t src_address
Definition: ip4_packet.h:170
#define PREDICT_TRUE(x)
Definition: clib.h:112
u64 as_u64[2]
Definition: ip6_packet.h:51
static int map_ip6_to_ip4_tcp_udp(vlib_main_t *vm, vlib_buffer_t *p, bool udp_checksum)
Definition: ip6_map_t.c:310
#define NULL
Definition: clib.h:58
static_always_inline map_domain_t * ip6_map_get_domain(ip6_address_t *addr, u32 *map_domain_index, u8 *error)
Definition: map.h:359
u32 thread_index
Definition: main.h:218
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
static uword ip6_map_t(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_map_t.c:461
uword ip_csum_t
Definition: ip_packet.h:244
static int ip6_to_ip4_set_icmp_cb(ip6_header_t *ip6, ip4_header_t *ip4, void *arg)
Definition: ip6_map_t.c:61
u16 flags_and_fragment_offset
Definition: ip4_packet.h:151
static u16 ip6_get_port(vlib_main_t *vm, vlib_buffer_t *b, ip6_header_t *ip6, u16 buffer_len, u8 *ip_protocol, u16 *src_port, u16 *dst_port, u8 *icmp_type_or_tcp_flags, u32 *tcp_ack_number, u32 *tcp_seq_number)
Get L4 information like port number or ICMP id from IPv6 packet.
Definition: ip6_to_ip4.h:117
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:470
struct _tcp_header tcp_header_t
ip6_address_t src_address
Definition: ip6_packet.h:307
unsigned char u8
Definition: types.h:56
IPv4 to IPv6 translation.
#define u8_ptr_add(ptr, index)
Definition: ip_types.h:34
static_always_inline u32 ip6_map_t_embedded_address(map_domain_t *d, ip6_address_t *addr)
Definition: map.h:393
static_always_inline u32 map_get_ip4(ip6_address_t *addr, u16 prefix_len)
Definition: map.h:328
ip4_address_t dst_address
Definition: ip4_packet.h:170
vlib_combined_counter_main_t * domain_counters
Definition: map.h:169
ip6_address_t * rules
Definition: map.h:78
static_always_inline u8 ip6_translate_tos(u32 ip_version_traffic_class_and_flow_label)
Translate TOS value from IPv6 to IPv4.
Definition: ip6_to_ip4.h:281
u8 ea_bits_len
Definition: map.h:86
unsigned int u32
Definition: types.h:88
#define frag_id_6to4(id)
Definition: ip6_to_ip4.h:49
vl_api_fib_path_type_t type
Definition: fib_types.api:123
#define ip6_frag_hdr_more(hdr)
Definition: ip6_packet.h:667
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
vnet_crypto_main_t * cm
Definition: quic_crypto.c:41
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
#define IP4_FRAG_NODE_NAME
Definition: ip_frag.h:43
long ctx[MAX_CONNS]
Definition: main.c:144
static_always_inline u64 map_get_pfx_net(map_domain_t *d, u32 addr, u16 port)
Definition: map.h:289
unsigned short u16
Definition: types.h:57
map_domain_t * domains
Definition: map.h:164
vlib_node_registration_t ip6_map_t_tcp_udp_node
(constructor) VLIB_REGISTER_NODE (ip6_map_t_tcp_udp_node)
Definition: ip6_map_t.c:684
static_always_inline u64 map_get_sfx_net(map_domain_t *d, u32 addr, u16 port)
Definition: map.h:321
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define PREDICT_FALSE(x)
Definition: clib.h:111
#define always_inline
Definition: ipsec.h:28
#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
u8 ip6_src_len
Definition: map.h:85
#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
vlib_node_registration_t ip6_map_t_fragmented_node
(constructor) VLIB_REGISTER_NODE (ip6_map_t_fragmented_node)
Definition: ip6_map_t.c:642
u8 ip6[16]
Definition: one.api:477
#define IP4_HEADER_FLAG_MORE_FRAGMENTS
Definition: ip4_packet.h:152
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u32 flags
Definition: vhost_user.h:141
ip6_mapt_tcp_udp_next_t
Definition: ip6_map_t.c:38
u16 n_vectors
Definition: node.h:397
static uword ip6_map_t_icmp(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_map_t.c:107
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:89
VNET_FEATURE_INIT(ip6_map_t_feature, static)
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
#define foreach_map_error
Definition: map.h:211
ip6_mapt_icmp_next_t
Definition: ip6_map_t.c:30
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:368
vlib_node_registration_t ip6_map_t_icmp_node
(constructor) VLIB_REGISTER_NODE (ip6_map_t_icmp_node)
Definition: ip6_map_t.c:663
static int ip6_to_ip4_set_inner_icmp_cb(ip6_header_t *ip6, ip4_header_t *ip4, void *arg)
Definition: ip6_map_t.c:84
signed int i32
Definition: types.h:77
#define ip6_frag_hdr_offset(hdr)
Definition: ip6_packet.h:661
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:515
ip_dscp_t tos
Definition: ip4_packet.h:141
static ip_csum_t ip_csum_sub_even(ip_csum_t c, ip_csum_t x)
Definition: ip_packet.h:272
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
u8 * format_map_trace(u8 *s, va_list *args)
Definition: map.c:1203
IPv6 to IPv4 translation.
#define VNET_FEATURES(...)
Definition: feature.h:442
static_always_inline void map_mss_clamping(tcp_header_t *tcp, ip_csum_t *sum, u16 mss_clamping)
Definition: map.h:448
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:294
u16 mtu
Definition: map.h:82
static uword ip6_map_t_fragmented(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_map_t.c:251
u16 payload_length
Definition: ip6_packet.h:298
static int icmp6_to_icmp(vlib_main_t *vm, vlib_buffer_t *p, ip6_to_ip4_icmp_set_fn_t fn, void *ctx, ip6_to_ip4_icmp_set_fn_t inner_fn, void *inner_ctx)
Translate ICMP6 packet to ICMP4.
Definition: ip6_to_ip4.h:299
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
u16 tcp_mss
Definition: map.h:183
A collection of combined counters.
Definition: counter.h:188
static char * map_t_error_strings[]
Definition: ip6_map_t.c:635
vlib_node_registration_t ip6_map_t_node
(constructor) VLIB_REGISTER_NODE (ip6_map_t_node)
Definition: ip6_map_t.c:712
#define vnet_buffer(b)
Definition: buffer.h:408
#define IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS
Definition: ip4_packet.h:194
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1811
#define u16_net_add(u, val)
Definition: ip_types.h:35
static_always_inline int ip6_parse(vlib_main_t *vm, vlib_buffer_t *b, const ip6_header_t *ip6, u32 buff_len, u8 *l4_protocol, u16 *l4_offset, u16 *frag_hdr_offset)
Parse some useful information from IPv6 header.
Definition: ip6_to_ip4.h:65
u8 ip_version_and_header_length
Definition: ip4_packet.h:138
u32 ip4
Definition: one.api:440
ip6_mapt_fragmented_next_t
Definition: ip6_map_t.c:46
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
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:247
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:300
static ip_csum_t ip_csum_add_even(ip_csum_t c, ip_csum_t x)
Definition: ip_packet.h:255
static int map_ip6_to_ip4_fragmented(vlib_main_t *vm, vlib_buffer_t *p)
Definition: ip6_map_t.c:204
ip6_address_t dst_address
Definition: ip6_packet.h:307