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,
222 else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY)
224 field_count = MAX_FRAGMENTS_FIELD_COUNT;
226 update_template_id(&silm->max_frags_ip4_template_id,
229 else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY_IP6)
231 field_count = MAX_FRAGMENTS_FIELD_COUNT;
233 update_template_id(&silm->max_frags_ip6_template_id,
238 /* allocate rewrite space */
239 vec_validate_aligned (rewrite,
240 sizeof (ip4_ipfix_template_packet_t)
241 + field_count * sizeof (ipfix_field_specifier_t) - 1,
242 CLIB_CACHE_LINE_BYTES);
244 tp = (ip4_ipfix_template_packet_t *) rewrite;
245 ip = (ip4_header_t *) & tp->ip4;
246 udp = (udp_header_t *) (ip + 1);
247 h = (ipfix_message_header_t *) (udp + 1);
248 s = (ipfix_set_header_t *) (h + 1);
249 t = (ipfix_template_header_t *) (s + 1);
250 first_field = f = (ipfix_field_specifier_t *) (t + 1);
252 ip->ip_version_and_header_length = 0x45;
254 ip->protocol = IP_PROTOCOL_UDP;
255 ip->src_address.as_u32 = src_address->as_u32;
256 ip->dst_address.as_u32 = collector_address->as_u32;
257 udp->src_port = clib_host_to_net_u16 (stream->src_port);
258 udp->dst_port = clib_host_to_net_u16 (collector_port);
259 udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip));
261 /* FIXUP: message header export_time */
262 h->domain_id = clib_host_to_net_u32 (stream->domain_id);
264 /* Add TLVs to the template */
265 if (event == NAT_ADDRESSES_EXHAUTED)
267 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
269 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
271 f->e_id_length = ipfix_e_id_length (0, natPoolId, 4);
274 else if (event == NAT44_SESSION_CREATE)
276 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
278 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
280 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
282 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
284 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
286 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
288 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
290 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
293 else if (event == NAT64_BIB_CREATE)
295 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
297 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
299 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
301 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
303 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
305 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
307 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
309 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
312 else if (event == NAT64_SESSION_CREATE)
314 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
316 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
318 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
320 f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
322 f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
324 f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
326 f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
328 f->e_id_length = ipfix_e_id_length (0, destinationIPv6Address, 16);
330 f->e_id_length = ipfix_e_id_length (0, postNATDestinationIPv4Address, 4);
332 f->e_id_length = ipfix_e_id_length (0, destinationTransportPort, 2);
334 f->e_id_length = ipfix_e_id_length (0, postNAPTDestinationTransportPort,
337 f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
340 else if (event == QUOTA_EXCEEDED)
342 if (quota_event == MAX_ENTRIES_PER_USER)
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, maxEntriesPerUser, 4);
353 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
356 else if (quota_event == MAX_SESSION_ENTRIES)
358 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
361 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
363 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
365 f->e_id_length = ipfix_e_id_length (0, maxSessionEntries, 4);
368 else if (quota_event == MAX_BIB_ENTRIES)
370 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
373 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
375 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
377 f->e_id_length = ipfix_e_id_length (0, maxBIBEntries, 4);
380 else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY)
382 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
385 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
387 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
389 f->e_id_length = ipfix_e_id_length (0, maxFragmentsPendingReassembly,
392 f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
395 else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY_IP6)
397 f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
400 f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
402 f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
404 f->e_id_length = ipfix_e_id_length (0, maxFragmentsPendingReassembly,
407 f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
412 /* Back to the template packet... */
413 ip = (ip4_header_t *) & tp->ip4;
414 udp = (udp_header_t *) (ip + 1);
416 ASSERT (f - first_field);
417 /* Field count in this template */
418 t->id_count = ipfix_id_count (fr->template_id, f - first_field);
420 /* set length in octets */
422 ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s);
424 /* message length in octets */
425 h->version_length = version_length ((u8 *) f - (u8 *) h);
427 ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip);
428 ip->checksum = ip4_header_checksum (ip);
434 snat_template_rewrite_addr_exhausted (flow_report_main_t * frm,
436 ip4_address_t * collector_address,
437 ip4_address_t * src_address,
439 ipfix_report_element_t *elts,
440 u32 n_elts, u32 *stream_index)
442 return snat_template_rewrite (frm, fr, collector_address, src_address,
443 collector_port, NAT_ADDRESSES_EXHAUTED, 0);
447 snat_template_rewrite_nat44_session (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 snat_template_rewrite (frm, fr, collector_address, src_address,
456 collector_port, NAT44_SESSION_CREATE, 0);
460 snat_template_rewrite_max_entries_per_usr (flow_report_main_t * frm,
462 ip4_address_t * collector_address,
463 ip4_address_t * src_address,
465 ipfix_report_element_t *elts,
466 u32 n_elts, u32 *stream_index)
468 return snat_template_rewrite (frm, fr, collector_address, src_address,
469 collector_port, QUOTA_EXCEEDED,
470 MAX_ENTRIES_PER_USER);
474 nat_template_rewrite_max_sessions (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 snat_template_rewrite (frm, fr, collector_address, src_address,
483 collector_port, QUOTA_EXCEEDED,
484 MAX_SESSION_ENTRIES);
488 nat_template_rewrite_max_bibs (flow_report_main_t * frm,
490 ip4_address_t * collector_address,
491 ip4_address_t * src_address,
493 ipfix_report_element_t *elts,
494 u32 n_elts, u32 *stream_index)
496 return snat_template_rewrite (frm, fr, collector_address, src_address,
497 collector_port, QUOTA_EXCEEDED,
502 nat_template_rewrite_max_frags_ip4 (flow_report_main_t * frm,
504 ip4_address_t * collector_address,
505 ip4_address_t * src_address,
507 ipfix_report_element_t *elts,
508 u32 n_elts, u32 *stream_index)
510 return snat_template_rewrite (frm, fr, collector_address, src_address,
511 collector_port, QUOTA_EXCEEDED,
512 MAX_FRAGMENTS_PENDING_REASSEMBLY);
516 nat_template_rewrite_max_frags_ip6 (flow_report_main_t * frm,
518 ip4_address_t * collector_address,
519 ip4_address_t * src_address,
521 ipfix_report_element_t *elts,
522 u32 n_elts, u32 *stream_index)
524 return snat_template_rewrite (frm, fr, collector_address, src_address,
525 collector_port, QUOTA_EXCEEDED,
526 MAX_FRAGMENTS_PENDING_REASSEMBLY_IP6);
530 nat_template_rewrite_nat64_bib (flow_report_main_t * frm,
532 ip4_address_t * collector_address,
533 ip4_address_t * src_address,
535 ipfix_report_element_t *elts,
536 u32 n_elts, u32 *stream_index)
538 return snat_template_rewrite (frm, fr, collector_address, src_address,
539 collector_port, NAT64_BIB_CREATE, 0);
543 nat_template_rewrite_nat64_session (flow_report_main_t * frm,
545 ip4_address_t * collector_address,
546 ip4_address_t * src_address,
548 ipfix_report_element_t *elts,
549 u32 n_elts, u32 *stream_index)
551 return snat_template_rewrite (frm, fr, collector_address, src_address,
552 collector_port, NAT64_SESSION_CREATE, 0);
556 snat_ipfix_header_create (flow_report_main_t * frm,
557 vlib_buffer_t * b0, u32 * offset)
559 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
560 flow_report_stream_t *stream;
561 ip4_ipfix_template_packet_t *tp;
562 ipfix_message_header_t *h = 0;
563 ipfix_set_header_t *s = 0;
569 stream_index = clib_atomic_fetch_or(&silm->stream_index, 0);
570 stream = &frm->streams[stream_index];
572 b0->current_data = 0;
573 b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) +
575 b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VNET_BUFFER_F_FLOW_REPORT);
576 vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
577 vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index;
578 tp = vlib_buffer_get_current (b0);
579 ip = (ip4_header_t *) & tp->ip4;
580 udp = (udp_header_t *) (ip + 1);
581 h = (ipfix_message_header_t *) (udp + 1);
582 s = (ipfix_set_header_t *) (h + 1);
584 ip->ip_version_and_header_length = 0x45;
586 ip->protocol = IP_PROTOCOL_UDP;
587 ip->flags_and_fragment_offset = 0;
588 ip->src_address.as_u32 = frm->src_address.as_u32;
589 ip->dst_address.as_u32 = frm->ipfix_collector.as_u32;
590 udp->src_port = clib_host_to_net_u16 (stream->src_port);
591 udp->dst_port = clib_host_to_net_u16 (frm->collector_port);
594 h->export_time = clib_host_to_net_u32 ((u32)
595 (((f64) frm->unix_time_0) +
596 (vlib_time_now (frm->vlib_main) -
599 sequence_number = clib_atomic_fetch_add (&stream->sequence_number, 1);
600 h->sequence_number = clib_host_to_net_u32 (sequence_number);
601 h->domain_id = clib_host_to_net_u32 (stream->domain_id);
603 *offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
607 snat_ipfix_send (flow_report_main_t * frm,
608 vlib_frame_t * f, vlib_buffer_t * b0, u16 template_id)
610 ip4_ipfix_template_packet_t *tp;
611 ipfix_message_header_t *h = 0;
612 ipfix_set_header_t *s = 0;
615 vlib_main_t *vm = frm->vlib_main;
617 tp = vlib_buffer_get_current (b0);
618 ip = (ip4_header_t *) & tp->ip4;
619 udp = (udp_header_t *) (ip + 1);
620 h = (ipfix_message_header_t *) (udp + 1);
621 s = (ipfix_set_header_t *) (h + 1);
623 s->set_id_length = ipfix_set_id_length (template_id,
625 (sizeof (*ip) + sizeof (*udp) +
627 h->version_length = version_length (b0->current_length -
628 (sizeof (*ip) + sizeof (*udp)));
630 ip->length = clib_host_to_net_u16 (b0->current_length);
631 ip->checksum = ip4_header_checksum (ip);
632 udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
634 if (frm->udp_checksum)
636 udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
637 if (udp->checksum == 0)
638 udp->checksum = 0xffff;
641 ASSERT (ip->checksum == ip4_header_checksum (ip));
643 vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
647 snat_ipfix_logging_nat44_ses (u32 thread_index, u8 nat_event, u32 src_ip,
648 u32 nat_src_ip, snat_protocol_t snat_proto,
649 u16 src_port, u16 nat_src_port, u32 vrf_id,
652 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
653 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
654 flow_report_main_t *frm = &flow_report_main;
656 vlib_buffer_t *b0 = 0;
659 vlib_main_t *vm = frm->vlib_main;
664 proto = snat_proto_to_ip_proto (snat_proto);
666 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
667 now += silm->milisecond_time_0;
669 b0 = sitd->nat44_session_buffer;
671 if (PREDICT_FALSE (b0 == 0))
676 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
678 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
682 b0 = sitd->nat44_session_buffer = vlib_get_buffer (vm, bi0);
683 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
688 bi0 = vlib_get_buffer_index (vm, b0);
689 offset = sitd->nat44_session_next_record_offset;
692 f = sitd->nat44_session_frame;
693 if (PREDICT_FALSE (f == 0))
696 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
697 sitd->nat44_session_frame = f;
698 to_next = vlib_frame_vector_args (f);
703 if (PREDICT_FALSE (offset == 0))
704 snat_ipfix_header_create (frm, b0, &offset);
706 if (PREDICT_TRUE (do_flush == 0))
708 u64 time_stamp = clib_host_to_net_u64 (now);
709 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
710 offset += sizeof (time_stamp);
712 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
713 offset += sizeof (nat_event);
715 clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
716 offset += sizeof (src_ip);
718 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
719 offset += sizeof (nat_src_ip);
721 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
722 offset += sizeof (proto);
724 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
725 offset += sizeof (src_port);
727 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
728 offset += sizeof (nat_src_port);
730 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
731 offset += sizeof (vrf_id);
733 b0->current_length += NAT44_SESSION_CREATE_LEN;
737 (do_flush || (offset + NAT44_SESSION_CREATE_LEN) > frm->path_mtu))
739 template_id = clib_atomic_fetch_or (
740 &silm->nat44_session_template_id,
742 snat_ipfix_send (frm, f, b0, template_id);
743 sitd->nat44_session_frame = 0;
744 sitd->nat44_session_buffer = 0;
747 sitd->nat44_session_next_record_offset = offset;
751 snat_ipfix_logging_addr_exhausted (u32 thread_index, u32 pool_id, int do_flush)
753 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
754 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
755 flow_report_main_t *frm = &flow_report_main;
757 vlib_buffer_t *b0 = 0;
760 vlib_main_t *vm = frm->vlib_main;
762 u8 nat_event = NAT_ADDRESSES_EXHAUTED;
765 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
766 now += silm->milisecond_time_0;
768 b0 = sitd->addr_exhausted_buffer;
770 if (PREDICT_FALSE (b0 == 0))
775 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
777 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
781 b0 = sitd->addr_exhausted_buffer = vlib_get_buffer (vm, bi0);
782 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
787 bi0 = vlib_get_buffer_index (vm, b0);
788 offset = sitd->addr_exhausted_next_record_offset;
791 f = sitd->addr_exhausted_frame;
792 if (PREDICT_FALSE (f == 0))
795 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
796 sitd->addr_exhausted_frame = f;
797 to_next = vlib_frame_vector_args (f);
802 if (PREDICT_FALSE (offset == 0))
803 snat_ipfix_header_create (frm, b0, &offset);
805 if (PREDICT_TRUE (do_flush == 0))
807 u64 time_stamp = clib_host_to_net_u64 (now);
808 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
809 offset += sizeof (time_stamp);
811 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
812 offset += sizeof (nat_event);
814 clib_memcpy_fast (b0->data + offset, &pool_id, sizeof (pool_id));
815 offset += sizeof (pool_id);
817 b0->current_length += NAT_ADDRESSES_EXHAUTED_LEN;
821 (do_flush || (offset + NAT_ADDRESSES_EXHAUTED_LEN) > frm->path_mtu))
823 template_id = clib_atomic_fetch_or (
824 &silm->addr_exhausted_template_id,
826 snat_ipfix_send (frm, f, b0, template_id);
827 sitd->addr_exhausted_frame = 0;
828 sitd->addr_exhausted_buffer = 0;
831 sitd->addr_exhausted_next_record_offset = offset;
835 snat_ipfix_logging_max_entries_per_usr (u32 thread_index,
836 u32 limit, u32 src_ip, int do_flush)
838 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
839 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
840 flow_report_main_t *frm = &flow_report_main;
842 vlib_buffer_t *b0 = 0;
845 vlib_main_t *vm = frm->vlib_main;
847 u8 nat_event = QUOTA_EXCEEDED;
848 u32 quota_event = MAX_ENTRIES_PER_USER;
851 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
852 now += silm->milisecond_time_0;
854 b0 = sitd->max_entries_per_user_buffer;
856 if (PREDICT_FALSE (b0 == 0))
861 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
863 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
867 b0 = sitd->max_entries_per_user_buffer = vlib_get_buffer (vm, bi0);
868 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
873 bi0 = vlib_get_buffer_index (vm, b0);
874 offset = sitd->max_entries_per_user_next_record_offset;
877 f = sitd->max_entries_per_user_frame;
878 if (PREDICT_FALSE (f == 0))
881 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
882 sitd->max_entries_per_user_frame = f;
883 to_next = vlib_frame_vector_args (f);
888 if (PREDICT_FALSE (offset == 0))
889 snat_ipfix_header_create (frm, b0, &offset);
891 if (PREDICT_TRUE (do_flush == 0))
893 u64 time_stamp = clib_host_to_net_u64 (now);
894 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
895 offset += sizeof (time_stamp);
897 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
898 offset += sizeof (nat_event);
900 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
901 offset += sizeof (quota_event);
903 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
904 offset += sizeof (limit);
906 clib_memcpy_fast (b0->data + offset, &src_ip, sizeof (src_ip));
907 offset += sizeof (src_ip);
909 b0->current_length += MAX_ENTRIES_PER_USER_LEN;
913 (do_flush || (offset + MAX_ENTRIES_PER_USER_LEN) > frm->path_mtu))
915 template_id = clib_atomic_fetch_or (
916 &silm->max_entries_per_user_template_id,
918 snat_ipfix_send (frm, f, b0, template_id);
919 sitd->max_entries_per_user_frame = 0;
920 sitd->max_entries_per_user_buffer = 0;
923 sitd->max_entries_per_user_next_record_offset = offset;
927 nat_ipfix_logging_max_ses (u32 thread_index, u32 limit, int do_flush)
929 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
930 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
931 flow_report_main_t *frm = &flow_report_main;
933 vlib_buffer_t *b0 = 0;
936 vlib_main_t *vm = frm->vlib_main;
938 u8 nat_event = QUOTA_EXCEEDED;
939 u32 quota_event = MAX_SESSION_ENTRIES;
942 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
943 now += silm->milisecond_time_0;
945 b0 = sitd->max_sessions_buffer;
947 if (PREDICT_FALSE (b0 == 0))
952 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
954 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
958 b0 = sitd->max_sessions_buffer = vlib_get_buffer (vm, bi0);
959 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
964 bi0 = vlib_get_buffer_index (vm, b0);
965 offset = sitd->max_sessions_next_record_offset;
968 f = sitd->max_sessions_frame;
969 if (PREDICT_FALSE (f == 0))
972 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
973 sitd->max_sessions_frame = f;
974 to_next = vlib_frame_vector_args (f);
979 if (PREDICT_FALSE (offset == 0))
980 snat_ipfix_header_create (frm, b0, &offset);
982 if (PREDICT_TRUE (do_flush == 0))
984 u64 time_stamp = clib_host_to_net_u64 (now);
985 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
986 offset += sizeof (time_stamp);
988 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
989 offset += sizeof (nat_event);
991 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
992 offset += sizeof (quota_event);
994 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
995 offset += sizeof (limit);
997 b0->current_length += MAX_SESSIONS_LEN;
1001 (do_flush || (offset + MAX_SESSIONS_LEN) > frm->path_mtu))
1003 template_id = clib_atomic_fetch_or (
1004 &silm->max_sessions_template_id,
1006 snat_ipfix_send (frm, f, b0, template_id);
1007 sitd->max_sessions_frame = 0;
1008 sitd->max_sessions_buffer = 0;
1011 sitd->max_sessions_next_record_offset = offset;
1015 nat_ipfix_logging_max_bib (u32 thread_index, u32 limit, int do_flush)
1017 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1018 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1019 flow_report_main_t *frm = &flow_report_main;
1021 vlib_buffer_t *b0 = 0;
1024 vlib_main_t *vm = frm->vlib_main;
1026 u8 nat_event = QUOTA_EXCEEDED;
1027 u32 quota_event = MAX_BIB_ENTRIES;
1030 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1031 now += silm->milisecond_time_0;
1033 b0 = sitd->max_bibs_buffer;
1035 if (PREDICT_FALSE (b0 == 0))
1040 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1042 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1046 b0 = sitd->max_bibs_buffer = vlib_get_buffer (vm, bi0);
1047 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1052 bi0 = vlib_get_buffer_index (vm, b0);
1053 offset = sitd->max_bibs_next_record_offset;
1056 f = sitd->max_bibs_frame;
1057 if (PREDICT_FALSE (f == 0))
1060 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1061 sitd->max_bibs_frame = f;
1062 to_next = vlib_frame_vector_args (f);
1067 if (PREDICT_FALSE (offset == 0))
1068 snat_ipfix_header_create (frm, b0, &offset);
1070 if (PREDICT_TRUE (do_flush == 0))
1072 u64 time_stamp = clib_host_to_net_u64 (now);
1073 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1074 offset += sizeof (time_stamp);
1076 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1077 offset += sizeof (nat_event);
1079 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
1080 offset += sizeof (quota_event);
1082 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
1083 offset += sizeof (limit);
1085 b0->current_length += MAX_BIBS_LEN;
1089 (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1091 template_id = clib_atomic_fetch_or (
1092 &silm->max_bibs_template_id,
1094 snat_ipfix_send (frm, f, b0, template_id);
1095 sitd->max_bibs_frame = 0;
1096 sitd->max_bibs_buffer = 0;
1099 sitd->max_bibs_next_record_offset = offset;
1103 nat_ipfix_logging_max_frag_ip4 (u32 thread_index,
1104 u32 limit, u32 src, int do_flush)
1106 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1107 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1108 flow_report_main_t *frm = &flow_report_main;
1110 vlib_buffer_t *b0 = 0;
1113 vlib_main_t *vm = frm->vlib_main;
1115 u8 nat_event = QUOTA_EXCEEDED;
1116 u32 quota_event = MAX_FRAGMENTS_PENDING_REASSEMBLY;
1119 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1120 now += silm->milisecond_time_0;
1122 b0 = sitd->max_frags_ip4_buffer;
1124 if (PREDICT_FALSE (b0 == 0))
1129 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1131 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1135 b0 = sitd->max_frags_ip4_buffer = vlib_get_buffer (vm, bi0);
1136 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1141 bi0 = vlib_get_buffer_index (vm, b0);
1142 offset = sitd->max_frags_ip4_next_record_offset;
1145 f = sitd->max_frags_ip4_frame;
1146 if (PREDICT_FALSE (f == 0))
1149 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1150 sitd->max_frags_ip4_frame = f;
1151 to_next = vlib_frame_vector_args (f);
1156 if (PREDICT_FALSE (offset == 0))
1157 snat_ipfix_header_create (frm, b0, &offset);
1159 if (PREDICT_TRUE (do_flush == 0))
1161 u64 time_stamp = clib_host_to_net_u64 (now);
1162 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1163 offset += sizeof (time_stamp);
1165 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1166 offset += sizeof (nat_event);
1168 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
1169 offset += sizeof (quota_event);
1171 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
1172 offset += sizeof (limit);
1174 clib_memcpy_fast (b0->data + offset, &src, sizeof (src));
1175 offset += sizeof (src);
1177 b0->current_length += MAX_FRAGMENTS_IP4_LEN;
1181 (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1183 template_id = clib_atomic_fetch_or (
1184 &silm->max_frags_ip4_template_id,
1186 snat_ipfix_send (frm, f, b0, template_id);
1187 sitd->max_frags_ip4_frame = 0;
1188 sitd->max_frags_ip4_buffer = 0;
1191 sitd->max_frags_ip4_next_record_offset = offset;
1195 nat_ipfix_logging_max_frag_ip6 (u32 thread_index,
1196 u32 limit, ip6_address_t * src, int do_flush)
1198 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1199 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1200 flow_report_main_t *frm = &flow_report_main;
1202 vlib_buffer_t *b0 = 0;
1205 vlib_main_t *vm = frm->vlib_main;
1207 u8 nat_event = QUOTA_EXCEEDED;
1208 u32 quota_event = MAX_FRAGMENTS_PENDING_REASSEMBLY;
1211 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1212 now += silm->milisecond_time_0;
1214 b0 = sitd->max_frags_ip6_buffer;
1216 if (PREDICT_FALSE (b0 == 0))
1221 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1223 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1227 b0 = sitd->max_frags_ip6_buffer = vlib_get_buffer (vm, bi0);
1228 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1233 bi0 = vlib_get_buffer_index (vm, b0);
1234 offset = sitd->max_frags_ip6_next_record_offset;
1237 f = sitd->max_frags_ip6_frame;
1238 if (PREDICT_FALSE (f == 0))
1241 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1242 sitd->max_frags_ip6_frame = f;
1243 to_next = vlib_frame_vector_args (f);
1248 if (PREDICT_FALSE (offset == 0))
1249 snat_ipfix_header_create (frm, b0, &offset);
1251 if (PREDICT_TRUE (do_flush == 0))
1253 u64 time_stamp = clib_host_to_net_u64 (now);
1254 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1255 offset += sizeof (time_stamp);
1257 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1258 offset += sizeof (nat_event);
1260 clib_memcpy_fast (b0->data + offset, "a_event, sizeof (quota_event));
1261 offset += sizeof (quota_event);
1263 clib_memcpy_fast (b0->data + offset, &limit, sizeof (limit));
1264 offset += sizeof (limit);
1266 clib_memcpy_fast (b0->data + offset, src, sizeof (ip6_address_t));
1267 offset += sizeof (ip6_address_t);
1269 b0->current_length += MAX_FRAGMENTS_IP6_LEN;
1273 (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1275 template_id = clib_atomic_fetch_or (
1276 &silm->max_frags_ip6_template_id,
1278 snat_ipfix_send (frm, f, b0, template_id);
1279 sitd->max_frags_ip6_frame = 0;
1280 sitd->max_frags_ip6_buffer = 0;
1283 sitd->max_frags_ip6_next_record_offset = offset;
1287 nat_ipfix_logging_nat64_bibe (u32 thread_index, u8 nat_event,
1288 ip6_address_t * src_ip, u32 nat_src_ip,
1289 u8 proto, u16 src_port, u16 nat_src_port,
1290 u32 vrf_id, int do_flush)
1292 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1293 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1294 flow_report_main_t *frm = &flow_report_main;
1296 vlib_buffer_t *b0 = 0;
1299 vlib_main_t *vm = frm->vlib_main;
1303 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1304 now += silm->milisecond_time_0;
1306 b0 = sitd->nat64_bib_buffer;
1308 if (PREDICT_FALSE (b0 == 0))
1313 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1315 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1319 b0 = sitd->nat64_bib_buffer = vlib_get_buffer (vm, bi0);
1320 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1325 bi0 = vlib_get_buffer_index (vm, b0);
1326 offset = sitd->nat64_bib_next_record_offset;
1329 f = sitd->nat64_bib_frame;
1330 if (PREDICT_FALSE (f == 0))
1333 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1334 sitd->nat64_bib_frame = f;
1335 to_next = vlib_frame_vector_args (f);
1340 if (PREDICT_FALSE (offset == 0))
1341 snat_ipfix_header_create (frm, b0, &offset);
1343 if (PREDICT_TRUE (do_flush == 0))
1345 u64 time_stamp = clib_host_to_net_u64 (now);
1346 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1347 offset += sizeof (time_stamp);
1349 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1350 offset += sizeof (nat_event);
1352 clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1353 offset += sizeof (ip6_address_t);
1355 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1356 offset += sizeof (nat_src_ip);
1358 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1359 offset += sizeof (proto);
1361 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1362 offset += sizeof (src_port);
1364 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1365 offset += sizeof (nat_src_port);
1367 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1368 offset += sizeof (vrf_id);
1370 b0->current_length += NAT64_BIB_LEN;
1374 (do_flush || (offset + NAT64_BIB_LEN) > frm->path_mtu))
1376 template_id = clib_atomic_fetch_or (
1377 &silm->nat64_bib_template_id,
1379 snat_ipfix_send (frm, f, b0, template_id);
1380 sitd->nat64_bib_frame = 0;
1381 sitd->nat64_bib_buffer = 0;
1384 sitd->nat64_bib_next_record_offset = offset;
1388 nat_ipfix_logging_nat64_ses (u32 thread_index, u8 nat_event,
1389 ip6_address_t * src_ip, u32 nat_src_ip,
1390 u8 proto, u16 src_port, u16 nat_src_port,
1391 ip6_address_t * dst_ip, u32 nat_dst_ip,
1392 u16 dst_port, u16 nat_dst_port,
1393 u32 vrf_id, int do_flush)
1395 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1396 snat_ipfix_per_thread_data_t *sitd = &silm->per_thread_data[thread_index];
1397 flow_report_main_t *frm = &flow_report_main;
1399 vlib_buffer_t *b0 = 0;
1402 vlib_main_t *vm = frm->vlib_main;
1406 now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1407 now += silm->milisecond_time_0;
1409 b0 = sitd->nat64_ses_buffer;
1411 if (PREDICT_FALSE (b0 == 0))
1416 if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1418 nat_elog_err ("can't allocate buffer for NAT IPFIX event");
1422 b0 = sitd->nat64_ses_buffer = vlib_get_buffer (vm, bi0);
1423 VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1428 bi0 = vlib_get_buffer_index (vm, b0);
1429 offset = sitd->nat64_ses_next_record_offset;
1432 f = sitd->nat64_ses_frame;
1433 if (PREDICT_FALSE (f == 0))
1436 f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1437 sitd->nat64_ses_frame = f;
1438 to_next = vlib_frame_vector_args (f);
1443 if (PREDICT_FALSE (offset == 0))
1444 snat_ipfix_header_create (frm, b0, &offset);
1446 if (PREDICT_TRUE (do_flush == 0))
1448 u64 time_stamp = clib_host_to_net_u64 (now);
1449 clib_memcpy_fast (b0->data + offset, &time_stamp, sizeof (time_stamp));
1450 offset += sizeof (time_stamp);
1452 clib_memcpy_fast (b0->data + offset, &nat_event, sizeof (nat_event));
1453 offset += sizeof (nat_event);
1455 clib_memcpy_fast (b0->data + offset, src_ip, sizeof (ip6_address_t));
1456 offset += sizeof (ip6_address_t);
1458 clib_memcpy_fast (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1459 offset += sizeof (nat_src_ip);
1461 clib_memcpy_fast (b0->data + offset, &proto, sizeof (proto));
1462 offset += sizeof (proto);
1464 clib_memcpy_fast (b0->data + offset, &src_port, sizeof (src_port));
1465 offset += sizeof (src_port);
1467 clib_memcpy_fast (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1468 offset += sizeof (nat_src_port);
1470 clib_memcpy_fast (b0->data + offset, dst_ip, sizeof (ip6_address_t));
1471 offset += sizeof (ip6_address_t);
1473 clib_memcpy_fast (b0->data + offset, &nat_dst_ip, sizeof (nat_dst_ip));
1474 offset += sizeof (nat_dst_ip);
1476 clib_memcpy_fast (b0->data + offset, &dst_port, sizeof (dst_port));
1477 offset += sizeof (dst_port);
1479 clib_memcpy_fast (b0->data + offset, &nat_dst_port, sizeof (nat_dst_port));
1480 offset += sizeof (nat_dst_port);
1482 clib_memcpy_fast (b0->data + offset, &vrf_id, sizeof (vrf_id));
1483 offset += sizeof (vrf_id);
1485 b0->current_length += NAT64_SES_LEN;
1489 (do_flush || (offset + NAT64_SES_LEN) > frm->path_mtu))
1491 template_id = clib_atomic_fetch_or (
1492 &silm->nat64_ses_template_id,
1494 snat_ipfix_send (frm, f, b0, template_id);
1495 sitd->nat64_ses_frame = 0;
1496 sitd->nat64_ses_buffer = 0;
1499 sitd->nat64_ses_next_record_offset = offset;
1503 snat_ipfix_flush (u32 thread_index)
1507 snat_ipfix_logging_nat44_ses (thread_index,
1508 0, 0, 0, 0, 0, 0, 0, do_flush);
1509 snat_ipfix_logging_addr_exhausted (thread_index, 0, do_flush);
1510 snat_ipfix_logging_max_entries_per_usr (thread_index, 0, 0, do_flush);
1511 nat_ipfix_logging_max_ses (thread_index, 0, do_flush);
1512 nat_ipfix_logging_max_bib (thread_index, 0, do_flush);
1513 nat_ipfix_logging_max_frag_ip4 (thread_index, 0, 0, do_flush);
1514 nat_ipfix_logging_max_frag_ip6 (thread_index, 0, 0, do_flush);
1515 nat_ipfix_logging_nat64_bibe (thread_index,
1516 0, 0, 0, 0, 0, 0, 0, do_flush);
1517 nat_ipfix_logging_nat64_ses (thread_index,
1518 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, do_flush);
1522 snat_ipfix_flush_from_main (void)
1524 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1525 vlib_main_t *worker_vm;
1528 if (PREDICT_TRUE (!clib_atomic_fetch_or(&silm->enabled, 0)))
1531 if (PREDICT_FALSE (!silm->worker_vms))
1533 for (i = 1; i < vec_len (vlib_mains); i++)
1535 worker_vm = vlib_mains[i];
1537 vec_add1 (silm->worker_vms, worker_vm);
1541 /* Trigger flush for each worker thread */
1542 for (i = 0; i < vec_len (silm->worker_vms); i++)
1544 worker_vm = silm->worker_vms[i];
1546 vlib_node_set_interrupt_pending (worker_vm,
1547 snat_ipfix_flush_node.index);
1550 /* Finally flush main thread */
1551 snat_ipfix_flush (0);
1555 * @brief Generate NAT44 session create event
1557 * @param thread_index thread index
1558 * @param src_ip source IPv4 address
1559 * @param nat_src_ip transaltes source IPv4 address
1560 * @param snat_proto NAT transport protocol
1561 * @param src_port source port
1562 * @param nat_src_port translated source port
1563 * @param vrf_id VRF ID
1566 snat_ipfix_logging_nat44_ses_create (u32 thread_index,
1569 snat_protocol_t snat_proto,
1571 u16 nat_src_port, u32 vrf_id)
1573 skip_if_disabled ();
1575 snat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_CREATE, src_ip,
1576 nat_src_ip, snat_proto, src_port, nat_src_port,
1581 * @brief Generate NAT44 session delete event
1583 * @param thread_index thread index
1584 * @param src_ip source IPv4 address
1585 * @param nat_src_ip transaltes source IPv4 address
1586 * @param snat_proto NAT transport protocol
1587 * @param src_port source port
1588 * @param nat_src_port translated source port
1589 * @param vrf_id VRF ID
1592 snat_ipfix_logging_nat44_ses_delete (u32 thread_index,
1595 snat_protocol_t snat_proto,
1597 u16 nat_src_port, u32 vrf_id)
1599 skip_if_disabled ();
1601 snat_ipfix_logging_nat44_ses (thread_index, NAT44_SESSION_DELETE, src_ip,
1602 nat_src_ip, snat_proto, src_port, nat_src_port,
1607 * @brief Generate NAT addresses exhausted event
1609 * @param thread_index thread index
1610 * @param pool_id NAT pool ID
1613 snat_ipfix_logging_addresses_exhausted (u32 thread_index, u32 pool_id)
1615 //TODO: This event SHOULD be rate limited
1616 skip_if_disabled ();
1618 snat_ipfix_logging_addr_exhausted (thread_index, pool_id, 0);
1622 * @brief Generate maximum entries per user exceeded event
1624 * @param thread_index thread index
1625 * @param limit maximum NAT entries that can be created per user
1626 * @param src_ip source IPv4 address
1629 snat_ipfix_logging_max_entries_per_user (u32 thread_index, u32 limit, u32 src_ip)
1631 //TODO: This event SHOULD be rate limited
1632 skip_if_disabled ();
1634 snat_ipfix_logging_max_entries_per_usr (thread_index, limit, src_ip, 0);
1638 deterministic_nat_data_callback
1639 (flow_report_main_t * frm,
1642 u32 * to_next, u32 node_index)
1644 snat_ipfix_flush_from_main();
1650 * @brief Generate maximum session entries exceeded event
1652 * @param thread_index thread index
1653 * @param limit configured limit
1656 nat_ipfix_logging_max_sessions (u32 thread_index, u32 limit)
1658 //TODO: This event SHOULD be rate limited
1659 skip_if_disabled ();
1661 nat_ipfix_logging_max_ses (thread_index, limit, 0);
1665 * @brief Generate maximum BIB entries exceeded event
1667 * @param thread_index thread index
1668 * @param limit configured limit
1671 nat_ipfix_logging_max_bibs (u32 thread_index, u32 limit)
1673 //TODO: This event SHOULD be rate limited
1674 skip_if_disabled ();
1676 nat_ipfix_logging_max_bib (thread_index, limit, 0);
1680 * @brief Generate maximum IPv4 fragments pending reassembly exceeded event
1682 * @param thread_index thread index
1683 * @param limit configured limit
1684 * @param src source IPv4 address
1687 nat_ipfix_logging_max_fragments_ip4 (u32 thread_index,
1688 u32 limit, ip4_address_t * src)
1690 //TODO: This event SHOULD be rate limited
1691 skip_if_disabled ();
1693 nat_ipfix_logging_max_frag_ip4 (thread_index, limit, src->as_u32, 0);
1697 * @brief Generate maximum IPv6 fragments pending reassembly exceeded event
1699 * @param thread_index thread index
1700 * @param limit configured limit
1701 * @param src source IPv6 address
1704 nat_ipfix_logging_max_fragments_ip6 (u32 thread_index,
1705 u32 limit, ip6_address_t * src)
1707 //TODO: This event SHOULD be rate limited
1708 skip_if_disabled ();
1710 nat_ipfix_logging_max_frag_ip6 (thread_index, limit, src, 0);
1714 * @brief Generate NAT64 BIB create and delete events
1716 * @param thread_index thread index
1717 * @param src_ip source IPv6 address
1718 * @param nat_src_ip transaltes source IPv4 address
1719 * @param proto L4 protocol
1720 * @param src_port source port
1721 * @param nat_src_port translated source port
1722 * @param vrf_id VRF ID
1723 * @param is_create non-zero value if create event otherwise delete event
1726 nat_ipfix_logging_nat64_bib (u32 thread_index, ip6_address_t * src_ip,
1727 ip4_address_t * nat_src_ip, u8 proto,
1728 u16 src_port, u16 nat_src_port, u32 vrf_id,
1733 skip_if_disabled ();
1735 nat_event = is_create ? NAT64_BIB_CREATE : NAT64_BIB_DELETE;
1737 nat_ipfix_logging_nat64_bibe (thread_index, nat_event, src_ip,
1738 nat_src_ip->as_u32, proto, src_port,
1739 nat_src_port, vrf_id, 0);
1743 * @brief Generate NAT64 session create and delete events
1745 * @param thread_index thread index
1746 * @param src_ip source IPv6 address
1747 * @param nat_src_ip transaltes source IPv4 address
1748 * @param proto L4 protocol
1749 * @param src_port source port
1750 * @param nat_src_port translated source port
1751 * @param dst_ip destination IPv6 address
1752 * @param nat_dst_ip destination IPv4 address
1753 * @param dst_port destination port
1754 * @param nat_dst_port translated destination port
1755 * @param vrf_id VRF ID
1756 * @param is_create non-zero value if create event otherwise delete event
1759 nat_ipfix_logging_nat64_session (u32 thread_index,
1760 ip6_address_t * src_ip,
1761 ip4_address_t * nat_src_ip, u8 proto,
1762 u16 src_port, u16 nat_src_port,
1763 ip6_address_t * dst_ip,
1764 ip4_address_t * nat_dst_ip, u16 dst_port,
1765 u16 nat_dst_port, u32 vrf_id, u8 is_create)
1769 skip_if_disabled ();
1771 nat_event = is_create ? NAT64_SESSION_CREATE : NAT64_SESSION_DELETE;
1773 nat_ipfix_logging_nat64_ses (thread_index, nat_event, src_ip,
1774 nat_src_ip->as_u32, proto, src_port,
1775 nat_src_port, dst_ip, nat_dst_ip->as_u32,
1776 dst_port, nat_dst_port, vrf_id, 0);
1780 data_callback (flow_report_main_t * frm, flow_report_t * fr,
1781 vlib_frame_t * f, u32 * to_next, u32 node_index)
1783 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1785 if (PREDICT_FALSE (++silm->call_counter >= vec_len (frm->reports)))
1787 snat_ipfix_flush_from_main();
1788 silm->call_counter = 0;
1795 * @brief Enable/disable NAT plugin IPFIX logging
1797 * @param enable 1 if enable, 0 if disable
1798 * @param domain_id observation domain ID
1799 * @param src_port source port number
1801 * @returns 0 if success
1804 snat_ipfix_logging_enable_disable (int enable, u32 domain_id, u16 src_port)
1806 snat_main_t *sm = &snat_main;
1807 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1808 flow_report_main_t *frm = &flow_report_main;
1809 vnet_flow_report_add_del_args_t a;
1811 u8 e = enable ? 1 : 0;
1813 if (clib_atomic_cmp_and_swap (&silm->enabled, e ^ 1, e) == e)
1816 clib_memset (&a, 0, sizeof (a));
1818 a.domain_id = domain_id ? domain_id : 1;
1819 a.src_port = src_port ? src_port : UDP_DST_PORT_ipfix;
1820 a.flow_data_callback = data_callback;
1822 if (sm->deterministic)
1824 a.rewrite_callback = snat_template_rewrite_max_entries_per_usr;
1826 rv = vnet_flow_report_add_del (frm, &a, NULL);
1829 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1835 a.rewrite_callback = snat_template_rewrite_nat44_session;
1837 rv = vnet_flow_report_add_del (frm, &a, NULL);
1840 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1844 a.rewrite_callback = snat_template_rewrite_addr_exhausted;
1846 rv = vnet_flow_report_add_del (frm, &a, NULL);
1849 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1853 a.rewrite_callback = nat_template_rewrite_max_sessions;
1855 rv = vnet_flow_report_add_del (frm, &a, NULL);
1858 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1862 a.rewrite_callback = nat_template_rewrite_max_bibs;
1864 rv = vnet_flow_report_add_del (frm, &a, NULL);
1867 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1871 a.rewrite_callback = nat_template_rewrite_max_frags_ip4;
1873 rv = vnet_flow_report_add_del (frm, &a, NULL);
1876 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1880 a.rewrite_callback = nat_template_rewrite_max_frags_ip6;
1882 rv = vnet_flow_report_add_del (frm, &a, NULL);
1885 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1889 a.rewrite_callback = nat_template_rewrite_nat64_bib;
1891 rv = vnet_flow_report_add_del (frm, &a, NULL);
1894 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1898 a.rewrite_callback = nat_template_rewrite_nat64_session;
1900 rv = vnet_flow_report_add_del (frm, &a, NULL);
1903 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1907 if (sm->endpoint_dependent)
1909 a.rewrite_callback = snat_template_rewrite_max_entries_per_usr;
1911 rv = vnet_flow_report_add_del (frm, &a, NULL);
1914 nat_elog_warn_X1 ("vnet_flow_report_add_del returned %d", "i4", rv);
1924 * @brief Initialize NAT plugin IPFIX logging
1926 * @param vm vlib main
1929 snat_ipfix_logging_init (vlib_main_t * vm)
1931 snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1932 vlib_thread_main_t *tm = vlib_get_thread_main ();
1935 silm->worker_vms = 0;
1936 silm->call_counter = 0;
1938 /* Set up time reference pair */
1939 silm->vlib_time_0 = vlib_time_now (vm);
1940 silm->milisecond_time_0 = unix_time_now_nsec () * 1e-6;
1942 vec_validate (silm->per_thread_data, tm->n_vlib_mains - 1);
1946 ipfix_flush_process (vlib_main_t *vm,
1947 vlib_node_runtime_t *rt,
1950 snat_ipfix_flush(vm->thread_index);
1955 VLIB_REGISTER_NODE (snat_ipfix_flush_node) = {
1956 .function = ipfix_flush_process,
1957 .name = "snat-ipfix-flush",
1958 .type = VLIB_NODE_TYPE_INPUT,
1959 .state = VLIB_NODE_STATE_INTERRUPT,