Flow: Rename IPFIX exporter.
[vpp.git] / src / plugins / nat / nat_ipfix_logging.c
1 /*
2  * nat_ipfix_logging.c - NAT Events IPFIX logging
3  *
4  * Copyright (c) 2016 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <vnet/ipfix-export/flow_report.h>
19 #include <vlibmemory/api.h>
20 #include <nat/nat_ipfix_logging.h>
21
22 snat_ipfix_logging_main_t snat_ipfix_logging_main;
23
24 #define NAT44_SESSION_CREATE_LEN 26
25 #define NAT_ADDRESSES_EXHAUTED_LEN 13
26 #define MAX_ENTRIES_PER_USER_LEN 21
27 #define MAX_SESSIONS_LEN 17
28 #define MAX_BIBS_LEN 17
29 #define MAX_FRAGMENTS_IP4_LEN 21
30 #define MAX_FRAGMENTS_IP6_LEN 33
31 #define NAT64_BIB_LEN 38
32 #define NAT64_SES_LEN 62
33
34 #define NAT44_SESSION_CREATE_FIELD_COUNT 8
35 #define NAT_ADDRESSES_EXHAUTED_FIELD_COUNT 3
36 #define MAX_ENTRIES_PER_USER_FIELD_COUNT 5
37 #define MAX_SESSIONS_FIELD_COUNT 4
38 #define MAX_BIBS_FIELD_COUNT 4
39 #define MAX_FRAGMENTS_FIELD_COUNT 5
40 #define NAT64_BIB_FIELD_COUNT 8
41 #define NAT64_SES_FIELD_COUNT 12
42
43 typedef struct
44 {
45   u8 nat_event;
46   u32 src_ip;
47   u32 nat_src_ip;
48   snat_protocol_t snat_proto;
49   u16 src_port;
50   u16 nat_src_port;
51   u32 vrf_id;
52 } snat_ipfix_logging_nat44_ses_args_t;
53
54 typedef struct
55 {
56   u32 pool_id;
57 } snat_ipfix_logging_addr_exhausted_args_t;
58
59 typedef struct
60 {
61   u32 limit;
62   u32 src_ip;
63 } snat_ipfix_logging_max_entries_per_user_args_t;
64
65 typedef struct
66 {
67   u32 limit;
68 } nat_ipfix_logging_max_sessions_args_t;
69
70 typedef struct
71 {
72   u32 limit;
73 } nat_ipfix_logging_max_bibs_args_t;
74
75 typedef struct
76 {
77   u32 limit;
78   u32 src;
79 } nat_ipfix_logging_max_frags_ip4_args_t;
80
81 typedef struct
82 {
83   u32 limit;
84   u64 src[2];
85 } nat_ipfix_logging_max_frags_ip6_args_t;
86
87 typedef struct
88 {
89   u8 nat_event;
90   u64 src_ip[2];
91   u32 nat_src_ip;
92   u8 proto;
93   u16 src_port;
94   u16 nat_src_port;
95   u64 dst_ip[2];
96   u32 nat_dst_ip;
97   u32 vrf_id;
98   u16 dst_port;
99   u16 nat_dst_port;
100 } nat_ipfix_logging_nat64_ses_args_t;
101
102 typedef struct
103 {
104   u8 nat_event;
105   u64 src_ip[2];
106   u32 nat_src_ip;
107   u8 proto;
108   u16 src_port;
109   u16 nat_src_port;
110   u32 vrf_id;
111 } nat_ipfix_logging_nat64_bib_args_t;
112
113 #define skip_if_disabled()                                    \
114 do {                                                          \
115   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main; \
116   if (PREDICT_TRUE (!silm->enabled))                          \
117     return;                                                   \
118 } while (0)
119
120 /**
121  * @brief Create an IPFIX template packet rewrite string
122  *
123  * @param frm               flow report main
124  * @param fr                flow report
125  * @param collector_address collector address
126  * @param src_address       source address
127  * @param collector_port    collector
128  * @param event             NAT event ID
129  * @param quota_event       NAT quota exceeded event ID
130  *
131  * @returns template packet
132  */
133 static inline u8 *
134 snat_template_rewrite (flow_report_main_t * frm,
135                        flow_report_t * fr,
136                        ip4_address_t * collector_address,
137                        ip4_address_t * src_address,
138                        u16 collector_port,
139                        nat_event_t event, quota_exceed_event_t quota_event)
140 {
141   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
142   ip4_header_t *ip;
143   udp_header_t *udp;
144   ipfix_message_header_t *h;
145   ipfix_set_header_t *s;
146   ipfix_template_header_t *t;
147   ipfix_field_specifier_t *f;
148   ipfix_field_specifier_t *first_field;
149   u8 *rewrite = 0;
150   ip4_ipfix_template_packet_t *tp;
151   u32 field_count = 0;
152   flow_report_stream_t *stream;
153
154   stream = &frm->streams[fr->stream_index];
155   silm->stream_index = fr->stream_index;
156
157   if (event == NAT_ADDRESSES_EXHAUTED)
158     {
159       field_count = NAT_ADDRESSES_EXHAUTED_FIELD_COUNT;
160       silm->addr_exhausted_template_id = fr->template_id;
161     }
162   else if (event == NAT44_SESSION_CREATE)
163     {
164       field_count = NAT44_SESSION_CREATE_FIELD_COUNT;
165       silm->nat44_session_template_id = fr->template_id;
166     }
167   else if (event == NAT64_BIB_CREATE)
168     {
169       field_count = NAT64_BIB_FIELD_COUNT;
170       silm->nat64_bib_template_id = fr->template_id;
171     }
172   else if (event == NAT64_SESSION_CREATE)
173     {
174       field_count = NAT64_SES_FIELD_COUNT;
175       silm->nat64_ses_template_id = fr->template_id;
176     }
177   else if (event == QUOTA_EXCEEDED)
178     {
179       if (quota_event == MAX_ENTRIES_PER_USER)
180         {
181           field_count = MAX_ENTRIES_PER_USER_FIELD_COUNT;
182           silm->max_entries_per_user_template_id = fr->template_id;
183         }
184       else if (quota_event == MAX_SESSION_ENTRIES)
185         {
186           field_count = MAX_SESSIONS_FIELD_COUNT;
187           silm->max_sessions_template_id = fr->template_id;
188         }
189       else if (quota_event == MAX_BIB_ENTRIES)
190         {
191           field_count = MAX_BIBS_FIELD_COUNT;
192           silm->max_bibs_template_id = fr->template_id;
193         }
194       else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY)
195         {
196           field_count = MAX_FRAGMENTS_FIELD_COUNT;
197           silm->max_frags_ip4_template_id = fr->template_id;
198         }
199       else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY_IP6)
200         {
201           field_count = MAX_FRAGMENTS_FIELD_COUNT;
202           silm->max_frags_ip6_template_id = fr->template_id;
203         }
204     }
205
206   /* allocate rewrite space */
207   vec_validate_aligned (rewrite,
208                         sizeof (ip4_ipfix_template_packet_t)
209                         + field_count * sizeof (ipfix_field_specifier_t) - 1,
210                         CLIB_CACHE_LINE_BYTES);
211
212   tp = (ip4_ipfix_template_packet_t *) rewrite;
213   ip = (ip4_header_t *) & tp->ip4;
214   udp = (udp_header_t *) (ip + 1);
215   h = (ipfix_message_header_t *) (udp + 1);
216   s = (ipfix_set_header_t *) (h + 1);
217   t = (ipfix_template_header_t *) (s + 1);
218   first_field = f = (ipfix_field_specifier_t *) (t + 1);
219
220   ip->ip_version_and_header_length = 0x45;
221   ip->ttl = 254;
222   ip->protocol = IP_PROTOCOL_UDP;
223   ip->src_address.as_u32 = src_address->as_u32;
224   ip->dst_address.as_u32 = collector_address->as_u32;
225   udp->src_port = clib_host_to_net_u16 (stream->src_port);
226   udp->dst_port = clib_host_to_net_u16 (collector_port);
227   udp->length = clib_host_to_net_u16 (vec_len (rewrite) - sizeof (*ip));
228
229   /* FIXUP: message header export_time */
230   h->domain_id = clib_host_to_net_u32 (stream->domain_id);
231
232   /* Add TLVs to the template */
233   if (event == NAT_ADDRESSES_EXHAUTED)
234     {
235       f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
236       f++;
237       f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
238       f++;
239       f->e_id_length = ipfix_e_id_length (0, natPoolId, 4);
240       f++;
241     }
242   else if (event == NAT44_SESSION_CREATE)
243     {
244       f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
245       f++;
246       f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
247       f++;
248       f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
249       f++;
250       f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
251       f++;
252       f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
253       f++;
254       f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
255       f++;
256       f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
257       f++;
258       f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
259       f++;
260     }
261   else if (event == NAT64_BIB_CREATE)
262     {
263       f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
264       f++;
265       f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
266       f++;
267       f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
268       f++;
269       f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
270       f++;
271       f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
272       f++;
273       f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
274       f++;
275       f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
276       f++;
277       f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
278       f++;
279     }
280   else if (event == NAT64_SESSION_CREATE)
281     {
282       f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds, 8);
283       f++;
284       f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
285       f++;
286       f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
287       f++;
288       f->e_id_length = ipfix_e_id_length (0, postNATSourceIPv4Address, 4);
289       f++;
290       f->e_id_length = ipfix_e_id_length (0, protocolIdentifier, 1);
291       f++;
292       f->e_id_length = ipfix_e_id_length (0, sourceTransportPort, 2);
293       f++;
294       f->e_id_length = ipfix_e_id_length (0, postNAPTSourceTransportPort, 2);
295       f++;
296       f->e_id_length = ipfix_e_id_length (0, destinationIPv6Address, 16);
297       f++;
298       f->e_id_length = ipfix_e_id_length (0, postNATDestinationIPv4Address, 4);
299       f++;
300       f->e_id_length = ipfix_e_id_length (0, destinationTransportPort, 2);
301       f++;
302       f->e_id_length = ipfix_e_id_length (0, postNAPTDestinationTransportPort,
303                                           2);
304       f++;
305       f->e_id_length = ipfix_e_id_length (0, ingressVRFID, 4);
306       f++;
307     }
308   else if (event == QUOTA_EXCEEDED)
309     {
310       if (quota_event == MAX_ENTRIES_PER_USER)
311         {
312           f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
313                                               8);
314           f++;
315           f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
316           f++;
317           f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
318           f++;
319           f->e_id_length = ipfix_e_id_length (0, maxEntriesPerUser, 4);
320           f++;
321           f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
322           f++;
323         }
324       else if (quota_event == MAX_SESSION_ENTRIES)
325         {
326           f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
327                                               8);
328           f++;
329           f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
330           f++;
331           f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
332           f++;
333           f->e_id_length = ipfix_e_id_length (0, maxSessionEntries, 4);
334           f++;
335         }
336       else if (quota_event == MAX_BIB_ENTRIES)
337         {
338           f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
339                                               8);
340           f++;
341           f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
342           f++;
343           f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
344           f++;
345           f->e_id_length = ipfix_e_id_length (0, maxBIBEntries, 4);
346           f++;
347         }
348       else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY)
349         {
350           f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
351                                               8);
352           f++;
353           f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
354           f++;
355           f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
356           f++;
357           f->e_id_length = ipfix_e_id_length (0, maxFragmentsPendingReassembly,
358                                               4);
359           f++;
360           f->e_id_length = ipfix_e_id_length (0, sourceIPv4Address, 4);
361           f++;
362         }
363       else if (quota_event == MAX_FRAGMENTS_PENDING_REASSEMBLY_IP6)
364         {
365           f->e_id_length = ipfix_e_id_length (0, observationTimeMilliseconds,
366                                               8);
367           f++;
368           f->e_id_length = ipfix_e_id_length (0, natEvent, 1);
369           f++;
370           f->e_id_length = ipfix_e_id_length (0, natQuotaExceededEvent, 4);
371           f++;
372           f->e_id_length = ipfix_e_id_length (0, maxFragmentsPendingReassembly,
373                                               4);
374           f++;
375           f->e_id_length = ipfix_e_id_length (0, sourceIPv6Address, 16);
376           f++;
377         }
378     }
379
380   /* Back to the template packet... */
381   ip = (ip4_header_t *) & tp->ip4;
382   udp = (udp_header_t *) (ip + 1);
383
384   ASSERT (f - first_field);
385   /* Field count in this template */
386   t->id_count = ipfix_id_count (fr->template_id, f - first_field);
387
388   /* set length in octets */
389   s->set_id_length =
390     ipfix_set_id_length (2 /* set_id */ , (u8 *) f - (u8 *) s);
391
392   /* message length in octets */
393   h->version_length = version_length ((u8 *) f - (u8 *) h);
394
395   ip->length = clib_host_to_net_u16 ((u8 *) f - (u8 *) ip);
396   ip->checksum = ip4_header_checksum (ip);
397
398   return rewrite;
399 }
400
401 u8 *
402 snat_template_rewrite_addr_exhausted (flow_report_main_t * frm,
403                                       flow_report_t * fr,
404                                       ip4_address_t * collector_address,
405                                       ip4_address_t * src_address,
406                                       u16 collector_port)
407 {
408   return snat_template_rewrite (frm, fr, collector_address, src_address,
409                                 collector_port, NAT_ADDRESSES_EXHAUTED, 0);
410 }
411
412 u8 *
413 snat_template_rewrite_nat44_session (flow_report_main_t * frm,
414                                      flow_report_t * fr,
415                                      ip4_address_t * collector_address,
416                                      ip4_address_t * src_address,
417                                      u16 collector_port)
418 {
419   return snat_template_rewrite (frm, fr, collector_address, src_address,
420                                 collector_port, NAT44_SESSION_CREATE, 0);
421 }
422
423 u8 *
424 snat_template_rewrite_max_entries_per_usr (flow_report_main_t * frm,
425                                            flow_report_t * fr,
426                                            ip4_address_t * collector_address,
427                                            ip4_address_t * src_address,
428                                            u16 collector_port)
429 {
430   return snat_template_rewrite (frm, fr, collector_address, src_address,
431                                 collector_port, QUOTA_EXCEEDED,
432                                 MAX_ENTRIES_PER_USER);
433 }
434
435 u8 *
436 nat_template_rewrite_max_sessions (flow_report_main_t * frm,
437                                    flow_report_t * fr,
438                                    ip4_address_t * collector_address,
439                                    ip4_address_t * src_address,
440                                    u16 collector_port)
441 {
442   return snat_template_rewrite (frm, fr, collector_address, src_address,
443                                 collector_port, QUOTA_EXCEEDED,
444                                 MAX_SESSION_ENTRIES);
445 }
446
447 u8 *
448 nat_template_rewrite_max_bibs (flow_report_main_t * frm,
449                                flow_report_t * fr,
450                                ip4_address_t * collector_address,
451                                ip4_address_t * src_address,
452                                u16 collector_port)
453 {
454   return snat_template_rewrite (frm, fr, collector_address, src_address,
455                                 collector_port, QUOTA_EXCEEDED,
456                                 MAX_BIB_ENTRIES);
457 }
458
459 u8 *
460 nat_template_rewrite_max_frags_ip4 (flow_report_main_t * frm,
461                                     flow_report_t * fr,
462                                     ip4_address_t * collector_address,
463                                     ip4_address_t * src_address,
464                                     u16 collector_port)
465 {
466   return snat_template_rewrite (frm, fr, collector_address, src_address,
467                                 collector_port, QUOTA_EXCEEDED,
468                                 MAX_FRAGMENTS_PENDING_REASSEMBLY);
469 }
470
471 u8 *
472 nat_template_rewrite_max_frags_ip6 (flow_report_main_t * frm,
473                                     flow_report_t * fr,
474                                     ip4_address_t * collector_address,
475                                     ip4_address_t * src_address,
476                                     u16 collector_port)
477 {
478   return snat_template_rewrite (frm, fr, collector_address, src_address,
479                                 collector_port, QUOTA_EXCEEDED,
480                                 MAX_FRAGMENTS_PENDING_REASSEMBLY_IP6);
481 }
482
483 u8 *
484 nat_template_rewrite_nat64_bib (flow_report_main_t * frm,
485                                 flow_report_t * fr,
486                                 ip4_address_t * collector_address,
487                                 ip4_address_t * src_address,
488                                 u16 collector_port)
489 {
490   return snat_template_rewrite (frm, fr, collector_address, src_address,
491                                 collector_port, NAT64_BIB_CREATE, 0);
492 }
493
494 u8 *
495 nat_template_rewrite_nat64_session (flow_report_main_t * frm,
496                                     flow_report_t * fr,
497                                     ip4_address_t * collector_address,
498                                     ip4_address_t * src_address,
499                                     u16 collector_port)
500 {
501   return snat_template_rewrite (frm, fr, collector_address, src_address,
502                                 collector_port, NAT64_SESSION_CREATE, 0);
503 }
504
505 static inline void
506 snat_ipfix_header_create (flow_report_main_t * frm,
507                           vlib_buffer_t * b0, u32 * offset)
508 {
509   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
510   flow_report_stream_t *stream;
511   ip4_ipfix_template_packet_t *tp;
512   ipfix_message_header_t *h = 0;
513   ipfix_set_header_t *s = 0;
514   ip4_header_t *ip;
515   udp_header_t *udp;
516
517   stream = &frm->streams[silm->stream_index];
518
519   b0->current_data = 0;
520   b0->current_length = sizeof (*ip) + sizeof (*udp) + sizeof (*h) +
521     sizeof (*s);
522   b0->flags |= (VLIB_BUFFER_TOTAL_LENGTH_VALID | VNET_BUFFER_F_FLOW_REPORT);
523   vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
524   vnet_buffer (b0)->sw_if_index[VLIB_TX] = frm->fib_index;
525   tp = vlib_buffer_get_current (b0);
526   ip = (ip4_header_t *) & tp->ip4;
527   udp = (udp_header_t *) (ip + 1);
528   h = (ipfix_message_header_t *) (udp + 1);
529   s = (ipfix_set_header_t *) (h + 1);
530
531   ip->ip_version_and_header_length = 0x45;
532   ip->ttl = 254;
533   ip->protocol = IP_PROTOCOL_UDP;
534   ip->flags_and_fragment_offset = 0;
535   ip->src_address.as_u32 = frm->src_address.as_u32;
536   ip->dst_address.as_u32 = frm->ipfix_collector.as_u32;
537   udp->src_port = clib_host_to_net_u16 (stream->src_port);
538   udp->dst_port = clib_host_to_net_u16 (frm->collector_port);
539   udp->checksum = 0;
540
541   h->export_time = clib_host_to_net_u32 ((u32)
542                                          (((f64) frm->unix_time_0) +
543                                           (vlib_time_now (frm->vlib_main) -
544                                            frm->vlib_time_0)));
545   h->sequence_number = clib_host_to_net_u32 (stream->sequence_number++);
546   h->domain_id = clib_host_to_net_u32 (stream->domain_id);
547
548   *offset = (u32) (((u8 *) (s + 1)) - (u8 *) tp);
549 }
550
551 static inline void
552 snat_ipfix_send (flow_report_main_t * frm,
553                  vlib_frame_t * f, vlib_buffer_t * b0, u16 template_id)
554 {
555   ip4_ipfix_template_packet_t *tp;
556   ipfix_message_header_t *h = 0;
557   ipfix_set_header_t *s = 0;
558   ip4_header_t *ip;
559   udp_header_t *udp;
560   vlib_main_t *vm = frm->vlib_main;
561
562   tp = vlib_buffer_get_current (b0);
563   ip = (ip4_header_t *) & tp->ip4;
564   udp = (udp_header_t *) (ip + 1);
565   h = (ipfix_message_header_t *) (udp + 1);
566   s = (ipfix_set_header_t *) (h + 1);
567
568   s->set_id_length = ipfix_set_id_length (template_id,
569                                           b0->current_length -
570                                           (sizeof (*ip) + sizeof (*udp) +
571                                            sizeof (*h)));
572   h->version_length = version_length (b0->current_length -
573                                       (sizeof (*ip) + sizeof (*udp)));
574
575   ip->length = clib_host_to_net_u16 (b0->current_length);
576   ip->checksum = ip4_header_checksum (ip);
577   udp->length = clib_host_to_net_u16 (b0->current_length - sizeof (*ip));
578
579   if (frm->udp_checksum)
580     {
581       udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
582       if (udp->checksum == 0)
583         udp->checksum = 0xffff;
584     }
585
586   ASSERT (ip->checksum == ip4_header_checksum (ip));
587
588   vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
589 }
590
591 static void
592 snat_ipfix_logging_nat44_ses (u8 nat_event, u32 src_ip, u32 nat_src_ip,
593                               snat_protocol_t snat_proto, u16 src_port,
594                               u16 nat_src_port, u32 vrf_id, int do_flush)
595 {
596   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
597   flow_report_main_t *frm = &flow_report_main;
598   vlib_frame_t *f;
599   vlib_buffer_t *b0 = 0;
600   u32 bi0 = ~0;
601   u32 offset;
602   vlib_main_t *vm = frm->vlib_main;
603   u64 now;
604   vlib_buffer_free_list_t *fl;
605   u8 proto = ~0;
606
607   if (!silm->enabled)
608     return;
609
610   proto = snat_proto_to_ip_proto (snat_proto);
611
612   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
613   now += silm->milisecond_time_0;
614
615   b0 = silm->nat44_session_buffer;
616
617   if (PREDICT_FALSE (b0 == 0))
618     {
619       if (do_flush)
620         return;
621
622       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
623         {
624           clib_warning ("can't allocate buffer for NAT IPFIX event");
625           return;
626         }
627
628       b0 = silm->nat44_session_buffer = vlib_get_buffer (vm, bi0);
629       fl =
630         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
631       vlib_buffer_init_for_free_list (b0, fl);
632       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
633       offset = 0;
634     }
635   else
636     {
637       bi0 = vlib_get_buffer_index (vm, b0);
638       offset = silm->nat44_session_next_record_offset;
639     }
640
641   f = silm->nat44_session_frame;
642   if (PREDICT_FALSE (f == 0))
643     {
644       u32 *to_next;
645       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
646       silm->nat44_session_frame = f;
647       to_next = vlib_frame_vector_args (f);
648       to_next[0] = bi0;
649       f->n_vectors = 1;
650     }
651
652   if (PREDICT_FALSE (offset == 0))
653     snat_ipfix_header_create (frm, b0, &offset);
654
655   if (PREDICT_TRUE (do_flush == 0))
656     {
657       u64 time_stamp = clib_host_to_net_u64 (now);
658       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
659       offset += sizeof (time_stamp);
660
661       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
662       offset += sizeof (nat_event);
663
664       clib_memcpy (b0->data + offset, &src_ip, sizeof (src_ip));
665       offset += sizeof (src_ip);
666
667       clib_memcpy (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
668       offset += sizeof (nat_src_ip);
669
670       clib_memcpy (b0->data + offset, &proto, sizeof (proto));
671       offset += sizeof (proto);
672
673       clib_memcpy (b0->data + offset, &src_port, sizeof (src_port));
674       offset += sizeof (src_port);
675
676       clib_memcpy (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
677       offset += sizeof (nat_src_port);
678
679       clib_memcpy (b0->data + offset, &vrf_id, sizeof (vrf_id));
680       offset += sizeof (vrf_id);
681
682       b0->current_length += NAT44_SESSION_CREATE_LEN;
683     }
684
685   if (PREDICT_FALSE
686       (do_flush || (offset + NAT44_SESSION_CREATE_LEN) > frm->path_mtu))
687     {
688       snat_ipfix_send (frm, f, b0, silm->nat44_session_template_id);
689       silm->nat44_session_frame = 0;
690       silm->nat44_session_buffer = 0;
691       offset = 0;
692     }
693   silm->nat44_session_next_record_offset = offset;
694 }
695
696 static void
697 snat_ipfix_logging_addr_exhausted (u32 pool_id, int do_flush)
698 {
699   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
700   flow_report_main_t *frm = &flow_report_main;
701   vlib_frame_t *f;
702   vlib_buffer_t *b0 = 0;
703   u32 bi0 = ~0;
704   u32 offset;
705   vlib_main_t *vm = frm->vlib_main;
706   u64 now;
707   vlib_buffer_free_list_t *fl;
708   u8 nat_event = NAT_ADDRESSES_EXHAUTED;
709
710   if (!silm->enabled)
711     return;
712
713   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
714   now += silm->milisecond_time_0;
715
716   b0 = silm->addr_exhausted_buffer;
717
718   if (PREDICT_FALSE (b0 == 0))
719     {
720       if (do_flush)
721         return;
722
723       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
724         {
725           clib_warning ("can't allocate buffer for NAT IPFIX event");
726           return;
727         }
728
729       b0 = silm->addr_exhausted_buffer = vlib_get_buffer (vm, bi0);
730       fl =
731         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
732       vlib_buffer_init_for_free_list (b0, fl);
733       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
734       offset = 0;
735     }
736   else
737     {
738       bi0 = vlib_get_buffer_index (vm, b0);
739       offset = silm->addr_exhausted_next_record_offset;
740     }
741
742   f = silm->addr_exhausted_frame;
743   if (PREDICT_FALSE (f == 0))
744     {
745       u32 *to_next;
746       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
747       silm->addr_exhausted_frame = f;
748       to_next = vlib_frame_vector_args (f);
749       to_next[0] = bi0;
750       f->n_vectors = 1;
751     }
752
753   if (PREDICT_FALSE (offset == 0))
754     snat_ipfix_header_create (frm, b0, &offset);
755
756   if (PREDICT_TRUE (do_flush == 0))
757     {
758       u64 time_stamp = clib_host_to_net_u64 (now);
759       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
760       offset += sizeof (time_stamp);
761
762       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
763       offset += sizeof (nat_event);
764
765       clib_memcpy (b0->data + offset, &pool_id, sizeof (pool_id));
766       offset += sizeof (pool_id);
767
768       b0->current_length += NAT_ADDRESSES_EXHAUTED_LEN;
769     }
770
771   if (PREDICT_FALSE
772       (do_flush || (offset + NAT_ADDRESSES_EXHAUTED_LEN) > frm->path_mtu))
773     {
774       snat_ipfix_send (frm, f, b0, silm->addr_exhausted_template_id);
775       silm->addr_exhausted_frame = 0;
776       silm->addr_exhausted_buffer = 0;
777       offset = 0;
778     }
779   silm->addr_exhausted_next_record_offset = offset;
780 }
781
782 static void
783 snat_ipfix_logging_max_entries_per_usr (u32 limit, u32 src_ip, int do_flush)
784 {
785   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
786   flow_report_main_t *frm = &flow_report_main;
787   vlib_frame_t *f;
788   vlib_buffer_t *b0 = 0;
789   u32 bi0 = ~0;
790   u32 offset;
791   vlib_main_t *vm = frm->vlib_main;
792   u64 now;
793   vlib_buffer_free_list_t *fl;
794   u8 nat_event = QUOTA_EXCEEDED;
795   u32 quota_event = MAX_ENTRIES_PER_USER;
796
797   if (!silm->enabled)
798     return;
799
800   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
801   now += silm->milisecond_time_0;
802
803   b0 = silm->max_entries_per_user_buffer;
804
805   if (PREDICT_FALSE (b0 == 0))
806     {
807       if (do_flush)
808         return;
809
810       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
811         {
812           clib_warning ("can't allocate buffer for NAT IPFIX event");
813           return;
814         }
815
816       b0 = silm->max_entries_per_user_buffer = vlib_get_buffer (vm, bi0);
817       fl =
818         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
819       vlib_buffer_init_for_free_list (b0, fl);
820       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
821       offset = 0;
822     }
823   else
824     {
825       bi0 = vlib_get_buffer_index (vm, b0);
826       offset = silm->max_entries_per_user_next_record_offset;
827     }
828
829   f = silm->max_entries_per_user_frame;
830   if (PREDICT_FALSE (f == 0))
831     {
832       u32 *to_next;
833       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
834       silm->max_entries_per_user_frame = f;
835       to_next = vlib_frame_vector_args (f);
836       to_next[0] = bi0;
837       f->n_vectors = 1;
838     }
839
840   if (PREDICT_FALSE (offset == 0))
841     snat_ipfix_header_create (frm, b0, &offset);
842
843   if (PREDICT_TRUE (do_flush == 0))
844     {
845       u64 time_stamp = clib_host_to_net_u64 (now);
846       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
847       offset += sizeof (time_stamp);
848
849       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
850       offset += sizeof (nat_event);
851
852       clib_memcpy (b0->data + offset, &quota_event, sizeof (quota_event));
853       offset += sizeof (quota_event);
854
855       clib_memcpy (b0->data + offset, &limit, sizeof (limit));
856       offset += sizeof (limit);
857
858       clib_memcpy (b0->data + offset, &src_ip, sizeof (src_ip));
859       offset += sizeof (src_ip);
860
861       b0->current_length += MAX_ENTRIES_PER_USER_LEN;
862     }
863
864   if (PREDICT_FALSE
865       (do_flush || (offset + MAX_ENTRIES_PER_USER_LEN) > frm->path_mtu))
866     {
867       snat_ipfix_send (frm, f, b0, silm->max_entries_per_user_template_id);
868       silm->max_entries_per_user_frame = 0;
869       silm->max_entries_per_user_buffer = 0;
870       offset = 0;
871     }
872   silm->max_entries_per_user_next_record_offset = offset;
873 }
874
875 static void
876 nat_ipfix_logging_max_ses (u32 limit, int do_flush)
877 {
878   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
879   flow_report_main_t *frm = &flow_report_main;
880   vlib_frame_t *f;
881   vlib_buffer_t *b0 = 0;
882   u32 bi0 = ~0;
883   u32 offset;
884   vlib_main_t *vm = frm->vlib_main;
885   u64 now;
886   vlib_buffer_free_list_t *fl;
887   u8 nat_event = QUOTA_EXCEEDED;
888   u32 quota_event = MAX_SESSION_ENTRIES;
889
890   if (!silm->enabled)
891     return;
892
893   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
894   now += silm->milisecond_time_0;
895
896   b0 = silm->max_sessions_buffer;
897
898   if (PREDICT_FALSE (b0 == 0))
899     {
900       if (do_flush)
901         return;
902
903       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
904         {
905           clib_warning ("can't allocate buffer for NAT IPFIX event");
906           return;
907         }
908
909       b0 = silm->max_sessions_buffer = vlib_get_buffer (vm, bi0);
910       fl =
911         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
912       vlib_buffer_init_for_free_list (b0, fl);
913       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
914       offset = 0;
915     }
916   else
917     {
918       bi0 = vlib_get_buffer_index (vm, b0);
919       offset = silm->max_sessions_next_record_offset;
920     }
921
922   f = silm->max_sessions_frame;
923   if (PREDICT_FALSE (f == 0))
924     {
925       u32 *to_next;
926       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
927       silm->max_sessions_frame = f;
928       to_next = vlib_frame_vector_args (f);
929       to_next[0] = bi0;
930       f->n_vectors = 1;
931     }
932
933   if (PREDICT_FALSE (offset == 0))
934     snat_ipfix_header_create (frm, b0, &offset);
935
936   if (PREDICT_TRUE (do_flush == 0))
937     {
938       u64 time_stamp = clib_host_to_net_u64 (now);
939       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
940       offset += sizeof (time_stamp);
941
942       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
943       offset += sizeof (nat_event);
944
945       clib_memcpy (b0->data + offset, &quota_event, sizeof (quota_event));
946       offset += sizeof (quota_event);
947
948       clib_memcpy (b0->data + offset, &limit, sizeof (limit));
949       offset += sizeof (limit);
950
951       b0->current_length += MAX_SESSIONS_LEN;
952     }
953
954   if (PREDICT_FALSE
955       (do_flush || (offset + MAX_SESSIONS_LEN) > frm->path_mtu))
956     {
957       snat_ipfix_send (frm, f, b0, silm->max_sessions_template_id);
958       silm->max_sessions_frame = 0;
959       silm->max_sessions_buffer = 0;
960       offset = 0;
961     }
962   silm->max_sessions_next_record_offset = offset;
963 }
964
965 static void
966 nat_ipfix_logging_max_bib (u32 limit, int do_flush)
967 {
968   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
969   flow_report_main_t *frm = &flow_report_main;
970   vlib_frame_t *f;
971   vlib_buffer_t *b0 = 0;
972   u32 bi0 = ~0;
973   u32 offset;
974   vlib_main_t *vm = frm->vlib_main;
975   u64 now;
976   vlib_buffer_free_list_t *fl;
977   u8 nat_event = QUOTA_EXCEEDED;
978   u32 quota_event = MAX_BIB_ENTRIES;
979
980   if (!silm->enabled)
981     return;
982
983   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
984   now += silm->milisecond_time_0;
985
986   b0 = silm->max_bibs_buffer;
987
988   if (PREDICT_FALSE (b0 == 0))
989     {
990       if (do_flush)
991         return;
992
993       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
994         {
995           clib_warning ("can't allocate buffer for NAT IPFIX event");
996           return;
997         }
998
999       b0 = silm->max_bibs_buffer = vlib_get_buffer (vm, bi0);
1000       fl =
1001         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
1002       vlib_buffer_init_for_free_list (b0, fl);
1003       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1004       offset = 0;
1005     }
1006   else
1007     {
1008       bi0 = vlib_get_buffer_index (vm, b0);
1009       offset = silm->max_bibs_next_record_offset;
1010     }
1011
1012   f = silm->max_bibs_frame;
1013   if (PREDICT_FALSE (f == 0))
1014     {
1015       u32 *to_next;
1016       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1017       silm->max_bibs_frame = f;
1018       to_next = vlib_frame_vector_args (f);
1019       to_next[0] = bi0;
1020       f->n_vectors = 1;
1021     }
1022
1023   if (PREDICT_FALSE (offset == 0))
1024     snat_ipfix_header_create (frm, b0, &offset);
1025
1026   if (PREDICT_TRUE (do_flush == 0))
1027     {
1028       u64 time_stamp = clib_host_to_net_u64 (now);
1029       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
1030       offset += sizeof (time_stamp);
1031
1032       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
1033       offset += sizeof (nat_event);
1034
1035       clib_memcpy (b0->data + offset, &quota_event, sizeof (quota_event));
1036       offset += sizeof (quota_event);
1037
1038       clib_memcpy (b0->data + offset, &limit, sizeof (limit));
1039       offset += sizeof (limit);
1040
1041       b0->current_length += MAX_BIBS_LEN;
1042     }
1043
1044   if (PREDICT_FALSE
1045       (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1046     {
1047       snat_ipfix_send (frm, f, b0, silm->max_bibs_template_id);
1048       silm->max_bibs_frame = 0;
1049       silm->max_bibs_buffer = 0;
1050       offset = 0;
1051     }
1052   silm->max_bibs_next_record_offset = offset;
1053 }
1054
1055 static void
1056 nat_ipfix_logging_max_frag_ip4 (u32 limit, u32 src, int do_flush)
1057 {
1058   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1059   flow_report_main_t *frm = &flow_report_main;
1060   vlib_frame_t *f;
1061   vlib_buffer_t *b0 = 0;
1062   u32 bi0 = ~0;
1063   u32 offset;
1064   vlib_main_t *vm = frm->vlib_main;
1065   u64 now;
1066   vlib_buffer_free_list_t *fl;
1067   u8 nat_event = QUOTA_EXCEEDED;
1068   u32 quota_event = MAX_FRAGMENTS_PENDING_REASSEMBLY;
1069
1070   if (!silm->enabled)
1071     return;
1072
1073   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1074   now += silm->milisecond_time_0;
1075
1076   b0 = silm->max_frags_ip4_buffer;
1077
1078   if (PREDICT_FALSE (b0 == 0))
1079     {
1080       if (do_flush)
1081         return;
1082
1083       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1084         {
1085           clib_warning ("can't allocate buffer for NAT IPFIX event");
1086           return;
1087         }
1088
1089       b0 = silm->max_frags_ip4_buffer = vlib_get_buffer (vm, bi0);
1090       fl =
1091         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
1092       vlib_buffer_init_for_free_list (b0, fl);
1093       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1094       offset = 0;
1095     }
1096   else
1097     {
1098       bi0 = vlib_get_buffer_index (vm, b0);
1099       offset = silm->max_frags_ip4_next_record_offset;
1100     }
1101
1102   f = silm->max_frags_ip4_frame;
1103   if (PREDICT_FALSE (f == 0))
1104     {
1105       u32 *to_next;
1106       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1107       silm->max_frags_ip4_frame = f;
1108       to_next = vlib_frame_vector_args (f);
1109       to_next[0] = bi0;
1110       f->n_vectors = 1;
1111     }
1112
1113   if (PREDICT_FALSE (offset == 0))
1114     snat_ipfix_header_create (frm, b0, &offset);
1115
1116   if (PREDICT_TRUE (do_flush == 0))
1117     {
1118       u64 time_stamp = clib_host_to_net_u64 (now);
1119       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
1120       offset += sizeof (time_stamp);
1121
1122       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
1123       offset += sizeof (nat_event);
1124
1125       clib_memcpy (b0->data + offset, &quota_event, sizeof (quota_event));
1126       offset += sizeof (quota_event);
1127
1128       clib_memcpy (b0->data + offset, &limit, sizeof (limit));
1129       offset += sizeof (limit);
1130
1131       clib_memcpy (b0->data + offset, &src, sizeof (src));
1132       offset += sizeof (src);
1133
1134       b0->current_length += MAX_FRAGMENTS_IP4_LEN;
1135     }
1136
1137   if (PREDICT_FALSE
1138       (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1139     {
1140       snat_ipfix_send (frm, f, b0, silm->max_frags_ip4_template_id);
1141       silm->max_frags_ip4_frame = 0;
1142       silm->max_frags_ip4_buffer = 0;
1143       offset = 0;
1144     }
1145   silm->max_frags_ip4_next_record_offset = offset;
1146 }
1147
1148 static void
1149 nat_ipfix_logging_max_frag_ip6 (u32 limit, ip6_address_t * src, int do_flush)
1150 {
1151   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1152   flow_report_main_t *frm = &flow_report_main;
1153   vlib_frame_t *f;
1154   vlib_buffer_t *b0 = 0;
1155   u32 bi0 = ~0;
1156   u32 offset;
1157   vlib_main_t *vm = frm->vlib_main;
1158   u64 now;
1159   vlib_buffer_free_list_t *fl;
1160   u8 nat_event = QUOTA_EXCEEDED;
1161   u32 quota_event = MAX_FRAGMENTS_PENDING_REASSEMBLY;
1162
1163   if (!silm->enabled)
1164     return;
1165
1166   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1167   now += silm->milisecond_time_0;
1168
1169   b0 = silm->max_frags_ip6_buffer;
1170
1171   if (PREDICT_FALSE (b0 == 0))
1172     {
1173       if (do_flush)
1174         return;
1175
1176       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1177         {
1178           clib_warning ("can't allocate buffer for NAT IPFIX event");
1179           return;
1180         }
1181
1182       b0 = silm->max_frags_ip6_buffer = vlib_get_buffer (vm, bi0);
1183       fl =
1184         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
1185       vlib_buffer_init_for_free_list (b0, fl);
1186       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1187       offset = 0;
1188     }
1189   else
1190     {
1191       bi0 = vlib_get_buffer_index (vm, b0);
1192       offset = silm->max_frags_ip6_next_record_offset;
1193     }
1194
1195   f = silm->max_frags_ip6_frame;
1196   if (PREDICT_FALSE (f == 0))
1197     {
1198       u32 *to_next;
1199       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1200       silm->max_frags_ip6_frame = f;
1201       to_next = vlib_frame_vector_args (f);
1202       to_next[0] = bi0;
1203       f->n_vectors = 1;
1204     }
1205
1206   if (PREDICT_FALSE (offset == 0))
1207     snat_ipfix_header_create (frm, b0, &offset);
1208
1209   if (PREDICT_TRUE (do_flush == 0))
1210     {
1211       u64 time_stamp = clib_host_to_net_u64 (now);
1212       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
1213       offset += sizeof (time_stamp);
1214
1215       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
1216       offset += sizeof (nat_event);
1217
1218       clib_memcpy (b0->data + offset, &quota_event, sizeof (quota_event));
1219       offset += sizeof (quota_event);
1220
1221       clib_memcpy (b0->data + offset, &limit, sizeof (limit));
1222       offset += sizeof (limit);
1223
1224       clib_memcpy (b0->data + offset, src, sizeof (ip6_address_t));
1225       offset += sizeof (ip6_address_t);
1226
1227       b0->current_length += MAX_FRAGMENTS_IP6_LEN;
1228     }
1229
1230   if (PREDICT_FALSE
1231       (do_flush || (offset + MAX_BIBS_LEN) > frm->path_mtu))
1232     {
1233       snat_ipfix_send (frm, f, b0, silm->max_frags_ip6_template_id);
1234       silm->max_frags_ip6_frame = 0;
1235       silm->max_frags_ip6_buffer = 0;
1236       offset = 0;
1237     }
1238   silm->max_frags_ip6_next_record_offset = offset;
1239 }
1240
1241 static void
1242 nat_ipfix_logging_nat64_bibe (u8 nat_event, ip6_address_t * src_ip,
1243                               u32 nat_src_ip, u8 proto, u16 src_port,
1244                               u16 nat_src_port, u32 vrf_id, int do_flush)
1245 {
1246   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1247   flow_report_main_t *frm = &flow_report_main;
1248   vlib_frame_t *f;
1249   vlib_buffer_t *b0 = 0;
1250   u32 bi0 = ~0;
1251   u32 offset;
1252   vlib_main_t *vm = frm->vlib_main;
1253   u64 now;
1254   vlib_buffer_free_list_t *fl;
1255
1256   if (!silm->enabled)
1257     return;
1258
1259   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1260   now += silm->milisecond_time_0;
1261
1262   b0 = silm->nat64_bib_buffer;
1263
1264   if (PREDICT_FALSE (b0 == 0))
1265     {
1266       if (do_flush)
1267         return;
1268
1269       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1270         {
1271           clib_warning ("can't allocate buffer for NAT IPFIX event");
1272           return;
1273         }
1274
1275       b0 = silm->nat64_bib_buffer = vlib_get_buffer (vm, bi0);
1276       fl =
1277         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
1278       vlib_buffer_init_for_free_list (b0, fl);
1279       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1280       offset = 0;
1281     }
1282   else
1283     {
1284       bi0 = vlib_get_buffer_index (vm, b0);
1285       offset = silm->nat64_bib_next_record_offset;
1286     }
1287
1288   f = silm->nat64_bib_frame;
1289   if (PREDICT_FALSE (f == 0))
1290     {
1291       u32 *to_next;
1292       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1293       silm->nat64_bib_frame = f;
1294       to_next = vlib_frame_vector_args (f);
1295       to_next[0] = bi0;
1296       f->n_vectors = 1;
1297     }
1298
1299   if (PREDICT_FALSE (offset == 0))
1300     snat_ipfix_header_create (frm, b0, &offset);
1301
1302   if (PREDICT_TRUE (do_flush == 0))
1303     {
1304       u64 time_stamp = clib_host_to_net_u64 (now);
1305       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
1306       offset += sizeof (time_stamp);
1307
1308       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
1309       offset += sizeof (nat_event);
1310
1311       clib_memcpy (b0->data + offset, src_ip, sizeof (ip6_address_t));
1312       offset += sizeof (ip6_address_t);
1313
1314       clib_memcpy (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1315       offset += sizeof (nat_src_ip);
1316
1317       clib_memcpy (b0->data + offset, &proto, sizeof (proto));
1318       offset += sizeof (proto);
1319
1320       clib_memcpy (b0->data + offset, &src_port, sizeof (src_port));
1321       offset += sizeof (src_port);
1322
1323       clib_memcpy (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1324       offset += sizeof (nat_src_port);
1325
1326       clib_memcpy (b0->data + offset, &vrf_id, sizeof (vrf_id));
1327       offset += sizeof (vrf_id);
1328
1329       b0->current_length += NAT64_BIB_LEN;
1330     }
1331
1332   if (PREDICT_FALSE
1333       (do_flush || (offset + NAT64_BIB_LEN) > frm->path_mtu))
1334     {
1335       snat_ipfix_send (frm, f, b0, silm->nat64_bib_template_id);
1336       silm->nat64_bib_frame = 0;
1337       silm->nat64_bib_buffer = 0;
1338       offset = 0;
1339     }
1340   silm->nat64_bib_next_record_offset = offset;
1341 }
1342
1343 static void
1344 nat_ipfix_logging_nat64_ses (u8 nat_event, ip6_address_t * src_ip,
1345                              u32 nat_src_ip, u8 proto, u16 src_port,
1346                              u16 nat_src_port, ip6_address_t * dst_ip,
1347                              u32 nat_dst_ip, u16 dst_port, u16 nat_dst_port,
1348                              u32 vrf_id, int do_flush)
1349 {
1350   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1351   flow_report_main_t *frm = &flow_report_main;
1352   vlib_frame_t *f;
1353   vlib_buffer_t *b0 = 0;
1354   u32 bi0 = ~0;
1355   u32 offset;
1356   vlib_main_t *vm = frm->vlib_main;
1357   u64 now;
1358   vlib_buffer_free_list_t *fl;
1359
1360   if (!silm->enabled)
1361     return;
1362
1363   now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
1364   now += silm->milisecond_time_0;
1365
1366   b0 = silm->nat64_ses_buffer;
1367
1368   if (PREDICT_FALSE (b0 == 0))
1369     {
1370       if (do_flush)
1371         return;
1372
1373       if (vlib_buffer_alloc (vm, &bi0, 1) != 1)
1374         {
1375           clib_warning ("can't allocate buffer for NAT IPFIX event");
1376           return;
1377         }
1378
1379       b0 = silm->nat64_ses_buffer = vlib_get_buffer (vm, bi0);
1380       fl =
1381         vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
1382       vlib_buffer_init_for_free_list (b0, fl);
1383       VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0);
1384       offset = 0;
1385     }
1386   else
1387     {
1388       bi0 = vlib_get_buffer_index (vm, b0);
1389       offset = silm->nat64_ses_next_record_offset;
1390     }
1391
1392   f = silm->nat64_ses_frame;
1393   if (PREDICT_FALSE (f == 0))
1394     {
1395       u32 *to_next;
1396       f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
1397       silm->nat64_ses_frame = f;
1398       to_next = vlib_frame_vector_args (f);
1399       to_next[0] = bi0;
1400       f->n_vectors = 1;
1401     }
1402
1403   if (PREDICT_FALSE (offset == 0))
1404     snat_ipfix_header_create (frm, b0, &offset);
1405
1406   if (PREDICT_TRUE (do_flush == 0))
1407     {
1408       u64 time_stamp = clib_host_to_net_u64 (now);
1409       clib_memcpy (b0->data + offset, &time_stamp, sizeof (time_stamp));
1410       offset += sizeof (time_stamp);
1411
1412       clib_memcpy (b0->data + offset, &nat_event, sizeof (nat_event));
1413       offset += sizeof (nat_event);
1414
1415       clib_memcpy (b0->data + offset, src_ip, sizeof (ip6_address_t));
1416       offset += sizeof (ip6_address_t);
1417
1418       clib_memcpy (b0->data + offset, &nat_src_ip, sizeof (nat_src_ip));
1419       offset += sizeof (nat_src_ip);
1420
1421       clib_memcpy (b0->data + offset, &proto, sizeof (proto));
1422       offset += sizeof (proto);
1423
1424       clib_memcpy (b0->data + offset, &src_port, sizeof (src_port));
1425       offset += sizeof (src_port);
1426
1427       clib_memcpy (b0->data + offset, &nat_src_port, sizeof (nat_src_port));
1428       offset += sizeof (nat_src_port);
1429
1430       clib_memcpy (b0->data + offset, dst_ip, sizeof (ip6_address_t));
1431       offset += sizeof (ip6_address_t);
1432
1433       clib_memcpy (b0->data + offset, &nat_dst_ip, sizeof (nat_dst_ip));
1434       offset += sizeof (nat_dst_ip);
1435
1436       clib_memcpy (b0->data + offset, &dst_port, sizeof (dst_port));
1437       offset += sizeof (dst_port);
1438
1439       clib_memcpy (b0->data + offset, &nat_dst_port, sizeof (nat_dst_port));
1440       offset += sizeof (nat_dst_port);
1441
1442       clib_memcpy (b0->data + offset, &vrf_id, sizeof (vrf_id));
1443       offset += sizeof (vrf_id);
1444
1445       b0->current_length += NAT64_SES_LEN;
1446     }
1447
1448   if (PREDICT_FALSE
1449       (do_flush || (offset + NAT64_SES_LEN) > frm->path_mtu))
1450     {
1451       snat_ipfix_send (frm, f, b0, silm->nat64_ses_template_id);
1452       silm->nat64_ses_frame = 0;
1453       silm->nat64_ses_buffer = 0;
1454       offset = 0;
1455     }
1456   silm->nat64_ses_next_record_offset = offset;
1457 }
1458
1459 static void
1460 snat_ipfix_logging_nat44_ses_rpc_cb (snat_ipfix_logging_nat44_ses_args_t * a)
1461 {
1462   snat_ipfix_logging_nat44_ses (a->nat_event, a->src_ip, a->nat_src_ip,
1463                                 a->snat_proto, a->src_port, a->nat_src_port,
1464                                 a->vrf_id, 0);
1465 }
1466
1467 /**
1468  * @brief Generate NAT44 session create event
1469  *
1470  * @param src_ip       source IPv4 address
1471  * @param nat_src_ip   transaltes source IPv4 address
1472  * @param snat_proto   NAT transport protocol
1473  * @param src_port     source port
1474  * @param nat_src_port translated source port
1475  * @param vrf_id       VRF ID
1476  */
1477 void
1478 snat_ipfix_logging_nat44_ses_create (u32 src_ip,
1479                                      u32 nat_src_ip,
1480                                      snat_protocol_t snat_proto,
1481                                      u16 src_port,
1482                                      u16 nat_src_port, u32 vrf_id)
1483 {
1484   snat_ipfix_logging_nat44_ses_args_t a;
1485
1486   skip_if_disabled ();
1487
1488   a.nat_event = NAT44_SESSION_CREATE;
1489   a.src_ip = src_ip;
1490   a.nat_src_ip = nat_src_ip;
1491   a.snat_proto = snat_proto;
1492   a.src_port = src_port;
1493   a.nat_src_port = nat_src_port;
1494   a.vrf_id = vrf_id;
1495
1496   vl_api_rpc_call_main_thread (snat_ipfix_logging_nat44_ses_rpc_cb,
1497                                (u8 *) & a, sizeof (a));
1498 }
1499
1500 /**
1501  * @brief Generate NAT44 session delete event
1502  *
1503  * @param src_ip       source IPv4 address
1504  * @param nat_src_ip   transaltes source IPv4 address
1505  * @param snat_proto   NAT transport protocol
1506  * @param src_port     source port
1507  * @param nat_src_port translated source port
1508  * @param vrf_id       VRF ID
1509  */
1510 void
1511 snat_ipfix_logging_nat44_ses_delete (u32 src_ip,
1512                                      u32 nat_src_ip,
1513                                      snat_protocol_t snat_proto,
1514                                      u16 src_port,
1515                                      u16 nat_src_port, u32 vrf_id)
1516 {
1517   snat_ipfix_logging_nat44_ses_args_t a;
1518
1519   skip_if_disabled ();
1520
1521   a.nat_event = NAT44_SESSION_DELETE;
1522   a.src_ip = src_ip;
1523   a.nat_src_ip = nat_src_ip;
1524   a.snat_proto = snat_proto;
1525   a.src_port = src_port;
1526   a.nat_src_port = nat_src_port;
1527   a.vrf_id = vrf_id;
1528
1529   vl_api_rpc_call_main_thread (snat_ipfix_logging_nat44_ses_rpc_cb,
1530                                (u8 *) & a, sizeof (a));
1531 }
1532
1533 vlib_frame_t *
1534 snat_data_callback_nat44_session (flow_report_main_t * frm,
1535                                   flow_report_t * fr,
1536                                   vlib_frame_t * f,
1537                                   u32 * to_next, u32 node_index)
1538 {
1539   snat_ipfix_logging_nat44_ses (0, 0, 0, 0, 0, 0, 0, 1);
1540   return f;
1541 }
1542
1543 static void
1544   snat_ipfix_logging_addr_exhausted_rpc_cb
1545   (snat_ipfix_logging_addr_exhausted_args_t * a)
1546 {
1547   snat_ipfix_logging_addr_exhausted (a->pool_id, 0);
1548 }
1549
1550 /**
1551  * @brief Generate NAT addresses exhausted event
1552  *
1553  * @param pool_id NAT pool ID
1554  */
1555 void
1556 snat_ipfix_logging_addresses_exhausted (u32 pool_id)
1557 {
1558   //TODO: This event SHOULD be rate limited
1559   snat_ipfix_logging_addr_exhausted_args_t a;
1560
1561   skip_if_disabled ();
1562
1563   a.pool_id = pool_id;
1564
1565   vl_api_rpc_call_main_thread (snat_ipfix_logging_addr_exhausted_rpc_cb,
1566                                (u8 *) & a, sizeof (a));
1567 }
1568
1569 vlib_frame_t *
1570 snat_data_callback_addr_exhausted (flow_report_main_t * frm,
1571                                    flow_report_t * fr,
1572                                    vlib_frame_t * f,
1573                                    u32 * to_next, u32 node_index)
1574 {
1575   snat_ipfix_logging_addr_exhausted (0, 1);
1576   return f;
1577 }
1578
1579 static void
1580   snat_ipfix_logging_max_entries_per_usr_rpc_cb
1581   (snat_ipfix_logging_max_entries_per_user_args_t * a)
1582 {
1583   snat_ipfix_logging_max_entries_per_usr (a->limit, a->src_ip, 0);
1584 }
1585
1586 /**
1587  * @brief Generate maximum entries per user exceeded event
1588  *
1589  * @param limit maximum NAT entries that can be created per user
1590  * @param src_ip source IPv4 address
1591  */
1592 void
1593 snat_ipfix_logging_max_entries_per_user (u32 limit, u32 src_ip)
1594 {
1595   //TODO: This event SHOULD be rate limited
1596   snat_ipfix_logging_max_entries_per_user_args_t a;
1597
1598   skip_if_disabled ();
1599
1600   a.limit = limit;
1601   a.src_ip = src_ip;
1602
1603   vl_api_rpc_call_main_thread (snat_ipfix_logging_max_entries_per_usr_rpc_cb,
1604                                (u8 *) & a, sizeof (a));
1605 }
1606
1607 vlib_frame_t *
1608 snat_data_callback_max_entries_per_usr (flow_report_main_t * frm,
1609                                         flow_report_t * fr,
1610                                         vlib_frame_t * f,
1611                                         u32 * to_next, u32 node_index)
1612 {
1613   snat_ipfix_logging_max_entries_per_usr (0, 0, 1);
1614   return f;
1615 }
1616
1617 static void
1618 nat_ipfix_logging_max_ses_rpc_cb (nat_ipfix_logging_max_sessions_args_t * a)
1619 {
1620   nat_ipfix_logging_max_ses (a->limit, 0);
1621 }
1622
1623 /**
1624  * @brief Generate maximum session entries exceeded event
1625  *
1626  * @param limit configured limit
1627  */
1628 void
1629 nat_ipfix_logging_max_sessions (u32 limit)
1630 {
1631   //TODO: This event SHOULD be rate limited
1632   nat_ipfix_logging_max_sessions_args_t a;
1633
1634   skip_if_disabled ();
1635
1636   a.limit = limit;
1637
1638   vl_api_rpc_call_main_thread (nat_ipfix_logging_max_ses_rpc_cb,
1639                                (u8 *) & a, sizeof (a));
1640 }
1641
1642 vlib_frame_t *
1643 nat_data_callback_max_sessions (flow_report_main_t * frm,
1644                                 flow_report_t * fr,
1645                                 vlib_frame_t * f,
1646                                 u32 * to_next, u32 node_index)
1647 {
1648   nat_ipfix_logging_max_ses (0, 1);
1649   return f;
1650 }
1651
1652 static void
1653 nat_ipfix_logging_max_bib_rpc_cb (nat_ipfix_logging_max_bibs_args_t * a)
1654 {
1655   nat_ipfix_logging_max_bib (a->limit, 0);
1656 }
1657
1658 /**
1659  * @brief Generate maximum BIB entries exceeded event
1660  *
1661  * @param limit configured limit
1662  */
1663 void
1664 nat_ipfix_logging_max_bibs (u32 limit)
1665 {
1666   //TODO: This event SHOULD be rate limited
1667   nat_ipfix_logging_max_bibs_args_t a;
1668
1669   skip_if_disabled ();
1670
1671   a.limit = limit;
1672
1673   vl_api_rpc_call_main_thread (nat_ipfix_logging_max_bib_rpc_cb,
1674                                (u8 *) & a, sizeof (a));
1675 }
1676
1677 vlib_frame_t *
1678 nat_data_callback_max_bibs (flow_report_main_t * frm,
1679                             flow_report_t * fr,
1680                             vlib_frame_t * f,
1681                             u32 * to_next, u32 node_index)
1682 {
1683   nat_ipfix_logging_max_bib (0, 1);
1684   return f;
1685 }
1686
1687 static void
1688 nat_ipfix_logging_max_frag_ip4_rpc_cb (nat_ipfix_logging_max_frags_ip4_args_t * a)
1689 {
1690   nat_ipfix_logging_max_frag_ip4 (a->limit, a->src, 0);
1691 }
1692
1693 /**
1694  * @brief Generate maximum IPv4 fragments pending reassembly exceeded event
1695  *
1696  * @param limit configured limit
1697  * @param src source IPv4 address
1698  */
1699 void
1700 nat_ipfix_logging_max_fragments_ip4 (u32 limit, ip4_address_t * src)
1701 {
1702   //TODO: This event SHOULD be rate limited
1703   nat_ipfix_logging_max_frags_ip4_args_t a;
1704
1705   skip_if_disabled ();
1706
1707   a.limit = limit;
1708   a.src = src->as_u32;
1709
1710   vl_api_rpc_call_main_thread (nat_ipfix_logging_max_frag_ip4_rpc_cb,
1711                                (u8 *) & a, sizeof (a));
1712 }
1713
1714 vlib_frame_t *
1715 nat_data_callback_max_frags_ip4 (flow_report_main_t * frm,
1716                                  flow_report_t * fr,
1717                                  vlib_frame_t * f,
1718                                  u32 * to_next, u32 node_index)
1719 {
1720   nat_ipfix_logging_max_frag_ip4 (0, 0, 1);
1721   return f;
1722 }
1723
1724 static void
1725 nat_ipfix_logging_max_frag_ip6_rpc_cb (nat_ipfix_logging_max_frags_ip6_args_t * a)
1726 {
1727   ip6_address_t src;
1728   src.as_u64[0] = a->src[0];
1729   src.as_u64[1] = a->src[1];
1730   nat_ipfix_logging_max_frag_ip6 (a->limit, &src, 0);
1731 }
1732
1733 /**
1734  * @brief Generate maximum IPv6 fragments pending reassembly exceeded event
1735  *
1736  * @param limit configured limit
1737  * @param src source IPv6 address
1738  */
1739 void
1740 nat_ipfix_logging_max_fragments_ip6 (u32 limit, ip6_address_t * src)
1741 {
1742   //TODO: This event SHOULD be rate limited
1743   nat_ipfix_logging_max_frags_ip6_args_t a;
1744
1745   skip_if_disabled ();
1746
1747   a.limit = limit;
1748   a.src[0] = src->as_u64[0];
1749   a.src[1] = src->as_u64[1];
1750
1751   vl_api_rpc_call_main_thread (nat_ipfix_logging_max_frag_ip6_rpc_cb,
1752                                (u8 *) & a, sizeof (a));
1753 }
1754
1755 vlib_frame_t *
1756 nat_data_callback_max_frags_ip6 (flow_report_main_t * frm,
1757                                  flow_report_t * fr,
1758                                  vlib_frame_t * f,
1759                                  u32 * to_next, u32 node_index)
1760 {
1761   nat_ipfix_logging_max_frag_ip6 (0, 0, 1);
1762   return f;
1763 }
1764
1765 static void
1766 nat_ipfix_logging_nat64_bib_rpc_cb (nat_ipfix_logging_nat64_bib_args_t * a)
1767 {
1768   ip6_address_t src_ip;
1769   src_ip.as_u64[0] = a->src_ip[0];
1770   src_ip.as_u64[1] = a->src_ip[1];
1771   nat_ipfix_logging_nat64_bibe (a->nat_event, &src_ip, a->nat_src_ip,
1772                                 a->proto, a->src_port, a->nat_src_port,
1773                                 a->vrf_id, 0);
1774 }
1775
1776 /**
1777  * @brief Generate NAT64 BIB create and delete events
1778  *
1779  * @param src_ip       source IPv6 address
1780  * @param nat_src_ip   transaltes source IPv4 address
1781  * @param proto        L4 protocol
1782  * @param src_port     source port
1783  * @param nat_src_port translated source port
1784  * @param vrf_id       VRF ID
1785  * @param is_create    non-zero value if create event otherwise delete event
1786  */
1787 void
1788 nat_ipfix_logging_nat64_bib (ip6_address_t * src_ip,
1789                              ip4_address_t * nat_src_ip, u8 proto,
1790                              u16 src_port, u16 nat_src_port, u32 vrf_id,
1791                              u8 is_create)
1792 {
1793   nat_ipfix_logging_nat64_bib_args_t a;
1794
1795   skip_if_disabled ();
1796
1797   a.src_ip[0] = src_ip->as_u64[0];
1798   a.src_ip[1] = src_ip->as_u64[1];
1799   a.nat_src_ip = nat_src_ip->as_u32;
1800   a.proto = proto;
1801   a.src_port = src_port;
1802   a.nat_src_port = nat_src_port;
1803   a.vrf_id = vrf_id;
1804   a.nat_event = is_create ? NAT64_BIB_CREATE : NAT64_BIB_DELETE;
1805
1806   vl_api_rpc_call_main_thread (nat_ipfix_logging_nat64_bib_rpc_cb,
1807                                (u8 *) & a, sizeof (a));
1808 }
1809
1810 vlib_frame_t *
1811 nat_data_callback_nat64_bib (flow_report_main_t * frm,
1812                              flow_report_t * fr,
1813                              vlib_frame_t * f,
1814                              u32 * to_next, u32 node_index)
1815 {
1816   nat_ipfix_logging_nat64_bibe (0, 0, 0, 0, 0, 0, 0, 1);
1817   return f;
1818 }
1819
1820 static void
1821 nat_ipfix_logging_nat64_ses_rpc_cb (nat_ipfix_logging_nat64_ses_args_t * a)
1822 {
1823   ip6_address_t src_ip, dst_ip;
1824   src_ip.as_u64[0] = a->src_ip[0];
1825   src_ip.as_u64[1] = a->src_ip[1];
1826   dst_ip.as_u64[0] = a->dst_ip[0];
1827   dst_ip.as_u64[1] = a->dst_ip[1];
1828   nat_ipfix_logging_nat64_ses (a->nat_event, &src_ip, a->nat_src_ip,
1829                                a->proto, a->src_port, a->nat_src_port,
1830                                &dst_ip, a->nat_dst_ip, a->dst_port,
1831                                a->nat_dst_port, a->vrf_id, 0);
1832 }
1833
1834 /**
1835  * @brief Generate NAT64 session create and delete events
1836  *
1837  * @param src_ip       source IPv6 address
1838  * @param nat_src_ip   transaltes source IPv4 address
1839  * @param proto        L4 protocol
1840  * @param src_port     source port
1841  * @param nat_src_port translated source port
1842  * @param dst_ip       destination IPv6 address
1843  * @param nat_dst_ip   destination IPv4 address
1844  * @param dst_port     destination port
1845  * @param nat_dst_port translated destination port
1846  * @param vrf_id       VRF ID
1847  * @param is_create    non-zero value if create event otherwise delete event
1848  */
1849 void
1850 nat_ipfix_logging_nat64_session (ip6_address_t * src_ip,
1851                                  ip4_address_t * nat_src_ip, u8 proto,
1852                                  u16 src_port, u16 nat_src_port,
1853                                  ip6_address_t * dst_ip,
1854                                  ip4_address_t * nat_dst_ip, u16 dst_port,
1855                                  u16 nat_dst_port, u32 vrf_id, u8 is_create)
1856 {
1857   nat_ipfix_logging_nat64_ses_args_t a;
1858
1859   skip_if_disabled ();
1860
1861   a.src_ip[0] = src_ip->as_u64[0];
1862   a.src_ip[1] = src_ip->as_u64[1];
1863   a.nat_src_ip = nat_src_ip->as_u32;
1864   a.proto = proto;
1865   a.src_port = src_port;
1866   a.nat_src_port = nat_src_port;
1867   a.dst_ip[0] = dst_ip->as_u64[0];
1868   a.dst_ip[1] = dst_ip->as_u64[1];
1869   a.nat_dst_ip = nat_dst_ip->as_u32;
1870   a.dst_port = dst_port;
1871   a.nat_dst_port = nat_dst_port;
1872   a.vrf_id = vrf_id;
1873   a.nat_event = is_create ? NAT64_SESSION_CREATE : NAT64_SESSION_DELETE;
1874
1875   vl_api_rpc_call_main_thread (nat_ipfix_logging_nat64_ses_rpc_cb,
1876                                (u8 *) & a, sizeof (a));
1877 }
1878
1879 vlib_frame_t *
1880 nat_data_callback_nat64_session (flow_report_main_t * frm,
1881                                  flow_report_t * fr,
1882                                  vlib_frame_t * f,
1883                                  u32 * to_next, u32 node_index)
1884 {
1885   nat_ipfix_logging_nat64_ses (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
1886   return f;
1887 }
1888
1889 /**
1890  * @brief Enable/disable NAT plugin IPFIX logging
1891  *
1892  * @param enable    1 if enable, 0 if disable
1893  * @param domain_id observation domain ID
1894  * @param src_port  source port number
1895  *
1896  * @returns 0 if success
1897  */
1898 int
1899 snat_ipfix_logging_enable_disable (int enable, u32 domain_id, u16 src_port)
1900 {
1901   snat_main_t *sm = &snat_main;
1902   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
1903   flow_report_main_t *frm = &flow_report_main;
1904   vnet_flow_report_add_del_args_t a;
1905   int rv;
1906   u8 e = enable ? 1 : 0;
1907
1908   if (silm->enabled == e)
1909     return 0;
1910
1911   silm->enabled = e;
1912
1913   memset (&a, 0, sizeof (a));
1914   a.is_add = enable;
1915   a.domain_id = domain_id ? domain_id : 1;
1916   a.src_port = src_port ? src_port : UDP_DST_PORT_ipfix;
1917
1918   if (sm->deterministic)
1919     {
1920       a.rewrite_callback = snat_template_rewrite_max_entries_per_usr;
1921       a.flow_data_callback = snat_data_callback_max_entries_per_usr;
1922
1923       rv = vnet_flow_report_add_del (frm, &a, NULL);
1924       if (rv)
1925         {
1926           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1927           return -1;
1928         }
1929     }
1930   else
1931     {
1932       a.rewrite_callback = snat_template_rewrite_nat44_session;
1933       a.flow_data_callback = snat_data_callback_nat44_session;
1934
1935       rv = vnet_flow_report_add_del (frm, &a, NULL);
1936       if (rv)
1937         {
1938           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1939           return -1;
1940         }
1941
1942       a.rewrite_callback = snat_template_rewrite_addr_exhausted;
1943       a.flow_data_callback = snat_data_callback_addr_exhausted;
1944
1945       rv = vnet_flow_report_add_del (frm, &a, NULL);
1946       if (rv)
1947         {
1948           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1949           return -1;
1950         }
1951
1952       a.rewrite_callback = nat_template_rewrite_max_sessions;
1953       a.flow_data_callback = nat_data_callback_max_sessions;
1954
1955       rv = vnet_flow_report_add_del (frm, &a, NULL);
1956       if (rv)
1957         {
1958           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1959           return -1;
1960         }
1961
1962       a.rewrite_callback = nat_template_rewrite_max_bibs;
1963       a.flow_data_callback = nat_data_callback_max_bibs;
1964
1965       rv = vnet_flow_report_add_del (frm, &a, NULL);
1966       if (rv)
1967         {
1968           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1969           return -1;
1970         }
1971
1972       a.rewrite_callback = nat_template_rewrite_max_frags_ip4;
1973       a.flow_data_callback = nat_data_callback_max_frags_ip4;
1974
1975       rv = vnet_flow_report_add_del (frm, &a, NULL);
1976       if (rv)
1977         {
1978           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1979           return -1;
1980         }
1981
1982       a.rewrite_callback = nat_template_rewrite_max_frags_ip6;
1983       a.flow_data_callback = nat_data_callback_max_frags_ip6;
1984
1985       rv = vnet_flow_report_add_del (frm, &a, NULL);
1986       if (rv)
1987         {
1988           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1989           return -1;
1990         }
1991
1992       a.rewrite_callback = nat_template_rewrite_nat64_bib;
1993       a.flow_data_callback = nat_data_callback_nat64_bib;
1994
1995       rv = vnet_flow_report_add_del (frm, &a, NULL);
1996       if (rv)
1997         {
1998           clib_warning ("vnet_flow_report_add_del returned %d", rv);
1999           return -1;
2000         }
2001
2002       a.rewrite_callback = nat_template_rewrite_nat64_session;
2003       a.flow_data_callback = nat_data_callback_nat64_session;
2004
2005       rv = vnet_flow_report_add_del (frm, &a, NULL);
2006       if (rv)
2007         {
2008           clib_warning ("vnet_flow_report_add_del returned %d", rv);
2009           return -1;
2010         }
2011     }
2012
2013   return 0;
2014 }
2015
2016 /**
2017  * @brief Initialize NAT plugin IPFIX logging
2018  *
2019  * @param vm vlib main
2020  */
2021 void
2022 snat_ipfix_logging_init (vlib_main_t * vm)
2023 {
2024   snat_ipfix_logging_main_t *silm = &snat_ipfix_logging_main;
2025
2026   silm->enabled = 0;
2027
2028   /* Set up time reference pair */
2029   silm->vlib_time_0 = vlib_time_now (vm);
2030   silm->milisecond_time_0 = unix_time_now_nsec () * 1e-6;
2031 }