FD.io VPP  v21.06-1-gbb7418cf9
Vector Packet Processing
ipfix_logging.c
Go to the documentation of this file.
1 /*
2  * nat_ipfix_logging.c - NAT Events IPFIX logging
3  *
4  * Copyright (c) 2016 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/fib/fib_table.h>
20 #include <vnet/ip/ip4.h>
21 #include <vnet/udp/udp_local.h>
22 #include <vlibmemory/api.h>
23 #include <vppinfra/atomics.h>
24 #include <nat/lib/ipfix_logging.h>
25 #include <nat/lib/inlines.h>
26 
29 
30 #define NAT44_SESSION_CREATE_LEN 26
31 #define NAT_ADDRESSES_EXHAUTED_LEN 13
32 #define MAX_ENTRIES_PER_USER_LEN 21
33 #define MAX_SESSIONS_LEN 17
34 #define MAX_BIBS_LEN 17
35 #define MAX_FRAGMENTS_IP4_LEN 21
36 #define MAX_FRAGMENTS_IP6_LEN 33
37 #define NAT64_BIB_LEN 38
38 #define NAT64_SES_LEN 62
39 
40 #define NAT44_SESSION_CREATE_FIELD_COUNT 8
41 #define NAT_ADDRESSES_EXHAUTED_FIELD_COUNT 3
42 #define MAX_ENTRIES_PER_USER_FIELD_COUNT 5
43 #define MAX_SESSIONS_FIELD_COUNT 4
44 #define MAX_BIBS_FIELD_COUNT 4
45 #define MAX_FRAGMENTS_FIELD_COUNT 5
46 #define NAT64_BIB_FIELD_COUNT 8
47 #define NAT64_SES_FIELD_COUNT 12
48 
49 typedef struct
50 {
59 
60 typedef struct
61 {
64 
65 typedef struct
66 {
70 
71 typedef struct
72 {
75 
76 typedef struct
77 {
80 
81 typedef struct
82 {
86 
87 typedef struct
88 {
90  u64 src[2];
92 
93 typedef struct
94 {
96  u64 src_ip[2];
107 
108 typedef struct
109 {
118 
119 #define skip_if_disabled() \
120 do { \
121  nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main; \
122  if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0))) \
123  return; \
124 } while (0)
125 
126 #define update_template_id(old_id, new_id) \
127 do { \
128  u16 template_id = clib_atomic_fetch_or(old_id, 0); \
129  clib_atomic_cmp_and_swap(old_id, template_id, new_id); \
130 } while (0)
131 
132 /**
133  * @brief Create an IPFIX template packet rewrite string
134  *
135  * @param frm flow report main
136  * @param fr flow report
137  * @param collector_address collector address
138  * @param src_address source address
139  * @param collector_port collector
140  * @param event NAT event ID
141  * @param quota_event NAT quota exceeded event ID
142  *
143  * @returns template packet
144  */
145 static inline u8 *
147  flow_report_t * fr,
148  ip4_address_t * collector_address,
150  u16 collector_port,
151  nat_event_t event, quota_exceed_event_t quota_event)
152 {
154  ip4_header_t *ip;
155  udp_header_t *udp;
160  ipfix_field_specifier_t *first_field;
161  u8 *rewrite = 0;
163  u32 field_count = 0;
164  flow_report_stream_t *stream;
165  u32 stream_index;
166 
167  stream = &frm->streams[fr->stream_index];
168 
169  stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
171  stream_index, fr->stream_index);
172 
173  if (event == NAT_ADDRESSES_EXHAUTED)
174  {
176 
178  fr->template_id);
179  }
180  else if (event == NAT44_SESSION_CREATE)
181  {
182  field_count = NAT44_SESSION_CREATE_FIELD_COUNT;
183 
185  fr->template_id);
186  }
187  else if (event == NAT64_BIB_CREATE)
188  {
189  field_count = NAT64_BIB_FIELD_COUNT;
190 
192  fr->template_id);
193  }
194  else if (event == NAT64_SESSION_CREATE)
195  {
196  field_count = NAT64_SES_FIELD_COUNT;
197 
199  fr->template_id);
200  }
201  else if (event == QUOTA_EXCEEDED)
202  {
203  if (quota_event == MAX_ENTRIES_PER_USER)
204  {
205  field_count = MAX_ENTRIES_PER_USER_FIELD_COUNT;
206 
208  fr->template_id);
209 
210  }
211  else if (quota_event == MAX_SESSION_ENTRIES)
212  {
213  field_count = MAX_SESSIONS_FIELD_COUNT;
214 
216  fr->template_id);
217  }
218  else if (quota_event == MAX_BIB_ENTRIES)
219  {
220  field_count = MAX_BIBS_FIELD_COUNT;
221 
223  fr->template_id);
224  }
225  }
226 
227  /* allocate rewrite space */
228  vec_validate_aligned (rewrite,
230  + field_count * sizeof (ipfix_field_specifier_t) - 1,
232 
233  tp = (ip4_ipfix_template_packet_t *) rewrite;
234  ip = (ip4_header_t *) & tp->ip4;
235  udp = (udp_header_t *) (ip + 1);
236  h = (ipfix_message_header_t *) (udp + 1);
237  s = (ipfix_set_header_t *) (h + 1);
238  t = (ipfix_template_header_t *) (s + 1);
239  first_field = f = (ipfix_field_specifier_t *) (t + 1);
240 
241  ip->ip_version_and_header_length = 0x45;
242  ip->ttl = 254;
243  ip->protocol = IP_PROTOCOL_UDP;
244  ip->src_address.as_u32 = src_address->as_u32;
245  ip->dst_address.as_u32 = collector_address->as_u32;
246  udp->src_port = clib_host_to_net_u16 (stream->src_port);
247  udp->dst_port = clib_host_to_net_u16 (collector_port);
248  udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip));
249 
250  /* FIXUP: message header export_time */
251  h->domain_id = clib_host_to_net_u32 (stream->domain_id);
252 
253  /* Add TLVs to the template */
254  if (event == NAT_ADDRESSES_EXHAUTED)
255  {
256  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
257  f++;
258  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
259  f++;
260  f->e_id_length = ipfix_e_id_length (0, natPoolId, 4);
261  f++;
262  }
263  else if (event == NAT44_SESSION_CREATE)
264  {
265  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
266  f++;
267  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
268  f++;
269  f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
270  f++;
271  f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
272  f++;
273  f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
274  f++;
275  f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
276  f++;
277  f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
278  f++;
279  f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
280  f++;
281  }
282  else if (event == NAT64_BIB_CREATE)
283  {
284  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
285  f++;
286  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
287  f++;
288  f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
289  f++;
290  f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
291  f++;
292  f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
293  f++;
294  f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
295  f++;
296  f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
297  f++;
298  f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
299  f++;
300  }
301  else if (event == NAT64_SESSION_CREATE)
302  {
303  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
304  f++;
305  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
306  f++;
307  f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
308  f++;
309  f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
310  f++;
311  f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
312  f++;
313  f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
314  f++;
315  f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
316  f++;
317  f->e_id_length = ipfix_e_id_length (0, destinationIPv6Address, 16);
318  f++;
319  f->e_id_length = ipfix_e_id_length (0, postNATDestinationIPv4Address, 4);
320  f++;
321  f->e_id_length = ipfix_e_id_length (0, destinationTransportPort, 2);
322  f++;
323  f->e_id_length = ipfix_e_id_length (0, postNAPTDestinationTransportPort,
324  2);
325  f++;
326  f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
327  f++;
328  }
329  else if (event == QUOTA_EXCEEDED)
330  {
331  if (quota_event == MAX_ENTRIES_PER_USER)
332  {
333  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
334  8);
335  f++;
336  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
337  f++;
338  f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
339  f++;
340  f->e_id_length = ipfix_e_id_length (0, maxEntriesPerUser, 4);
341  f++;
342  f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
343  f++;
344  }
345  else if (quota_event == MAX_SESSION_ENTRIES)
346  {
347  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
348  8);
349  f++;
350  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
351  f++;
352  f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
353  f++;
354  f->e_id_length = ipfix_e_id_length (0, maxSessionEntries, 4);
355  f++;
356  }
357  else if (quota_event == MAX_BIB_ENTRIES)
358  {
359  f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
360  8);
361  f++;
362  f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
363  f++;
364  f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
365  f++;
366  f->e_id_length = ipfix_e_id_length (0, maxBIBEntries, 4);
367  f++;
368  }
369  }
370 
371  /* Back to the template packet... */
372  ip = (ip4_header_t *) & tp->ip4;
373  udp = (udp_header_t *) (ip + 1);
374 
375  ASSERT (f - first_field);
376  /* Field count in this template */
377  t->id_count = ipfix_id_count (fr->template_id, f - first_field);
378 
379  /* set length in octets */
380  s->set_id_length =
381  ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s);
382 
383  /* message length in octets */
384  h->version_length = version_length ((u8 *) f - (u8 *) h);
385 
386  ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip);
387  ip->checksum = ip4_header_checksum (ip);
388 
389  return rewrite;
390 }
391 
392 u8 *
394  flow_report_t * fr,
395  ip4_address_t * collector_address,
397  u16 collector_port,
399  u32 n_elts, u32 *stream_index)
400 {
401  return nat_template_rewrite (frm, fr, collector_address, src_address,
402  collector_port, NAT_ADDRESSES_EXHAUTED, 0);
403 }
404 
405 u8 *
407  flow_report_t * fr,
408  ip4_address_t * collector_address,
410  u16 collector_port,
412  u32 n_elts, u32 *stream_index)
413 {
414  return nat_template_rewrite (frm, fr, collector_address, src_address,
415  collector_port, NAT44_SESSION_CREATE, 0);
416 }
417 
418 u8 *
420  flow_report_t * fr,
421  ip4_address_t * collector_address,
423  u16 collector_port,
425  u32 n_elts, u32 *stream_index)
426 {
427  return nat_template_rewrite (frm, fr, collector_address, src_address,
428  collector_port, QUOTA_EXCEEDED,
430 }
431 
432 u8 *
434  flow_report_t * fr,
435  ip4_address_t * collector_address,
437  u16 collector_port,
439  u32 n_elts, u32 *stream_index)
440 {
441  return nat_template_rewrite (frm, fr, collector_address, src_address,
442  collector_port, QUOTA_EXCEEDED,
444 }
445 
446 u8 *
448  flow_report_t * fr,
449  ip4_address_t * collector_address,
451  u16 collector_port,
453  u32 n_elts, u32 *stream_index)
454 {
455  return nat_template_rewrite (frm, fr, collector_address, src_address,
456  collector_port, QUOTA_EXCEEDED,
458 }
459 
460 u8 *
462  flow_report_t * fr,
463  ip4_address_t * collector_address,
465  u16 collector_port,
467  u32 n_elts, u32 *stream_index)
468 {
469  return nat_template_rewrite (frm, fr, collector_address, src_address,
470  collector_port, NAT64_BIB_CREATE, 0);
471 }
472 
473 u8 *
475  flow_report_t * fr,
476  ip4_address_t * collector_address,
478  u16 collector_port,
480  u32 n_elts, u32 *stream_index)
481 {
482  return nat_template_rewrite (frm, fr, collector_address, src_address,
483  collector_port, NAT64_SESSION_CREATE, 0);
484 }
485 
486 static inline void
488  vlib_buffer_t * b0, u32 * offset)
489 {
491  flow_report_stream_t *stream;
494  ipfix_set_header_t *s = 0;
495  u32 sequence_number;
496  u32 stream_index;
497  ip4_header_t *ip;
498  udp_header_t *udp;
500 
501  stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
502  stream = &frm->streams[stream_index];
503 
504  b0->current_data = 0;
505  b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) +
506  sizeof (*s);
507  b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VNET_BUFFER_F_FLOW_REPORT);
508  vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
509  vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index;
510  tp = vlib_buffer_get_current (b0);
511  ip = (ip4_header_t *) & tp->ip4;
512  udp = (udp_header_t *) (ip + 1);
513  h = (ipfix_message_header_t *) (udp + 1);
514  s = (ipfix_set_header_t *) (h + 1);
515 
516  ip->ip_version_and_header_length = 0x45;
517  ip->ttl = 254;
518  ip->protocol = IP_PROTOCOL_UDP;
522  udp->src_port = clib_host_to_net_u16 (stream->src_port);
523  udp->dst_port = clib_host_to_net_u16 (frm->collector_port);
524  udp->checksum = 0;
525 
526  h->export_time = clib_host_to_net_u32 ((u32)
527  (((f64) frm->unix_time_0) +
528  (vlib_time_now (vm) -
529  frm->vlib_time_0)));
530 
531  sequence_number = clib_atomic_fetch_add (&stream->sequence_number, 1);
532  h->sequence_number = clib_host_to_net_u32 (sequence_number);
533  h->domain_id = clib_host_to_net_u32 (stream->domain_id);
534 
535  *offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
536 }
537 
538 static inline void
540  u16 template_id)
541 {
544  ipfix_set_header_t *s = 0;
545  ip4_header_t *ip;
546  udp_header_t *udp;
548 
549  tp = vlib_buffer_get_current (b0);
550  ip = (ip4_header_t *) & tp->ip4;
551  udp = (udp_header_t *) (ip + 1);
552  h = (ipfix_message_header_t *) (udp + 1);
553  s = (ipfix_set_header_t *) (h + 1);
554 
555  s->set_id_length = ipfix_set_id_length (template_id,
556  b0->current_length -
557  (sizeof (*ip) + sizeof (*udp) +
558  sizeof (*h)));
560  (sizeof (*ip) + sizeof (*udp)));
561 
562  ip->length = clib_host_to_net_u16 (b0->current_length);
563  ip->checksum = ip4_header_checksum (ip);
564  udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
565 
566  if (frm->udp_checksum)
567  {
568  udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
569  if (udp->checksum == 0)
570  udp->checksum = 0xffff;
571  }
572 
574 
576 }
577 
578 static void
580  u32 nat_src_ip, nat_protocol_t nat_proto,
581  u16 src_port, u16 nat_src_port, u32 fib_index,
582  int do_flush)
583 {
587  vlib_frame_t *f;
588  vlib_buffer_t *b0 = 0;
589  u32 bi0 = ~0;
590  u32 offset;
592  u64 now;
593  u8 proto;
594  u16 template_id;
595  u32 vrf_id;
596 
597  proto = nat_proto_to_ip_proto (nat_proto);
598 
599  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
600  now += silm->milisecond_time_0;
601 
602  b0 = sitd->nat44_session_buffer;
603 
604  if (PREDICT_FALSE (b0 == 0))
605  {
606  if (do_flush)
607  return;
608 
609  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
610  {
611  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
612  return;
613  }
614 
615  b0 = sitd->nat44_session_buffer = vlib_get_buffer (vm, bi0);
616  offset = 0;
617  }
618  else
619  {
620  bi0 = vlib_get_buffer_index (vm, b0);
621  offset = sitd->nat44_session_next_record_offset;
622  }
623 
624  f = sitd->nat44_session_frame;
625  if (PREDICT_FALSE (f == 0))
626  {
627  u32 *to_next;
628  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
629  sitd->nat44_session_frame = f;
630  to_next = vlib_frame_vector_args (f);
631  to_next[0] = bi0;
632  f->n_vectors = 1;
633  }
634 
635  if (PREDICT_FALSE (offset == 0))
636  nat_ipfix_header_create (frm, b0, &offset);
637 
638  if (PREDICT_TRUE (do_flush == 0))
639  {
640  u64 time_stamp = clib_host_to_net_u64 (now);
641  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
642  offset += sizeof (time_stamp);
643 
644  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
645  offset += sizeof (nat_event);
646 
647  clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
648  offset += sizeof (src_ip);
649 
650  clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
651  offset += sizeof (nat_src_ip);
652 
653  clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
654  offset += sizeof (proto);
655 
656  clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
657  offset += sizeof (src_port);
658 
659  clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
660  offset += sizeof (nat_src_port);
661 
662  vrf_id = fib_table_get_table_id (fib_index, FIB_PROTOCOL_IP4);
663  vrf_id = clib_host_to_net_u32 (vrf_id);
664  clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
665  offset += sizeof (vrf_id);
666 
668  }
669 
670  if (PREDICT_FALSE
671  (do_flush || (offset + NAT44_SESSION_CREATE_LEN) > frm->path_mtu))
672  {
673  template_id = clib_atomic_fetch_or (
675  0);
676  nat_ipfix_send (frm, f, b0, template_id);
677  sitd->nat44_session_frame = 0;
678  sitd->nat44_session_buffer = 0;
679  offset = 0;
680  }
682 }
683 
684 static void
686 {
690  vlib_frame_t *f;
691  vlib_buffer_t *b0 = 0;
692  u32 bi0 = ~0;
693  u32 offset;
695  u64 now;
696  u8 nat_event = NAT_ADDRESSES_EXHAUTED;
697  u16 template_id;
698 
699  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
700  now += silm->milisecond_time_0;
701 
702  b0 = sitd->addr_exhausted_buffer;
703 
704  if (PREDICT_FALSE (b0 == 0))
705  {
706  if (do_flush)
707  return;
708 
709  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
710  {
711  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
712  return;
713  }
714 
715  b0 = sitd->addr_exhausted_buffer = vlib_get_buffer (vm, bi0);
716  offset = 0;
717  }
718  else
719  {
720  bi0 = vlib_get_buffer_index (vm, b0);
721  offset = sitd->addr_exhausted_next_record_offset;
722  }
723 
724  f = sitd->addr_exhausted_frame;
725  if (PREDICT_FALSE (f == 0))
726  {
727  u32 *to_next;
728  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
729  sitd->addr_exhausted_frame = f;
730  to_next = vlib_frame_vector_args (f);
731  to_next[0] = bi0;
732  f->n_vectors = 1;
733  }
734 
735  if (PREDICT_FALSE (offset == 0))
736  nat_ipfix_header_create (frm, b0, &offset);
737 
738  if (PREDICT_TRUE (do_flush == 0))
739  {
740  u64 time_stamp = clib_host_to_net_u64 (now);
741  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
742  offset += sizeof (time_stamp);
743 
744  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
745  offset += sizeof (nat_event);
746 
747  clib_memcpy_fast (b0->data + offset, &pool_id, sizeof (pool_id));
748  offset += sizeof (pool_id);
749 
751  }
752 
753  if (PREDICT_FALSE
754  (do_flush || (offset + NAT_ADDRESSES_EXHAUTED_LEN) > frm->path_mtu))
755  {
756  template_id = clib_atomic_fetch_or (
758  0);
759  nat_ipfix_send (frm, f, b0, template_id);
760  sitd->addr_exhausted_frame = 0;
761  sitd->addr_exhausted_buffer = 0;
762  offset = 0;
763  }
765 }
766 
767 static void
769  u32 limit, u32 src_ip, int do_flush)
770 {
774  vlib_frame_t *f;
775  vlib_buffer_t *b0 = 0;
776  u32 bi0 = ~0;
777  u32 offset;
779  u64 now;
780  u8 nat_event = QUOTA_EXCEEDED;
781  u32 quota_event = clib_host_to_net_u32 (MAX_ENTRIES_PER_USER);
782  u16 template_id;
783 
784  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
785  now += silm->milisecond_time_0;
786 
787  b0 = sitd->max_entries_per_user_buffer;
788 
789  if (PREDICT_FALSE (b0 == 0))
790  {
791  if (do_flush)
792  return;
793 
794  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
795  {
796  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
797  return;
798  }
799 
800  b0 = sitd->max_entries_per_user_buffer = vlib_get_buffer (vm, bi0);
801  offset = 0;
802  }
803  else
804  {
805  bi0 = vlib_get_buffer_index (vm, b0);
807  }
808 
809  f = sitd->max_entries_per_user_frame;
810  if (PREDICT_FALSE (f == 0))
811  {
812  u32 *to_next;
813  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
815  to_next = vlib_frame_vector_args (f);
816  to_next[0] = bi0;
817  f->n_vectors = 1;
818  }
819 
820  if (PREDICT_FALSE (offset == 0))
821  nat_ipfix_header_create (frm, b0, &offset);
822 
823  if (PREDICT_TRUE (do_flush == 0))
824  {
825  u64 time_stamp = clib_host_to_net_u64 (now);
826  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
827  offset += sizeof (time_stamp);
828 
829  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
830  offset += sizeof (nat_event);
831 
832  clib_memcpy_fast (b0->data + offset, &quota_event, sizeof (quota_event));
833  offset += sizeof (quota_event);
834 
835  limit = clib_host_to_net_u32 (limit);
836  clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
837  offset += sizeof (limit);
838 
839  clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
840  offset += sizeof (src_ip);
841 
843  }
844 
845  if (PREDICT_FALSE
846  (do_flush || (offset + MAX_ENTRIES_PER_USER_LEN) > frm->path_mtu))
847  {
848  template_id = clib_atomic_fetch_or (
850  0);
851  nat_ipfix_send (frm, f, b0, template_id);
852  sitd->max_entries_per_user_frame = 0;
853  sitd->max_entries_per_user_buffer = 0;
854  offset = 0;
855  }
857 }
858 
859 static void
861 {
865  vlib_frame_t *f;
866  vlib_buffer_t *b0 = 0;
867  u32 bi0 = ~0;
868  u32 offset;
870  u64 now;
871  u8 nat_event = QUOTA_EXCEEDED;
872  u32 quota_event = clib_host_to_net_u32 (MAX_SESSION_ENTRIES);
873  u16 template_id;
874 
875  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
876  now += silm->milisecond_time_0;
877 
878  b0 = sitd->max_sessions_buffer;
879 
880  if (PREDICT_FALSE (b0 == 0))
881  {
882  if (do_flush)
883  return;
884 
885  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
886  {
887  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
888  return;
889  }
890 
891  b0 = sitd->max_sessions_buffer = vlib_get_buffer (vm, bi0);
892  offset = 0;
893  }
894  else
895  {
896  bi0 = vlib_get_buffer_index (vm, b0);
897  offset = sitd->max_sessions_next_record_offset;
898  }
899 
900  f = sitd->max_sessions_frame;
901  if (PREDICT_FALSE (f == 0))
902  {
903  u32 *to_next;
904  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
905  sitd->max_sessions_frame = f;
906  to_next = vlib_frame_vector_args (f);
907  to_next[0] = bi0;
908  f->n_vectors = 1;
909  }
910 
911  if (PREDICT_FALSE (offset == 0))
912  nat_ipfix_header_create (frm, b0, &offset);
913 
914  if (PREDICT_TRUE (do_flush == 0))
915  {
916  u64 time_stamp = clib_host_to_net_u64 (now);
917  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
918  offset += sizeof (time_stamp);
919 
920  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
921  offset += sizeof (nat_event);
922 
923  clib_memcpy_fast (b0->data + offset, &quota_event, sizeof (quota_event));
924  offset += sizeof (quota_event);
925 
926  limit = clib_host_to_net_u32 (limit);
927  clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
928  offset += sizeof (limit);
929 
931  }
932 
933  if (PREDICT_FALSE
934  (do_flush || (offset + MAX_SESSIONS_LEN) > frm->path_mtu))
935  {
936  template_id = clib_atomic_fetch_or (
938  0);
939  nat_ipfix_send (frm, f, b0, template_id);
940  sitd->max_sessions_frame = 0;
941  sitd->max_sessions_buffer = 0;
942  offset = 0;
943  }
945 }
946 
947 static void
949 {
953  vlib_frame_t *f;
954  vlib_buffer_t *b0 = 0;
955  u32 bi0 = ~0;
956  u32 offset;
958  u64 now;
959  u8 nat_event = QUOTA_EXCEEDED;
960  u32 quota_event = clib_host_to_net_u32 (MAX_BIB_ENTRIES);
961  u16 template_id;
962 
963  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
964  now += silm->milisecond_time_0;
965 
966  b0 = sitd->max_bibs_buffer;
967 
968  if (PREDICT_FALSE (b0 == 0))
969  {
970  if (do_flush)
971  return;
972 
973  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
974  {
975  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
976  return;
977  }
978 
979  b0 = sitd->max_bibs_buffer = vlib_get_buffer (vm, bi0);
980  offset = 0;
981  }
982  else
983  {
984  bi0 = vlib_get_buffer_index (vm, b0);
985  offset = sitd->max_bibs_next_record_offset;
986  }
987 
988  f = sitd->max_bibs_frame;
989  if (PREDICT_FALSE (f == 0))
990  {
991  u32 *to_next;
992  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
993  sitd->max_bibs_frame = f;
994  to_next = vlib_frame_vector_args (f);
995  to_next[0] = bi0;
996  f->n_vectors = 1;
997  }
998 
999  if (PREDICT_FALSE (offset == 0))
1000  nat_ipfix_header_create (frm, b0, &offset);
1001 
1002  if (PREDICT_TRUE (do_flush == 0))
1003  {
1004  u64 time_stamp = clib_host_to_net_u64 (now);
1005  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1006  offset += sizeof (time_stamp);
1007 
1008  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1009  offset += sizeof (nat_event);
1010 
1011  clib_memcpy_fast (b0->data + offset, &quota_event, sizeof (quota_event));
1012  offset += sizeof (quota_event);
1013 
1014  limit = clib_host_to_net_u32 (limit);
1015  clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
1016  offset += sizeof (limit);
1017 
1019  }
1020 
1021  if (PREDICT_FALSE
1022  (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1023  {
1024  template_id = clib_atomic_fetch_or (
1025  &silm->max_bibs_template_id,
1026  0);
1027  nat_ipfix_send (frm, f, b0, template_id);
1028  sitd->max_bibs_frame = 0;
1029  sitd->max_bibs_buffer = 0;
1030  offset = 0;
1031  }
1033 }
1034 
1035 static void
1037  ip6_address_t * src_ip, u32 nat_src_ip,
1038  u8 proto, u16 src_port, u16 nat_src_port,
1039  u32 vrf_id, int do_flush)
1040 {
1044  vlib_frame_t *f;
1045  vlib_buffer_t *b0 = 0;
1046  u32 bi0 = ~0;
1047  u32 offset;
1049  u64 now;
1050  u16 template_id;
1051 
1052  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1053  now += silm->milisecond_time_0;
1054 
1055  b0 = sitd->nat64_bib_buffer;
1056 
1057  if (PREDICT_FALSE (b0 == 0))
1058  {
1059  if (do_flush)
1060  return;
1061 
1062  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1063  {
1064  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1065  return;
1066  }
1067 
1068  b0 = sitd->nat64_bib_buffer = vlib_get_buffer (vm, bi0);
1069  offset = 0;
1070  }
1071  else
1072  {
1073  bi0 = vlib_get_buffer_index (vm, b0);
1074  offset = sitd->nat64_bib_next_record_offset;
1075  }
1076 
1077  f = sitd->nat64_bib_frame;
1078  if (PREDICT_FALSE (f == 0))
1079  {
1080  u32 *to_next;
1081  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1082  sitd->nat64_bib_frame = f;
1083  to_next = vlib_frame_vector_args (f);
1084  to_next[0] = bi0;
1085  f->n_vectors = 1;
1086  }
1087 
1088  if (PREDICT_FALSE (offset == 0))
1089  nat_ipfix_header_create (frm, b0, &offset);
1090 
1091  if (PREDICT_TRUE (do_flush == 0))
1092  {
1093  u64 time_stamp = clib_host_to_net_u64 (now);
1094  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1095  offset += sizeof (time_stamp);
1096 
1097  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1098  offset += sizeof (nat_event);
1099 
1100  clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1101  offset += sizeof (ip6_address_t);
1102 
1103  clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1104  offset += sizeof (nat_src_ip);
1105 
1106  clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1107  offset += sizeof (proto);
1108 
1109  clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1110  offset += sizeof (src_port);
1111 
1112  clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1113  offset += sizeof (nat_src_port);
1114 
1115  vrf_id = clib_host_to_net_u32 (vrf_id);
1116  clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1117  offset += sizeof (vrf_id);
1118 
1120  }
1121 
1122  if (PREDICT_FALSE
1123  (do_flush || (offset + NAT64_BIB_LEN) > frm->path_mtu))
1124  {
1125  template_id = clib_atomic_fetch_or (
1126  &silm->nat64_bib_template_id,
1127  0);
1128  nat_ipfix_send (frm, f, b0, template_id);
1129  sitd->nat64_bib_frame = 0;
1130  sitd->nat64_bib_buffer = 0;
1131  offset = 0;
1132  }
1134 }
1135 
1136 static void
1138  ip6_address_t * src_ip, u32 nat_src_ip,
1139  u8 proto, u16 src_port, u16 nat_src_port,
1140  ip6_address_t * dst_ip, u32 nat_dst_ip,
1141  u16 dst_port, u16 nat_dst_port,
1142  u32 vrf_id, int do_flush)
1143 {
1147  vlib_frame_t *f;
1148  vlib_buffer_t *b0 = 0;
1149  u32 bi0 = ~0;
1150  u32 offset;
1152  u64 now;
1153  u16 template_id;
1154 
1155  now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1156  now += silm->milisecond_time_0;
1157 
1158  b0 = sitd->nat64_ses_buffer;
1159 
1160  if (PREDICT_FALSE (b0 == 0))
1161  {
1162  if (do_flush)
1163  return;
1164 
1165  if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1166  {
1167  //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1168  return;
1169  }
1170 
1171  b0 = sitd->nat64_ses_buffer = vlib_get_buffer (vm, bi0);
1172  offset = 0;
1173  }
1174  else
1175  {
1176  bi0 = vlib_get_buffer_index (vm, b0);
1177  offset = sitd->nat64_ses_next_record_offset;
1178  }
1179 
1180  f = sitd->nat64_ses_frame;
1181  if (PREDICT_FALSE (f == 0))
1182  {
1183  u32 *to_next;
1184  f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1185  sitd->nat64_ses_frame = f;
1186  to_next = vlib_frame_vector_args (f);
1187  to_next[0] = bi0;
1188  f->n_vectors = 1;
1189  }
1190 
1191  if (PREDICT_FALSE (offset == 0))
1192  nat_ipfix_header_create (frm, b0, &offset);
1193 
1194  if (PREDICT_TRUE (do_flush == 0))
1195  {
1196  u64 time_stamp = clib_host_to_net_u64 (now);
1197  clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1198  offset += sizeof (time_stamp);
1199 
1200  clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1201  offset += sizeof (nat_event);
1202 
1203  clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1204  offset += sizeof (ip6_address_t);
1205 
1206  clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1207  offset += sizeof (nat_src_ip);
1208 
1209  clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1210  offset += sizeof (proto);
1211 
1212  clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1213  offset += sizeof (src_port);
1214 
1215  clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1216  offset += sizeof (nat_src_port);
1217 
1218  clib_memcpy_fast (b0->data + offset, dst_ip, sizeof (ip6_address_t));
1219  offset += sizeof (ip6_address_t);
1220 
1221  clib_memcpy_fast (b0->data + offset, &nat_dst_ip, sizeof (nat_dst_ip));
1222  offset += sizeof (nat_dst_ip);
1223 
1224  clib_memcpy_fast (b0->data + offset, &dst_port, sizeof (dst_port));
1225  offset += sizeof (dst_port);
1226 
1227  clib_memcpy_fast (b0->data + offset, &nat_dst_port, sizeof (nat_dst_port));
1228  offset += sizeof (nat_dst_port);
1229 
1230  vrf_id = clib_host_to_net_u32 (vrf_id);
1231  clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1232  offset += sizeof (vrf_id);
1233 
1235  }
1236 
1237  if (PREDICT_FALSE
1238  (do_flush || (offset + NAT64_SES_LEN) > frm->path_mtu))
1239  {
1240  template_id = clib_atomic_fetch_or (
1241  &silm->nat64_ses_template_id,
1242  0);
1243  nat_ipfix_send (frm, f, b0, template_id);
1244  sitd->nat64_ses_frame = 0;
1245  sitd->nat64_ses_buffer = 0;
1246  offset = 0;
1247  }
1249 }
1250 
1251 void
1253 {
1254  int do_flush = 1;
1255 
1256  nat_ipfix_logging_nat44_ses (thread_index,
1257  0, 0, 0, 0, 0, 0, 0, do_flush);
1258  nat_ipfix_logging_addr_exhausted (thread_index, 0, do_flush);
1259  nat_ipfix_logging_max_entries_per_usr (thread_index, 0, 0, do_flush);
1260  nat_ipfix_logging_max_ses (thread_index, 0, do_flush);
1261  nat_ipfix_logging_max_bib (thread_index, 0, do_flush);
1262  nat_ipfix_logging_nat64_bibe (thread_index,
1263  0, 0, 0, 0, 0, 0, 0, do_flush);
1264  nat_ipfix_logging_nat64_ses (thread_index,
1265  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, do_flush);
1266 }
1267 
1268 int
1270 {
1272  return !clib_atomic_fetch_or(&silm->enabled, 0);
1273 }
1274 
1275 void
1277 {
1279  vlib_main_t *worker_vm;
1280  int i;
1281 
1282  if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0)))
1283  return;
1284 
1285  if (PREDICT_FALSE (!silm->worker_vms))
1286  {
1287  for (i = 1; i < vlib_get_n_threads (); i++)
1288  {
1289  worker_vm = vlib_get_main_by_index (i);
1290  if (worker_vm)
1291  vec_add1 (silm->worker_vms, worker_vm);
1292  }
1293  }
1294 
1295  /* Trigger flush for each worker thread */
1296  for (i = 0; i < vec_len (silm->worker_vms); i++)
1297  {
1298  worker_vm = silm->worker_vms[i];
1299  if (worker_vm)
1301  nat_ipfix_flush_node.index);
1302  }
1303 
1304  /* Finally flush main thread */
1305  nat_ipfix_flush (0);
1306 }
1307 
1308 /**
1309  * @brief Generate NAT44 session create event
1310  *
1311  * @param thread_index thread index
1312  * @param src_ip source IPv4 address
1313  * @param nat_src_ip transaltes source IPv4 address
1314  * @param nat_proto NAT transport protocol
1315  * @param src_port source port
1316  * @param nat_src_port translated source port
1317  * @param vrf_id VRF ID
1318  */
1319 void
1321  u32 src_ip,
1322  u32 nat_src_ip,
1323  nat_protocol_t nat_proto,
1324  u16 src_port,
1325  u16 nat_src_port, u32 fib_index)
1326 {
1327  skip_if_disabled ();
1328 
1329  nat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_CREATE, src_ip,
1330  nat_src_ip, nat_proto, src_port, nat_src_port,
1331  fib_index, 0);
1332 }
1333 
1334 /**
1335  * @brief Generate NAT44 session delete event
1336  *
1337  * @param thread_index thread index
1338  * @param src_ip source IPv4 address
1339  * @param nat_src_ip transaltes source IPv4 address
1340  * @param nat_proto NAT transport protocol
1341  * @param src_port source port
1342  * @param nat_src_port translated source port
1343  * @param vrf_id VRF ID
1344  */
1345 void
1347  u32 src_ip,
1348  u32 nat_src_ip,
1349  nat_protocol_t nat_proto,
1350  u16 src_port,
1351  u16 nat_src_port, u32 fib_index)
1352 {
1353  skip_if_disabled ();
1354 
1355  nat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_DELETE, src_ip,
1356  nat_src_ip, nat_proto, src_port, nat_src_port,
1357  fib_index, 0);
1358 }
1359 
1360 /**
1361  * @brief Generate NAT addresses exhausted event
1362  *
1363  * @param thread_index thread index
1364  * @param pool_id NAT pool ID
1365  */
1366 void
1368 {
1369  //TODO: This event SHOULD be rate limited
1370  skip_if_disabled ();
1371 
1372  nat_ipfix_logging_addr_exhausted (thread_index, pool_id, 0);
1373 }
1374 
1375 /**
1376  * @brief Generate maximum entries per user exceeded event
1377  *
1378  * @param thread_index thread index
1379  * @param limit maximum NAT entries that can be created per user
1380  * @param src_ip source IPv4 address
1381  */
1382 void
1384 {
1385  //TODO: This event SHOULD be rate limited
1386  skip_if_disabled ();
1387 
1388  nat_ipfix_logging_max_entries_per_usr (thread_index, limit, src_ip, 0);
1389 }
1390 
1391 vlib_frame_t *
1394  flow_report_t * fr,
1395  vlib_frame_t * f,
1396  u32 * to_next, u32 node_index)
1397 {
1399 
1400  return f;
1401 }
1402 
1403 /**
1404  * @brief Generate maximum session entries exceeded event
1405  *
1406  * @param thread_index thread index
1407  * @param limit configured limit
1408  */
1409 void
1411 {
1412  //TODO: This event SHOULD be rate limited
1413  skip_if_disabled ();
1414 
1415  nat_ipfix_logging_max_ses (thread_index, limit, 0);
1416 }
1417 
1418 /**
1419  * @brief Generate maximum BIB entries exceeded event
1420  *
1421  * @param thread_index thread index
1422  * @param limit configured limit
1423  */
1424 void
1426 {
1427  //TODO: This event SHOULD be rate limited
1428  skip_if_disabled ();
1429 
1430  nat_ipfix_logging_max_bib (thread_index, limit, 0);
1431 }
1432 
1433 /**
1434  * @brief Generate NAT64 BIB create and delete events
1435  *
1436  * @param thread_index thread index
1437  * @param src_ip source IPv6 address
1438  * @param nat_src_ip transaltes source IPv4 address
1439  * @param proto L4 protocol
1440  * @param src_port source port
1441  * @param nat_src_port translated source port
1442  * @param vrf_id VRF ID
1443  * @param is_create non-zero value if create event otherwise delete event
1444  */
1445 void
1447  ip4_address_t * nat_src_ip, u8 proto,
1448  u16 src_port, u16 nat_src_port, u32 vrf_id,
1449  u8 is_create)
1450 {
1451  u8 nat_event;
1452 
1453  skip_if_disabled ();
1454 
1455  nat_event = is_create ? NAT64_BIB_CREATE : NAT64_BIB_DELETE;
1456 
1457  nat_ipfix_logging_nat64_bibe (thread_index, nat_event, src_ip,
1458  nat_src_ip->as_u32, proto, src_port,
1459  nat_src_port, vrf_id, 0);
1460 }
1461 
1462 /**
1463  * @brief Generate NAT64 session create and delete events
1464  *
1465  * @param thread_index thread index
1466  * @param src_ip source IPv6 address
1467  * @param nat_src_ip transaltes source IPv4 address
1468  * @param proto L4 protocol
1469  * @param src_port source port
1470  * @param nat_src_port translated source port
1471  * @param dst_ip destination IPv6 address
1472  * @param nat_dst_ip destination IPv4 address
1473  * @param dst_port destination port
1474  * @param nat_dst_port translated destination port
1475  * @param vrf_id VRF ID
1476  * @param is_create non-zero value if create event otherwise delete event
1477  */
1478 void
1480  ip6_address_t * src_ip,
1481  ip4_address_t * nat_src_ip, u8 proto,
1482  u16 src_port, u16 nat_src_port,
1483  ip6_address_t * dst_ip,
1484  ip4_address_t * nat_dst_ip, u16 dst_port,
1485  u16 nat_dst_port, u32 vrf_id, u8 is_create)
1486 {
1487  u8 nat_event;
1488 
1489  skip_if_disabled ();
1490 
1491  nat_event = is_create ? NAT64_SESSION_CREATE : NAT64_SESSION_DELETE;
1492 
1493  nat_ipfix_logging_nat64_ses (thread_index, nat_event, src_ip,
1494  nat_src_ip->as_u32, proto, src_port,
1495  nat_src_port, dst_ip, nat_dst_ip->as_u32,
1496  dst_port, nat_dst_port, vrf_id, 0);
1497 }
1498 
1499 vlib_frame_t *
1501  vlib_frame_t * f, u32 * to_next, u32 node_index)
1502 {
1504 
1505  if (PREDICT_FALSE (++silm->call_counter >= vec_len (frm->reports)))
1506  {
1508  silm->call_counter = 0;
1509  }
1510 
1511  return f;
1512 }
1513 
1514 /**
1515  * @brief Enable/disable NAT plugin IPFIX logging
1516  *
1517  * @param enable 1 if enable, 0 if disable
1518  * @param domain_id observation domain ID
1519  * @param src_port source port number
1520  *
1521  * @returns 0 if success
1522  */
1523 int
1525 {
1529  int rv;
1530  u8 e = enable ? 1 : 0;
1531 
1532  if (clib_atomic_cmp_and_swap (&silm->enabled, e ^ 1, e) == e)
1533  return 0;
1534 
1535  clib_memset (&a, 0, sizeof (a));
1536  a.is_add = enable;
1537  a.domain_id = domain_id ? domain_id : 1;
1538  a.src_port = src_port ? src_port : UDP_DST_PORT_ipfix;
1540 
1542  rv = vnet_flow_report_add_del (frm, &a, NULL);
1543  if (rv)
1544  {
1545  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1546  return -1;
1547  }
1548 
1550  rv = vnet_flow_report_add_del (frm, &a, NULL);
1551  if (rv)
1552  {
1553  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1554  return -1;
1555  }
1556 
1558  rv = vnet_flow_report_add_del (frm, &a, NULL);
1559  if (rv)
1560  {
1561  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1562  return -1;
1563  }
1564 
1566  rv = vnet_flow_report_add_del (frm, &a, NULL);
1567  if (rv)
1568  {
1569  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1570  return -1;
1571  }
1572 
1574  rv = vnet_flow_report_add_del (frm, &a, NULL);
1575  if (rv)
1576  {
1577  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1578  return -1;
1579  }
1580 
1582  rv = vnet_flow_report_add_del (frm, &a, NULL);
1583  if (rv)
1584  {
1585  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1586  return -1;
1587  }
1588 
1589  // if endpoint dependent per user max entries is also required
1590  /*
1591  a.rewrite_callback = nat_template_rewrite_max_entries_per_usr;
1592  rv = vnet_flow_report_add_del (frm, &a, NULL);
1593  if (rv)
1594  {
1595  //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1596  return -1;
1597  }
1598  */
1599 
1600  return 0;
1601 }
1602 
1603 /**
1604  * @brief Initialize NAT plugin IPFIX logging
1605  *
1606  * @param vm vlib main
1607  */
1608 void
1610 {
1613 
1614  silm->enabled = 0;
1615  silm->worker_vms = 0;
1616  silm->call_counter = 0;
1617 
1618  /* Set up time reference pair */
1619  silm->vlib_time_0 = vlib_time_now (vm);
1620  silm->milisecond_time_0 = unix_time_now_nsec () * 1e-6;
1621 
1622  vec_validate (silm->per_thread_data, tm->n_vlib_mains - 1);
1623 }
1624 
1625 static uword
1628  vlib_frame_t *f)
1629 {
1631  return 0;
1632 }
1633 
1634 /* *INDENT-OFF* */
1635 VLIB_REGISTER_NODE (nat_ipfix_flush_node) = {
1636  .function = ipfix_flush_process,
1637  .name = "nat-ipfix-flush",
1638  .type = VLIB_NODE_TYPE_INPUT,
1639  .state = VLIB_NODE_STATE_INTERRUPT,
1640 };
1641 /* *INDENT-ON* */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
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:133
static void nat_ipfix_logging_nat64_ses(u32 thread_index, u8 nat_event, ip6_address_t *src_ip, u32 nat_src_ip, u8 proto, u16 src_port, u16 nat_src_port, ip6_address_t *dst_ip, u32 nat_dst_ip, u16 dst_port, u16 nat_dst_port, u32 vrf_id, int do_flush)
u32 stream_index
stream index
#define NAT64_BIB_LEN
Definition: ipfix_logging.c:37
static uword ipfix_flush_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
vnet_interface_output_runtime_t * rt
u8 * nat_template_rewrite_addr_exhausted(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
a
Definition: bitmap.h:544
ip4_address_t src_address
Definition: ip4_packet.h:125
void nat_ipfix_logging_init(vlib_main_t *vm)
Initialize NAT plugin IPFIX logging.
void nat_ipfix_logging_addresses_exhausted(u32 thread_index, u32 pool_id)
Generate NAT addresses exhausted event.
static void nat_ipfix_send(flow_report_main_t *frm, vlib_frame_t *f, vlib_buffer_t *b0, u16 template_id)
vlib_frame_t * addr_exhausted_frame
Definition: ipfix_logging.h:58
u32 thread_index
#define PREDICT_TRUE(x)
Definition: clib.h:125
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
unsigned long u64
Definition: types.h:89
vl_api_ip_port_and_mask_t dst_port
Definition: flow_types.api:92
u32 vrf_id
Definition: nat44_ed.api:1053
static void nat_ipfix_logging_nat44_ses(u32 thread_index, u8 nat_event, u32 src_ip, u32 nat_src_ip, nat_protocol_t nat_proto, u16 src_port, u16 nat_src_port, u32 fib_index, int do_flush)
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:249
vlib_buffer_t * nat64_ses_buffer
Definition: ipfix_logging.h:54
static u32 ipfix_e_id_length(int e, u16 id, u16 length)
Definition: ipfix_packet.h:77
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:325
u32 stream_index
Definition: flow_report.h:91
int vnet_flow_report_add_del(flow_report_main_t *frm, vnet_flow_report_add_del_args_t *a, u16 *template_id)
Definition: flow_report.c:344
u32 thread_index
Definition: main.h:213
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
void nat_ipfix_logging_nat64_session(u32 thread_index, ip6_address_t *src_ip, ip4_address_t *nat_src_ip, u8 proto, u16 src_port, u16 nat_src_port, ip6_address_t *dst_ip, ip4_address_t *nat_dst_ip, u16 dst_port, u16 nat_dst_port, u32 vrf_id, u8 is_create)
Generate NAT64 session create and delete events.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
#define NAT_ADDRESSES_EXHAUTED_LEN
Definition: ipfix_logging.c:31
vl_api_address_t src
Definition: gre.api:54
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
ip4_address_t src_address
Definition: flow_report.h:119
static u8 * nat_template_rewrite(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, nat_event_t event, quota_exceed_event_t quota_event)
Create an IPFIX template packet rewrite string.
u16 flags_and_fragment_offset
Definition: ip4_packet.h:106
nat_protocol_t
Definition: lib.h:63
static void nat_ipfix_logging_max_bib(u32 thread_index, u32 limit, int do_flush)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:535
int nat_ipfix_logging_enable_disable(int enable, u32 domain_id, u16 src_port)
Enable/disable NAT plugin IPFIX logging.
vlib_buffer_t * max_entries_per_user_buffer
Definition: ipfix_logging.h:48
u8 * nat_template_rewrite_nat44_session(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
#define NAT64_BIB_FIELD_COUNT
Definition: ipfix_logging.c:46
unsigned char u8
Definition: types.h:56
vlib_frame_t * max_sessions_frame
Definition: ipfix_logging.h:60
#define MAX_SESSIONS_FIELD_COUNT
Definition: ipfix_logging.c:43
nat_ipfix_per_thread_data_t * per_thread_data
Definition: ipfix_logging.h:89
ip4_address_t ipfix_collector
Definition: flow_report.h:117
double f64
Definition: types.h:142
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:104
unsigned int u32
Definition: types.h:88
#define NAT_ADDRESSES_EXHAUTED_FIELD_COUNT
Definition: ipfix_logging.c:41
vlib_frame_t * f
flow_report_stream_t * streams
Definition: flow_report.h:114
vlib_frame_t * max_bibs_frame
Definition: ipfix_logging.h:61
u8 * nat_template_rewrite_max_sessions(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
static uword ip4_header_checksum_is_valid(ip4_header_t *i)
Definition: ip4_packet.h:396
ip4_address_t dst_address
Definition: ip4_packet.h:125
static void nat_ipfix_logging_max_entries_per_usr(u32 thread_index, u32 limit, u32 src_ip, int do_flush)
vnet_flow_rewrite_callback_t * rewrite_callback
Definition: flow_report.h:149
u8 * nat_template_rewrite_max_bibs(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
#define NAT44_SESSION_CREATE_FIELD_COUNT
Definition: ipfix_logging.c:40
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:184
#define clib_atomic_fetch_or(a, b)
Definition: atomics.h:27
vlib_frame_t * nat64_bib_frame
Definition: ipfix_logging.h:64
static_always_inline u8 nat_proto_to_ip_proto(nat_protocol_t nat_proto)
Definition: inlines.h:37
int __clib_unused rv
Definition: application.c:491
#define MAX_ENTRIES_PER_USER_FIELD_COUNT
Definition: ipfix_logging.c:42
vlib_buffer_t * max_sessions_buffer
Definition: ipfix_logging.h:49
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
Definition: buffer_funcs.h:324
flow_report_t * reports
Definition: flow_report.h:113
flow_report_main_t flow_report_main
Definition: flow_report.c:22
vlib_node_registration_t nat_ipfix_flush_node
(constructor) VLIB_REGISTER_NODE (nat_ipfix_flush_node)
Definition: ipfix_logging.c:27
void nat_ipfix_flush_from_main(void)
vl_api_ip_proto_t proto
Definition: acl_types.api:51
#define MAX_ENTRIES_PER_USER_LEN
Definition: ipfix_logging.c:32
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:708
unsigned short u16
Definition: types.h:57
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:218
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
int nat_ipfix_logging_enabled()
#define PREDICT_FALSE(x)
Definition: clib.h:124
#define MAX_BIBS_FIELD_COUNT
Definition: ipfix_logging.c:44
vl_api_address_union_t src_address
Definition: ip_types.api:122
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
static u32 version_length(u16 length)
Definition: ipfix_packet.h:33
#define MAX_SESSIONS_LEN
Definition: ipfix_logging.c:33
vlib_frame_t * deterministic_nat_data_callback(flow_report_main_t *frm, flow_report_t *fr, vlib_frame_t *f, u32 *to_next, u32 node_index)
#define NAT64_SES_FIELD_COUNT
Definition: ipfix_logging.c:47
vl_api_ip_port_and_mask_t src_port
Definition: flow_types.api:91
void nat_ipfix_logging_max_entries_per_user(u32 thread_index, u32 limit, u32 src_ip)
Generate maximum entries per user exceeded event.
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:388
vlib_buffer_t * nat44_session_buffer
ipfix buffers under construction
Definition: ipfix_logging.h:46
void nat_ipfix_flush(u32 thread_index)
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
static u32 ipfix_id_count(u16 id, u16 count)
Definition: ipfix_packet.h:184
u8 data[]
Packet data.
Definition: buffer.h:204
void nat_ipfix_logging_nat44_ses_create(u32 thread_index, u32 src_ip, u32 nat_src_ip, nat_protocol_t nat_proto, u16 src_port, u16 nat_src_port, u32 fib_index)
Generate NAT44 session create event.
static u64 unix_time_now_nsec(void)
Definition: time.h:270
u8 * nat_template_rewrite_nat64_session(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
static void nat_ipfix_logging_addr_exhausted(u32 thread_index, u32 pool_id, int do_flush)
#define clib_atomic_cmp_and_swap(addr, old, new)
Definition: atomics.h:37
vlib_buffer_t * nat64_bib_buffer
Definition: ipfix_logging.h:53
u32 nat44_session_next_record_offset
next record offset
Definition: ipfix_logging.h:68
#define update_template_id(old_id, new_id)
u16 nat44_session_template_id
template IDs
Definition: ipfix_logging.h:92
#define ASSERT(truth)
u8 enabled
NAT plugin IPFIX logging enabled.
Definition: ipfix_logging.h:82
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1095
u16 template_id
Definition: flow_report.h:90
nat_event_t
Definition: ipfix_logging.h:25
static u32 vlib_get_n_threads()
Definition: global_funcs.h:23
vlib_frame_t * max_entries_per_user_frame
Definition: ipfix_logging.h:59
u8 * nat_template_rewrite_nat64_bib(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
quota_exceed_event_t
Definition: ipfix_logging.h:37
static void nat_ipfix_logging_max_ses(u32 thread_index, u32 limit, int do_flush)
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
void nat_ipfix_logging_max_sessions(u32 thread_index, u32 limit)
Generate maximum session entries exceeded event.
#define clib_atomic_fetch_add(a, b)
Definition: atomics.h:23
static void nat_ipfix_header_create(flow_report_main_t *frm, vlib_buffer_t *b0, u32 *offset)
#define skip_if_disabled()
struct _vlib_node_registration vlib_node_registration_t
template key/value backing page structure
Definition: bihash_doc.h:44
u8 * nat_template_rewrite_max_entries_per_usr(flow_report_main_t *frm, flow_report_t *fr, ip4_address_t *collector_address, ip4_address_t *src_address, u16 collector_port, ipfix_report_element_t *elts, u32 n_elts, u32 *stream_index)
static u32 ipfix_set_id_length(u16 set_id, u16 length)
Definition: ipfix_packet.h:121
static void nat_ipfix_logging_nat64_bibe(u32 thread_index, u8 nat_event, ip6_address_t *src_ip, u32 nat_src_ip, u8 proto, u16 src_port, u16 nat_src_port, u32 vrf_id, int do_flush)
u16 call_counter
nat data callbacks call counter
Definition: defs.h:47
static vlib_main_t * vlib_get_main_by_index(u32 thread_index)
Definition: global_funcs.h:29
vl_api_address_t ip
Definition: l2.api:558
vlib_buffer_t * max_bibs_buffer
Definition: ipfix_logging.h:50
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_buffer_t * addr_exhausted_buffer
Definition: ipfix_logging.h:47
VLIB buffer representation.
Definition: buffer.h:111
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:301
vl_api_address_t src_ip
Definition: wireguard.api:38
vlib_main_t ** worker_vms
vector of worker vlib mains
#define NAT64_SES_LEN
Definition: ipfix_logging.c:38
vnet_flow_data_callback_t * flow_data_callback
Definition: flow_report.h:148
struct clib_bihash_value offset
template key/value backing page structure
vl_api_address_t dst_ip
Definition: udp.api:44
vlib_frame_t * data_callback(flow_report_main_t *frm, flow_report_t *fr, vlib_frame_t *f, u32 *to_next, u32 node_index)
#define vnet_buffer(b)
Definition: buffer.h:437
#define MAX_BIBS_LEN
Definition: ipfix_logging.c:34
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
f64 now
#define NAT44_SESSION_CREATE_LEN
Definition: ipfix_logging.c:30
nat_ipfix_logging_main_t nat_ipfix_logging_main
Definition: ipfix_logging.c:28
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
void nat_ipfix_logging_max_bibs(u32 thread_index, u32 limit)
Generate maximum BIB entries exceeded event.
void nat_ipfix_logging_nat64_bib(u32 thread_index, ip6_address_t *src_ip, ip4_address_t *nat_src_ip, u8 proto, u16 src_port, u16 nat_src_port, u32 vrf_id, u8 is_create)
Generate NAT64 BIB create and delete events.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
vlib_frame_t * nat64_ses_frame
Definition: ipfix_logging.h:65
Definition: defs.h:46
vlib_frame_t * nat44_session_frame
frames containing ipfix buffers
Definition: ipfix_logging.h:57
void nat_ipfix_logging_nat44_ses_delete(u32 thread_index, u32 src_ip, u32 nat_src_ip, nat_protocol_t nat_proto, u16 src_port, u16 nat_src_port, u32 fib_index)
Generate NAT44 session delete event.
rewrite
Definition: pnat.api:158
u64 milisecond_time_0
Time reference pair.
Definition: ipfix_logging.h:85