2 * nat_ipfix_logging.c - NAT Events IPFIX logging
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <vnet/fib/fib_table.h>
19 #include <vnet/ipfix-export/flow_report.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>
27 vlib_node_registration_t nat_ipfix_flush_node;
28 nat_ipfix_logging_main_t nat_ipfix_logging_main;
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
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
54 nat_protocol_t nat_proto;
58 } nat_ipfix_logging_nat44_ses_args_t;
63 } nat_ipfix_logging_addr_exhausted_args_t;
69 } nat_ipfix_logging_max_entries_per_user_args_t;
74 } nat_ipfix_logging_max_sessions_args_t;
79 } nat_ipfix_logging_max_bibs_args_t;
85 } nat_ipfix_logging_max_frags_ip4_args_t;
91 } nat_ipfix_logging_max_frags_ip6_args_t;
106 } nat_ipfix_logging_nat64_ses_args_t;
117 } nat_ipfix_logging_nat64_bib_args_t;
119 #define skip_if_disabled() \
121 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main; \
122 if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0))) \
126 #define update_template_id(old_id, new_id) \
128 u16 template_id = clib_atomic_fetch_or(old_id, 0); \
129 clib_atomic_cmp_and_swap(old_id, template_id, new_id); \
133 * @brief Create an IPFIX template packet rewrite string
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
143 * @returns template packet
146 nat_template_rewrite (flow_report_main_t * frm,
148 ip4_address_t * collector_address,
149 ip4_address_t * src_address,
151 nat_event_t event, quota_exceed_event_t quota_event)
153 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
156 ipfix_message_header_t *h;
157 ipfix_set_header_t *s;
158 ipfix_template_header_t *t;
159 ipfix_field_specifier_t *f;
160 ipfix_field_specifier_t *first_field;
162 ip4_ipfix_template_packet_t *tp;
164 flow_report_stream_t *stream;
167 stream = &frm->streams[fr->stream_index];
169 stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
170 clib_atomic_cmp_and_swap (&silm->stream_index,
171 stream_index, fr->stream_index);
173 if (event == NAT_ADDRESSES_EXHAUTED)
175 field_count = NAT_ADDRESSES_EXHAUTED_FIELD_COUNT;
177 update_template_id(&silm->addr_exhausted_template_id,
180 else if (event == NAT44_SESSION_CREATE)
182 field_count = NAT44_SESSION_CREATE_FIELD_COUNT;
184 update_template_id(&silm->nat44_session_template_id,
187 else if (event == NAT64_BIB_CREATE)
189 field_count = NAT64_BIB_FIELD_COUNT;
191 update_template_id(&silm->nat64_bib_template_id,
194 else if (event == NAT64_SESSION_CREATE)
196 field_count = NAT64_SES_FIELD_COUNT;
198 update_template_id(&silm->nat64_ses_template_id,
201 else if (event == QUOTA_EXCEEDED)
203 if (quota_event == MAX_ENTRIES_PER_USER)
205 field_count = MAX_ENTRIES_PER_USER_FIELD_COUNT;
207 update_template_id(&silm->max_entries_per_user_template_id,
211 else if (quota_event == MAX_SESSION_ENTRIES)
213 field_count = MAX_SESSIONS_FIELD_COUNT;
215 update_template_id(&silm->max_sessions_template_id,
218 else if (quota_event == MAX_BIB_ENTRIES)
220 field_count = MAX_BIBS_FIELD_COUNT;
222 update_template_id(&silm->max_bibs_template_id,
227 /* allocate rewrite space */
228 vec_validate_aligned (rewrite,
229 sizeof (ip4_ipfix_template_packet_t)
230 + field_count * sizeof (ipfix_field_specifier_t) - 1,
231 CLIB_CACHE_LINE_BYTES);
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);
241 ip->ip_version_and_header_length = 0x45;
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));
250 /* FIXUP: message header export_time */
251 h->domain_id = clib_host_to_net_u32 (stream->domain_id);
253 /* Add TLVs to the template */
254 if (event == NAT_ADDRESSES_EXHAUTED)
256 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
258 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
260 f->e_id_length = ipfix_e_id_length (0, natPoolId, 4);
263 else if (event == NAT44_SESSION_CREATE)
265 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
267 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
269 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
271 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
273 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
275 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
277 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
279 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
282 else if (event == NAT64_BIB_CREATE)
284 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
286 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
288 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
290 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
292 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
294 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
296 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
298 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
301 else if (event == NAT64_SESSION_CREATE)
303 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
305 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
307 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
309 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
311 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
313 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
315 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
317 f->e_id_length = ipfix_e_id_length (0, destinationIPv6Address, 16);
319 f->e_id_length = ipfix_e_id_length (0, postNATDestinationIPv4Address, 4);
321 f->e_id_length = ipfix_e_id_length (0, destinationTransportPort, 2);
323 f->e_id_length = ipfix_e_id_length (0, postNAPTDestinationTransportPort,
326 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
329 else if (event == QUOTA_EXCEEDED)
331 if (quota_event == MAX_ENTRIES_PER_USER)
333 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
336 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
338 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
340 f->e_id_length = ipfix_e_id_length (0, maxEntriesPerUser, 4);
342 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
345 else if (quota_event == MAX_SESSION_ENTRIES)
347 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
350 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
352 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
354 f->e_id_length = ipfix_e_id_length (0, maxSessionEntries, 4);
357 else if (quota_event == MAX_BIB_ENTRIES)
359 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
362 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
364 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
366 f->e_id_length = ipfix_e_id_length (0, maxBIBEntries, 4);
371 /* Back to the template packet... */
372 ip = (ip4_header_t *) & tp->ip4;
373 udp = (udp_header_t *) (ip + 1);
375 ASSERT (f - first_field);
376 /* Field count in this template */
377 t->id_count = ipfix_id_count (fr->template_id, f - first_field);
379 /* set length in octets */
381 ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s);
383 /* message length in octets */
384 h->version_length = version_length ((u8 *) f - (u8 *) h);
386 ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip);
387 ip->checksum = ip4_header_checksum (ip);
393 nat_template_rewrite_addr_exhausted (flow_report_main_t * frm,
395 ip4_address_t * collector_address,
396 ip4_address_t * src_address,
398 ipfix_report_element_t *elts,
399 u32 n_elts, u32 *stream_index)
401 return nat_template_rewrite (frm, fr, collector_address, src_address,
402 collector_port, NAT_ADDRESSES_EXHAUTED, 0);
406 nat_template_rewrite_nat44_session (flow_report_main_t * frm,
408 ip4_address_t * collector_address,
409 ip4_address_t * src_address,
411 ipfix_report_element_t *elts,
412 u32 n_elts, u32 *stream_index)
414 return nat_template_rewrite (frm, fr, collector_address, src_address,
415 collector_port, NAT44_SESSION_CREATE, 0);
419 nat_template_rewrite_max_entries_per_usr (flow_report_main_t * frm,
421 ip4_address_t * collector_address,
422 ip4_address_t * src_address,
424 ipfix_report_element_t *elts,
425 u32 n_elts, u32 *stream_index)
427 return nat_template_rewrite (frm, fr, collector_address, src_address,
428 collector_port, QUOTA_EXCEEDED,
429 MAX_ENTRIES_PER_USER);
433 nat_template_rewrite_max_sessions (flow_report_main_t * frm,
435 ip4_address_t * collector_address,
436 ip4_address_t * src_address,
438 ipfix_report_element_t *elts,
439 u32 n_elts, u32 *stream_index)
441 return nat_template_rewrite (frm, fr, collector_address, src_address,
442 collector_port, QUOTA_EXCEEDED,
443 MAX_SESSION_ENTRIES);
447 nat_template_rewrite_max_bibs (flow_report_main_t * frm,
449 ip4_address_t * collector_address,
450 ip4_address_t * src_address,
452 ipfix_report_element_t *elts,
453 u32 n_elts, u32 *stream_index)
455 return nat_template_rewrite (frm, fr, collector_address, src_address,
456 collector_port, QUOTA_EXCEEDED,
461 nat_template_rewrite_nat64_bib (flow_report_main_t * frm,
463 ip4_address_t * collector_address,
464 ip4_address_t * src_address,
466 ipfix_report_element_t *elts,
467 u32 n_elts, u32 *stream_index)
469 return nat_template_rewrite (frm, fr, collector_address, src_address,
470 collector_port, NAT64_BIB_CREATE, 0);
474 nat_template_rewrite_nat64_session (flow_report_main_t * frm,
476 ip4_address_t * collector_address,
477 ip4_address_t * src_address,
479 ipfix_report_element_t *elts,
480 u32 n_elts, u32 *stream_index)
482 return nat_template_rewrite (frm, fr, collector_address, src_address,
483 collector_port, NAT64_SESSION_CREATE, 0);
487 nat_ipfix_header_create (flow_report_main_t * frm,
488 vlib_buffer_t * b0, u32 * offset)
490 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
491 flow_report_stream_t *stream;
492 ip4_ipfix_template_packet_t *tp;
493 ipfix_message_header_t *h = 0;
494 ipfix_set_header_t *s = 0;
499 vlib_main_t *vm = vlib_get_main ();
501 stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
502 stream = &frm->streams[stream_index];
504 b0->current_data = 0;
505 b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) +
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);
516 ip->ip_version_and_header_length = 0x45;
518 ip->protocol = IP_PROTOCOL_UDP;
519 ip->flags_and_fragment_offset = 0;
520 ip->src_address.as_u32 = frm->src_address.as_u32;
521 ip->dst_address.as_u32 = frm->ipfix_collector.as_u32;
522 udp->src_port = clib_host_to_net_u16 (stream->src_port);
523 udp->dst_port = clib_host_to_net_u16 (frm->collector_port);
526 h->export_time = clib_host_to_net_u32 ((u32)
527 (((f64) frm->unix_time_0) +
528 (vlib_time_now (vm) -
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);
535 *offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
539 nat_ipfix_send (flow_report_main_t *frm, vlib_frame_t *f, vlib_buffer_t *b0,
542 ip4_ipfix_template_packet_t *tp;
543 ipfix_message_header_t *h = 0;
544 ipfix_set_header_t *s = 0;
547 vlib_main_t *vm = vlib_get_main ();
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);
555 s->set_id_length = ipfix_set_id_length (template_id,
557 (sizeof (*ip) + sizeof (*udp) +
559 h->version_length = version_length (b0->current_length -
560 (sizeof (*ip) + sizeof (*udp)));
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));
566 if (frm->udp_checksum)
568 udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
569 if (udp->checksum == 0)
570 udp->checksum = 0xffff;
573 ASSERT (ip4_header_checksum_is_valid (ip));
575 vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
579 nat_ipfix_logging_nat44_ses (u32 thread_index, u8 nat_event, u32 src_ip,
580 u32 nat_src_ip, nat_protocol_t nat_proto,
581 u16 src_port, u16 nat_src_port, u32 fib_index,
584 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
585 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
586 flow_report_main_t *frm = &flow_report_main;
588 vlib_buffer_t *b0 = 0;
591 vlib_main_t *vm = vlib_get_main ();
597 proto = nat_proto_to_ip_proto (nat_proto);
599 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
600 now += silm->milisecond_time_0;
602 b0 = sitd->nat44_session_buffer;
604 if (PREDICT_FALSE (b0 == 0))
609 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
611 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
615 b0 = sitd->nat44_session_buffer = vlib_get_buffer (vm, bi0);
616 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
621 bi0 = vlib_get_buffer_index (vm, b0);
622 offset = sitd->nat44_session_next_record_offset;
625 f = sitd->nat44_session_frame;
626 if (PREDICT_FALSE (f == 0))
629 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
630 sitd->nat44_session_frame = f;
631 to_next = vlib_frame_vector_args (f);
636 if (PREDICT_FALSE (offset == 0))
637 nat_ipfix_header_create (frm, b0, &offset);
639 if (PREDICT_TRUE (do_flush == 0))
641 u64 time_stamp = clib_host_to_net_u64 (now);
642 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
643 offset += sizeof (time_stamp);
645 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
646 offset += sizeof (nat_event);
648 clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
649 offset += sizeof (src_ip);
651 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
652 offset += sizeof (nat_src_ip);
654 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
655 offset += sizeof (proto);
657 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
658 offset += sizeof (src_port);
660 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
661 offset += sizeof (nat_src_port);
663 vrf_id = fib_table_get_table_id (fib_index, FIB_PROTOCOL_IP4);
664 vrf_id = clib_host_to_net_u32 (vrf_id);
665 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
666 offset += sizeof (vrf_id);
668 b0->current_length += NAT44_SESSION_CREATE_LEN;
672 (do_flush || (offset + NAT44_SESSION_CREATE_LEN) > frm->path_mtu))
674 template_id = clib_atomic_fetch_or (
675 &silm->nat44_session_template_id,
677 nat_ipfix_send (frm, f, b0, template_id);
678 sitd->nat44_session_frame = 0;
679 sitd->nat44_session_buffer = 0;
682 sitd->nat44_session_next_record_offset = offset;
686 nat_ipfix_logging_addr_exhausted (u32 thread_index, u32 pool_id, int do_flush)
688 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
689 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
690 flow_report_main_t *frm = &flow_report_main;
692 vlib_buffer_t *b0 = 0;
695 vlib_main_t *vm = vlib_get_main ();
697 u8 nat_event = NAT_ADDRESSES_EXHAUTED;
700 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
701 now += silm->milisecond_time_0;
703 b0 = sitd->addr_exhausted_buffer;
705 if (PREDICT_FALSE (b0 == 0))
710 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
712 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
716 b0 = sitd->addr_exhausted_buffer = vlib_get_buffer (vm, bi0);
717 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
722 bi0 = vlib_get_buffer_index (vm, b0);
723 offset = sitd->addr_exhausted_next_record_offset;
726 f = sitd->addr_exhausted_frame;
727 if (PREDICT_FALSE (f == 0))
730 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
731 sitd->addr_exhausted_frame = f;
732 to_next = vlib_frame_vector_args (f);
737 if (PREDICT_FALSE (offset == 0))
738 nat_ipfix_header_create (frm, b0, &offset);
740 if (PREDICT_TRUE (do_flush == 0))
742 u64 time_stamp = clib_host_to_net_u64 (now);
743 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
744 offset += sizeof (time_stamp);
746 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
747 offset += sizeof (nat_event);
749 clib_memcpy_fast (b0->data + offset, &pool_id, sizeof (pool_id));
750 offset += sizeof (pool_id);
752 b0->current_length += NAT_ADDRESSES_EXHAUTED_LEN;
756 (do_flush || (offset + NAT_ADDRESSES_EXHAUTED_LEN) > frm->path_mtu))
758 template_id = clib_atomic_fetch_or (
759 &silm->addr_exhausted_template_id,
761 nat_ipfix_send (frm, f, b0, template_id);
762 sitd->addr_exhausted_frame = 0;
763 sitd->addr_exhausted_buffer = 0;
766 sitd->addr_exhausted_next_record_offset = offset;
770 nat_ipfix_logging_max_entries_per_usr (u32 thread_index,
771 u32 limit, u32 src_ip, int do_flush)
773 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
774 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
775 flow_report_main_t *frm = &flow_report_main;
777 vlib_buffer_t *b0 = 0;
780 vlib_main_t *vm = vlib_get_main ();
782 u8 nat_event = QUOTA_EXCEEDED;
783 u32 quota_event = clib_host_to_net_u32 (MAX_ENTRIES_PER_USER);
786 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
787 now += silm->milisecond_time_0;
789 b0 = sitd->max_entries_per_user_buffer;
791 if (PREDICT_FALSE (b0 == 0))
796 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
798 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
802 b0 = sitd->max_entries_per_user_buffer = vlib_get_buffer (vm, bi0);
803 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
808 bi0 = vlib_get_buffer_index (vm, b0);
809 offset = sitd->max_entries_per_user_next_record_offset;
812 f = sitd->max_entries_per_user_frame;
813 if (PREDICT_FALSE (f == 0))
816 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
817 sitd->max_entries_per_user_frame = f;
818 to_next = vlib_frame_vector_args (f);
823 if (PREDICT_FALSE (offset == 0))
824 nat_ipfix_header_create (frm, b0, &offset);
826 if (PREDICT_TRUE (do_flush == 0))
828 u64 time_stamp = clib_host_to_net_u64 (now);
829 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
830 offset += sizeof (time_stamp);
832 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
833 offset += sizeof (nat_event);
835 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
836 offset += sizeof (quota_event);
838 limit = clib_host_to_net_u32 (limit);
839 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
840 offset += sizeof (limit);
842 clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
843 offset += sizeof (src_ip);
845 b0->current_length += MAX_ENTRIES_PER_USER_LEN;
849 (do_flush || (offset + MAX_ENTRIES_PER_USER_LEN) > frm->path_mtu))
851 template_id = clib_atomic_fetch_or (
852 &silm->max_entries_per_user_template_id,
854 nat_ipfix_send (frm, f, b0, template_id);
855 sitd->max_entries_per_user_frame = 0;
856 sitd->max_entries_per_user_buffer = 0;
859 sitd->max_entries_per_user_next_record_offset = offset;
863 nat_ipfix_logging_max_ses (u32 thread_index, u32 limit, int do_flush)
865 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
866 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
867 flow_report_main_t *frm = &flow_report_main;
869 vlib_buffer_t *b0 = 0;
872 vlib_main_t *vm = vlib_get_main ();
874 u8 nat_event = QUOTA_EXCEEDED;
875 u32 quota_event = clib_host_to_net_u32 (MAX_SESSION_ENTRIES);
878 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
879 now += silm->milisecond_time_0;
881 b0 = sitd->max_sessions_buffer;
883 if (PREDICT_FALSE (b0 == 0))
888 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
890 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
894 b0 = sitd->max_sessions_buffer = vlib_get_buffer (vm, bi0);
895 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
900 bi0 = vlib_get_buffer_index (vm, b0);
901 offset = sitd->max_sessions_next_record_offset;
904 f = sitd->max_sessions_frame;
905 if (PREDICT_FALSE (f == 0))
908 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
909 sitd->max_sessions_frame = f;
910 to_next = vlib_frame_vector_args (f);
915 if (PREDICT_FALSE (offset == 0))
916 nat_ipfix_header_create (frm, b0, &offset);
918 if (PREDICT_TRUE (do_flush == 0))
920 u64 time_stamp = clib_host_to_net_u64 (now);
921 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
922 offset += sizeof (time_stamp);
924 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
925 offset += sizeof (nat_event);
927 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
928 offset += sizeof (quota_event);
930 limit = clib_host_to_net_u32 (limit);
931 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
932 offset += sizeof (limit);
934 b0->current_length += MAX_SESSIONS_LEN;
938 (do_flush || (offset + MAX_SESSIONS_LEN) > frm->path_mtu))
940 template_id = clib_atomic_fetch_or (
941 &silm->max_sessions_template_id,
943 nat_ipfix_send (frm, f, b0, template_id);
944 sitd->max_sessions_frame = 0;
945 sitd->max_sessions_buffer = 0;
948 sitd->max_sessions_next_record_offset = offset;
952 nat_ipfix_logging_max_bib (u32 thread_index, u32 limit, int do_flush)
954 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
955 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
956 flow_report_main_t *frm = &flow_report_main;
958 vlib_buffer_t *b0 = 0;
961 vlib_main_t *vm = vlib_get_main ();
963 u8 nat_event = QUOTA_EXCEEDED;
964 u32 quota_event = clib_host_to_net_u32 (MAX_BIB_ENTRIES);
967 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
968 now += silm->milisecond_time_0;
970 b0 = sitd->max_bibs_buffer;
972 if (PREDICT_FALSE (b0 == 0))
977 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
979 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
983 b0 = sitd->max_bibs_buffer = vlib_get_buffer (vm, bi0);
984 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
989 bi0 = vlib_get_buffer_index (vm, b0);
990 offset = sitd->max_bibs_next_record_offset;
993 f = sitd->max_bibs_frame;
994 if (PREDICT_FALSE (f == 0))
997 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
998 sitd->max_bibs_frame = f;
999 to_next = vlib_frame_vector_args (f);
1004 if (PREDICT_FALSE (offset == 0))
1005 nat_ipfix_header_create (frm, b0, &offset);
1007 if (PREDICT_TRUE (do_flush == 0))
1009 u64 time_stamp = clib_host_to_net_u64 (now);
1010 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1011 offset += sizeof (time_stamp);
1013 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1014 offset += sizeof (nat_event);
1016 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
1017 offset += sizeof (quota_event);
1019 limit = clib_host_to_net_u32 (limit);
1020 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
1021 offset += sizeof (limit);
1023 b0->current_length += MAX_BIBS_LEN;
1027 (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1029 template_id = clib_atomic_fetch_or (
1030 &silm->max_bibs_template_id,
1032 nat_ipfix_send (frm, f, b0, template_id);
1033 sitd->max_bibs_frame = 0;
1034 sitd->max_bibs_buffer = 0;
1037 sitd->max_bibs_next_record_offset = offset;
1041 nat_ipfix_logging_nat64_bibe (u32 thread_index, u8 nat_event,
1042 ip6_address_t * src_ip, u32 nat_src_ip,
1043 u8 proto, u16 src_port, u16 nat_src_port,
1044 u32 vrf_id, int do_flush)
1046 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1047 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1048 flow_report_main_t *frm = &flow_report_main;
1050 vlib_buffer_t *b0 = 0;
1053 vlib_main_t *vm = vlib_get_main ();
1057 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1058 now += silm->milisecond_time_0;
1060 b0 = sitd->nat64_bib_buffer;
1062 if (PREDICT_FALSE (b0 == 0))
1067 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1069 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1073 b0 = sitd->nat64_bib_buffer = vlib_get_buffer (vm, bi0);
1074 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1079 bi0 = vlib_get_buffer_index (vm, b0);
1080 offset = sitd->nat64_bib_next_record_offset;
1083 f = sitd->nat64_bib_frame;
1084 if (PREDICT_FALSE (f == 0))
1087 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1088 sitd->nat64_bib_frame = f;
1089 to_next = vlib_frame_vector_args (f);
1094 if (PREDICT_FALSE (offset == 0))
1095 nat_ipfix_header_create (frm, b0, &offset);
1097 if (PREDICT_TRUE (do_flush == 0))
1099 u64 time_stamp = clib_host_to_net_u64 (now);
1100 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1101 offset += sizeof (time_stamp);
1103 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1104 offset += sizeof (nat_event);
1106 clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1107 offset += sizeof (ip6_address_t);
1109 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1110 offset += sizeof (nat_src_ip);
1112 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1113 offset += sizeof (proto);
1115 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1116 offset += sizeof (src_port);
1118 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1119 offset += sizeof (nat_src_port);
1121 vrf_id = clib_host_to_net_u32 (vrf_id);
1122 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1123 offset += sizeof (vrf_id);
1125 b0->current_length += NAT64_BIB_LEN;
1129 (do_flush || (offset + NAT64_BIB_LEN) > frm->path_mtu))
1131 template_id = clib_atomic_fetch_or (
1132 &silm->nat64_bib_template_id,
1134 nat_ipfix_send (frm, f, b0, template_id);
1135 sitd->nat64_bib_frame = 0;
1136 sitd->nat64_bib_buffer = 0;
1139 sitd->nat64_bib_next_record_offset = offset;
1143 nat_ipfix_logging_nat64_ses (u32 thread_index, u8 nat_event,
1144 ip6_address_t * src_ip, u32 nat_src_ip,
1145 u8 proto, u16 src_port, u16 nat_src_port,
1146 ip6_address_t * dst_ip, u32 nat_dst_ip,
1147 u16 dst_port, u16 nat_dst_port,
1148 u32 vrf_id, int do_flush)
1150 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1151 nat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1152 flow_report_main_t *frm = &flow_report_main;
1154 vlib_buffer_t *b0 = 0;
1157 vlib_main_t *vm = vlib_get_main ();
1161 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1162 now += silm->milisecond_time_0;
1164 b0 = sitd->nat64_ses_buffer;
1166 if (PREDICT_FALSE (b0 == 0))
1171 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1173 //nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1177 b0 = sitd->nat64_ses_buffer = vlib_get_buffer (vm, bi0);
1178 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1183 bi0 = vlib_get_buffer_index (vm, b0);
1184 offset = sitd->nat64_ses_next_record_offset;
1187 f = sitd->nat64_ses_frame;
1188 if (PREDICT_FALSE (f == 0))
1191 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1192 sitd->nat64_ses_frame = f;
1193 to_next = vlib_frame_vector_args (f);
1198 if (PREDICT_FALSE (offset == 0))
1199 nat_ipfix_header_create (frm, b0, &offset);
1201 if (PREDICT_TRUE (do_flush == 0))
1203 u64 time_stamp = clib_host_to_net_u64 (now);
1204 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1205 offset += sizeof (time_stamp);
1207 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1208 offset += sizeof (nat_event);
1210 clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1211 offset += sizeof (ip6_address_t);
1213 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1214 offset += sizeof (nat_src_ip);
1216 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1217 offset += sizeof (proto);
1219 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1220 offset += sizeof (src_port);
1222 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1223 offset += sizeof (nat_src_port);
1225 clib_memcpy_fast (b0->data + offset, dst_ip, sizeof (ip6_address_t));
1226 offset += sizeof (ip6_address_t);
1228 clib_memcpy_fast (b0->data + offset, &nat_dst_ip, sizeof (nat_dst_ip));
1229 offset += sizeof (nat_dst_ip);
1231 clib_memcpy_fast (b0->data + offset, &dst_port, sizeof (dst_port));
1232 offset += sizeof (dst_port);
1234 clib_memcpy_fast (b0->data + offset, &nat_dst_port, sizeof (nat_dst_port));
1235 offset += sizeof (nat_dst_port);
1237 vrf_id = clib_host_to_net_u32 (vrf_id);
1238 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1239 offset += sizeof (vrf_id);
1241 b0->current_length += NAT64_SES_LEN;
1245 (do_flush || (offset + NAT64_SES_LEN) > frm->path_mtu))
1247 template_id = clib_atomic_fetch_or (
1248 &silm->nat64_ses_template_id,
1250 nat_ipfix_send (frm, f, b0, template_id);
1251 sitd->nat64_ses_frame = 0;
1252 sitd->nat64_ses_buffer = 0;
1255 sitd->nat64_ses_next_record_offset = offset;
1259 nat_ipfix_flush (u32 thread_index)
1263 nat_ipfix_logging_nat44_ses (thread_index,
1264 0, 0, 0, 0, 0, 0, 0, do_flush);
1265 nat_ipfix_logging_addr_exhausted (thread_index, 0, do_flush);
1266 nat_ipfix_logging_max_entries_per_usr (thread_index, 0, 0, do_flush);
1267 nat_ipfix_logging_max_ses (thread_index, 0, do_flush);
1268 nat_ipfix_logging_max_bib (thread_index, 0, do_flush);
1269 nat_ipfix_logging_nat64_bibe (thread_index,
1270 0, 0, 0, 0, 0, 0, 0, do_flush);
1271 nat_ipfix_logging_nat64_ses (thread_index,
1272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, do_flush);
1276 nat_ipfix_logging_enabled ()
1278 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1279 return !clib_atomic_fetch_or(&silm->enabled, 0);
1283 nat_ipfix_flush_from_main (void)
1285 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1286 vlib_main_t *worker_vm;
1289 if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0)))
1292 if (PREDICT_FALSE (!silm->worker_vms))
1294 for (i = 1; i < vlib_get_n_threads (); i++)
1296 worker_vm = vlib_get_main_by_index (i);
1298 vec_add1 (silm->worker_vms, worker_vm);
1302 /* Trigger flush for each worker thread */
1303 for (i = 0; i < vec_len (silm->worker_vms); i++)
1305 worker_vm = silm->worker_vms[i];
1307 vlib_node_set_interrupt_pending (worker_vm,
1308 nat_ipfix_flush_node.index);
1311 /* Finally flush main thread */
1312 nat_ipfix_flush (0);
1316 * @brief Generate NAT44 session create event
1318 * @param thread_index thread index
1319 * @param src_ip source IPv4 address
1320 * @param nat_src_ip transaltes source IPv4 address
1321 * @param nat_proto NAT transport protocol
1322 * @param src_port source port
1323 * @param nat_src_port translated source port
1324 * @param vrf_id VRF ID
1327 nat_ipfix_logging_nat44_ses_create (u32 thread_index,
1330 nat_protocol_t nat_proto,
1332 u16 nat_src_port, u32 fib_index)
1334 skip_if_disabled ();
1336 nat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_CREATE, src_ip,
1337 nat_src_ip, nat_proto, src_port, nat_src_port,
1342 * @brief Generate NAT44 session delete event
1344 * @param thread_index thread index
1345 * @param src_ip source IPv4 address
1346 * @param nat_src_ip transaltes source IPv4 address
1347 * @param nat_proto NAT transport protocol
1348 * @param src_port source port
1349 * @param nat_src_port translated source port
1350 * @param vrf_id VRF ID
1353 nat_ipfix_logging_nat44_ses_delete (u32 thread_index,
1356 nat_protocol_t nat_proto,
1358 u16 nat_src_port, u32 fib_index)
1360 skip_if_disabled ();
1362 nat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_DELETE, src_ip,
1363 nat_src_ip, nat_proto, src_port, nat_src_port,
1368 * @brief Generate NAT addresses exhausted event
1370 * @param thread_index thread index
1371 * @param pool_id NAT pool ID
1374 nat_ipfix_logging_addresses_exhausted (u32 thread_index, u32 pool_id)
1376 //TODO: This event SHOULD be rate limited
1377 skip_if_disabled ();
1379 nat_ipfix_logging_addr_exhausted (thread_index, pool_id, 0);
1383 * @brief Generate maximum entries per user exceeded event
1385 * @param thread_index thread index
1386 * @param limit maximum NAT entries that can be created per user
1387 * @param src_ip source IPv4 address
1390 nat_ipfix_logging_max_entries_per_user (u32 thread_index, u32 limit, u32 src_ip)
1392 //TODO: This event SHOULD be rate limited
1393 skip_if_disabled ();
1395 nat_ipfix_logging_max_entries_per_usr (thread_index, limit, src_ip, 0);
1399 deterministic_nat_data_callback
1400 (flow_report_main_t * frm,
1403 u32 * to_next, u32 node_index)
1405 nat_ipfix_flush_from_main();
1411 * @brief Generate maximum session entries exceeded event
1413 * @param thread_index thread index
1414 * @param limit configured limit
1417 nat_ipfix_logging_max_sessions (u32 thread_index, u32 limit)
1419 //TODO: This event SHOULD be rate limited
1420 skip_if_disabled ();
1422 nat_ipfix_logging_max_ses (thread_index, limit, 0);
1426 * @brief Generate maximum BIB entries exceeded event
1428 * @param thread_index thread index
1429 * @param limit configured limit
1432 nat_ipfix_logging_max_bibs (u32 thread_index, u32 limit)
1434 //TODO: This event SHOULD be rate limited
1435 skip_if_disabled ();
1437 nat_ipfix_logging_max_bib (thread_index, limit, 0);
1441 * @brief Generate NAT64 BIB create and delete events
1443 * @param thread_index thread index
1444 * @param src_ip source IPv6 address
1445 * @param nat_src_ip transaltes source IPv4 address
1446 * @param proto L4 protocol
1447 * @param src_port source port
1448 * @param nat_src_port translated source port
1449 * @param vrf_id VRF ID
1450 * @param is_create non-zero value if create event otherwise delete event
1453 nat_ipfix_logging_nat64_bib (u32 thread_index, ip6_address_t * src_ip,
1454 ip4_address_t * nat_src_ip, u8 proto,
1455 u16 src_port, u16 nat_src_port, u32 vrf_id,
1460 skip_if_disabled ();
1462 nat_event = is_create ? NAT64_BIB_CREATE : NAT64_BIB_DELETE;
1464 nat_ipfix_logging_nat64_bibe (thread_index, nat_event, src_ip,
1465 nat_src_ip->as_u32, proto, src_port,
1466 nat_src_port, vrf_id, 0);
1470 * @brief Generate NAT64 session create and delete events
1472 * @param thread_index thread index
1473 * @param src_ip source IPv6 address
1474 * @param nat_src_ip transaltes source IPv4 address
1475 * @param proto L4 protocol
1476 * @param src_port source port
1477 * @param nat_src_port translated source port
1478 * @param dst_ip destination IPv6 address
1479 * @param nat_dst_ip destination IPv4 address
1480 * @param dst_port destination port
1481 * @param nat_dst_port translated destination port
1482 * @param vrf_id VRF ID
1483 * @param is_create non-zero value if create event otherwise delete event
1486 nat_ipfix_logging_nat64_session (u32 thread_index,
1487 ip6_address_t * src_ip,
1488 ip4_address_t * nat_src_ip, u8 proto,
1489 u16 src_port, u16 nat_src_port,
1490 ip6_address_t * dst_ip,
1491 ip4_address_t * nat_dst_ip, u16 dst_port,
1492 u16 nat_dst_port, u32 vrf_id, u8 is_create)
1496 skip_if_disabled ();
1498 nat_event = is_create ? NAT64_SESSION_CREATE : NAT64_SESSION_DELETE;
1500 nat_ipfix_logging_nat64_ses (thread_index, nat_event, src_ip,
1501 nat_src_ip->as_u32, proto, src_port,
1502 nat_src_port, dst_ip, nat_dst_ip->as_u32,
1503 dst_port, nat_dst_port, vrf_id, 0);
1507 data_callback (flow_report_main_t * frm, flow_report_t * fr,
1508 vlib_frame_t * f, u32 * to_next, u32 node_index)
1510 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1512 if (PREDICT_FALSE (++silm->call_counter >= vec_len (frm->reports)))
1514 nat_ipfix_flush_from_main();
1515 silm->call_counter = 0;
1522 * @brief Enable/disable NAT plugin IPFIX logging
1524 * @param enable 1 if enable, 0 if disable
1525 * @param domain_id observation domain ID
1526 * @param src_port source port number
1528 * @returns 0 if success
1531 nat_ipfix_logging_enable_disable (int enable, u32 domain_id, u16 src_port)
1533 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1534 flow_report_main_t *frm = &flow_report_main;
1535 vnet_flow_report_add_del_args_t a;
1537 u8 e = enable ? 1 : 0;
1539 if (clib_atomic_cmp_and_swap (&silm->enabled, e ^ 1, e) == e)
1542 clib_memset (&a, 0, sizeof (a));
1544 a.domain_id = domain_id ? domain_id : 1;
1545 a.src_port = src_port ? src_port : UDP_DST_PORT_ipfix;
1546 a.flow_data_callback = data_callback;
1548 a.rewrite_callback = nat_template_rewrite_nat44_session;
1549 rv = vnet_flow_report_add_del (frm, &a, NULL);
1552 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1556 a.rewrite_callback = nat_template_rewrite_addr_exhausted;
1557 rv = vnet_flow_report_add_del (frm, &a, NULL);
1560 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1564 a.rewrite_callback = nat_template_rewrite_max_sessions;
1565 rv = vnet_flow_report_add_del (frm, &a, NULL);
1568 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1572 a.rewrite_callback = nat_template_rewrite_max_bibs;
1573 rv = vnet_flow_report_add_del (frm, &a, NULL);
1576 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1580 a.rewrite_callback = nat_template_rewrite_nat64_bib;
1581 rv = vnet_flow_report_add_del (frm, &a, NULL);
1584 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1588 a.rewrite_callback = nat_template_rewrite_nat64_session;
1589 rv = vnet_flow_report_add_del (frm, &a, NULL);
1592 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1596 // if endpoint dependent per user max entries is also required
1598 a.rewrite_callback = nat_template_rewrite_max_entries_per_usr;
1599 rv = vnet_flow_report_add_del (frm, &a, NULL);
1602 //nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1611 * @brief Initialize NAT plugin IPFIX logging
1613 * @param vm vlib main
1616 nat_ipfix_logging_init (vlib_main_t * vm)
1618 nat_ipfix_logging_main_t *silm = &nat_ipfix_logging_main;
1619 vlib_thread_main_t *tm = vlib_get_thread_main ();
1622 silm->worker_vms = 0;
1623 silm->call_counter = 0;
1625 /* Set up time reference pair */
1626 silm->vlib_time_0 = vlib_time_now (vm);
1627 silm->milisecond_time_0 = unix_time_now_nsec () * 1e-6;
1629 vec_validate (silm->per_thread_data, tm->n_vlib_mains - 1);
1633 ipfix_flush_process (vlib_main_t *vm,
1634 vlib_node_runtime_t *rt,
1637 nat_ipfix_flush(vm->thread_index);
1642 VLIB_REGISTER_NODE (nat_ipfix_flush_node) = {
1643 .function = ipfix_flush_process,
1644 .name = "nat-ipfix-flush",
1645 .type = VLIB_NODE_TYPE_INPUT,
1646 .state = VLIB_NODE_STATE_INTERRUPT,