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/ipfix-export/flow_report.h>
19 #include <vlibmemory/api.h>
20 #include <nat/nat_inlines.h>
21 #include <nat/nat_ipfix_logging.h>
22 #include <vppinfra/atomics.h>
24 vlib_node_registration_t snat_ipfix_flush_node;
25 snat_ipfix_logging_main_t snat_ipfix_logging_main;
27 #define NAT44_SESSION_CREATE_LEN 26
28 #define NAT_ADDRESSES_EXHAUTED_LEN 13
29 #define MAX_ENTRIES_PER_USER_LEN 21
30 #define MAX_SESSIONS_LEN 17
31 #define MAX_BIBS_LEN 17
32 #define MAX_FRAGMENTS_IP4_LEN 21
33 #define MAX_FRAGMENTS_IP6_LEN 33
34 #define NAT64_BIB_LEN 38
35 #define NAT64_SES_LEN 62
37 #define NAT44_SESSION_CREATE_FIELD_COUNT 8
38 #define NAT_ADDRESSES_EXHAUTED_FIELD_COUNT 3
39 #define MAX_ENTRIES_PER_USER_FIELD_COUNT 5
40 #define MAX_SESSIONS_FIELD_COUNT 4
41 #define MAX_BIBS_FIELD_COUNT 4
42 #define MAX_FRAGMENTS_FIELD_COUNT 5
43 #define NAT64_BIB_FIELD_COUNT 8
44 #define NAT64_SES_FIELD_COUNT 12
51 snat_protocol_t snat_proto;
55 } snat_ipfix_logging_nat44_ses_args_t;
60 } snat_ipfix_logging_addr_exhausted_args_t;
66 } snat_ipfix_logging_max_entries_per_user_args_t;
71 } nat_ipfix_logging_max_sessions_args_t;
76 } nat_ipfix_logging_max_bibs_args_t;
82 } nat_ipfix_logging_max_frags_ip4_args_t;
88 } nat_ipfix_logging_max_frags_ip6_args_t;
103 } nat_ipfix_logging_nat64_ses_args_t;
114 } nat_ipfix_logging_nat64_bib_args_t;
116 #define skip_if_disabled() \
118 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main; \
119 if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0))) \
123 #define update_template_id(old_id, new_id) \
125 u16 template_id = clib_atomic_fetch_or(old_id, 0); \
126 clib_atomic_cmp_and_swap(old_id, template_id, new_id); \
130 * @brief Create an IPFIX template packet rewrite string
132 * @param frm flow report main
133 * @param fr flow report
134 * @param collector_address collector address
135 * @param src_address source address
136 * @param collector_port collector
137 * @param event NAT event ID
138 * @param quota_event NAT quota exceeded event ID
140 * @returns template packet
143 snat_template_rewrite (flow_report_main_t * frm,
145 ip4_address_t * collector_address,
146 ip4_address_t * src_address,
148 nat_event_t event, quota_exceed_event_t quota_event)
150 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
153 ipfix_message_header_t *h;
154 ipfix_set_header_t *s;
155 ipfix_template_header_t *t;
156 ipfix_field_specifier_t *f;
157 ipfix_field_specifier_t *first_field;
159 ip4_ipfix_template_packet_t *tp;
161 flow_report_stream_t *stream;
164 stream = &frm->streams[fr->stream_index];
166 stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
167 clib_atomic_cmp_and_swap (&silm->stream_index,
168 stream_index, fr->stream_index);
170 if (event == NAT_ADDRESSES_EXHAUTED)
172 field_count = NAT_ADDRESSES_EXHAUTED_FIELD_COUNT;
174 update_template_id(&silm->addr_exhausted_template_id,
177 else if (event == NAT44_SESSION_CREATE)
179 field_count = NAT44_SESSION_CREATE_FIELD_COUNT;
181 update_template_id(&silm->nat44_session_template_id,
184 else if (event == NAT64_BIB_CREATE)
186 field_count = NAT64_BIB_FIELD_COUNT;
188 update_template_id(&silm->nat64_bib_template_id,
191 else if (event == NAT64_SESSION_CREATE)
193 field_count = NAT64_SES_FIELD_COUNT;
195 update_template_id(&silm->nat64_ses_template_id,
198 else if (event == QUOTA_EXCEEDED)
200 if (quota_event == MAX_ENTRIES_PER_USER)
202 field_count = MAX_ENTRIES_PER_USER_FIELD_COUNT;
204 update_template_id(&silm->max_entries_per_user_template_id,
208 else if (quota_event == MAX_SESSION_ENTRIES)
210 field_count = MAX_SESSIONS_FIELD_COUNT;
212 update_template_id(&silm->max_sessions_template_id,
215 else if (quota_event == MAX_BIB_ENTRIES)
217 field_count = MAX_BIBS_FIELD_COUNT;
219 update_template_id(&silm->max_bibs_template_id,
224 /* allocate rewrite space */
225 vec_validate_aligned (rewrite,
226 sizeof (ip4_ipfix_template_packet_t)
227 + field_count * sizeof (ipfix_field_specifier_t) - 1,
228 CLIB_CACHE_LINE_BYTES);
230 tp = (ip4_ipfix_template_packet_t *) rewrite;
231 ip = (ip4_header_t *) & tp->ip4;
232 udp = (udp_header_t *) (ip + 1);
233 h = (ipfix_message_header_t *) (udp + 1);
234 s = (ipfix_set_header_t *) (h + 1);
235 t = (ipfix_template_header_t *) (s + 1);
236 first_field = f = (ipfix_field_specifier_t *) (t + 1);
238 ip->ip_version_and_header_length = 0x45;
240 ip->protocol = IP_PROTOCOL_UDP;
241 ip->src_address.as_u32 = src_address->as_u32;
242 ip->dst_address.as_u32 = collector_address->as_u32;
243 udp->src_port = clib_host_to_net_u16 (stream->src_port);
244 udp->dst_port = clib_host_to_net_u16 (collector_port);
245 udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip));
247 /* FIXUP: message header export_time */
248 h->domain_id = clib_host_to_net_u32 (stream->domain_id);
250 /* Add TLVs to the template */
251 if (event == NAT_ADDRESSES_EXHAUTED)
253 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
255 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
257 f->e_id_length = ipfix_e_id_length (0, natPoolId, 4);
260 else if (event == NAT44_SESSION_CREATE)
262 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
264 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
266 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
268 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
270 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
272 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
274 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
276 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
279 else if (event == NAT64_BIB_CREATE)
281 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
283 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
285 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
287 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
289 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
291 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
293 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
295 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
298 else if (event == NAT64_SESSION_CREATE)
300 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
302 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
304 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
306 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
308 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
310 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
312 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
314 f->e_id_length = ipfix_e_id_length (0, destinationIPv6Address, 16);
316 f->e_id_length = ipfix_e_id_length (0, postNATDestinationIPv4Address, 4);
318 f->e_id_length = ipfix_e_id_length (0, destinationTransportPort, 2);
320 f->e_id_length = ipfix_e_id_length (0, postNAPTDestinationTransportPort,
323 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
326 else if (event == QUOTA_EXCEEDED)
328 if (quota_event == MAX_ENTRIES_PER_USER)
330 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
333 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
335 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
337 f->e_id_length = ipfix_e_id_length (0, maxEntriesPerUser, 4);
339 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
342 else if (quota_event == MAX_SESSION_ENTRIES)
344 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
347 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
349 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
351 f->e_id_length = ipfix_e_id_length (0, maxSessionEntries, 4);
354 else if (quota_event == MAX_BIB_ENTRIES)
356 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
359 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
361 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
363 f->e_id_length = ipfix_e_id_length (0, maxBIBEntries, 4);
368 /* Back to the template packet... */
369 ip = (ip4_header_t *) & tp->ip4;
370 udp = (udp_header_t *) (ip + 1);
372 ASSERT (f - first_field);
373 /* Field count in this template */
374 t->id_count = ipfix_id_count (fr->template_id, f - first_field);
376 /* set length in octets */
378 ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s);
380 /* message length in octets */
381 h->version_length = version_length ((u8 *) f - (u8 *) h);
383 ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip);
384 ip->checksum = ip4_header_checksum (ip);
390 snat_template_rewrite_addr_exhausted (flow_report_main_t * frm,
392 ip4_address_t * collector_address,
393 ip4_address_t * src_address,
395 ipfix_report_element_t *elts,
396 u32 n_elts, u32 *stream_index)
398 return snat_template_rewrite (frm, fr, collector_address, src_address,
399 collector_port, NAT_ADDRESSES_EXHAUTED, 0);
403 snat_template_rewrite_nat44_session (flow_report_main_t * frm,
405 ip4_address_t * collector_address,
406 ip4_address_t * src_address,
408 ipfix_report_element_t *elts,
409 u32 n_elts, u32 *stream_index)
411 return snat_template_rewrite (frm, fr, collector_address, src_address,
412 collector_port, NAT44_SESSION_CREATE, 0);
416 snat_template_rewrite_max_entries_per_usr (flow_report_main_t * frm,
418 ip4_address_t * collector_address,
419 ip4_address_t * src_address,
421 ipfix_report_element_t *elts,
422 u32 n_elts, u32 *stream_index)
424 return snat_template_rewrite (frm, fr, collector_address, src_address,
425 collector_port, QUOTA_EXCEEDED,
426 MAX_ENTRIES_PER_USER);
430 nat_template_rewrite_max_sessions (flow_report_main_t * frm,
432 ip4_address_t * collector_address,
433 ip4_address_t * src_address,
435 ipfix_report_element_t *elts,
436 u32 n_elts, u32 *stream_index)
438 return snat_template_rewrite (frm, fr, collector_address, src_address,
439 collector_port, QUOTA_EXCEEDED,
440 MAX_SESSION_ENTRIES);
444 nat_template_rewrite_max_bibs (flow_report_main_t * frm,
446 ip4_address_t * collector_address,
447 ip4_address_t * src_address,
449 ipfix_report_element_t *elts,
450 u32 n_elts, u32 *stream_index)
452 return snat_template_rewrite (frm, fr, collector_address, src_address,
453 collector_port, QUOTA_EXCEEDED,
458 nat_template_rewrite_nat64_bib (flow_report_main_t * frm,
460 ip4_address_t * collector_address,
461 ip4_address_t * src_address,
463 ipfix_report_element_t *elts,
464 u32 n_elts, u32 *stream_index)
466 return snat_template_rewrite (frm, fr, collector_address, src_address,
467 collector_port, NAT64_BIB_CREATE, 0);
471 nat_template_rewrite_nat64_session (flow_report_main_t * frm,
473 ip4_address_t * collector_address,
474 ip4_address_t * src_address,
476 ipfix_report_element_t *elts,
477 u32 n_elts, u32 *stream_index)
479 return snat_template_rewrite (frm, fr, collector_address, src_address,
480 collector_port, NAT64_SESSION_CREATE, 0);
484 snat_ipfix_header_create (flow_report_main_t * frm,
485 vlib_buffer_t * b0, u32 * offset)
487 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
488 flow_report_stream_t *stream;
489 ip4_ipfix_template_packet_t *tp;
490 ipfix_message_header_t *h = 0;
491 ipfix_set_header_t *s = 0;
497 stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
498 stream = &frm->streams[stream_index];
500 b0->current_data = 0;
501 b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) +
503 b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VNET_BUFFER_F_FLOW_REPORT);
504 vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
505 vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index;
506 tp = vlib_buffer_get_current (b0);
507 ip = (ip4_header_t *) & tp->ip4;
508 udp = (udp_header_t *) (ip + 1);
509 h = (ipfix_message_header_t *) (udp + 1);
510 s = (ipfix_set_header_t *) (h + 1);
512 ip->ip_version_and_header_length = 0x45;
514 ip->protocol = IP_PROTOCOL_UDP;
515 ip->flags_and_fragment_offset = 0;
516 ip->src_address.as_u32 = frm->src_address.as_u32;
517 ip->dst_address.as_u32 = frm->ipfix_collector.as_u32;
518 udp->src_port = clib_host_to_net_u16 (stream->src_port);
519 udp->dst_port = clib_host_to_net_u16 (frm->collector_port);
522 h->export_time = clib_host_to_net_u32 ((u32)
523 (((f64) frm->unix_time_0) +
524 (vlib_time_now (frm->vlib_main) -
527 sequence_number = clib_atomic_fetch_add (&stream->sequence_number, 1);
528 h->sequence_number = clib_host_to_net_u32 (sequence_number);
529 h->domain_id = clib_host_to_net_u32 (stream->domain_id);
531 *offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
535 snat_ipfix_send (flow_report_main_t * frm,
536 vlib_frame_t * f, vlib_buffer_t * b0, u16 template_id)
538 ip4_ipfix_template_packet_t *tp;
539 ipfix_message_header_t *h = 0;
540 ipfix_set_header_t *s = 0;
543 vlib_main_t *vm = frm->vlib_main;
545 tp = vlib_buffer_get_current (b0);
546 ip = (ip4_header_t *) & tp->ip4;
547 udp = (udp_header_t *) (ip + 1);
548 h = (ipfix_message_header_t *) (udp + 1);
549 s = (ipfix_set_header_t *) (h + 1);
551 s->set_id_length = ipfix_set_id_length (template_id,
553 (sizeof (*ip) + sizeof (*udp) +
555 h->version_length = version_length (b0->current_length -
556 (sizeof (*ip) + sizeof (*udp)));
558 ip->length = clib_host_to_net_u16 (b0->current_length);
559 ip->checksum = ip4_header_checksum (ip);
560 udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
562 if (frm->udp_checksum)
564 udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
565 if (udp->checksum == 0)
566 udp->checksum = 0xffff;
569 ASSERT (ip->checksum == ip4_header_checksum (ip));
571 vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
575 snat_ipfix_logging_nat44_ses (u32 thread_index, u8 nat_event, u32 src_ip,
576 u32 nat_src_ip, snat_protocol_t snat_proto,
577 u16 src_port, u16 nat_src_port, u32 vrf_id,
580 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
581 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
582 flow_report_main_t *frm = &flow_report_main;
584 vlib_buffer_t *b0 = 0;
587 vlib_main_t *vm = frm->vlib_main;
592 proto = snat_proto_to_ip_proto (snat_proto);
594 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
595 now += silm->milisecond_time_0;
597 b0 = sitd->nat44_session_buffer;
599 if (PREDICT_FALSE (b0 == 0))
604 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
606 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
610 b0 = sitd->nat44_session_buffer = vlib_get_buffer (vm, bi0);
611 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
616 bi0 = vlib_get_buffer_index (vm, b0);
617 offset = sitd->nat44_session_next_record_offset;
620 f = sitd->nat44_session_frame;
621 if (PREDICT_FALSE (f == 0))
624 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
625 sitd->nat44_session_frame = f;
626 to_next = vlib_frame_vector_args (f);
631 if (PREDICT_FALSE (offset == 0))
632 snat_ipfix_header_create (frm, b0, &offset);
634 if (PREDICT_TRUE (do_flush == 0))
636 u64 time_stamp = clib_host_to_net_u64 (now);
637 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
638 offset += sizeof (time_stamp);
640 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
641 offset += sizeof (nat_event);
643 clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
644 offset += sizeof (src_ip);
646 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
647 offset += sizeof (nat_src_ip);
649 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
650 offset += sizeof (proto);
652 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
653 offset += sizeof (src_port);
655 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
656 offset += sizeof (nat_src_port);
658 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
659 offset += sizeof (vrf_id);
661 b0->current_length += NAT44_SESSION_CREATE_LEN;
665 (do_flush || (offset + NAT44_SESSION_CREATE_LEN) > frm->path_mtu))
667 template_id = clib_atomic_fetch_or (
668 &silm->nat44_session_template_id,
670 snat_ipfix_send (frm, f, b0, template_id);
671 sitd->nat44_session_frame = 0;
672 sitd->nat44_session_buffer = 0;
675 sitd->nat44_session_next_record_offset = offset;
679 snat_ipfix_logging_addr_exhausted (u32 thread_index, u32 pool_id, int do_flush)
681 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
682 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
683 flow_report_main_t *frm = &flow_report_main;
685 vlib_buffer_t *b0 = 0;
688 vlib_main_t *vm = frm->vlib_main;
690 u8 nat_event = NAT_ADDRESSES_EXHAUTED;
693 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
694 now += silm->milisecond_time_0;
696 b0 = sitd->addr_exhausted_buffer;
698 if (PREDICT_FALSE (b0 == 0))
703 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
705 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
709 b0 = sitd->addr_exhausted_buffer = vlib_get_buffer (vm, bi0);
710 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
715 bi0 = vlib_get_buffer_index (vm, b0);
716 offset = sitd->addr_exhausted_next_record_offset;
719 f = sitd->addr_exhausted_frame;
720 if (PREDICT_FALSE (f == 0))
723 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
724 sitd->addr_exhausted_frame = f;
725 to_next = vlib_frame_vector_args (f);
730 if (PREDICT_FALSE (offset == 0))
731 snat_ipfix_header_create (frm, b0, &offset);
733 if (PREDICT_TRUE (do_flush == 0))
735 u64 time_stamp = clib_host_to_net_u64 (now);
736 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
737 offset += sizeof (time_stamp);
739 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
740 offset += sizeof (nat_event);
742 clib_memcpy_fast (b0->data + offset, &pool_id, sizeof (pool_id));
743 offset += sizeof (pool_id);
745 b0->current_length += NAT_ADDRESSES_EXHAUTED_LEN;
749 (do_flush || (offset + NAT_ADDRESSES_EXHAUTED_LEN) > frm->path_mtu))
751 template_id = clib_atomic_fetch_or (
752 &silm->addr_exhausted_template_id,
754 snat_ipfix_send (frm, f, b0, template_id);
755 sitd->addr_exhausted_frame = 0;
756 sitd->addr_exhausted_buffer = 0;
759 sitd->addr_exhausted_next_record_offset = offset;
763 snat_ipfix_logging_max_entries_per_usr (u32 thread_index,
764 u32 limit, u32 src_ip, int do_flush)
766 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
767 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
768 flow_report_main_t *frm = &flow_report_main;
770 vlib_buffer_t *b0 = 0;
773 vlib_main_t *vm = frm->vlib_main;
775 u8 nat_event = QUOTA_EXCEEDED;
776 u32 quota_event = MAX_ENTRIES_PER_USER;
779 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
780 now += silm->milisecond_time_0;
782 b0 = sitd->max_entries_per_user_buffer;
784 if (PREDICT_FALSE (b0 == 0))
789 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
791 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
795 b0 = sitd->max_entries_per_user_buffer = vlib_get_buffer (vm, bi0);
796 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
801 bi0 = vlib_get_buffer_index (vm, b0);
802 offset = sitd->max_entries_per_user_next_record_offset;
805 f = sitd->max_entries_per_user_frame;
806 if (PREDICT_FALSE (f == 0))
809 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
810 sitd->max_entries_per_user_frame = f;
811 to_next = vlib_frame_vector_args (f);
816 if (PREDICT_FALSE (offset == 0))
817 snat_ipfix_header_create (frm, b0, &offset);
819 if (PREDICT_TRUE (do_flush == 0))
821 u64 time_stamp = clib_host_to_net_u64 (now);
822 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
823 offset += sizeof (time_stamp);
825 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
826 offset += sizeof (nat_event);
828 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
829 offset += sizeof (quota_event);
831 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
832 offset += sizeof (limit);
834 clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
835 offset += sizeof (src_ip);
837 b0->current_length += MAX_ENTRIES_PER_USER_LEN;
841 (do_flush || (offset + MAX_ENTRIES_PER_USER_LEN) > frm->path_mtu))
843 template_id = clib_atomic_fetch_or (
844 &silm->max_entries_per_user_template_id,
846 snat_ipfix_send (frm, f, b0, template_id);
847 sitd->max_entries_per_user_frame = 0;
848 sitd->max_entries_per_user_buffer = 0;
851 sitd->max_entries_per_user_next_record_offset = offset;
855 nat_ipfix_logging_max_ses (u32 thread_index, u32 limit, int do_flush)
857 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
858 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
859 flow_report_main_t *frm = &flow_report_main;
861 vlib_buffer_t *b0 = 0;
864 vlib_main_t *vm = frm->vlib_main;
866 u8 nat_event = QUOTA_EXCEEDED;
867 u32 quota_event = MAX_SESSION_ENTRIES;
870 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
871 now += silm->milisecond_time_0;
873 b0 = sitd->max_sessions_buffer;
875 if (PREDICT_FALSE (b0 == 0))
880 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
882 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
886 b0 = sitd->max_sessions_buffer = vlib_get_buffer (vm, bi0);
887 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
892 bi0 = vlib_get_buffer_index (vm, b0);
893 offset = sitd->max_sessions_next_record_offset;
896 f = sitd->max_sessions_frame;
897 if (PREDICT_FALSE (f == 0))
900 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
901 sitd->max_sessions_frame = f;
902 to_next = vlib_frame_vector_args (f);
907 if (PREDICT_FALSE (offset == 0))
908 snat_ipfix_header_create (frm, b0, &offset);
910 if (PREDICT_TRUE (do_flush == 0))
912 u64 time_stamp = clib_host_to_net_u64 (now);
913 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
914 offset += sizeof (time_stamp);
916 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
917 offset += sizeof (nat_event);
919 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
920 offset += sizeof (quota_event);
922 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
923 offset += sizeof (limit);
925 b0->current_length += MAX_SESSIONS_LEN;
929 (do_flush || (offset + MAX_SESSIONS_LEN) > frm->path_mtu))
931 template_id = clib_atomic_fetch_or (
932 &silm->max_sessions_template_id,
934 snat_ipfix_send (frm, f, b0, template_id);
935 sitd->max_sessions_frame = 0;
936 sitd->max_sessions_buffer = 0;
939 sitd->max_sessions_next_record_offset = offset;
943 nat_ipfix_logging_max_bib (u32 thread_index, u32 limit, int do_flush)
945 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
946 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
947 flow_report_main_t *frm = &flow_report_main;
949 vlib_buffer_t *b0 = 0;
952 vlib_main_t *vm = frm->vlib_main;
954 u8 nat_event = QUOTA_EXCEEDED;
955 u32 quota_event = MAX_BIB_ENTRIES;
958 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
959 now += silm->milisecond_time_0;
961 b0 = sitd->max_bibs_buffer;
963 if (PREDICT_FALSE (b0 == 0))
968 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
970 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
974 b0 = sitd->max_bibs_buffer = vlib_get_buffer (vm, bi0);
975 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
980 bi0 = vlib_get_buffer_index (vm, b0);
981 offset = sitd->max_bibs_next_record_offset;
984 f = sitd->max_bibs_frame;
985 if (PREDICT_FALSE (f == 0))
988 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
989 sitd->max_bibs_frame = f;
990 to_next = vlib_frame_vector_args (f);
995 if (PREDICT_FALSE (offset == 0))
996 snat_ipfix_header_create (frm, b0, &offset);
998 if (PREDICT_TRUE (do_flush == 0))
1000 u64 time_stamp = clib_host_to_net_u64 (now);
1001 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1002 offset += sizeof (time_stamp);
1004 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1005 offset += sizeof (nat_event);
1007 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
1008 offset += sizeof (quota_event);
1010 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
1011 offset += sizeof (limit);
1013 b0->current_length += MAX_BIBS_LEN;
1017 (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1019 template_id = clib_atomic_fetch_or (
1020 &silm->max_bibs_template_id,
1022 snat_ipfix_send (frm, f, b0, template_id);
1023 sitd->max_bibs_frame = 0;
1024 sitd->max_bibs_buffer = 0;
1027 sitd->max_bibs_next_record_offset = offset;
1031 nat_ipfix_logging_nat64_bibe (u32 thread_index, u8 nat_event,
1032 ip6_address_t * src_ip, u32 nat_src_ip,
1033 u8 proto, u16 src_port, u16 nat_src_port,
1034 u32 vrf_id, int do_flush)
1036 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1037 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1038 flow_report_main_t *frm = &flow_report_main;
1040 vlib_buffer_t *b0 = 0;
1043 vlib_main_t *vm = frm->vlib_main;
1047 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1048 now += silm->milisecond_time_0;
1050 b0 = sitd->nat64_bib_buffer;
1052 if (PREDICT_FALSE (b0 == 0))
1057 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1059 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1063 b0 = sitd->nat64_bib_buffer = vlib_get_buffer (vm, bi0);
1064 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1069 bi0 = vlib_get_buffer_index (vm, b0);
1070 offset = sitd->nat64_bib_next_record_offset;
1073 f = sitd->nat64_bib_frame;
1074 if (PREDICT_FALSE (f == 0))
1077 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1078 sitd->nat64_bib_frame = f;
1079 to_next = vlib_frame_vector_args (f);
1084 if (PREDICT_FALSE (offset == 0))
1085 snat_ipfix_header_create (frm, b0, &offset);
1087 if (PREDICT_TRUE (do_flush == 0))
1089 u64 time_stamp = clib_host_to_net_u64 (now);
1090 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1091 offset += sizeof (time_stamp);
1093 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1094 offset += sizeof (nat_event);
1096 clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1097 offset += sizeof (ip6_address_t);
1099 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1100 offset += sizeof (nat_src_ip);
1102 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1103 offset += sizeof (proto);
1105 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1106 offset += sizeof (src_port);
1108 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1109 offset += sizeof (nat_src_port);
1111 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1112 offset += sizeof (vrf_id);
1114 b0->current_length += NAT64_BIB_LEN;
1118 (do_flush || (offset + NAT64_BIB_LEN) > frm->path_mtu))
1120 template_id = clib_atomic_fetch_or (
1121 &silm->nat64_bib_template_id,
1123 snat_ipfix_send (frm, f, b0, template_id);
1124 sitd->nat64_bib_frame = 0;
1125 sitd->nat64_bib_buffer = 0;
1128 sitd->nat64_bib_next_record_offset = offset;
1132 nat_ipfix_logging_nat64_ses (u32 thread_index, u8 nat_event,
1133 ip6_address_t * src_ip, u32 nat_src_ip,
1134 u8 proto, u16 src_port, u16 nat_src_port,
1135 ip6_address_t * dst_ip, u32 nat_dst_ip,
1136 u16 dst_port, u16 nat_dst_port,
1137 u32 vrf_id, int do_flush)
1139 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1140 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1141 flow_report_main_t *frm = &flow_report_main;
1143 vlib_buffer_t *b0 = 0;
1146 vlib_main_t *vm = frm->vlib_main;
1150 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1151 now += silm->milisecond_time_0;
1153 b0 = sitd->nat64_ses_buffer;
1155 if (PREDICT_FALSE (b0 == 0))
1160 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1162 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1166 b0 = sitd->nat64_ses_buffer = vlib_get_buffer (vm, bi0);
1167 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1172 bi0 = vlib_get_buffer_index (vm, b0);
1173 offset = sitd->nat64_ses_next_record_offset;
1176 f = sitd->nat64_ses_frame;
1177 if (PREDICT_FALSE (f == 0))
1180 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1181 sitd->nat64_ses_frame = f;
1182 to_next = vlib_frame_vector_args (f);
1187 if (PREDICT_FALSE (offset == 0))
1188 snat_ipfix_header_create (frm, b0, &offset);
1190 if (PREDICT_TRUE (do_flush == 0))
1192 u64 time_stamp = clib_host_to_net_u64 (now);
1193 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1194 offset += sizeof (time_stamp);
1196 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1197 offset += sizeof (nat_event);
1199 clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1200 offset += sizeof (ip6_address_t);
1202 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1203 offset += sizeof (nat_src_ip);
1205 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1206 offset += sizeof (proto);
1208 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1209 offset += sizeof (src_port);
1211 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1212 offset += sizeof (nat_src_port);
1214 clib_memcpy_fast (b0->data + offset, dst_ip, sizeof (ip6_address_t));
1215 offset += sizeof (ip6_address_t);
1217 clib_memcpy_fast (b0->data + offset, &nat_dst_ip, sizeof (nat_dst_ip));
1218 offset += sizeof (nat_dst_ip);
1220 clib_memcpy_fast (b0->data + offset, &dst_port, sizeof (dst_port));
1221 offset += sizeof (dst_port);
1223 clib_memcpy_fast (b0->data + offset, &nat_dst_port, sizeof (nat_dst_port));
1224 offset += sizeof (nat_dst_port);
1226 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1227 offset += sizeof (vrf_id);
1229 b0->current_length += NAT64_SES_LEN;
1233 (do_flush || (offset + NAT64_SES_LEN) > frm->path_mtu))
1235 template_id = clib_atomic_fetch_or (
1236 &silm->nat64_ses_template_id,
1238 snat_ipfix_send (frm, f, b0, template_id);
1239 sitd->nat64_ses_frame = 0;
1240 sitd->nat64_ses_buffer = 0;
1243 sitd->nat64_ses_next_record_offset = offset;
1247 snat_ipfix_flush (u32 thread_index)
1251 snat_ipfix_logging_nat44_ses (thread_index,
1252 0, 0, 0, 0, 0, 0, 0, do_flush);
1253 snat_ipfix_logging_addr_exhausted (thread_index, 0, do_flush);
1254 snat_ipfix_logging_max_entries_per_usr (thread_index, 0, 0, do_flush);
1255 nat_ipfix_logging_max_ses (thread_index, 0, do_flush);
1256 nat_ipfix_logging_max_bib (thread_index, 0, do_flush);
1257 nat_ipfix_logging_nat64_bibe (thread_index,
1258 0, 0, 0, 0, 0, 0, 0, do_flush);
1259 nat_ipfix_logging_nat64_ses (thread_index,
1260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, do_flush);
1264 snat_ipfix_flush_from_main (void)
1266 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1267 vlib_main_t *worker_vm;
1270 if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0)))
1273 if (PREDICT_FALSE (!silm->worker_vms))
1275 for (i = 1; i < vec_len (vlib_mains); i++)
1277 worker_vm = vlib_mains[i];
1279 vec_add1 (silm->worker_vms, worker_vm);
1283 /* Trigger flush for each worker thread */
1284 for (i = 0; i < vec_len (silm->worker_vms); i++)
1286 worker_vm = silm->worker_vms[i];
1288 vlib_node_set_interrupt_pending (worker_vm,
1289 snat_ipfix_flush_node.index);
1292 /* Finally flush main thread */
1293 snat_ipfix_flush (0);
1297 * @brief Generate NAT44 session create event
1299 * @param thread_index thread index
1300 * @param src_ip source IPv4 address
1301 * @param nat_src_ip transaltes source IPv4 address
1302 * @param snat_proto NAT transport protocol
1303 * @param src_port source port
1304 * @param nat_src_port translated source port
1305 * @param vrf_id VRF ID
1308 snat_ipfix_logging_nat44_ses_create (u32 thread_index,
1311 snat_protocol_t snat_proto,
1313 u16 nat_src_port, u32 vrf_id)
1315 skip_if_disabled ();
1317 snat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_CREATE, src_ip,
1318 nat_src_ip, snat_proto, src_port, nat_src_port,
1323 * @brief Generate NAT44 session delete event
1325 * @param thread_index thread index
1326 * @param src_ip source IPv4 address
1327 * @param nat_src_ip transaltes source IPv4 address
1328 * @param snat_proto NAT transport protocol
1329 * @param src_port source port
1330 * @param nat_src_port translated source port
1331 * @param vrf_id VRF ID
1334 snat_ipfix_logging_nat44_ses_delete (u32 thread_index,
1337 snat_protocol_t snat_proto,
1339 u16 nat_src_port, u32 vrf_id)
1341 skip_if_disabled ();
1343 snat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_DELETE, src_ip,
1344 nat_src_ip, snat_proto, src_port, nat_src_port,
1349 * @brief Generate NAT addresses exhausted event
1351 * @param thread_index thread index
1352 * @param pool_id NAT pool ID
1355 snat_ipfix_logging_addresses_exhausted (u32 thread_index, u32 pool_id)
1357 //TODO: This event SHOULD be rate limited
1358 skip_if_disabled ();
1360 snat_ipfix_logging_addr_exhausted (thread_index, pool_id, 0);
1364 * @brief Generate maximum entries per user exceeded event
1366 * @param thread_index thread index
1367 * @param limit maximum NAT entries that can be created per user
1368 * @param src_ip source IPv4 address
1371 snat_ipfix_logging_max_entries_per_user (u32 thread_index, u32 limit, u32 src_ip)
1373 //TODO: This event SHOULD be rate limited
1374 skip_if_disabled ();
1376 snat_ipfix_logging_max_entries_per_usr (thread_index, limit, src_ip, 0);
1380 deterministic_nat_data_callback
1381 (flow_report_main_t * frm,
1384 u32 * to_next, u32 node_index)
1386 snat_ipfix_flush_from_main();
1392 * @brief Generate maximum session entries exceeded event
1394 * @param thread_index thread index
1395 * @param limit configured limit
1398 nat_ipfix_logging_max_sessions (u32 thread_index, u32 limit)
1400 //TODO: This event SHOULD be rate limited
1401 skip_if_disabled ();
1403 nat_ipfix_logging_max_ses (thread_index, limit, 0);
1407 * @brief Generate maximum BIB entries exceeded event
1409 * @param thread_index thread index
1410 * @param limit configured limit
1413 nat_ipfix_logging_max_bibs (u32 thread_index, u32 limit)
1415 //TODO: This event SHOULD be rate limited
1416 skip_if_disabled ();
1418 nat_ipfix_logging_max_bib (thread_index, limit, 0);
1422 * @brief Generate NAT64 BIB create and delete events
1424 * @param thread_index thread index
1425 * @param src_ip source IPv6 address
1426 * @param nat_src_ip transaltes source IPv4 address
1427 * @param proto L4 protocol
1428 * @param src_port source port
1429 * @param nat_src_port translated source port
1430 * @param vrf_id VRF ID
1431 * @param is_create non-zero value if create event otherwise delete event
1434 nat_ipfix_logging_nat64_bib (u32 thread_index, ip6_address_t * src_ip,
1435 ip4_address_t * nat_src_ip, u8 proto,
1436 u16 src_port, u16 nat_src_port, u32 vrf_id,
1441 skip_if_disabled ();
1443 nat_event = is_create ? NAT64_BIB_CREATE : NAT64_BIB_DELETE;
1445 nat_ipfix_logging_nat64_bibe (thread_index, nat_event, src_ip,
1446 nat_src_ip->as_u32, proto, src_port,
1447 nat_src_port, vrf_id, 0);
1451 * @brief Generate NAT64 session create and delete events
1453 * @param thread_index thread index
1454 * @param src_ip source IPv6 address
1455 * @param nat_src_ip transaltes source IPv4 address
1456 * @param proto L4 protocol
1457 * @param src_port source port
1458 * @param nat_src_port translated source port
1459 * @param dst_ip destination IPv6 address
1460 * @param nat_dst_ip destination IPv4 address
1461 * @param dst_port destination port
1462 * @param nat_dst_port translated destination port
1463 * @param vrf_id VRF ID
1464 * @param is_create non-zero value if create event otherwise delete event
1467 nat_ipfix_logging_nat64_session (u32 thread_index,
1468 ip6_address_t * src_ip,
1469 ip4_address_t * nat_src_ip, u8 proto,
1470 u16 src_port, u16 nat_src_port,
1471 ip6_address_t * dst_ip,
1472 ip4_address_t * nat_dst_ip, u16 dst_port,
1473 u16 nat_dst_port, u32 vrf_id, u8 is_create)
1477 skip_if_disabled ();
1479 nat_event = is_create ? NAT64_SESSION_CREATE : NAT64_SESSION_DELETE;
1481 nat_ipfix_logging_nat64_ses (thread_index, nat_event, src_ip,
1482 nat_src_ip->as_u32, proto, src_port,
1483 nat_src_port, dst_ip, nat_dst_ip->as_u32,
1484 dst_port, nat_dst_port, vrf_id, 0);
1488 data_callback (flow_report_main_t * frm, flow_report_t * fr,
1489 vlib_frame_t * f, u32 * to_next, u32 node_index)
1491 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1493 if (PREDICT_FALSE (++silm->call_counter >= vec_len (frm->reports)))
1495 snat_ipfix_flush_from_main();
1496 silm->call_counter = 0;
1503 * @brief Enable/disable NAT plugin IPFIX logging
1505 * @param enable 1 if enable, 0 if disable
1506 * @param domain_id observation domain ID
1507 * @param src_port source port number
1509 * @returns 0 if success
1512 snat_ipfix_logging_enable_disable (int enable, u32 domain_id, u16 src_port)
1514 snat_main_t *sm = &snat_main;
1515 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1516 flow_report_main_t *frm = &flow_report_main;
1517 vnet_flow_report_add_del_args_t a;
1519 u8 e = enable ? 1 : 0;
1521 if (clib_atomic_cmp_and_swap (&silm->enabled, e ^ 1, e) == e)
1524 clib_memset (&a, 0, sizeof (a));
1526 a.domain_id = domain_id ? domain_id : 1;
1527 a.src_port = src_port ? src_port : UDP_DST_PORT_ipfix;
1528 a.flow_data_callback = data_callback;
1530 if (sm->deterministic)
1532 a.rewrite_callback = snat_template_rewrite_max_entries_per_usr;
1534 rv = vnet_flow_report_add_del (frm, &a, NULL);
1537 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1543 a.rewrite_callback = snat_template_rewrite_nat44_session;
1545 rv = vnet_flow_report_add_del (frm, &a, NULL);
1548 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1552 a.rewrite_callback = snat_template_rewrite_addr_exhausted;
1554 rv = vnet_flow_report_add_del (frm, &a, NULL);
1557 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1561 a.rewrite_callback = nat_template_rewrite_max_sessions;
1563 rv = vnet_flow_report_add_del (frm, &a, NULL);
1566 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1570 a.rewrite_callback = nat_template_rewrite_max_bibs;
1572 rv = vnet_flow_report_add_del (frm, &a, NULL);
1575 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1579 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;
1590 rv = vnet_flow_report_add_del (frm, &a, NULL);
1593 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1597 if (sm->endpoint_dependent)
1599 a.rewrite_callback = snat_template_rewrite_max_entries_per_usr;
1601 rv = vnet_flow_report_add_del (frm, &a, NULL);
1604 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1614 * @brief Initialize NAT plugin IPFIX logging
1616 * @param vm vlib main
1619 snat_ipfix_logging_init (vlib_main_t * vm)
1621 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1622 vlib_thread_main_t *tm = vlib_get_thread_main ();
1625 silm->worker_vms = 0;
1626 silm->call_counter = 0;
1628 /* Set up time reference pair */
1629 silm->vlib_time_0 = vlib_time_now (vm);
1630 silm->milisecond_time_0 = unix_time_now_nsec () * 1e-6;
1632 vec_validate (silm->per_thread_data, tm->n_vlib_mains - 1);
1636 ipfix_flush_process (vlib_main_t *vm,
1637 vlib_node_runtime_t *rt,
1640 snat_ipfix_flush(vm->thread_index);
1645 VLIB_REGISTER_NODE (snat_ipfix_flush_node) = {
1646 .function = ipfix_flush_process,
1647 .name = "snat-ipfix-flush",
1648 .type = VLIB_NODE_TYPE_INPUT,
1649 .state = VLIB_NODE_STATE_INTERRUPT,