Temporary remove inlines to unbreak compilation with GCC 5
[vpp.git] / vnet / vnet / vcgn / cnat_logging.c
1 /*
2  *------------------------------------------------------------------
3  * cnat_logging.c 
4  *
5  * Copyright (c) 2009-2013 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vlib/vlib.h>
21 #include <vnet/vnet.h>
22 #include <vppinfra/error.h>
23 #include <vnet/buffer.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip4.h>
26 #include <vnet/ip/ip4_packet.h>
27 #include <vnet/ip/format.h>
28 #include <vnet/ip/udp.h>
29
30
31 #include "cnat_config.h"
32 #include "cnat_global.h"
33 #include "cnat_v4_functions.h"
34 #include "tcp_header_definitions.h"
35 #include "cnat_v4_ftp_alg.h"
36 #include "cnat_logging.h"
37 #include "platform_common.h"
38
39 #define CNAT_NFV9_DEBUG_CODE 2
40 #if CNAT_NFV9_DEBUG_CODE > 3
41
42 #define NFV9_COND if ((my_instance_number != 0) && (my_instance_number != 15))
43
44 #define NFV9_DEBUG_PRINTF1(a) NFV9_COND printf(a);
45 #define NFV9_DEBUG_PRINTF2(a, b) NFV9_COND printf(a, b);
46 #define NFV9_DEBUG_PRINTF3(a, b, c) NFV9_COND printf(a, b, c);
47 #define NFV9_DEBUG_PRINTF4(a, b, c, d) NFV9_COND printf(a, b, c, d);
48
49 #else
50
51 #define NFV9_DEBUG_PRINTF1(a) 
52 #define NFV9_DEBUG_PRINTF2(a, b)
53 #define NFV9_DEBUG_PRINTF3(a, b, c)
54 #define NFV9_DEBUG_PRINTF4(a, b, c, d)
55
56 #endif
57
58 static void cnat_nfv9_insert_ingress_vrfid_name_record(cnat_nfv9_logging_info_t *nfv9_logging_info, u16 index);
59 void cnat_nfv9_ingress_vrfid_name_mapping_create(
60                 cnat_nfv9_logging_info_t *nfv9_logging_info);
61
62
63 cnat_nfv9_global_info_t cnat_nfv9_global_info;
64
65 cnat_nfv9_template_t cnat_nfv9_template_info;
66
67 #define CNAT_NFV9_OPTION_TEMPLATE cnat_nfv9_template_info.cnat_nfv9_option_template
68
69 u16 cnat_template_id[MAX_RECORDS] =
70   {0, CNAT_NFV9_ADD_TEMPLATE_ID, CNAT_NFV9_DEL_TEMPLATE_ID, 
71    CNAT_NFV9_NAT64_ADD_BIB_TEMPLATE_ID,CNAT_NFV9_NAT64_DEL_BIB_TEMPLATE_ID,
72    CNAT_NFV9_NAT64_ADD_SESSION_TEMPLATE_ID, 
73    CNAT_NFV9_NAT64_DEL_SESSION_TEMPLATE_ID,
74    CNAT_NFV9_DS_LITE_ADD_TEMPLATE_ID,
75    CNAT_NFV9_DS_LITE_DEL_TEMPLATE_ID
76 #ifndef NO_BULK_LOGGING
77     , CNAT_NFV9_NAT44_BULK_ADD_TEMPLATE_ID,
78     CNAT_NFV9_NAT44_BULK_DEL_TEMPLATE_ID,
79     CNAT_NFV9_DS_LITE_BULK_ADD_TEMPLATE_ID,
80     CNAT_NFV9_DS_LITE_BULK_DEL_TEMPLATE_ID
81 #endif /* #ifndef NO_BULK_LOGGING */
82     , CNAT_NFV9_INGRESS_VRF_ID_NAME_TEMPLATE_ID,
83    CNAT_NFV9_NAT44_ADD_SESSION_TEMPLATE_ID,
84    CNAT_NFV9_NAT44_DEL_SESSION_TEMPLATE_ID,
85    CNAT_NFV9_DS_LITE_ADD_SESSION_TEMPLATE_ID,
86    CNAT_NFV9_DS_LITE_DEL_SESSION_TEMPLATE_ID
87    };
88
89 /*
90  * Logging information structures
91  */
92 cnat_nfv9_logging_info_t cnat_default_nfv9_logging_info;
93 cnat_nfv9_logging_info_t *cnat_nfv9_logging_info_pool;
94 #define NFV9_SERVER_POOL_SIZE   16
95 nfv9_server_info_t *nfv9_server_info_pool;
96
97 u32 nfv9_src_id = 0;
98
99 u32
100 cnat_get_sys_up_time_in_ms (void)
101 {
102     vlib_main_t * vm = vlib_get_main();
103     u32 cnat_curr_time;
104
105     cnat_curr_time = (u32)vlib_time_now (vm);
106     return cnat_curr_time;
107 }
108
109 void
110 cnat_dump_time_change_logs (void)
111 {
112     return;
113 }
114
115 inline void cnat_nfv9_handle_sys_time_change(time_t current_unix_time)
116 {
117     return;
118     #if 0
119     cnat_handle_sys_time_change(current_unix_time);
120     #endif
121 }
122
123 void cnat_nfv9_update_sys_time_change()
124 {
125     cnat_nfv9_logging_info_t *my_nfv9_logging_info = NULL;
126     pool_foreach (my_nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
127         nfv9_server_info_t *server =  nfv9_server_info_pool +
128             my_nfv9_logging_info->server_index;
129         server->last_template_sent_time = 0;
130         }));
131 }
132
133 void nfv9_params_show(u32 logging_index)
134 {
135     cnat_nfv9_logging_info_t *log_info;
136     if(logging_index == EMPTY) {
137         PLATFORM_DEBUG_PRINT("\nNetflow logging not configured\n");
138         return;
139     }
140     
141     log_info = cnat_nfv9_logging_info_pool + logging_index;
142     nfv9_server_info_t *server __attribute__((unused)) 
143         =  nfv9_server_info_pool + log_info->server_index;
144     
145
146     PLATFORM_DEBUG_PRINT("\nNetflow parameters --\n");
147     PLATFORM_DEBUG_PRINT("Server index %d IPV4 address: %x, port %d, max log size %d\n", 
148         log_info->server_index, server->ipv4_address,
149         server->port, log_info->max_length_minus_max_record_size);
150
151     PLATFORM_DEBUG_PRINT("Server ref count %d Refresh rate %d timeout rate %d\n",
152         server->ref_count, server->refresh_rate,
153         server->timeout_rate);
154         
155 }
156
157 /*
158  * Code to dump NFV9 packets before they are sent
159  */
160 void
161 cnat_nfv9_dump_logging_context (u32 value1, 
162                                 cnat_nfv9_logging_info_t *nfv9_logging_info,
163                                 u32 value2)
164 {
165     u8 *pkt_ptr;
166     u32 i;
167     u32 next_nfv9_template_data_index = 0xffff;
168     u32 next_data_flow_index = 0xffff;
169     u32 next_data_record = 0xffff;
170     u32 data_record_size = 0;
171     vlib_main_t                  *vm =  vlib_get_main();
172
173     nfv9_server_info_t *server =  nfv9_server_info_pool + 
174         nfv9_logging_info->server_index;
175
176     vlib_cli_output(vm,"\nDumping %s packet at locn %d: time 0x%x", 
177             (value2 == 1) ? "CURRENT" : "QUEUED",
178             value1,
179             cnat_nfv9_get_unix_time_in_seconds());
180
181     vlib_cli_output(vm, "\ni_vrf 0x%x, ip_address 0x%x, port %d",
182              nfv9_logging_info->i_vrf,
183              server->ipv4_address,
184              server->port);
185
186     vlib_cli_output(vm,"\nseq_num %d",
187              server->sequence_num);
188
189     vlib_cli_output(vm,"\nlast_template_sent time 0x%x, pkts_since_last_template %d",
190              server->last_template_sent_time,
191              server->pkts_since_last_template);
192
193     vlib_cli_output(vm, "\npkt_len %d, add_rec_len %d, del_rec_len %d, total_rec_count %d",
194              nfv9_logging_info->pkt_length,
195              nfv9_logging_info->record_length[NAT44_ADD_RECORD],
196              nfv9_logging_info->record_length[NAT44_DEL_RECORD],
197              nfv9_logging_info->total_record_count);
198
199     vlib_cli_output(vm,"\nbulk_add_rec_len %d, bulk_del_rec_len %d",
200              nfv9_logging_info->record_length[NAT44_BULK_ADD_RECORD],
201              nfv9_logging_info->record_length[NAT44_BULK_DEL_RECORD]);
202
203     vlib_cli_output(vm,"\ncurr_logging_ctx 0x%p, timestamp 0x%x, queued_logging_ctx 0x%p",
204              nfv9_logging_info->current_logging_context,
205              nfv9_logging_info->current_logging_context_timestamp,
206              nfv9_logging_info->queued_logging_context);
207
208     vlib_cli_output(vm,"\nnfv9_hdr 0x%p, tmpl_hdr 0x%p, dataflow_hdr 0x%p",
209              nfv9_logging_info->nfv9_header,
210              nfv9_logging_info->nfv9_template_header,
211              nfv9_logging_info->dataflow_header);
212
213     vlib_cli_output(vm,"\nadd_rec 0x%p, del_rec 0x%p, next_data_ptr 0x%p",
214              nfv9_logging_info->record[NAT44_ADD_RECORD],
215              nfv9_logging_info->record[NAT44_DEL_RECORD],
216              nfv9_logging_info->next_data_ptr);
217
218     vlib_cli_output(vm,"\n");
219
220     pkt_ptr = vlib_buffer_get_current(nfv9_logging_info->current_logging_context); 
221     /*
222      * Dump along with 8 bytes of SHIM header
223      */
224     for (i = 0; i < (nfv9_logging_info->pkt_length + CNAT_NFV9_IP_HDR_OFFSET); 
225          i = i + 1) {
226         u8 c1, c2, c3;
227         if (i == CNAT_NFV9_IP_HDR_OFFSET) {
228             vlib_cli_output(vm,"\nIP_HEADER: \n");
229         } else if (i == CNAT_NFV9_UDP_HDR_OFFSET) {
230             vlib_cli_output(vm,"\nUDP_HEADER: \n");
231         } else if (i == CNAT_NFV9_HDR_OFFSET) {
232             vlib_cli_output(vm,"\nNFV9 Header: Version:Count: \n");
233         } else if (i == (CNAT_NFV9_HDR_OFFSET+4)) {
234             vlib_cli_output(vm,"\nBoot_Up_Time_In_ms: \n");
235         } else if (i == (CNAT_NFV9_HDR_OFFSET+8)) {
236             vlib_cli_output(vm, "\nUNIX_Time: \n");
237         } else if (i == (CNAT_NFV9_HDR_OFFSET+12)) {
238             vlib_cli_output(vm,"\nSeq_Num: \n");
239         } else if (i == (CNAT_NFV9_HDR_OFFSET+16)) {
240             vlib_cli_output(vm,"\nSource ID: \n");
241         } else if (i == (CNAT_NFV9_HDR_OFFSET+20)) {
242             if (nfv9_logging_info->nfv9_template_header) {
243                 vlib_cli_output(vm,"\nNFV9 TEMPLATE HDR: \n");
244                 next_nfv9_template_data_index = i + 4;
245             } else {
246                 next_data_flow_index = i;       
247             }
248         } else if (i == (CNAT_NFV9_TEMPLATE_OFFSET+CNAT_NFV9_TEMPLATE_LENGTH)) {
249             if (nfv9_logging_info->nfv9_template_header) {
250                 next_data_flow_index = i;       
251             }
252         }
253
254         if (i == next_nfv9_template_data_index) {
255             vlib_cli_output(vm,"\nNFV9 TEMPLATE DATA: \n");
256         } else if (i == next_data_flow_index) {
257             if (*(pkt_ptr + i) == 0x01) {
258                 if (*(pkt_ptr + i + 1) == 0x00) {
259                     data_record_size = 21;
260                     next_data_record = i + 4;
261                     next_data_flow_index = i + *(pkt_ptr + i + 3) +
262                                                *(pkt_ptr + i + 2)*0x100;
263                     vlib_cli_output(vm,"\nADD_RECORD (total %d): next_data_flow_index (%d->%d)\n", (next_data_flow_index - i), i, next_data_flow_index);
264                 } else if (*(pkt_ptr + i + 1) == 0x01) {
265                     data_record_size = 11;
266                     next_data_record = i + 4;
267                     next_data_flow_index = i + *(pkt_ptr + i + 3) +
268                                                *(pkt_ptr + i + 2)*0x100;
269                     vlib_cli_output(vm,"\nDEL_RECORD (total %d) : next_data_flow_index (%d->%d)\n", (next_data_flow_index - i), i, next_data_flow_index);
270                 } else if (*(pkt_ptr + i + 1) == 0x09) {
271                     data_record_size = 20;
272                     next_data_record = i + 4;
273                     next_data_flow_index = i + *(pkt_ptr + i + 3) +
274                                                *(pkt_ptr + i + 2)*0x100;
275                     vlib_cli_output(vm,"\nBULK_ADD_RECORD (total %d) : next_data_flow_index (%d->%d)\n", (next_data_flow_index - i), i, next_data_flow_index);
276                 } else if (*(pkt_ptr + i + 1) == 0x0a) {
277                     data_record_size = 10;
278                     next_data_record = i + 4;
279                     next_data_flow_index = i + *(pkt_ptr + i + 3) +
280                                                *(pkt_ptr + i + 2)*0x100;
281                     vlib_cli_output(vm,"\nBULK_DEL_RECORD (total %d) : next_data_flow_index (%d->%d)\n", (next_data_flow_index - i), i, next_data_flow_index);
282                 }
283
284             }
285         } else if (i == next_data_record) {
286             vlib_cli_output(vm,"\n");
287             next_data_record += data_record_size;
288         }
289
290         c3 = *(pkt_ptr + i);
291
292         c2 = c3 & 0xf;
293         c1 = (c3 >> 4) & 0xf;
294
295
296         vlib_cli_output(vm,"%c%c ", 
297                 ((c1 <= 9) ? (c1 + '0') : (c1 - 10 + 'a')),
298                 ((c2 <= 9) ? (c2 + '0') : (c2 - 10 + 'a')));
299
300     }
301     vlib_cli_output(vm,"\n");
302 }
303
304 /*
305  * edt: * * cnat_nfv9_pad_added_to_an_addr
306  *
307  * Returns the difference (no# of bytes) between new_addr
308  * & org_addr
309  *
310  * Argument: u8 *new_addr, u8 *org_addr
311  * returns the difference
312  */
313
314 int cnat_nfv9_pad_added_to_an_addr(u8 *new_addr, u8 *org_addr)
315 {
316     uword addr1 = (uword) new_addr;
317     uword addr2 = (uword) org_addr;
318     return (addr1 - addr2);
319 }
320
321 /*
322  * edt: * * cnat_nfv9_add_end_of_record_padding
323  *
324  * Tries to add padding to data_ptr to ensure it is word aligned
325  *
326  * Argument: u8 * data_ptr
327  * pointer to the data pointer
328  */
329
330 u8 *cnat_nfv9_add_end_of_record_padding (u8 *data_ptr)
331 {
332     uword tmp       = (uword) data_ptr;
333     uword pad_value = (uword) NFV9_PAD_VALUE;
334
335     tmp = (tmp + pad_value) & (~pad_value);
336
337     return ((u8 *) tmp);
338 }
339
340 /*
341  * edt: * * cnat_nfv9_pad_end_of_record_length
342  *
343  * Tries to add padding to data_ptr to ensure it is word aligned
344  *
345  * Argument: u8 * data_ptr
346  * pointer to the data pointer
347  */
348
349 u16 cnat_nfv9_pad_end_of_record_length (u16 record_length)
350 {
351     u16 pad_value = NFV9_PAD_VALUE;
352
353     return ((record_length + pad_value) & (~pad_value));
354 }
355
356 /* get first interface address */
357 static ip4_address_t *
358 ip4_interface_first_address (ip4_main_t * im, u32 sw_if_index)
359 {
360   ip_lookup_main_t * lm = &im->lookup_main;
361   ip_interface_address_t * ia = 0;
362   ip4_address_t * result = 0;
363
364   foreach_ip_interface_address (lm, ia, sw_if_index,
365                                 1 /* honor unnumbered */,
366   ({
367     ip4_address_t * a = ip_interface_address_get_address (lm, ia);
368     result = a;
369     break;
370   }));
371   return result;
372 }
373
374 void fill_ip_n_udp_hdr (u32 ipv4_addr, u16 port, 
375                        cnat_nfv9_logging_info_t *nfv9_logging_info)
376
377     vlib_buffer_t * b0 = nfv9_logging_info->current_logging_context;
378     ipv4_header    *ip_header = vlib_buffer_get_current(b0);
379     udp_hdr_type_t *udp_header = (udp_hdr_type_t *)((u8*)ip_header + sizeof(ipv4_header));
380     vlib_main_t                  *vm =  vlib_get_main();
381     u16 ip_length __attribute__((unused));
382     u16 pkt_len = nfv9_logging_info->pkt_length;
383     ip4_address_t *ia0 = 0;
384     u16 src_port = 0x0a0a;
385
386     /*
387      * Clear the SHIM header fields.  The PD nodes will set it
388      * appropriately.
389      */
390     PLATFORM_MEMSET_CNAT_LOG_PKT_DATA
391
392     /*
393      * Don't need a special define for 0x45 - IP version and hdr len
394      */
395     ip_header->version_hdr_len_words = 0x45;
396     ip_header->tos                   = 0;
397     ip_header->frag_flags_offset            = 0;
398     ip_header->ttl                   = 0xff;
399     ip_header->protocol              = UDP_PROT;
400     ip_header->dest_addr =  clib_host_to_net_u32(ipv4_addr);
401     ip_length = vlib_buffer_length_in_chain (vm, b0);
402     ip_header->total_len_bytes = clib_host_to_net_u16(pkt_len);
403     ia0 = ip4_interface_first_address(&ip4_main, nfv9_logging_info->i_vrf_id);
404     ip_header->src_addr =  ia0->as_u32;
405     udp_header->src_port = clib_host_to_net_u16(src_port);
406     udp_header->dest_port = clib_host_to_net_u16(port);
407     udp_header->udp_checksum = 0;
408     udp_header->udp_length =
409         clib_host_to_net_u16(pkt_len - sizeof(ipv4_header));
410     ip_header->checksum = ip4_header_checksum((ip4_header_t *)ip_header);
411 }
412
413 /*
414  * edt: * * cnat_nfv9_fill_nfv9_ip_header
415  *
416  * Tries to fill the fields of the IP header before it
417  * is sent to the L3 infra node.
418  *
419  * Argument: cnat_nfv9_logging_info_t *nfv9_logging_info
420  * structure that contains the packet context
421  */
422
423 void cnat_nfv9_fill_nfv9_ip_header (cnat_nfv9_logging_info_t *nfv9_logging_info)
424 {
425     u16             new_record_length  = 0;
426     u16             orig_record_length = 0;
427     vlib_buffer_t * b0 = nfv9_logging_info->current_logging_context;
428
429     /*
430      * Fill in the IP header and port number of the Netflow collector
431      * The L3 Infra node will fill in the rest of the fields
432      */
433
434     nfv9_logging_info->nfv9_header->count = 
435             clib_host_to_net_u16(nfv9_logging_info->total_record_count);
436
437     /*
438      * Pad the last add/del record to ensure multiple of 4 bytes
439      */
440
441     if(nfv9_logging_info->last_record != RECORD_INVALID) {
442
443         orig_record_length = 
444            nfv9_logging_info->record_length[nfv9_logging_info->last_record];
445
446          new_record_length = cnat_nfv9_pad_end_of_record_length(
447                                               orig_record_length);
448
449          nfv9_logging_info->dataflow_header->dataflow_length =
450               clib_host_to_net_u16(new_record_length);
451     } 
452
453     /*
454      * If the record is padded, ensure the padded bytes are ZERO
455      */
456     if (PREDICT_TRUE(new_record_length - orig_record_length)) {
457         u8 *pkt_ptr = (u8 *) (b0 + nfv9_logging_info->pkt_length); 
458
459         /*
460          * Blindly copy 3 bytes of data to Zero to avoid for loops
461          * We have sufficient padding bytes for safety and we won't
462          * go over buffer limits
463          */
464         *pkt_ptr++ =  0;
465         *pkt_ptr++ =  0;
466         *pkt_ptr++ =  0;
467
468         nfv9_logging_info->pkt_length += 
469             (new_record_length - orig_record_length);
470     }
471     nfv9_server_info_t *server =  nfv9_server_info_pool + 
472         nfv9_logging_info->server_index;
473     fill_ip_n_udp_hdr(server->ipv4_address, 
474         server->port, nfv9_logging_info);
475     /*
476      * It is important to set the sw_if_index for the new buffer create
477      */
478     vnet_buffer(b0)->sw_if_index[VLIB_TX] = (u32)~0;
479
480 }
481
482 /*
483  * edt: * * cnat_nfv9_send_queued_pkt
484  *
485  * Tries to send a logging pkt that has been queued earlier
486  * because it could not be sent due to downstream constipation
487  *
488  * Argument: cnat_nfv9_logging_info_t *nfv9_logging_info
489  * structure that contains the packet context
490  */
491
492 void cnat_nfv9_send_queued_pkt (cnat_nfv9_logging_info_t *nfv9_logging_info)
493 {
494 }
495
496 /*
497  * edt: * * cnat_nfv9_send_pkt
498  *
499  * Tries to send a logging pkt.  If the packet cannot be sent
500  * because of rewrite_output node cannot process it, queue
501  * it temporarily and try to send it later.
502  *
503  * Argument: cnat_nfv9_logging_info_t *nfv9_logging_info
504  * structure that contains the packet context
505  */
506
507 void cnat_nfv9_send_pkt (cnat_nfv9_logging_info_t *nfv9_logging_info)
508 {
509     cnat_nfv9_fill_nfv9_ip_header(nfv9_logging_info);
510
511     nfv9_server_info_t *server =  nfv9_server_info_pool + 
512         nfv9_logging_info->server_index;
513
514     /* Update sequence number just before sending.
515      * So that, multiple NAT44/NAT64/DSLite instances sharing a 
516      * a single server instance can stamp the sequence number
517      * in the right sequence (as seen by the server).
518      */
519     server->sequence_num += 1;
520     nfv9_logging_info->nfv9_header->sequence_num  = 
521             clib_host_to_net_u32(server->sequence_num);
522
523 #if DEBUG
524     cnat_nfv9_dump_logging_context (2, nfv9_logging_info, 1);
525 #endif
526 #if 0 /* commented out below */
527     send_vpp3_nfv9_pkt(nfv9_logging_info);
528 #endif
529     nfv9_logging_info->current_logging_context = NULL;
530     /*
531      * Increase last packet sent count
532      */
533      server->pkts_since_last_template++;
534
535     /*
536      * If we are sending an nfv9 tempate with this packet
537      * log this timestamp
538      */
539      if (nfv9_logging_info->nfv9_template_header) {
540          server->last_template_sent_time = 
541                cnat_nfv9_get_unix_time_in_seconds();
542          server->pkts_since_last_template = 0;
543      }
544
545     return;
546 }
547
548 /*
549  * send_vpp3_nfv9_pkt: to send multiple b0 in a frame
550  */
551 #if 0
552 inline void send_vpp3_nfv9_pkt (cnat_nfv9_logging_info_t *nfv9_logging_info)
553 {
554     vlib_main_t                  *vm =  vlib_get_main();
555     vlib_frame_t                 *f;
556     vlib_buffer_t                *b0; 
557     u32 ip4_input_node_index;
558     //u32 * to_next, * from, bi0 =0;
559     u32 bi0 =0;
560     ipv4_header * h0, *ip;
561     static u32 * buffers;
562     u32 nalloc;
563     udp_header_t * udp;
564     u16 udp_length, ip_length;
565
566
567     ip4_input_node_index = nfv9_logging_info->ip4_input_node_index;
568     f = nfv9_logging_info->f;
569     if (f == NULL) {
570         nfv9_logging_info->f = vlib_get_frame_to_node(vm, ip4_input_node_index);
571         f = nfv9_logging_info->f;
572         f->n_vectors = 0;
573         nfv9_logging_info->to_next = vlib_frame_vector_args (f);
574     }
575     /* Build a pkt from whole cloth */
576     b0 = nfv9_logging_info->current_logging_context;
577     //to_next = nfv9_logging_info->to_next;
578     ip = vlib_buffer_get_current (b0);
579     //if (PREDICT_TRUE(f->n_vectors < VLIB_FRAME_SIZE)) {
580     if (PREDICT_TRUE(f->n_vectors < 5)) {
581
582        b0->current_length = clib_net_to_host_u16(ip->total_len_bytes);
583        bi0 = vlib_get_buffer_index (vm, b0); 
584        nfv9_logging_info->to_next[0] = bi0;
585        printf("f->n_vec %d f %p to_next %p val %d b0 %p\n", 
586             f->n_vectors, f, nfv9_logging_info->to_next, 
587             nfv9_logging_info->to_next[0], b0);
588        //to_next++;
589        nfv9_logging_info->to_next++; // = to_next;
590        f->n_vectors++;
591     }
592
593     //if (f->n_vectors == VLIB_FRAME_SIZE) 
594     if (f->n_vectors == 5) {
595         printf("sending pkt on 256\n");
596         printf("%s: total_len_bytes %d bi %d nfv9_logging_info->pkt_length %d index %d\n", 
597             __func__, clib_net_to_host_u16(ip->total_len_bytes),
598             bi0, nfv9_logging_info->pkt_length, ip4_input_node_index);
599         vlib_put_frame_to_node(vm, ip4_input_node_index, f);  
600         nfv9_logging_info->f = NULL;
601         nfv9_logging_info->to_next = NULL;
602     }
603     return;
604 }
605 #endif
606 /*
607  * send_vpp3_nfv9_pkt: to send one b0 in a frame
608  */
609 void send_vpp3_nfv9_pkt (cnat_nfv9_logging_info_t *nfv9_logging_info)
610 {
611     vlib_node_t                  *output_node;
612     vlib_main_t                  *vm =  vlib_get_main();
613     vlib_frame_t                 *f;
614     vlib_buffer_t                *b0; 
615     u32 *to_next;
616     u32 bi=0;
617     ipv4_header *ip;
618
619     //Lets check and send it to ip4-lookup node
620     output_node =  vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
621     f = vlib_get_frame_to_node (vm, output_node->index);
622    
623     if ( nfv9_logging_info->current_logging_context != NULL) {
624         /* Build a pkt from whole cloth */
625         b0 = nfv9_logging_info->current_logging_context;
626         ip = vlib_buffer_get_current(b0);
627         to_next = vlib_frame_vector_args (f);
628         bi =  vlib_get_buffer_index (vm, b0);
629         to_next[0] =  bi;
630
631         f->n_vectors = 1;
632         b0->current_length = clib_net_to_host_u16(ip->total_len_bytes);
633         vlib_put_frame_to_node (vm, output_node->index, f);  
634      }
635      return;
636 }
637 /*
638  * edt: * * cnat_nfv9_send_pkt_always_success
639  *
640  * Tries to send a logging pkt.  This cannot fail due to downstream
641  * constipation because we have already checked if the rewrite_output
642  * node can accept it.
643  *
644  * Argument: cnat_nfv9_logging_info_t *nfv9_logging_info
645  * structure that contains the packet context
646  *
647  * Argument: vlib_node_t *output_node
648  * vlib_node_t structure for rewrite_output node
649  */
650
651 void cnat_nfv9_send_pkt_always_success (
652                          cnat_nfv9_logging_info_t *nfv9_logging_info,
653                          vlib_node_t               *output_node)
654 {
655     nfv9_server_info_t *server =  nfv9_server_info_pool + 
656         nfv9_logging_info->server_index;
657     vlib_main_t * vm = vlib_get_main();
658
659     /*
660      * At this point we either have a current or queued logging context
661      */
662     if (PREDICT_TRUE(nfv9_logging_info->current_logging_context != NULL)) { 
663         server->sequence_num += 1;
664         nfv9_logging_info->nfv9_header->sequence_num  = 
665                 clib_host_to_net_u32(server->sequence_num);
666             cnat_nfv9_fill_nfv9_ip_header(nfv9_logging_info);
667
668         nfv9_logging_info->current_logging_context->current_length =
669                                             nfv9_logging_info->pkt_length;
670         vlib_cli_output(vm, "\nNFV9: 3. Sending Current packet\n");
671 #if DEBUG
672        cnat_nfv9_dump_logging_context (3, nfv9_logging_info, 1);
673 #endif
674        send_vpp3_nfv9_pkt(nfv9_logging_info);
675        nfv9_logging_info->current_logging_context = NULL;
676     } else {
677         /*
678          * For queued logging context, nfv9_header-> count is already set
679          */
680         nfv9_logging_info->queued_logging_context->current_length =
681                                              nfv9_logging_info->pkt_length;
682         vlib_cli_output(vm,"\nNFV9: 4. Sending Queued packet\n");
683 #if DEBUG
684         cnat_nfv9_dump_logging_context (4, nfv9_logging_info, 2);
685 #endif
686         send_vpp3_nfv9_pkt(nfv9_logging_info);
687
688         nfv9_logging_info->queued_logging_context = NULL;
689     }
690
691     /*
692      * NF Logging info already deleted, just free it and return
693      */
694     if (PREDICT_FALSE(nfv9_logging_info->deleted)) {
695         pool_put(cnat_nfv9_logging_info_pool, nfv9_logging_info);
696         return;
697     }
698
699     /*
700      * Increase last packet sent count and timestamp
701      */
702     server->pkts_since_last_template++;
703
704     /*
705      * If we are sending an nfv9 tempate with this packet
706      * log this timestamp
707      */
708     if (nfv9_logging_info->nfv9_template_header) {
709             server->last_template_sent_time = 
710             cnat_nfv9_get_unix_time_in_seconds();
711             server->pkts_since_last_template = 0;
712     }
713 }
714
715 /*
716  * edt: * * cnat_nfv9_create_logging_context
717  *
718  * Tries to create a logging context with packet buffer
719  * to send a new logging packet
720  *
721  * Argument: cnat_nfv9_logging_info_t *nfv9_logging_info
722  * structure that contains the nfv9 logging info and will store
723  * the packet context as well.
724  */
725
726 void cnat_nfv9_create_logging_context (
727                               cnat_nfv9_logging_info_t      *nfv9_logging_info,
728                               cnat_nfv9_template_add_flag_t  template_flag)
729 {
730     vlib_main_t     *vm =  vlib_get_main();
731     vlib_buffer_t   *b0;
732     static u32       bi; 
733     u8 i;
734
735     /*
736      * If queued_logging_context_index is non-EMPTY, we already have a logging
737      * packet queued to be sent.  First try sending this before allocating
738      * a new context.  We can have only one active packet context per
739      * nfv9_logging_info structure
740      */
741     if (PREDICT_FALSE(nfv9_logging_info->queued_logging_context != NULL)) {
742         cnat_nfv9_send_queued_pkt(nfv9_logging_info);
743         /*
744          * If we cannot still send the queued pkt, just return 
745          * Downstream Constipation count would have increased anyway
746          */
747         if (nfv9_logging_info->queued_logging_context != NULL) {
748             cnat_global_counters.nfv9_logging_context_creation_deferred_count++;
749             return;
750         }
751     }
752
753
754     /*
755      * No context can be allocated, return silently
756      * calling routine will handle updating the error counters
757      */
758     if (vlib_buffer_alloc (vm, &bi, 1) != 1) {
759         vlib_cli_output(vm, "buffer allocation failure");
760         return;
761     }
762     /* Build a  pkt from whole cloth */
763     b0 = vlib_get_buffer (vm, bi);
764     b0->current_data = 0;
765
766     nfv9_server_info_t *server =  nfv9_server_info_pool + 
767         nfv9_logging_info->server_index;
768
769     nfv9_logging_info->current_logging_context = b0; 
770     nfv9_logging_info->current_logging_context_timestamp =
771         cnat_nfv9_get_sys_up_time_in_ms();
772
773
774     nfv9_logging_info->nfv9_header = 
775         (nfv9_header_t *) (vlib_buffer_get_current(b0) + 
776                            (sizeof(ipv4_header)) + 
777                            (sizeof(udp_hdr_type_t)));
778
779     nfv9_logging_info->nfv9_header->version = 
780         clib_host_to_net_u16(CNAT_NFV9_VERSION_NUMBER);
781
782     nfv9_logging_info->nfv9_header->sys_up_time  = 
783         clib_host_to_net_u32(cnat_nfv9_get_sys_up_time_in_ms());
784
785     nfv9_logging_info->nfv9_header->timestamp  = 
786         clib_host_to_net_u32(cnat_nfv9_get_unix_time_in_seconds());
787
788
789     nfv9_logging_info->nfv9_header->source_id  = 
790         clib_host_to_net_u32(nfv9_src_id);
791
792     nfv9_logging_info->dataflow_header = 0;
793
794     for(i = 0; i < MAX_RECORDS;i++) {
795         nfv9_logging_info->record[i] = NULL;
796         nfv9_logging_info->record_length[i] = 0;
797     }
798     nfv9_logging_info->last_record = 0;
799
800
801     nfv9_logging_info->nfv9_template_header = 0;
802     nfv9_logging_info->next_data_ptr = 
803         (u8 *) (vlib_buffer_get_current(b0) +
804                sizeof(ipv4_header) + sizeof(udp_hdr_type_t) +
805                sizeof(nfv9_header_t));
806
807     nfv9_logging_info->pkt_length = (CNAT_NFV9_TEMPLATE_OFFSET - 
808                                      CNAT_NFV9_IP_HDR_OFFSET);
809
810
811     /*
812      * Now we have 0 records to start with
813      */
814
815     nfv9_logging_info->total_record_count = 0;
816
817     if ((template_flag == cnat_nfv9_template_add_always) ||
818         (server->pkts_since_last_template >
819                       server->refresh_rate) ||
820         ((cnat_nfv9_get_unix_time_in_seconds() -
821           server->last_template_sent_time) >
822                      server->timeout_rate)) {
823
824         /*
825          * Send a new template
826          */
827        nfv9_logging_info->nfv9_template_header = 
828            (cnat_nfv9_template_t *) nfv9_logging_info->next_data_ptr;
829
830        memcpy(nfv9_logging_info->nfv9_template_header,
831               &cnat_nfv9_template_info,
832               sizeof(cnat_nfv9_template_info));
833
834        /*
835         * Templates are sent irrespective of particular service-type config
836         */
837        nfv9_logging_info->total_record_count = MAX_RECORDS - 1;
838
839        nfv9_logging_info->pkt_length += CNAT_NFV9_TEMPLATE_LENGTH;
840
841        /*
842         * Set the data pointer beyond the template field
843         */
844        nfv9_logging_info->next_data_ptr = 
845            (u8 *) (nfv9_logging_info->nfv9_template_header + 1);
846         /*
847          * Setting template_sent flag as TRUE. this will be checked in
848          * handle_vrfid_name_mapping()
849          */
850         server->template_sent = TEMPLATE_SENT_TRUE;
851     }
852 }
853
854 void cnat_nfv9_record_create (
855         cnat_nfv9_logging_info_t *nfv9_logging_info, u16 cur_record)
856 {
857     int byte_diff = 0;
858     u16 last_record = nfv9_logging_info->last_record;
859
860     if(last_record != 0 && last_record != cur_record) {
861         u16 orig_length, new_length;
862
863         orig_length = nfv9_logging_info->record_length[last_record];
864         new_length  = cnat_nfv9_pad_end_of_record_length(orig_length);
865
866         /*
867          * The padding bytes are required after the last record
868          * Ensure length of last record accounts for padding bytes
869          */
870         nfv9_logging_info->dataflow_header->dataflow_length =
871             clib_host_to_net_u16(new_length);
872
873         /*
874          * Since we are working on the del record, set add record to 0
875          */
876         nfv9_logging_info->record[last_record] = 0;
877
878         nfv9_logging_info->record_length[last_record] = 0;
879
880         nfv9_logging_info->last_record = 0;
881     }
882
883     nfv9_logging_info->last_record = cur_record;
884
885     /*
886      * The padding bytes are required after the last record
887      * Ensure that we skip over the padding bytes
888      */
889     nfv9_logging_info->dataflow_header = (nfv9_dataflow_record_header_t *)
890         cnat_nfv9_add_end_of_record_padding(nfv9_logging_info->next_data_ptr);
891     /*
892      * Get the difference 
893      */       
894     byte_diff = cnat_nfv9_pad_added_to_an_addr(
895                         (u8 *)nfv9_logging_info->dataflow_header,
896                         nfv9_logging_info->next_data_ptr); 
897     if(byte_diff > 0) {
898         /*
899          * Update the packet length to account for the pad bytes
900          */
901         nfv9_logging_info->pkt_length += byte_diff;           
902         u8 *pkt_ptr =  nfv9_logging_info->next_data_ptr;
903
904         /*
905          * Blindly copy 3 bytes of data to Zero to avoid for loops
906          * We have sufficient padding bytes for safety and we won't
907          * go over buffer limits
908          */
909         *pkt_ptr++ =  0;
910         *pkt_ptr++ =  0;
911         *pkt_ptr++ =  0;
912     }
913     /*
914      * Initialize the template_id and the length of the add record
915      */
916     nfv9_logging_info->dataflow_header->dataflow_template_id =
917         clib_host_to_net_u16(cnat_template_id[cur_record]);
918
919     nfv9_logging_info->record[cur_record]  =
920         (u8 *) (nfv9_logging_info->dataflow_header + 1);
921
922     nfv9_logging_info->record_length[cur_record] =
923         CNAT_NFV9_DATAFLOW_RECORD_HEADER_LENGTH;
924
925     /*
926      * Update the length of the total NFV9 record
927      */
928     nfv9_logging_info->pkt_length +=
929     CNAT_NFV9_DATAFLOW_RECORD_HEADER_LENGTH;
930
931     /*
932      * Set the data pointer beyond the dataflow header field
933      */
934     nfv9_logging_info->next_data_ptr =
935         (u8 *) (nfv9_logging_info->dataflow_header + 1);
936
937 }
938
939 static void cnat_nfv9_insert_add_record(
940         cnat_nfv9_logging_info_t *nfv9_logging_info,
941         cnat_main_db_entry_t *db,
942         cnat_vrfmap_t *vrfmap)
943 {
944     u16 my_proto_mask;
945     u8 my_protocol;
946     nfv9_add_record_t nfv9_logging_add_record;
947     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_ADD_RECORD] == NULL)) {
948         cnat_nfv9_record_create(nfv9_logging_info, NAT44_ADD_RECORD);
949     }
950
951    /*
952     * We should definitely have add_record now, no need to sanitize
953     */
954
955     nfv9_logging_add_record.inside_vrf_id =
956         clib_host_to_net_u32(vrfmap->i_vrf_id);
957
958     nfv9_logging_add_record.outside_vrf_id =
959         clib_host_to_net_u32(vrfmap->o_vrf_id);
960
961     nfv9_logging_add_record.inside_ip_addr =
962         clib_host_to_net_u32(db->in2out_key.k.ipv4);
963     nfv9_logging_add_record.outside_ip_addr =
964         clib_host_to_net_u32(db->out2in_key.k.ipv4);
965
966     nfv9_logging_add_record.inside_ip_port =
967         clib_host_to_net_u16(db->in2out_key.k.port);
968     nfv9_logging_add_record.outside_ip_port =
969         clib_host_to_net_u16(db->out2in_key.k.port);
970
971     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
972     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
973                 ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
974                 ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
975
976     nfv9_logging_add_record.protocol = my_protocol;
977
978     memcpy(nfv9_logging_info->record[NAT44_ADD_RECORD], 
979             &nfv9_logging_add_record, CNAT_NFV9_ADD_RECORD_LENGTH);
980
981     nfv9_logging_info->record_length[NAT44_ADD_RECORD] 
982             += CNAT_NFV9_ADD_RECORD_LENGTH;
983
984     nfv9_logging_info->pkt_length += CNAT_NFV9_ADD_RECORD_LENGTH;
985
986     nfv9_logging_info->record[NAT44_ADD_RECORD] 
987                       += CNAT_NFV9_ADD_RECORD_LENGTH;
988     nfv9_logging_info->next_data_ptr = 
989                       nfv9_logging_info->record[NAT44_ADD_RECORD];
990
991     nfv9_logging_info->dataflow_header->dataflow_length =
992         clib_host_to_net_u32(
993         nfv9_logging_info->record_length[NAT44_ADD_RECORD]);
994
995 }
996
997
998 static void cnat_nfv9_ds_lite_insert_add_record(
999         cnat_nfv9_logging_info_t *nfv9_logging_info,
1000         cnat_main_db_entry_t *db,
1001         dslite_table_entry_t *dslite_entry)
1002 {
1003
1004     nfv9_ds_lite_add_record_t   nfv9_logging_add_record = {0};
1005     cnat_user_db_entry_t        *udb = NULL;
1006     u16     my_proto_mask;
1007     u8      my_protocol;
1008
1009     udb = cnat_user_db + db->user_index; 
1010     if (PREDICT_FALSE(!udb)) {
1011         return;
1012     }
1013     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_ADD_RECORD] == NULL)) {
1014         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_ADD_RECORD);
1015     }
1016     /*
1017      * We should definitely have add_record now, no need to sanitize
1018      */
1019     nfv9_logging_add_record.inside_vrf_id =
1020                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
1021     nfv9_logging_add_record.outside_vrf_id = 
1022                     clib_host_to_net_u32(dslite_entry->o_vrf_id);
1023
1024 #ifdef DSLITE_USER_IPV4
1025     nfv9_logging_add_record.inside_ip_addr = 
1026                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
1027 #else
1028     /*
1029      * Inside ipv4 address is sent as 0.0.0.0 for ds-lite case as 
1030      * ipv6 is user here. 
1031      */
1032     nfv9_logging_add_record.inside_ip_addr = 0; 
1033 #endif
1034
1035     nfv9_logging_add_record.inside_v6_src_addr[0] = 
1036                     clib_host_to_net_u32(udb->ipv6[0]);
1037     nfv9_logging_add_record.inside_v6_src_addr[1] = 
1038                     clib_host_to_net_u32(udb->ipv6[1]);
1039     nfv9_logging_add_record.inside_v6_src_addr[2] = 
1040                     clib_host_to_net_u32(udb->ipv6[2]);
1041     nfv9_logging_add_record.inside_v6_src_addr[3] = 
1042                     clib_host_to_net_u32(udb->ipv6[3]);
1043
1044     nfv9_logging_add_record.outside_ip_addr = 
1045                     clib_host_to_net_u32(db->out2in_key.k.ipv4);
1046
1047     nfv9_logging_add_record.inside_ip_port = 
1048                     clib_host_to_net_u16(db->in2out_key.k.port);
1049     nfv9_logging_add_record.outside_ip_port = 
1050                     clib_host_to_net_u16(db->out2in_key.k.port);
1051
1052     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
1053
1054     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1055                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1056                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
1057     nfv9_logging_add_record.protocol = my_protocol;
1058
1059     memcpy(nfv9_logging_info->record[DS_LITE_ADD_RECORD], 
1060             &nfv9_logging_add_record, CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH);
1061
1062     nfv9_logging_info->record_length[DS_LITE_ADD_RECORD] 
1063                                   += CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH;
1064
1065     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH;
1066     nfv9_logging_info->total_record_count += 1;
1067
1068     nfv9_logging_info->record[DS_LITE_ADD_RECORD] 
1069                       += CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH;
1070     nfv9_logging_info->next_data_ptr = 
1071                          nfv9_logging_info->record[DS_LITE_ADD_RECORD];
1072
1073     nfv9_logging_info->dataflow_header->dataflow_length =
1074         clib_host_to_net_u32(
1075         nfv9_logging_info->record_length[DS_LITE_ADD_RECORD]);
1076 }
1077
1078
1079 static void cnat_nfv9_ds_lite_insert_del_record(
1080         cnat_nfv9_logging_info_t *nfv9_logging_info,
1081         cnat_main_db_entry_t *db,
1082         dslite_table_entry_t *dslite_entry)
1083 {
1084
1085     nfv9_ds_lite_del_record_t   nfv9_logging_del_record = {0};
1086     cnat_user_db_entry_t        *udb = NULL;
1087     u16     my_proto_mask;
1088     u8      my_protocol;
1089
1090     udb = cnat_user_db + db->user_index; 
1091     if (PREDICT_FALSE(!udb)) {
1092         return;
1093     }
1094     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_DEL_RECORD] == NULL)) {
1095         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_DEL_RECORD);
1096     }
1097     /*
1098      * We should definitely have a del record now.
1099      * No need to sanitize
1100      */
1101     nfv9_logging_del_record.inside_vrf_id = 
1102                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
1103
1104 #ifdef DSLITE_USER_IPV4
1105     nfv9_logging_del_record.inside_ip_addr = 
1106                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
1107 #else
1108     /*
1109      * Inside ipv4 address is sent as 0.0.0.0 for ds-lite case as 
1110      * ipv6 is user here. 
1111      */
1112     nfv9_logging_del_record.inside_ip_addr = 0;
1113 #endif
1114
1115     nfv9_logging_del_record.inside_v6_src_addr[0] = 
1116                     clib_host_to_net_u32(udb->ipv6[0]);
1117     nfv9_logging_del_record.inside_v6_src_addr[1] = 
1118                     clib_host_to_net_u32(udb->ipv6[1]);
1119     nfv9_logging_del_record.inside_v6_src_addr[2] = 
1120                     clib_host_to_net_u32(udb->ipv6[2]);
1121     nfv9_logging_del_record.inside_v6_src_addr[3] = 
1122                     clib_host_to_net_u32(udb->ipv6[3]);
1123
1124     nfv9_logging_del_record.inside_ip_port = 
1125                     clib_host_to_net_u16(db->in2out_key.k.port);
1126
1127     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
1128
1129     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1130                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1131                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
1132     nfv9_logging_del_record.protocol = my_protocol;
1133
1134     memcpy(nfv9_logging_info->record[DS_LITE_DEL_RECORD], 
1135             &nfv9_logging_del_record, CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH);
1136
1137     nfv9_logging_info->record_length[DS_LITE_DEL_RECORD] += 
1138                              CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH;
1139
1140     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH;
1141     nfv9_logging_info->total_record_count += 1;
1142
1143     nfv9_logging_info->record[DS_LITE_DEL_RECORD] 
1144                                 += CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH;
1145     nfv9_logging_info->next_data_ptr = 
1146             nfv9_logging_info->record[DS_LITE_DEL_RECORD];
1147
1148     nfv9_logging_info->dataflow_header->dataflow_length =
1149         clib_host_to_net_u32(
1150            nfv9_logging_info->record_length[DS_LITE_DEL_RECORD]);
1151 }
1152
1153 #ifndef NO_BULK_LOGGING
1154 static void cnat_nfv9_insert_bulk_add_record(
1155         cnat_nfv9_logging_info_t *nfv9_logging_info,
1156         cnat_main_db_entry_t *db,
1157         cnat_vrfmap_t *vrfmap,
1158         int bulk_alloc_start_port)
1159 {
1160     nfv9_bulk_add_record_t nfv9_logging_bulk_add_record;
1161     bulk_alloc_size_t bulk_size = BULKSIZE_FROM_VRFMAP(vrfmap);
1162     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_BULK_ADD_RECORD] == NULL)) {
1163         cnat_nfv9_record_create(nfv9_logging_info, NAT44_BULK_ADD_RECORD);
1164     }
1165
1166    /*
1167     * We should definitely have add_record now, no need to sanitize
1168     */
1169
1170     nfv9_logging_bulk_add_record.inside_vrf_id =
1171         clib_host_to_net_u32(vrfmap->i_vrf_id);
1172     nfv9_logging_bulk_add_record.outside_vrf_id =
1173         clib_host_to_net_u32(vrfmap->o_vrf_id);
1174
1175     nfv9_logging_bulk_add_record.inside_ip_addr =
1176         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1177     nfv9_logging_bulk_add_record.outside_ip_addr =
1178         clib_host_to_net_u32(db->out2in_key.k.ipv4);
1179
1180     nfv9_logging_bulk_add_record.outside_ip_port_start =
1181         clib_host_to_net_u16(bulk_alloc_start_port);
1182     nfv9_logging_bulk_add_record.outside_ip_port_end =
1183         clib_host_to_net_u16(bulk_alloc_start_port + bulk_size -1);
1184
1185     memcpy(nfv9_logging_info->record[NAT44_BULK_ADD_RECORD], 
1186             &nfv9_logging_bulk_add_record, CNAT_NFV9_BULK_ADD_RECORD_LENGTH);
1187
1188     nfv9_logging_info->record_length[NAT44_BULK_ADD_RECORD] 
1189             += CNAT_NFV9_BULK_ADD_RECORD_LENGTH;
1190
1191     nfv9_logging_info->pkt_length += CNAT_NFV9_BULK_ADD_RECORD_LENGTH;
1192
1193     nfv9_logging_info->record[NAT44_BULK_ADD_RECORD] 
1194                       += CNAT_NFV9_BULK_ADD_RECORD_LENGTH;
1195     nfv9_logging_info->next_data_ptr = 
1196                       nfv9_logging_info->record[NAT44_BULK_ADD_RECORD];
1197
1198     nfv9_logging_info->dataflow_header->dataflow_length =
1199         clib_host_to_net_u32(
1200         nfv9_logging_info->record_length[NAT44_BULK_ADD_RECORD]);
1201
1202 }
1203
1204
1205 static void cnat_nfv9_ds_lite_insert_bulk_add_record(
1206         cnat_nfv9_logging_info_t *nfv9_logging_info,
1207         cnat_main_db_entry_t *db,
1208         dslite_table_entry_t *dslite_entry,
1209         int bulk_alloc_start_port)
1210 {
1211
1212     nfv9_ds_lite_bulk_add_record_t  nfv9_logging_bulk_add_record = {0};
1213     cnat_user_db_entry_t            *udb = NULL;
1214     bulk_alloc_size_t               bulk_size = BULKSIZE_FROM_VRFMAP(dslite_entry);
1215
1216     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD] == NULL)) {
1217         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_BULK_ADD_RECORD);
1218     }
1219     udb = cnat_user_db + db->user_index; 
1220     if (PREDICT_FALSE(!udb)) {
1221         return;
1222     }
1223     /*
1224      * We should definitely have add_record now, no need to sanitize
1225      */
1226
1227     nfv9_logging_bulk_add_record.inside_vrf_id =
1228         clib_host_to_net_u32(dslite_entry->i_vrf_id);
1229     nfv9_logging_bulk_add_record.outside_vrf_id =
1230         clib_host_to_net_u32(dslite_entry->o_vrf_id);
1231
1232 #ifdef DSLITE_USER_IPV4
1233     nfv9_logging_bulk_add_record.inside_ip_addr =
1234         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1235 #else
1236     /*
1237      * Inside ipv4 address is sent as 0.0.0.0 for ds-lite case as 
1238      * ipv6 is user here. 
1239      */
1240     nfv9_logging_bulk_add_record.inside_ip_addr = 0;
1241 #endif
1242
1243     nfv9_logging_bulk_add_record.inside_v6_src_addr[0] = 
1244                     clib_host_to_net_u32(udb->ipv6[0]);
1245     nfv9_logging_bulk_add_record.inside_v6_src_addr[1] = 
1246                     clib_host_to_net_u32(udb->ipv6[1]);
1247     nfv9_logging_bulk_add_record.inside_v6_src_addr[2] = 
1248                     clib_host_to_net_u32(udb->ipv6[2]);
1249     nfv9_logging_bulk_add_record.inside_v6_src_addr[3] = 
1250                     clib_host_to_net_u32(udb->ipv6[3]);
1251
1252     nfv9_logging_bulk_add_record.outside_ip_addr =
1253         clib_host_to_net_u32(db->out2in_key.k.ipv4);
1254
1255     nfv9_logging_bulk_add_record.outside_ip_port_start =
1256         clib_host_to_net_u16(bulk_alloc_start_port);
1257     nfv9_logging_bulk_add_record.outside_ip_port_end =
1258         clib_host_to_net_u16(bulk_alloc_start_port + bulk_size -1);
1259
1260     memcpy(nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD], 
1261             &nfv9_logging_bulk_add_record, CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH);
1262
1263     nfv9_logging_info->record_length[DS_LITE_BULK_ADD_RECORD] 
1264             += CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH;
1265
1266     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH;
1267     nfv9_logging_info->total_record_count += 1;
1268     nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD] 
1269                       += CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH;
1270     nfv9_logging_info->next_data_ptr = 
1271                       nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD];
1272     nfv9_logging_info->dataflow_header->dataflow_length =
1273         clib_host_to_net_u32(
1274         nfv9_logging_info->record_length[DS_LITE_BULK_ADD_RECORD]);
1275 }
1276
1277
1278 static void cnat_nfv9_ds_lite_insert_bulk_del_record(
1279         cnat_nfv9_logging_info_t *nfv9_logging_info,
1280         cnat_main_db_entry_t *db,
1281         dslite_table_entry_t *dslite_entry,
1282         int bulk_alloc_start_port)
1283 {
1284
1285     nfv9_ds_lite_bulk_del_record_t nfv9_logging_bulk_del_record = {0};
1286     cnat_user_db_entry_t           *udb = NULL;
1287
1288     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD] == NULL)) {
1289         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_BULK_DEL_RECORD);
1290     }
1291     udb = cnat_user_db + db->user_index; 
1292     if (PREDICT_FALSE(!udb)) {
1293         return;
1294     }
1295     /*
1296      * We should definitely have add_record now, no need to sanitize
1297      */
1298
1299     nfv9_logging_bulk_del_record.inside_vrf_id =
1300         clib_host_to_net_u32(dslite_entry->i_vrf_id);
1301
1302 #ifdef DSLITE_USER_IPV4
1303     nfv9_logging_bulk_del_record.inside_ip_addr =
1304         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1305 #else
1306     nfv9_logging_bulk_del_record.inside_ip_addr =
1307         clib_host_to_net_u32(0);
1308 #endif
1309
1310     nfv9_logging_bulk_del_record.inside_v6_src_addr[0] = 
1311         clib_host_to_net_u32(udb->ipv6[0]);
1312     nfv9_logging_bulk_del_record.inside_v6_src_addr[1] = 
1313         clib_host_to_net_u32(udb->ipv6[1]);
1314     nfv9_logging_bulk_del_record.inside_v6_src_addr[2] = 
1315         clib_host_to_net_u32(udb->ipv6[2]);
1316     nfv9_logging_bulk_del_record.inside_v6_src_addr[3] = 
1317         clib_host_to_net_u32(udb->ipv6[3]);
1318
1319     nfv9_logging_bulk_del_record.outside_ip_port_start =
1320         clib_host_to_net_u16(bulk_alloc_start_port);
1321
1322     memcpy(nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD], 
1323         &nfv9_logging_bulk_del_record, 
1324         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH);
1325     nfv9_logging_info->record_length[DS_LITE_BULK_DEL_RECORD] += 
1326         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH;
1327     nfv9_logging_info->pkt_length += 
1328         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH;
1329     nfv9_logging_info->total_record_count += 1;
1330     nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD] += 
1331         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH;
1332     nfv9_logging_info->next_data_ptr = 
1333         nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD];
1334     nfv9_logging_info->dataflow_header->dataflow_length =
1335         clib_host_to_net_u32(
1336         nfv9_logging_info->record_length[DS_LITE_BULK_DEL_RECORD]);
1337 }
1338 #endif /* #ifndef NO_BULK_LOGGING */
1339
1340 static void cnat_nfv9_insert_del_record(
1341         cnat_nfv9_logging_info_t *nfv9_logging_info,
1342         cnat_main_db_entry_t *db,
1343         cnat_vrfmap_t *vrfmap)
1344 {
1345     u16 my_proto_mask;
1346     u8 my_protocol;
1347     nfv9_del_record_t nfv9_logging_del_record;
1348
1349     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_DEL_RECORD] == NULL)) {
1350         cnat_nfv9_record_create(nfv9_logging_info, NAT44_DEL_RECORD);
1351     }
1352
1353    /*
1354     * We should definitely have add_record now, no need to sanitize
1355     */
1356
1357     nfv9_logging_del_record.inside_vrf_id =
1358         clib_host_to_net_u32(vrfmap->i_vrf_id);
1359
1360     nfv9_logging_del_record.inside_ip_addr =
1361         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1362
1363     nfv9_logging_del_record.inside_ip_port =
1364         clib_host_to_net_u16(db->in2out_key.k.port);
1365
1366     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
1367     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1368                 ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1369                 ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
1370
1371     nfv9_logging_del_record.protocol = my_protocol;
1372
1373     memcpy(nfv9_logging_info->record[NAT44_DEL_RECORD], 
1374             &nfv9_logging_del_record, CNAT_NFV9_DEL_RECORD_LENGTH);
1375
1376     nfv9_logging_info->record_length[NAT44_DEL_RECORD] 
1377             += CNAT_NFV9_DEL_RECORD_LENGTH;
1378
1379     nfv9_logging_info->pkt_length += CNAT_NFV9_DEL_RECORD_LENGTH;
1380
1381     nfv9_logging_info->record[NAT44_DEL_RECORD] 
1382                       += CNAT_NFV9_DEL_RECORD_LENGTH;
1383     nfv9_logging_info->next_data_ptr = 
1384                       nfv9_logging_info->record[NAT44_DEL_RECORD];
1385
1386     nfv9_logging_info->dataflow_header->dataflow_length =
1387         clib_host_to_net_u32(
1388         nfv9_logging_info->record_length[NAT44_DEL_RECORD]);
1389
1390 }
1391
1392 #ifndef NO_BULK_LOGGING
1393 static void cnat_nfv9_insert_bulk_del_record(
1394         cnat_nfv9_logging_info_t *nfv9_logging_info,
1395         cnat_main_db_entry_t *db,
1396         cnat_vrfmap_t *vrfmap,
1397         int bulk_alloc_start_port)
1398 {
1399     nfv9_bulk_del_record_t nfv9_logging_bulk_del_record;
1400     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_BULK_DEL_RECORD] == NULL)) {
1401         cnat_nfv9_record_create(nfv9_logging_info, NAT44_BULK_DEL_RECORD);
1402     }
1403
1404    /*
1405     * We should definitely have add_record now, no need to sanitize
1406     */
1407
1408     nfv9_logging_bulk_del_record.inside_vrf_id =
1409         clib_host_to_net_u32(vrfmap->i_vrf_id);
1410
1411     nfv9_logging_bulk_del_record.inside_ip_addr =
1412         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1413
1414     nfv9_logging_bulk_del_record.outside_ip_port_start =
1415         clib_host_to_net_u16(bulk_alloc_start_port);
1416
1417     memcpy(nfv9_logging_info->record[NAT44_BULK_DEL_RECORD], 
1418             &nfv9_logging_bulk_del_record, CNAT_NFV9_BULK_DEL_RECORD_LENGTH);
1419
1420     nfv9_logging_info->record_length[NAT44_BULK_DEL_RECORD] 
1421             += CNAT_NFV9_BULK_DEL_RECORD_LENGTH;
1422
1423     nfv9_logging_info->pkt_length += CNAT_NFV9_BULK_DEL_RECORD_LENGTH;
1424
1425     nfv9_logging_info->record[NAT44_BULK_DEL_RECORD] 
1426                       += CNAT_NFV9_BULK_DEL_RECORD_LENGTH;
1427     nfv9_logging_info->next_data_ptr = 
1428                       nfv9_logging_info->record[NAT44_BULK_DEL_RECORD];
1429
1430     nfv9_logging_info->dataflow_header->dataflow_length =
1431         clib_host_to_net_u32(
1432         nfv9_logging_info->record_length[NAT44_BULK_DEL_RECORD]);
1433
1434 }
1435
1436 #endif /* #ifndef NO_BULK_LOGGING */
1437 /*
1438  * edt: * * cnat_nfv9_log_mapping_create
1439  *
1440  * Tries to log a creation of mapping record
1441  *
1442  * Argument: cnat_main_db_entry_t *db
1443  * Main DB entry being created
1444  *
1445  * Argument: cnat_vrfmap_t *vrfmap
1446  * VRF Map for the Main DB entry being created
1447  */
1448 void cnat_nfv9_log_mapping_create (cnat_main_db_entry_t *db,
1449                                    cnat_vrfmap_t *vrfmap
1450 #ifndef NO_BULK_LOGGING
1451                        , int bulk_alloc
1452 #endif
1453                        )
1454 {
1455     cnat_nfv9_logging_info_t *nfv9_logging_info = 0; 
1456     vlib_main_t * vm = vlib_get_main();
1457
1458     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
1459
1460         //vlib_cli_output(vm, "\n1. Log Mapping failed");
1461         /*
1462          * No logging configured, silently return
1463          */
1464         return;
1465     }
1466
1467     if (cnat_nfv9_logging_info_pool == NULL) {
1468         vlib_cli_output(vm, "%s: info_pool pointer is NULL !!!!\n", __func__);
1469         return;
1470     }
1471     nfv9_logging_info = 
1472         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
1473
1474     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1475         cnat_nfv9_create_logging_context(nfv9_logging_info,
1476                                          cnat_nfv9_template_add_default);
1477
1478         /*
1479          * If still empty, return after increasing the count
1480          */
1481         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1482             //vlib_cli_output(vm, "\n2. Log Mapping failed");
1483             return;
1484         }
1485         
1486     }
1487
1488 #ifndef NO_BULK_LOGGING
1489     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
1490         cnat_nfv9_insert_bulk_add_record(nfv9_logging_info, db, vrfmap,
1491             bulk_alloc);
1492     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
1493         return; /* No logging required.. bulk port usage */
1494     else /* Individual logging .. fall back to old method */
1495 #endif
1496     cnat_nfv9_insert_add_record(nfv9_logging_info, db, vrfmap);
1497
1498     nfv9_logging_info->total_record_count += 1;
1499
1500     /*
1501      * If we have exceeded the packet length, let us send the
1502      * packet now.  There is buffer of additional bytes beyond
1503      * max_pkt_length to ensure that the last add/delete record
1504      * can be stored safely.
1505      */
1506     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
1507             nfv9_logging_info->max_length_minus_max_record_size)) {
1508             cnat_nfv9_send_pkt(nfv9_logging_info);
1509     }
1510 }
1511
1512 /*
1513  * edt: * * cnat_nfv9_log_mapping_delete
1514  *
1515  * Tries to log a deletion of mapping record
1516  *
1517  * Argument: cnat_main_db_entry_t *db
1518  * Main DB entry being deleted
1519  *
1520  * Argument: cnat_vrfmap_t *vrfmap
1521  * VRF Map for the Main DB entry being deleted
1522  */
1523 void cnat_nfv9_log_mapping_delete (cnat_main_db_entry_t * db,
1524                               cnat_vrfmap_t *vrfmap
1525 #ifndef NO_BULK_LOGGING
1526                               , int bulk_alloc
1527 #endif
1528                               )
1529 {
1530     cnat_nfv9_logging_info_t *nfv9_logging_info = 0; 
1531
1532     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
1533         //vlib_cli_output(vm, "\n3. Log Mapping failed");
1534         /*
1535          * No logging configured, silently return
1536          */
1537         return;
1538     }
1539
1540     nfv9_logging_info = 
1541         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
1542
1543     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1544         cnat_nfv9_create_logging_context(nfv9_logging_info,
1545                                          cnat_nfv9_template_add_default);
1546
1547         /*
1548          * If still empty, return after increasing the count
1549          */
1550         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1551             //vlib_cli_output(vm, "\n4. Log Mapping failed");
1552             return;
1553         }
1554     }
1555 #ifndef NO_BULK_LOGGING
1556     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
1557         cnat_nfv9_insert_bulk_del_record(nfv9_logging_info, db, vrfmap,
1558             bulk_alloc);
1559     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
1560         return; /* No logging required.. bulk port usage */
1561     else /* Individual logging .. fall back to old method */
1562 #endif
1563     cnat_nfv9_insert_del_record(nfv9_logging_info, db, vrfmap);
1564
1565     nfv9_logging_info->total_record_count += 1;
1566
1567     /*
1568      * If we have exceeded the packet length, let us send the
1569      * packet now.  There is buffer of additional bytes beyond
1570      * max_pkt_length to ensure that the last add/delete record
1571      * can be stored safely.
1572      */
1573     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
1574         nfv9_logging_info->max_length_minus_max_record_size)) {
1575             cnat_nfv9_send_pkt(nfv9_logging_info);
1576     }
1577 }
1578
1579
1580 /* NAT64 Related routines */
1581
1582 /*
1583  * edt: * * cnat_nfv9_bib_mapping_create
1584  *
1585  * Tries to log a creation of Bib mapping record
1586  *
1587  * Argument: nat64_bib_entry_t *db
1588  * BIB DB entry being created
1589  *
1590  * Argument: nat64_table_entry_t *nat64_entry
1591  * NAT64 Instance where this BIB belongs 
1592  */
1593 void cnat_nfv9_bib_mapping_create (nat64_bib_entry_t *db,
1594                        nat64_table_entry_t *nat64_entry)
1595 {
1596     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1597     u16 my_proto_mask;
1598     u8 my_protocol;
1599     nfv9_nat64_add_bib_record_t nfv9_logging_add_record;
1600
1601     if (PREDICT_FALSE(nat64_entry->logging_index == EMPTY)) {
1602         /*
1603          * No logging configured, silently return
1604          */
1605         return;
1606     }
1607
1608     nfv9_logging_info =
1609         cnat_nfv9_logging_info_pool + nat64_entry->logging_index;
1610
1611
1612     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1613         cnat_nfv9_create_logging_context(nfv9_logging_info,
1614                                         cnat_nfv9_template_add_default);
1615
1616         /*
1617          * If still empty, return after increasing the count
1618          */
1619         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1620             return;
1621         }
1622     }
1623
1624     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_ADD_BIB_RECORD] == NULL)){
1625         cnat_nfv9_record_create(nfv9_logging_info,NAT64_ADD_BIB_RECORD);
1626     }
1627
1628
1629     nfv9_logging_add_record.inside_v6_src_addr[0] = 
1630             clib_host_to_net_u32(db->v6_in_key.ipv6[0]);
1631     nfv9_logging_add_record.inside_v6_src_addr[1] = 
1632             clib_host_to_net_u32(db->v6_in_key.ipv6[1]);
1633     nfv9_logging_add_record.inside_v6_src_addr[2] = 
1634             clib_host_to_net_u32(db->v6_in_key.ipv6[2]);
1635     nfv9_logging_add_record.inside_v6_src_addr[3] = 
1636             clib_host_to_net_u32(db->v6_in_key.ipv6[3]);
1637
1638
1639     nfv9_logging_add_record.outside_v4_src_addr =
1640             clib_host_to_net_u32(db->v4_out_key.k.ipv4);
1641
1642     nfv9_logging_add_record.inside_src_port =
1643             clib_host_to_net_u16(db->v6_in_key.port);
1644     nfv9_logging_add_record.outside_src_port =
1645             clib_host_to_net_u16(db->v4_out_key.k.port);
1646
1647     my_proto_mask = db->v6_in_key.vrf & CNAT_PRO_MASK;
1648
1649     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1650            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1651            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
1652     nfv9_logging_add_record.protocol = my_protocol;
1653
1654
1655     memcpy(nfv9_logging_info->record[NAT64_ADD_BIB_RECORD], 
1656             &nfv9_logging_add_record, CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH);
1657
1658     nfv9_logging_info->record_length[NAT64_ADD_BIB_RECORD] += 
1659                          CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH;
1660     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH;
1661     nfv9_logging_info->total_record_count += 1;
1662
1663     nfv9_logging_info->record[NAT64_ADD_BIB_RECORD] 
1664                            += CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH;
1665
1666     nfv9_logging_info->next_data_ptr = 
1667                       nfv9_logging_info->record[NAT64_ADD_BIB_RECORD];
1668
1669     nfv9_logging_info->dataflow_header->dataflow_length =
1670     clib_host_to_net_u32(
1671             nfv9_logging_info->record_length[NAT64_ADD_BIB_RECORD]);
1672
1673     /*
1674      * If we have exceeded the packet length, let us send the
1675      * packet now.  There is buffer of additional bytes beyond
1676      * max_pkt_length to ensure that the last add/delete record
1677      * can be stored safely.
1678      */
1679     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
1680         nfv9_logging_info->max_length_minus_max_record_size)) {
1681         cnat_nfv9_send_pkt(nfv9_logging_info);
1682     }
1683 }
1684
1685
1686 /*
1687  * edt: * * cnat_nfv9_session_mapping_create
1688  *
1689  * Tries to log a creation of Bib mapping record
1690  *
1691  * Argument: nat64_bib_entry_t *bdb
1692  * BIB DB entry for the session that is created
1693  *
1694  * Argument: nat64_session_entry_t *sdb
1695  * Session DB entry being created
1696  * 
1697  * Argument: nat64_table_entry_t *nat64_entry
1698  * NAT64 Instance where this BIB and Session belongs 
1699  */
1700 void cnat_nfv9_session_mapping_create (nat64_bib_entry_t *bdb,
1701                        nat64_session_entry_t *sdb,
1702                        nat64_table_entry_t *nat64_entry_ptr)
1703 {
1704     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1705     u16 my_proto_mask;
1706     u8 my_protocol;
1707     u32 dest_v6[4];
1708     nfv9_nat64_add_session_record_t nfv9_logging_add_record;
1709     u8            *ipv6_addr_ptr;
1710     u8            *ipv4_addr_ptr;
1711
1712
1713     if (PREDICT_FALSE(nat64_entry_ptr->logging_index == EMPTY)) {
1714         /*
1715          * No logging configured, silently return
1716          */
1717         return;
1718     }
1719
1720     nfv9_logging_info =
1721         cnat_nfv9_logging_info_pool + nat64_entry_ptr->logging_index;
1722
1723
1724     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1725         cnat_nfv9_create_logging_context(nfv9_logging_info,
1726                                         cnat_nfv9_template_add_default);
1727
1728         /*
1729          * If still empty, return after increasing the count
1730          */
1731         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)){
1732             return;
1733         }
1734     }
1735
1736     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD] 
1737                                                   == NULL)){
1738         cnat_nfv9_record_create(nfv9_logging_info, NAT64_ADD_SESSION_RECORD);
1739     }
1740
1741
1742     nfv9_logging_add_record.inside_v6_src_addr[0] =
1743             clib_host_to_net_u32(bdb->v6_in_key.ipv6[0]);
1744     nfv9_logging_add_record.inside_v6_src_addr[1] =
1745             clib_host_to_net_u32(bdb->v6_in_key.ipv6[1]);
1746     nfv9_logging_add_record.inside_v6_src_addr[2] =
1747             clib_host_to_net_u32(bdb->v6_in_key.ipv6[2]);
1748     nfv9_logging_add_record.inside_v6_src_addr[3] =
1749             clib_host_to_net_u32(bdb->v6_in_key.ipv6[3]);
1750
1751
1752     nfv9_logging_add_record.outside_v4_src_addr =
1753             clib_host_to_net_u32(bdb->v4_out_key.k.ipv4);
1754
1755
1756     nfv9_logging_add_record.outside_v4_dest_addr =
1757           clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
1758
1759     /* Need to create the V6 address using prefix */
1760     dest_v6[0] = nat64_entry_ptr->v6_prefix[0];
1761     dest_v6[1] = nat64_entry_ptr->v6_prefix[1];
1762     dest_v6[2] = nat64_entry_ptr->v6_prefix[2];
1763     dest_v6[3] = nat64_entry_ptr->v6_prefix[3];
1764
1765     ipv6_addr_ptr = (u8 *) (&(dest_v6[0]));
1766     ipv4_addr_ptr = (u8 *) (&(sdb->v4_dest_key.k.ipv4));
1767
1768     *(ipv6_addr_ptr + nat64_entry_ptr->octet0_position) = *(ipv4_addr_ptr);
1769     *(ipv6_addr_ptr + nat64_entry_ptr->octet1_position) = *(ipv4_addr_ptr + 1);
1770     *(ipv6_addr_ptr + nat64_entry_ptr->octet2_position) = *(ipv4_addr_ptr + 2);
1771     *(ipv6_addr_ptr + nat64_entry_ptr->octet3_position) = *(ipv4_addr_ptr + 3);
1772
1773     nfv9_logging_add_record.inside_v6_dest_addr[0] =
1774           clib_host_to_net_u32(dest_v6[0]);
1775     nfv9_logging_add_record.inside_v6_dest_addr[1] =
1776           clib_host_to_net_u32(dest_v6[1]);
1777     nfv9_logging_add_record.inside_v6_dest_addr[2] =
1778           clib_host_to_net_u32(dest_v6[2]);
1779     nfv9_logging_add_record.inside_v6_dest_addr[3] =
1780           clib_host_to_net_u32(dest_v6[3]);
1781
1782     nfv9_logging_add_record.outside_v4_dest_addr =
1783           clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
1784
1785     nfv9_logging_add_record.inside_src_port =
1786             clib_host_to_net_u16(bdb->v6_in_key.port);
1787     nfv9_logging_add_record.outside_src_port =
1788             clib_host_to_net_u16(bdb->v4_out_key.k.port);
1789
1790     nfv9_logging_add_record.dest_port =
1791             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
1792
1793
1794     my_proto_mask = bdb->v6_in_key.vrf & CNAT_PRO_MASK;
1795
1796     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1797            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1798            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
1799     nfv9_logging_add_record.protocol = my_protocol;
1800
1801
1802     memcpy(nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD],
1803        &nfv9_logging_add_record, CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH);
1804
1805     nfv9_logging_info->record_length[NAT64_ADD_SESSION_RECORD] +=
1806                          CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH;
1807     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH;
1808     nfv9_logging_info->total_record_count += 1;
1809
1810     nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD]
1811                            += CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH;
1812
1813     nfv9_logging_info->next_data_ptr =
1814                       nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD];
1815
1816     nfv9_logging_info->dataflow_header->dataflow_length =
1817     clib_host_to_net_u32(
1818             nfv9_logging_info->record_length[NAT64_ADD_SESSION_RECORD]);
1819
1820     /*
1821      * If we have exceeded the packet length, let us send the
1822      * packet now.  There is buffer of additional bytes beyond
1823      * max_pkt_length to ensure that the last add/delete record
1824      * can be stored safely.
1825      */
1826     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
1827         nfv9_logging_info->max_length_minus_max_record_size)) {
1828         cnat_nfv9_send_pkt(nfv9_logging_info);
1829     }
1830 }
1831
1832
1833 /*
1834  * edt: * * cnat_nfv9_bib_mapping_delete
1835  *
1836  * Tries to log a deletion of Bib mapping record
1837  *
1838  * Argument: nat64_bib_entry_t *db
1839  * BIB DB entry being created
1840  *
1841  * Argument: nat64_table_entry_t *nat64_entry
1842  * NAT64 Instance where this BIB belongs 
1843  */
1844 void cnat_nfv9_bib_mapping_delete (nat64_bib_entry_t *db,
1845                        nat64_table_entry_t *nat64_entry)
1846 {
1847     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1848     u16 my_proto_mask;
1849     u8 my_protocol;
1850     nfv9_nat64_del_bib_record_t nfv9_logging_del_record;
1851     if (PREDICT_FALSE(nat64_entry->logging_index == EMPTY)) {
1852         /*
1853          * No logging configured, silently return
1854          */
1855         return;
1856     }
1857
1858     nfv9_logging_info =
1859         cnat_nfv9_logging_info_pool + nat64_entry->logging_index;
1860
1861
1862     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1863         cnat_nfv9_create_logging_context(nfv9_logging_info,
1864                                          cnat_nfv9_template_add_default);
1865
1866         /*
1867          * If still empty, return after increasing the count
1868          */
1869         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)){
1870             return;
1871         }
1872     }
1873
1874     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_DEL_BIB_RECORD] == NULL)){
1875         cnat_nfv9_record_create(nfv9_logging_info,NAT64_DEL_BIB_RECORD);
1876     }
1877
1878
1879     nfv9_logging_del_record.inside_v6_src_addr[0] =
1880             clib_host_to_net_u32(db->v6_in_key.ipv6[0]);
1881     nfv9_logging_del_record.inside_v6_src_addr[1] =
1882             clib_host_to_net_u32(db->v6_in_key.ipv6[1]);
1883     nfv9_logging_del_record.inside_v6_src_addr[2] =
1884             clib_host_to_net_u32(db->v6_in_key.ipv6[2]);
1885     nfv9_logging_del_record.inside_v6_src_addr[3] =
1886             clib_host_to_net_u32(db->v6_in_key.ipv6[3]);
1887
1888
1889     nfv9_logging_del_record.inside_src_port =
1890             clib_host_to_net_u16(db->v6_in_key.port);
1891
1892     my_proto_mask = db->v6_in_key.vrf & CNAT_PRO_MASK;
1893
1894     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1895            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1896            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
1897     nfv9_logging_del_record.protocol = my_protocol;
1898
1899
1900     memcpy(nfv9_logging_info->record[NAT64_DEL_BIB_RECORD],
1901             &nfv9_logging_del_record, CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH);
1902
1903     nfv9_logging_info->record_length[NAT64_DEL_BIB_RECORD] +=
1904                          CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH;
1905     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH;
1906     nfv9_logging_info->total_record_count += 1;
1907
1908     nfv9_logging_info->record[NAT64_DEL_BIB_RECORD]
1909                            += CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH;
1910
1911     nfv9_logging_info->next_data_ptr =
1912                       nfv9_logging_info->record[NAT64_DEL_BIB_RECORD];
1913
1914     nfv9_logging_info->dataflow_header->dataflow_length =
1915     clib_host_to_net_u32(
1916             nfv9_logging_info->record_length[NAT64_DEL_BIB_RECORD]);
1917
1918     /*
1919      * If we have exceeded the packet length, let us send the
1920      * packet now.  There is buffer of additional bytes beyond
1921      * max_pkt_length to ensure that the last add/delete record
1922      * can be stored safely.
1923      */
1924     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
1925         nfv9_logging_info->max_length_minus_max_record_size)) {
1926         cnat_nfv9_send_pkt(nfv9_logging_info);
1927     }
1928 }
1929
1930
1931 /*
1932  * edt: * * cnat_nfv9_session_mapping_delete
1933  *
1934  * Tries to log a deletion of Bib mapping record
1935  *
1936  * Argument: nat64_bib_entry_t *bdb
1937  * BIB DB entry for the session that is created
1938  *
1939  * Argument: nat64_session_entry_t *sdb
1940  * Session DB entry being created
1941  * 
1942  * Argument: nat64_table_entry_t *nat64_entry
1943  * NAT64 Instance where this BIB and Session belongs 
1944  */
1945 void cnat_nfv9_session_mapping_delete (nat64_bib_entry_t *bdb,
1946                        nat64_session_entry_t *sdb,
1947                        nat64_table_entry_t *nat64_entry_ptr)
1948 {
1949     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1950     u16 my_proto_mask;
1951     u8 my_protocol;
1952     u32 dest_v6[4];
1953     nfv9_nat64_del_session_record_t nfv9_logging_del_record;
1954     u8            *ipv6_addr_ptr;
1955     u8            *ipv4_addr_ptr;
1956
1957     if (PREDICT_FALSE(nat64_entry_ptr->logging_index == EMPTY)) {
1958         /*
1959          * No logging configured, silently return
1960          */
1961         return;
1962     }
1963
1964     nfv9_logging_info =
1965         cnat_nfv9_logging_info_pool + nat64_entry_ptr->logging_index;
1966
1967
1968     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1969         cnat_nfv9_create_logging_context(nfv9_logging_info,
1970                                         cnat_nfv9_template_add_default);
1971
1972         /*
1973          * If still empty, return after increasing the count
1974          */
1975         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)){
1976             return;
1977         }
1978     }
1979
1980     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD]
1981                                                   == NULL)){
1982         cnat_nfv9_record_create(nfv9_logging_info, NAT64_DEL_SESSION_RECORD);
1983     }
1984
1985
1986     nfv9_logging_del_record.inside_v6_src_addr[0] =
1987             clib_host_to_net_u32(bdb->v6_in_key.ipv6[0]);
1988     nfv9_logging_del_record.inside_v6_src_addr[1] =
1989             clib_host_to_net_u32(bdb->v6_in_key.ipv6[1]);
1990     nfv9_logging_del_record.inside_v6_src_addr[2] =
1991             clib_host_to_net_u32(bdb->v6_in_key.ipv6[2]);
1992     nfv9_logging_del_record.inside_v6_src_addr[3] =
1993             clib_host_to_net_u32(bdb->v6_in_key.ipv6[3]);
1994
1995     /* Need to create the V6 address using prefix */
1996     dest_v6[0] = nat64_entry_ptr->v6_prefix[0];
1997     dest_v6[1] = nat64_entry_ptr->v6_prefix[1];
1998     dest_v6[2] = nat64_entry_ptr->v6_prefix[2];
1999     dest_v6[3] = nat64_entry_ptr->v6_prefix[3];
2000
2001     ipv6_addr_ptr = (u8 *) (&(dest_v6[0]));
2002     ipv4_addr_ptr = (u8 *) (&(sdb->v4_dest_key.k.ipv4));
2003
2004     *(ipv6_addr_ptr + nat64_entry_ptr->octet0_position) = *(ipv4_addr_ptr);
2005     *(ipv6_addr_ptr + nat64_entry_ptr->octet1_position) = *(ipv4_addr_ptr + 1);
2006     *(ipv6_addr_ptr + nat64_entry_ptr->octet2_position) = *(ipv4_addr_ptr + 2);
2007     *(ipv6_addr_ptr + nat64_entry_ptr->octet3_position) = *(ipv4_addr_ptr + 3);
2008
2009     nfv9_logging_del_record.inside_v6_dest_addr[0] =
2010           clib_host_to_net_u32(dest_v6[0]);
2011     nfv9_logging_del_record.inside_v6_dest_addr[1] =
2012           clib_host_to_net_u32(dest_v6[1]);
2013     nfv9_logging_del_record.inside_v6_dest_addr[2] =
2014           clib_host_to_net_u32(dest_v6[2]);
2015     nfv9_logging_del_record.inside_v6_dest_addr[3] =
2016           clib_host_to_net_u32(dest_v6[3]);
2017
2018     nfv9_logging_del_record.inside_src_port =
2019             clib_host_to_net_u16(bdb->v6_in_key.port);
2020
2021     nfv9_logging_del_record.dest_port =
2022             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2023
2024
2025     my_proto_mask = bdb->v6_in_key.vrf & CNAT_PRO_MASK;
2026
2027     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2028            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2029            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
2030     nfv9_logging_del_record.protocol = my_protocol;
2031
2032     memcpy(nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD],
2033        &nfv9_logging_del_record, CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH);
2034
2035     nfv9_logging_info->record_length[NAT64_DEL_SESSION_RECORD] +=
2036                          CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH;
2037     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH;
2038     nfv9_logging_info->total_record_count += 1;
2039
2040     nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD]
2041                            += CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH;
2042
2043     nfv9_logging_info->next_data_ptr =
2044                       nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD];
2045
2046     nfv9_logging_info->dataflow_header->dataflow_length =
2047     clib_host_to_net_u32(
2048             nfv9_logging_info->record_length[NAT64_DEL_SESSION_RECORD]);
2049
2050     /*
2051      * If we have exceeded the packet length, let us send the
2052      * packet now.  There is buffer of additional bytes beyond
2053      * max_pkt_length to ensure that the last add/delete record
2054      * can be stored safely.
2055      */
2056     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2057         nfv9_logging_info->max_length_minus_max_record_size)) {
2058         cnat_nfv9_send_pkt(nfv9_logging_info);
2059     }
2060 }
2061
2062 /*
2063  * edt: * * cnat_nfv9_nat44_log_session_create
2064  *
2065  * Tries to log a creation of mapping record (session based)
2066  *
2067  * Argument: cnat_main_db_entry_t *db
2068  * Main DB entry being created
2069  * Arugment: cnat_session_entry_t *sdb
2070  * Session DB entry if the destination is not the first dest
2071  * Argument: cnat_vrfmap_t *vrfmap
2072  * VRF Map for the Main DB entry being created
2073  */
2074
2075 void cnat_nfv9_nat44_log_session_create(cnat_main_db_entry_t *db,
2076                 cnat_session_entry_t *sdb,
2077                 cnat_vrfmap_t *vrfmap)
2078 {
2079     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
2080     u16 my_proto_mask;
2081     u8 my_protocol;
2082     nfv9_add_session_record_t nfv9_logging_add_session_record;
2083
2084     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
2085         //vlib_cli_output(vm,"\n1. Log Mapping failed");
2086         /*
2087          * No logging configured, silently return
2088          */
2089         return;
2090     }
2091
2092     nfv9_logging_info =
2093         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
2094
2095     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2096         cnat_nfv9_create_logging_context(nfv9_logging_info,
2097                     cnat_nfv9_template_add_default);
2098
2099         /*
2100          * If still empty, return after increasing the count
2101          */
2102         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2103             //vlib_cli_output(vm,"\n2. Log Mapping failed");
2104             return;
2105         }
2106     }
2107
2108     if(PREDICT_FALSE(nfv9_logging_info->record[
2109             NAT44_ADD_SESSION_RECORD] == NULL)) {
2110         cnat_nfv9_record_create(nfv9_logging_info, NAT44_ADD_SESSION_RECORD);
2111     }
2112
2113     /*
2114      * We should definitely have add_record now, no need to sanitize
2115      */
2116     nfv9_logging_add_session_record.inside_vrf_id =
2117             clib_host_to_net_u32(vrfmap->i_vrf_id);
2118     nfv9_logging_add_session_record.outside_vrf_id =
2119             clib_host_to_net_u32(vrfmap->o_vrf_id);
2120
2121     nfv9_logging_add_session_record.inside_ip_addr =
2122             clib_host_to_net_u32(db->in2out_key.k.ipv4);
2123     nfv9_logging_add_session_record.outside_ip_addr =
2124         clib_host_to_net_u32(db->out2in_key.k.ipv4);
2125
2126     /* If sdb is null, it is assumed that logging is being done
2127      * for the first destination which is held in the main db
2128
2129      * itself
2130      */
2131     if(PREDICT_TRUE(sdb == NULL)) {
2132         nfv9_logging_add_session_record.dest_ip_addr =
2133             clib_host_to_net_u32(db->dst_ipv4);
2134         nfv9_logging_add_session_record.dest_port =
2135             clib_host_to_net_u16(db->dst_port);
2136     } else {
2137         nfv9_logging_add_session_record.dest_ip_addr =
2138             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2139         nfv9_logging_add_session_record.dest_port =
2140             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2141     }
2142
2143     nfv9_logging_add_session_record.inside_ip_port =
2144             clib_host_to_net_u16(db->in2out_key.k.port);
2145     nfv9_logging_add_session_record.outside_ip_port =
2146             clib_host_to_net_u16(db->out2in_key.k.port);
2147
2148
2149     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2150
2151     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2152             ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2153             ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
2154     nfv9_logging_add_session_record.protocol = my_protocol;
2155
2156     memcpy(nfv9_logging_info->record[NAT44_ADD_SESSION_RECORD],
2157             &nfv9_logging_add_session_record,
2158             CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH);
2159
2160     nfv9_logging_info->record_length[NAT44_ADD_SESSION_RECORD]
2161             += CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH;
2162     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH;
2163     nfv9_logging_info->total_record_count += 1;
2164
2165
2166     nfv9_logging_info->record[NAT44_ADD_SESSION_RECORD]
2167             += CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH;
2168
2169     nfv9_logging_info->next_data_ptr =
2170             nfv9_logging_info->record[NAT44_ADD_SESSION_RECORD];
2171
2172     nfv9_logging_info->dataflow_header->dataflow_length =
2173         clib_host_to_net_u32(
2174     nfv9_logging_info->record_length[NAT44_ADD_SESSION_RECORD]);
2175
2176     /*
2177      * If we have exceeded the packet length, let us send the
2178      * packet now.  There is buffer of additional bytes beyond
2179      * max_pkt_length to ensure that the last add/delete record
2180      * can be stored safely.
2181      */
2182     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2183         nfv9_logging_info->max_length_minus_max_record_size)) {
2184         cnat_nfv9_send_pkt(nfv9_logging_info);
2185     }
2186 }
2187
2188 /*
2189  * edt: * * cnat_nfv9_nat44_log_session_delete
2190  *
2191  * Tries to log a deletion of mapping record (session based)
2192  *
2193  * Argument: cnat_main_db_entry_t *db
2194  * Main DB entry being created
2195  * Arugment: cnat_session_entry_t *sdb
2196  * Session DB entry if the destination is not the first dest
2197  * Argument: cnat_vrfmap_t *vrfmap
2198  * VRF Map for the Main DB entry being deleted
2199  */
2200
2201 void cnat_nfv9_nat44_log_session_delete(cnat_main_db_entry_t *db,
2202                 cnat_session_entry_t *sdb,
2203                 cnat_vrfmap_t *vrfmap)
2204 {
2205     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
2206     u16 my_proto_mask;
2207     u8 my_protocol;
2208     nfv9_del_session_record_t nfv9_logging_del_session_record;
2209
2210     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
2211         //vlib_cli_output(vm, "\n1. Log Mapping failed");
2212         /*
2213          * No logging configured, silently return
2214          */
2215         return;
2216     }
2217
2218     nfv9_logging_info =
2219         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
2220
2221     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2222         cnat_nfv9_create_logging_context(nfv9_logging_info,
2223                     cnat_nfv9_template_add_default);
2224
2225         /*
2226          * If still empty, return after increasing the count
2227          */
2228         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2229             //vlib_cli_output(vm, "\n2. Log Mapping failed");
2230             return;
2231         }
2232     }
2233
2234     if(PREDICT_FALSE(nfv9_logging_info->record[
2235             NAT44_DEL_SESSION_RECORD] == NULL)) {
2236         cnat_nfv9_record_create(nfv9_logging_info, NAT44_DEL_SESSION_RECORD);
2237     }
2238
2239     /*
2240      * We should definitely have add_record now, no need to sanitize
2241      */
2242     nfv9_logging_del_session_record.inside_vrf_id =
2243             clib_host_to_net_u32(vrfmap->i_vrf_id);
2244
2245     nfv9_logging_del_session_record.inside_ip_addr =
2246             clib_host_to_net_u32(db->in2out_key.k.ipv4);
2247
2248     /* If sdb is null, it is assumed that logging is being done
2249      * for the first destination which is held in the main db
2250      * itself
2251      */
2252     if(PREDICT_TRUE(sdb == NULL)) {
2253         nfv9_logging_del_session_record.dest_ip_addr =
2254             clib_host_to_net_u32(db->dst_ipv4);
2255         nfv9_logging_del_session_record.dest_port =
2256             clib_host_to_net_u16(db->dst_port);
2257     } else {
2258         nfv9_logging_del_session_record.dest_ip_addr =
2259             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2260         nfv9_logging_del_session_record.dest_port =
2261             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2262     }
2263
2264     nfv9_logging_del_session_record.inside_ip_port =
2265             clib_host_to_net_u16(db->in2out_key.k.port);
2266
2267     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2268     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2269             ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2270             ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
2271
2272     nfv9_logging_del_session_record.protocol = my_protocol;
2273
2274     memcpy(nfv9_logging_info->record[NAT44_DEL_SESSION_RECORD],
2275             &nfv9_logging_del_session_record,
2276             CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH);
2277
2278     nfv9_logging_info->record_length[NAT44_DEL_SESSION_RECORD]
2279             += CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH;
2280     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH;
2281     nfv9_logging_info->total_record_count += 1;
2282
2283     nfv9_logging_info->record[NAT44_DEL_SESSION_RECORD]
2284             += CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH;
2285
2286     nfv9_logging_info->next_data_ptr =
2287             nfv9_logging_info->record[NAT44_DEL_SESSION_RECORD];
2288
2289     nfv9_logging_info->dataflow_header->dataflow_length =
2290         clib_host_to_net_u32(
2291     nfv9_logging_info->record_length[NAT44_DEL_SESSION_RECORD]);
2292
2293     /*
2294      * If we have exceeded the packet length, let us send the
2295      * packet now.  There is buffer of additional bytes beyond
2296      * max_pkt_length to ensure that the last add/delete record
2297      * can be stored safely.
2298      */
2299     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2300         nfv9_logging_info->max_length_minus_max_record_size)) {
2301         cnat_nfv9_send_pkt(nfv9_logging_info);
2302     }
2303 }
2304
2305 /*
2306  * DS-Lite APIs for netflow logging
2307  */
2308
2309 /*
2310  * edt: * * cnat_nfv9_ds_lite_mapping_create
2311  *
2312  * Tries to log a creation of mapping record
2313  *
2314  * Argument: cnat_main_db_entry_t *db
2315  * Main DB entry being created
2316  *
2317  * Argument: dslite_table_entry_t *dslite_entry
2318  * ds-lite instance for the Main DB entry being created
2319  */
2320 void cnat_nfv9_ds_lite_mapping_create(cnat_main_db_entry_t *db,
2321                         dslite_table_entry_t *dslite_entry
2322 #ifndef NO_BULK_LOGGING
2323                         , int bulk_alloc
2324 #endif
2325                        )
2326 {
2327     
2328     cnat_nfv9_logging_info_t    *nfv9_logging_info = NULL; 
2329
2330     if (PREDICT_FALSE(!(db && dslite_entry))) {
2331         return;
2332     }
2333     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2334         /*
2335          * no logging configured, silently return
2336          */
2337         return;
2338     }
2339
2340     nfv9_logging_info = 
2341         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2342     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2343         cnat_nfv9_create_logging_context(nfv9_logging_info,
2344                                         cnat_nfv9_template_add_default);
2345         /*
2346          * If still empty, return after increasing the count
2347          */
2348         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2349             return;
2350         }
2351     }
2352 #ifndef NO_BULK_LOGGING
2353     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
2354         cnat_nfv9_ds_lite_insert_bulk_add_record(nfv9_logging_info, 
2355                 db, dslite_entry, bulk_alloc);
2356     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
2357         return; /* No logging required.. bulk port usage */
2358     else  /* Individual logging .. fall back to old method */
2359 #endif /*NO_BULK_LOGGING*/
2360     cnat_nfv9_ds_lite_insert_add_record(nfv9_logging_info, db, dslite_entry);
2361     /*
2362      * If we have exceeded the packet length, let us send the
2363      * packet now.  There is buffer of additional bytes beyond
2364      * max_pkt_length to ensure that the last add/delete record
2365      * can be stored safely.
2366      */
2367     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
2368         nfv9_logging_info->max_length_minus_max_record_size)) {
2369         cnat_nfv9_send_pkt(nfv9_logging_info);
2370     }
2371 }
2372
2373 /*
2374  * edt: * * cnat_nfv9_ds_lite_mapping_delete
2375  *
2376  * Tries to log a deletion of mapping record
2377  *
2378  * Argument: cnat_main_db_entry_t *db
2379  * Main DB entry being deleted
2380  *
2381  * Argument: dslite_table_entry_t *dslite_entry
2382  * ds-lite instance for the Main DB entry being deleted
2383  */
2384 void cnat_nfv9_ds_lite_mapping_delete(cnat_main_db_entry_t *db,
2385                            dslite_table_entry_t *dslite_entry
2386 #ifndef NO_BULK_LOGGING
2387                            , int bulk_alloc
2388 #endif
2389                               )
2390 {
2391
2392     cnat_nfv9_logging_info_t    *nfv9_logging_info = NULL; 
2393     if (PREDICT_FALSE(!(db && dslite_entry))) {
2394         return;
2395     }
2396     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2397         /*
2398          * No logging configured, silently return
2399          */
2400         return;
2401     }
2402     nfv9_logging_info = 
2403         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2404
2405
2406     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2407         cnat_nfv9_create_logging_context(nfv9_logging_info,
2408                                          cnat_nfv9_template_add_default);
2409         /*
2410          * If still empty, return after increasing the count
2411          */
2412         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2413             return;
2414         }
2415     }
2416 #ifndef NO_BULK_LOGGING
2417     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
2418         cnat_nfv9_ds_lite_insert_bulk_del_record(nfv9_logging_info, 
2419                     db, dslite_entry, bulk_alloc);
2420     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
2421         return; /* No logging required.. bulk port usage */
2422     else  /* Individual logging .. fall back to old method */
2423 #endif /*NO_BULK_LOGGING*/
2424     cnat_nfv9_ds_lite_insert_del_record(nfv9_logging_info, db, dslite_entry);
2425     /*
2426      * If we have exceeded the packet length, let us send the
2427      * packet now.  There is buffer of additional bytes beyond
2428      * max_pkt_length to ensure that the last add/delete record
2429      * can be stored safely.
2430      */
2431     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
2432         nfv9_logging_info->max_length_minus_max_record_size)) {
2433         cnat_nfv9_send_pkt(nfv9_logging_info);
2434     }
2435 }
2436
2437 /*
2438  * edt: * * cnat_nfv9_dslite_log_session_create
2439  *
2440  * Tries to log a creation of mapping record (session based)
2441  * Argument: cnat_main_db_entry_t *db
2442  * Main DB entry being created
2443  * Arugment: cnat_session_entry_t *sdb
2444  * Session DB entry if the destination is not the first dest
2445  * Argument: dslite_table_entry_t *dslite_entry,
2446  * dslite table entry for dslite instance
2447  */
2448
2449 void cnat_nfv9_ds_lite_log_session_create(
2450                 cnat_main_db_entry_t *db,
2451                 dslite_table_entry_t *dslite_entry,
2452                 cnat_session_entry_t *sdb)
2453 {
2454
2455     nfv9_ds_lite_add_session_record_t   nfv9_logging_add_record ;
2456     cnat_user_db_entry_t        *udb = NULL;
2457     u16     my_proto_mask;
2458     u8      my_protocol;
2459     cnat_nfv9_logging_info_t  *nfv9_logging_info = 0;
2460
2461     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2462         /*
2463          * no logging configured, silently return
2464          */
2465         return;
2466     }
2467
2468     nfv9_logging_info =
2469         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2470     udb = cnat_user_db + db->user_index;
2471
2472     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2473         cnat_nfv9_create_logging_context(nfv9_logging_info,
2474                     cnat_nfv9_template_add_default);
2475
2476         /*
2477          * If still empty, return after increasing the count
2478          */
2479         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2480             return;
2481         }
2482     }
2483
2484     udb = cnat_user_db + db->user_index;
2485     if (PREDICT_FALSE(!udb)) {
2486          return;
2487     }
2488     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD] == NULL)) {
2489         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_ADD_SESSION_RECORD);
2490     }
2491     /*
2492      * We should definitely have add_record now, no need to sanitize
2493      */
2494     nfv9_logging_add_record.inside_vrf_id =
2495                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
2496     nfv9_logging_add_record.outside_vrf_id =
2497                     clib_host_to_net_u32(dslite_entry->o_vrf_id);
2498
2499     nfv9_logging_add_record.inside_ip_addr =
2500                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
2501
2502     nfv9_logging_add_record.inside_v6_src_addr[0] =
2503                     clib_host_to_net_u32(udb->ipv6[0]);
2504     nfv9_logging_add_record.inside_v6_src_addr[1] =
2505                     clib_host_to_net_u32(udb->ipv6[1]);
2506     nfv9_logging_add_record.inside_v6_src_addr[2] =
2507                     clib_host_to_net_u32(udb->ipv6[2]);
2508     nfv9_logging_add_record.inside_v6_src_addr[3] =
2509                     clib_host_to_net_u32(udb->ipv6[3]);
2510
2511     nfv9_logging_add_record.outside_ip_addr =
2512                     clib_host_to_net_u32(db->out2in_key.k.ipv4);
2513
2514     nfv9_logging_add_record.inside_ip_port =
2515                     clib_host_to_net_u16(db->in2out_key.k.port);
2516     nfv9_logging_add_record.outside_ip_port =
2517                     clib_host_to_net_u16(db->out2in_key.k.port);
2518
2519     /* If sdb is null, it is assumed that logging is being done
2520      * for the first destination which is held in the main db
2521
2522      * itself
2523      */
2524     if(PREDICT_TRUE(sdb == NULL)) {
2525         nfv9_logging_add_record.dest_ip_addr =
2526             clib_host_to_net_u32(db->dst_ipv4);
2527         nfv9_logging_add_record.dest_port =
2528             clib_host_to_net_u16(db->dst_port);
2529     } else {
2530         nfv9_logging_add_record.dest_ip_addr =
2531             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2532         nfv9_logging_add_record.dest_port =
2533             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2534     }
2535
2536
2537     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2538
2539     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2540                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2541                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
2542     nfv9_logging_add_record.protocol = my_protocol;
2543
2544     memcpy(nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD],
2545             &nfv9_logging_add_record, CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH);
2546
2547     nfv9_logging_info->record_length[DS_LITE_ADD_SESSION_RECORD]
2548                                   += CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH;
2549
2550     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH;
2551     nfv9_logging_info->total_record_count += 1;
2552
2553     nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD]
2554                       += CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH;
2555     nfv9_logging_info->next_data_ptr =
2556                          nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD];
2557
2558     nfv9_logging_info->dataflow_header->dataflow_length =
2559         clib_host_to_net_u32(
2560         nfv9_logging_info->record_length[DS_LITE_ADD_SESSION_RECORD]);
2561
2562     /*
2563      * If we have exceeded the packet length, let us send the
2564      * packet now.  There is buffer of additional bytes beyond
2565      * max_pkt_length to ensure that the last add/delete record
2566      * can be stored safely.
2567      */
2568     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2569         nfv9_logging_info->max_length_minus_max_record_size)) {
2570         cnat_nfv9_send_pkt(nfv9_logging_info);
2571     }
2572
2573 }
2574
2575 /*
2576  * edt: * * cnat_nfv9_dslite_log_session_delete
2577  *
2578  * Tries to log a creation of mapping record (session based)
2579  * Argument: cnat_main_db_entry_t *db
2580  * Main DB entry being created
2581  * Arugment: cnat_session_entry_t *sdb
2582  * Session DB entry if the destination is not the first dest
2583  * Argument: dslite_table_entry_t *dslite_entry,
2584  * dslite table entry for dslite instance
2585  */
2586
2587 void cnat_nfv9_ds_lite_log_session_delete(
2588                 cnat_main_db_entry_t *db,
2589                 dslite_table_entry_t *dslite_entry,
2590                 cnat_session_entry_t *sdb)
2591 {
2592
2593     nfv9_ds_lite_del_session_record_t   nfv9_logging_add_record = {0};
2594     cnat_user_db_entry_t        *udb = NULL;
2595     u16     my_proto_mask;
2596     u8      my_protocol;
2597     cnat_nfv9_logging_info_t  *nfv9_logging_info = NULL;
2598
2599     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2600         /*
2601          * no logging configured, silently return
2602          */
2603         return;
2604     }
2605
2606     nfv9_logging_info =
2607         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2608     udb = cnat_user_db + db->user_index;
2609
2610     if (PREDICT_FALSE(!udb)) {
2611         return;
2612     }
2613
2614     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2615         cnat_nfv9_create_logging_context(nfv9_logging_info,
2616                     cnat_nfv9_template_add_default);
2617
2618         /*
2619          * If still empty, return after increasing the count
2620          */
2621         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2622             return;
2623         }
2624     }
2625
2626     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD] == NULL)) {
2627         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_DEL_SESSION_RECORD);
2628     }
2629     /*
2630      * We should definitely have add_record now, no need to sanitize
2631      */
2632     nfv9_logging_add_record.inside_vrf_id =
2633                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
2634
2635     nfv9_logging_add_record.inside_ip_addr =
2636                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
2637
2638     nfv9_logging_add_record.inside_v6_src_addr[0] =
2639                     clib_host_to_net_u32(udb->ipv6[0]);
2640     nfv9_logging_add_record.inside_v6_src_addr[1] =
2641                     clib_host_to_net_u32(udb->ipv6[1]);
2642     nfv9_logging_add_record.inside_v6_src_addr[2] =
2643                     clib_host_to_net_u32(udb->ipv6[2]);
2644     nfv9_logging_add_record.inside_v6_src_addr[3] =
2645                     clib_host_to_net_u32(udb->ipv6[3]);
2646
2647     nfv9_logging_add_record.inside_ip_port =
2648                     clib_host_to_net_u16(db->in2out_key.k.port);
2649
2650     /* If sdb is null, it is assumed that logging is being done
2651      * for the first destination which is held in the main db
2652      * itself
2653      */
2654     if(PREDICT_TRUE(sdb == NULL)) {
2655         nfv9_logging_add_record.dest_ip_addr =
2656             clib_host_to_net_u32(db->dst_ipv4);
2657         nfv9_logging_add_record.dest_port = 
2658             clib_host_to_net_u16(db->dst_port);
2659     } else {
2660         nfv9_logging_add_record.dest_ip_addr =
2661             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2662         nfv9_logging_add_record.dest_port =
2663             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2664     }
2665
2666
2667     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2668
2669     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2670                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2671                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
2672     nfv9_logging_add_record.protocol = my_protocol;
2673     
2674     memcpy(nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD],
2675             &nfv9_logging_add_record, CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH);
2676
2677     nfv9_logging_info->record_length[DS_LITE_DEL_SESSION_RECORD]
2678                                   += CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH;
2679
2680     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH;
2681     nfv9_logging_info->total_record_count += 1;
2682
2683     nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD]
2684                       += CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH;
2685     nfv9_logging_info->next_data_ptr = 
2686                          nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD];
2687
2688     nfv9_logging_info->dataflow_header->dataflow_length =
2689         clib_host_to_net_u32(
2690         nfv9_logging_info->record_length[DS_LITE_DEL_SESSION_RECORD]);
2691
2692     /*
2693      * If we have exceeded the packet length, let us send the
2694      * packet now.  There is buffer of additional bytes beyond
2695      * max_pkt_length to ensure that the last add/delete record
2696      * can be stored safely.
2697      */
2698     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2699         nfv9_logging_info->max_length_minus_max_record_size)) {
2700         cnat_nfv9_send_pkt(nfv9_logging_info);
2701     }
2702
2703 }
2704
2705
2706 /*
2707  * netflow logging API for ingress vrf_id to name mapping
2708  */
2709
2710 /*
2711  * edt: * * handle_vrfid_name_mapping
2712  * It will search for valid natflow entry in netflow pool,
2713  * once found one, will send all vrfid name mapping info
2714  * using that entry
2715  */
2716
2717
2718 inline
2719 void handle_vrfid_name_mapping(void)
2720 {
2721     cnat_nfv9_logging_info_t    *nfv9_logging_info = NULL;
2722
2723     pool_foreach (nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
2724         if(PREDICT_FALSE(nfv9_logging_info == NULL)) {
2725             continue;
2726         }
2727         nfv9_server_info_t *server =  nfv9_server_info_pool + 
2728             nfv9_logging_info->server_index;
2729         if(server->template_sent == TEMPLATE_SENT_TRUE) {
2730             cnat_nfv9_ingress_vrfid_name_mapping_create(nfv9_logging_info);
2731             server->template_sent = TEMPLATE_SENT_FALSE;
2732         }
2733     }));
2734 }
2735
2736 /*
2737  * edt: * * cnat_nfv9_ingress_vrfid_name_mapping_create
2738  * 
2739  * Tries to log vrfid-name mapping record
2740  * Argument: netflow pointer
2741  */
2742
2743
2744 void cnat_nfv9_ingress_vrfid_name_mapping_create(
2745                 cnat_nfv9_logging_info_t *nfv9_logging_info)
2746 {
2747     u16 index = 0;
2748
2749     for (index = 0; index < MAX_VRFID; index++) {
2750         if(vrfid_name_map[index].ref_count == 0) {
2751             continue;
2752         }
2753         if (PREDICT_FALSE(
2754                     nfv9_logging_info->current_logging_context == NULL)) {
2755             cnat_nfv9_create_logging_context(nfv9_logging_info,
2756                     cnat_nfv9_template_add_default);
2757         }
2758         cnat_nfv9_insert_ingress_vrfid_name_record(
2759                 nfv9_logging_info,index);
2760         if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2761                     nfv9_logging_info->max_length_minus_max_record_size) ||
2762                     PREDICT_FALSE(index == MAX_VRFID - 1)) {
2763             if (PREDICT_TRUE(nfv9_logging_info->current_logging_context
2764                         != NULL)) {
2765                 cnat_nfv9_send_pkt(nfv9_logging_info);
2766             }
2767         }
2768     }/*for()*/
2769     return;
2770 }
2771
2772 static void cnat_nfv9_insert_ingress_vrfid_name_record(
2773         cnat_nfv9_logging_info_t *nfv9_logging_info, u16 index)
2774 {
2775     nfv9_ingress_vrfid_name_record_t  nfv9_ingress_vrfid_name_record = {0};
2776  
2777     if (PREDICT_FALSE(
2778             nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD] == NULL)) {
2779         cnat_nfv9_record_create(nfv9_logging_info, INGRESS_VRF_ID_NAME_RECORD);
2780     }
2781     nfv9_ingress_vrfid_name_record.ingress_vrf_id = 
2782                     clib_host_to_net_u32(vrfid_name_map[index].vrf_id);
2783
2784     memcpy(nfv9_ingress_vrfid_name_record.ingress_vrf_name,
2785             vrfid_name_map[index].vrf_name, NFV9_VRF_NAME_LEN);
2786
2787     memcpy(nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD], 
2788             &nfv9_ingress_vrfid_name_record, 
2789             CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH);
2790
2791     nfv9_logging_info->record_length[INGRESS_VRF_ID_NAME_RECORD] 
2792             += CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH;
2793
2794     nfv9_logging_info->pkt_length += 
2795             CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH;
2796
2797     nfv9_logging_info->total_record_count += 1;
2798
2799     nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD] 
2800             += CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH;
2801
2802     nfv9_logging_info->next_data_ptr = 
2803             nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD];
2804
2805     nfv9_logging_info->dataflow_header->dataflow_length =
2806         clib_host_to_net_u32(
2807         nfv9_logging_info->record_length[INGRESS_VRF_ID_NAME_RECORD]);
2808     return;
2809 }
2810 /*
2811  * edt: * * cnat_log_timer_handler
2812  *
2813  * Timer handler for sending any pending NFV9 record
2814  *
2815  * Argument: spp_timer_t * timer_p
2816  * Timer handler structure
2817  */
2818 void handle_pending_nfv9_pkts()
2819 {
2820     vlib_node_t *output_node;
2821     vlib_main_t * vm = vlib_get_main();
2822     cnat_nfv9_logging_info_t *my_nfv9_logging_info = 0;
2823     u32 current_timestamp = cnat_nfv9_get_sys_up_time_in_ms();
2824     u32 current_unix_time_in_seconds = cnat_nfv9_get_unix_time_in_seconds();
2825     
2826     output_node =  vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
2827
2828     pool_foreach (my_nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
2829         nfv9_server_info_t *server =  nfv9_server_info_pool + 
2830                                       my_nfv9_logging_info->server_index;
2831         if (my_nfv9_logging_info->queued_logging_context ||
2832             (my_nfv9_logging_info->current_logging_context &&
2833              (current_timestamp - 
2834               my_nfv9_logging_info->current_logging_context_timestamp) 
2835              > 1000)) {
2836             /*
2837              * If there is a current logging context and timestamp
2838              * indicates it is pending for long, send it out
2839              * Also if there is a queued context send it out as well
2840               */
2841               vlib_cli_output(vm, "\nNFV9_TIMER: queued %p, curr %p",
2842                                my_nfv9_logging_info->queued_logging_context, 
2843                                my_nfv9_logging_info->current_logging_context);
2844
2845
2846               cnat_nfv9_send_pkt_always_success(my_nfv9_logging_info,
2847                                               output_node);
2848         } else {
2849             /*
2850              * If the last_template_sent_time is too far back in time
2851              * send the template even if there is no NFv9 records to send
2852              */
2853             if ((my_nfv9_logging_info->queued_logging_context == NULL) &&
2854                  (my_nfv9_logging_info->current_logging_context == NULL) &&
2855                  ((current_unix_time_in_seconds -
2856                  server->last_template_sent_time) >
2857                  server->timeout_rate)) {
2858                  cnat_nfv9_create_logging_context(my_nfv9_logging_info,
2859                                                  cnat_nfv9_template_add_always);
2860                  if (PREDICT_TRUE(my_nfv9_logging_info->current_logging_context
2861                                   != NULL)) {
2862                      cnat_nfv9_send_pkt(my_nfv9_logging_info);
2863                  }
2864             }
2865         }
2866     }));
2867 }
2868
2869 /*
2870  * Code to initialize NFV9 Template.  This is done when a NFV9 is enabled
2871  * It is done only once and later used when sending NFV9 template records.
2872  */
2873 static void
2874 cnat_nfv9_template_init (void)
2875 {
2876     cnat_nfv9_template_info.flowset_id =
2877         clib_host_to_net_u16(CNAT_NFV9_TEMPLATE_FLOWSET_ID);
2878     cnat_nfv9_template_info.length =
2879         clib_host_to_net_u16(CNAT_NFV9_TEMPLATE_LENGTH - 
2880                         CNAT_NFV9_OPTION_TEMPLATE_LENGTH);
2881     /*
2882      * Create the add Template
2883      */
2884     cnat_nfv9_template_info.add_template_id =
2885         clib_host_to_net_u16(CNAT_NFV9_ADD_TEMPLATE_ID);
2886     cnat_nfv9_template_info.add_field_count =
2887         clib_host_to_net_u16(CNAT_NFV9_ADD_FIELD_COUNT);
2888
2889     cnat_nfv9_template_info.add_inside_vrf_id_field_type =
2890         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
2891     cnat_nfv9_template_info.add_inside_vrf_id_field_size =
2892         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
2893
2894     cnat_nfv9_template_info.add_outside_vrf_id_field_type =
2895         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
2896     cnat_nfv9_template_info.add_outside_vrf_id_field_size =
2897         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
2898
2899     cnat_nfv9_template_info.add_inside_ip_addr_field_type =
2900         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
2901     cnat_nfv9_template_info.add_inside_ip_addr_field_size =
2902         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
2903
2904     cnat_nfv9_template_info.add_outside_ip_addr_field_type =
2905         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
2906     cnat_nfv9_template_info.add_outside_ip_addr_field_size =
2907         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
2908
2909     cnat_nfv9_template_info.add_inside_ip_port_field_type =
2910         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
2911     cnat_nfv9_template_info.add_inside_ip_port_field_size =
2912         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
2913
2914     cnat_nfv9_template_info.add_outside_ip_port_field_type =
2915         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
2916     cnat_nfv9_template_info.add_outside_ip_port_field_size =
2917         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
2918
2919     cnat_nfv9_template_info.add_protocol_field_type = 
2920         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
2921     cnat_nfv9_template_info.add_protocol_field_size =
2922         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
2923
2924     /*
2925      * Create the delete Template
2926      */
2927     cnat_nfv9_template_info.del_template_id =
2928         clib_host_to_net_u16(CNAT_NFV9_DEL_TEMPLATE_ID);
2929     cnat_nfv9_template_info.del_field_count =
2930         clib_host_to_net_u16(CNAT_NFV9_DEL_FIELD_COUNT);
2931
2932     cnat_nfv9_template_info.del_inside_vrf_id_field_type =
2933         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
2934     cnat_nfv9_template_info.del_inside_vrf_id_field_size =
2935         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
2936
2937     cnat_nfv9_template_info.del_inside_ip_addr_field_type =
2938         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
2939     cnat_nfv9_template_info.del_inside_ip_addr_field_size =
2940         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
2941
2942     cnat_nfv9_template_info.del_inside_ip_port_field_type =
2943         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
2944     cnat_nfv9_template_info.del_inside_ip_port_field_size =
2945         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
2946
2947     cnat_nfv9_template_info.del_protocol_field_type =
2948         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
2949     cnat_nfv9_template_info.del_protocol_field_size =
2950         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
2951
2952
2953     /* Create NAT64 BIB Add template */
2954 #if 0
2955     cnat_nfv9_template_info.nat64_add_bib_template_id =
2956         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_BIB_TEMPLATE_ID);
2957     cnat_nfv9_template_info.nat64_add_bib_field_count =
2958         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_BIB_FIELD_COUNT);
2959
2960
2961     cnat_nfv9_template_info.nat64_add_bib_inside_ipv6_addr_field_type =
2962       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
2963     cnat_nfv9_template_info.nat64_add_bib_inside_ipv6_addr_field_size =
2964       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
2965
2966     cnat_nfv9_template_info.nat64_add_bib_outside_ip_addr_field_type =
2967         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
2968     cnat_nfv9_template_info.nat64_add_bib_outside_ip_addr_field_size =
2969         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
2970
2971     cnat_nfv9_template_info.nat64_add_bib_inside_ip_port_field_type =
2972       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
2973     cnat_nfv9_template_info.nat64_add_bib_inside_ip_port_field_size =
2974       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
2975
2976     cnat_nfv9_template_info.nat64_add_bib_outside_ip_port_field_type =
2977         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
2978     cnat_nfv9_template_info.nat64_add_bib_outside_ip_port_field_size =
2979         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
2980
2981     cnat_nfv9_template_info.nat64_add_bib_protocol_field_type =
2982         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
2983     cnat_nfv9_template_info.nat64_add_bib_protocol_field_size =
2984         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
2985
2986  
2987     /* NAT64 BIB Delete */
2988     cnat_nfv9_template_info.nat64_del_bib_template_id =
2989         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_BIB_TEMPLATE_ID);
2990     cnat_nfv9_template_info.nat64_del_bib_field_count =
2991         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_BIB_FIELD_COUNT);
2992
2993     cnat_nfv9_template_info.nat64_del_bib_inside_ip_addr_field_type =
2994       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
2995     cnat_nfv9_template_info.nat64_del_bib_inside_ip_addr_field_size =
2996       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
2997
2998     cnat_nfv9_template_info.nat64_del_bib_inside_ip_port_field_type =
2999       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3000     cnat_nfv9_template_info.nat64_del_bib_inside_ip_port_field_size =
3001       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3002
3003     cnat_nfv9_template_info.nat64_del_bib_protocol_field_type =
3004         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3005     cnat_nfv9_template_info.nat64_del_bib_protocol_field_size =
3006         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3007
3008
3009     /* NAt64 SESSION ADD */
3010
3011     cnat_nfv9_template_info.nat64_add_session_template_id =
3012         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_SESSION_TEMPLATE_ID);
3013     cnat_nfv9_template_info.nat64_add_session_field_count =
3014         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_SESSION_FIELD_COUNT);
3015
3016
3017     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_src_addr_field_type =
3018       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3019     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_src_addr_field_size =
3020       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3021
3022     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_addr_field_type =
3023         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3024     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_addr_field_size =
3025         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3026
3027
3028     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_dst_addr_field_type =
3029       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_TYPE);
3030     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_dst_addr_field_size =
3031       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_SIZE);
3032
3033
3034     cnat_nfv9_template_info.nat64_add_session_outside_ip_dst_addr_field_type =
3035       clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_DST_ADDR_FIELD_TYPE);
3036     cnat_nfv9_template_info.nat64_add_session_outside_ip_dst_addr_field_size =
3037       clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_DST_ADDR_FIELD_SIZE);
3038
3039     cnat_nfv9_template_info.nat64_add_session_inside_ip_src_port_field_type =
3040       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3041     cnat_nfv9_template_info.nat64_add_session_inside_ip_src_port_field_size =
3042       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3043
3044
3045     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_port_field_type =
3046         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3047     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_port_field_size =
3048         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3049    
3050
3051     cnat_nfv9_template_info.nat64_add_session_ip_dest_port_field_type =
3052       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3053     cnat_nfv9_template_info.nat64_add_session_ip_dest_port_field_size =
3054       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3055  
3056     cnat_nfv9_template_info.nat64_add_session_protocol_field_type =
3057         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3058     cnat_nfv9_template_info.nat64_add_session_protocol_field_size =
3059         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3060
3061
3062
3063     /* Session Delete */
3064     cnat_nfv9_template_info.nat64_del_session_template_id =
3065         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_SESSION_TEMPLATE_ID);
3066     cnat_nfv9_template_info.nat64_del_session_field_count =
3067         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_SESSION_FIELD_COUNT);
3068
3069     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_addr_field_type =
3070       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3071     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_addr_field_size =
3072       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3073
3074     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_addr_field_type =
3075       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_TYPE);
3076     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_addr_field_size =
3077       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_SIZE);
3078
3079     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_port_field_type =
3080       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3081     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_port_field_size =
3082       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3083
3084     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_port_field_type =
3085       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3086     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_port_field_size =
3087       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3088
3089     cnat_nfv9_template_info.nat64_del_session_protocol_field_type =
3090         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3091     cnat_nfv9_template_info.nat64_del_session_protocol_field_size =
3092         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3093 #endif
3094     /*
3095      * Create the nat44 session add Template
3096      */
3097     cnat_nfv9_template_info.nat44_session_add_template_id =
3098         clib_host_to_net_u16(CNAT_NFV9_NAT44_ADD_SESSION_TEMPLATE_ID);
3099     cnat_nfv9_template_info.nat44_session_add_field_count =
3100         clib_host_to_net_u16(CNAT_NFV9_NAT44_ADD_SESSION_FIELD_COUNT);
3101
3102     cnat_nfv9_template_info.nat44_session_add_inside_vrf_id_field_type =
3103         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3104     cnat_nfv9_template_info.nat44_session_add_inside_vrf_id_field_size =
3105         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3106
3107     cnat_nfv9_template_info.nat44_session_add_outside_vrf_id_field_type =
3108         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3109     cnat_nfv9_template_info.nat44_session_add_outside_vrf_id_field_size =
3110         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3111
3112     cnat_nfv9_template_info.nat44_session_add_inside_ip_addr_field_type =
3113         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3114     cnat_nfv9_template_info.nat44_session_add_inside_ip_addr_field_size =
3115         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3116
3117     cnat_nfv9_template_info.nat44_session_add_outside_ip_addr_field_type =
3118         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3119     cnat_nfv9_template_info.nat44_session_add_outside_ip_addr_field_size =
3120         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3121
3122     cnat_nfv9_template_info.nat44_session_add_inside_ip_port_field_type =
3123         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3124     cnat_nfv9_template_info.nat44_session_add_inside_ip_port_field_size =
3125         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3126
3127     cnat_nfv9_template_info.nat44_session_add_outside_ip_port_field_type =
3128         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3129    cnat_nfv9_template_info.nat44_session_add_outside_ip_port_field_size =
3130         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3131
3132     cnat_nfv9_template_info.nat44_session_add_dest_ip_addr_field_type =
3133         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3134     cnat_nfv9_template_info.nat44_session_add_dest_ip_addr_field_size =
3135         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3136
3137     cnat_nfv9_template_info.nat44_session_add_dest_port_field_type =
3138         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3139     cnat_nfv9_template_info.nat44_session_add_dest_port_field_size =
3140         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3141
3142     cnat_nfv9_template_info.nat44_session_add_protocol_field_type =
3143         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3144     cnat_nfv9_template_info.nat44_session_add_protocol_field_size =
3145         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3146
3147     /*
3148      * Create the nat44 session del Template
3149      */
3150     cnat_nfv9_template_info.nat44_session_del_template_id =
3151         clib_host_to_net_u16(CNAT_NFV9_NAT44_DEL_SESSION_TEMPLATE_ID);
3152     cnat_nfv9_template_info.nat44_session_del_field_count =
3153         clib_host_to_net_u16(CNAT_NFV9_NAT44_DEL_SESSION_FIELD_COUNT);
3154
3155     cnat_nfv9_template_info.nat44_session_del_inside_vrf_id_field_type =
3156         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3157     cnat_nfv9_template_info.nat44_session_del_inside_vrf_id_field_size =
3158         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3159
3160     cnat_nfv9_template_info.nat44_session_del_inside_ip_addr_field_type =
3161         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3162     cnat_nfv9_template_info.nat44_session_del_inside_ip_addr_field_size =
3163         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3164
3165     cnat_nfv9_template_info.nat44_session_del_dest_ip_addr_field_type =
3166         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3167     cnat_nfv9_template_info.nat44_session_del_dest_ip_addr_field_size =
3168         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3169
3170     cnat_nfv9_template_info.nat44_session_del_inside_ip_port_field_type =
3171         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3172     cnat_nfv9_template_info.nat44_session_del_inside_ip_port_field_size =
3173         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3174
3175     cnat_nfv9_template_info.nat44_session_del_dest_port_field_type =
3176         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3177     cnat_nfv9_template_info.nat44_session_del_dest_port_field_size =
3178         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3179
3180     cnat_nfv9_template_info.nat44_session_del_protocol_field_type =
3181         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3182     cnat_nfv9_template_info.nat44_session_del_protocol_field_size =
3183         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3184     /*
3185      * Ds-lite add template
3186      */
3187 #if 0
3188     cnat_nfv9_template_info.add_dslite_template_id =
3189         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_TEMPLATE_ID);
3190     cnat_nfv9_template_info.add_dslite_field_count =
3191         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_FIELD_COUNT);
3192
3193     cnat_nfv9_template_info.add_dslite_inside_vrf_id_field_type =
3194         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3195     cnat_nfv9_template_info.add_dslite_inside_vrf_id_field_size =
3196         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3197
3198     cnat_nfv9_template_info.add_dslite_outside_vrf_id_field_type =
3199         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3200     cnat_nfv9_template_info.add_dslite_outside_vrf_id_field_size =
3201         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3202
3203     cnat_nfv9_template_info.add_dslite_inside_ip_addr_field_type =
3204         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3205     cnat_nfv9_template_info.add_dslite_inside_ip_addr_field_size =
3206         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3207
3208     cnat_nfv9_template_info.add_dslite_inside_ipv6_addr_field_type =
3209       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3210     cnat_nfv9_template_info.add_dslite_inside_ipv6_addr_field_size =
3211       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3212
3213     cnat_nfv9_template_info.add_dslite_outside_ip_addr_field_type =
3214         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3215     cnat_nfv9_template_info.add_dslite_outside_ip_addr_field_size =
3216         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3217
3218     cnat_nfv9_template_info.add_dslite_inside_ip_port_field_type =
3219         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3220     cnat_nfv9_template_info.add_dslite_inside_ip_port_field_size =
3221         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3222
3223     cnat_nfv9_template_info.add_dslite_outside_ip_port_field_type =
3224         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3225     cnat_nfv9_template_info.add_dslite_outside_ip_port_field_size =
3226         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3227
3228     cnat_nfv9_template_info.add_dslite_protocol_field_type = 
3229         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3230     cnat_nfv9_template_info.add_dslite_protocol_field_size =
3231         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3232
3233     /*
3234      * Ds-lite delete template 
3235      */
3236     cnat_nfv9_template_info.del_dslite_template_id =
3237         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_TEMPLATE_ID);
3238     cnat_nfv9_template_info.del_dslite_field_count =
3239         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_FIELD_COUNT);
3240
3241     cnat_nfv9_template_info.del_dslite_inside_vrf_id_field_type =
3242         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3243     cnat_nfv9_template_info.del_dslite_inside_vrf_id_field_size =
3244         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3245
3246     cnat_nfv9_template_info.del_dslite_inside_ip_addr_field_type =
3247         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3248     cnat_nfv9_template_info.del_dslite_inside_ip_addr_field_size =
3249         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3250
3251     cnat_nfv9_template_info.del_dslite_inside_ipv6_addr_field_type =
3252       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3253     cnat_nfv9_template_info.del_dslite_inside_ipv6_addr_field_size =
3254       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3255
3256     cnat_nfv9_template_info.del_dslite_inside_ip_port_field_type =
3257         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3258     cnat_nfv9_template_info.del_dslite_inside_ip_port_field_size =
3259         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3260
3261     cnat_nfv9_template_info.del_dslite_protocol_field_type =
3262         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3263     cnat_nfv9_template_info.del_dslite_protocol_field_size =
3264         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3265
3266     /*
3267      * Ds-lite session add template
3268      */
3269
3270     cnat_nfv9_template_info.add_dslite_session_template_id =
3271         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_SESSION_TEMPLATE_ID);
3272     cnat_nfv9_template_info.add_dslite_session_field_count =
3273         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_SESSION_FIELD_COUNT);
3274
3275     cnat_nfv9_template_info.add_dslite_session_inside_vrf_id_field_type =
3276         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3277     cnat_nfv9_template_info.add_dslite_session_inside_vrf_id_field_size =
3278         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3279
3280     cnat_nfv9_template_info.add_dslite_session_outside_vrf_id_field_type =
3281         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3282     cnat_nfv9_template_info.add_dslite_session_outside_vrf_id_field_size =
3283         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3284
3285     cnat_nfv9_template_info.add_dslite_session_inside_ip_addr_field_type =
3286         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3287     cnat_nfv9_template_info.add_dslite_session_inside_ip_addr_field_size =
3288         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3289
3290     cnat_nfv9_template_info.add_dslite_session_inside_ipv6_addr_field_type =
3291       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3292     cnat_nfv9_template_info.add_dslite_session_inside_ipv6_addr_field_size =
3293       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3294
3295     cnat_nfv9_template_info.add_dslite_session_outside_ip_addr_field_type =
3296         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3297     cnat_nfv9_template_info.add_dslite_session_outside_ip_addr_field_size =
3298         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3299
3300     cnat_nfv9_template_info.add_dslite_session_inside_ip_port_field_type =
3301         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3302     cnat_nfv9_template_info.add_dslite_session_inside_ip_port_field_size =
3303         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3304
3305     cnat_nfv9_template_info.add_dslite_session_outside_ip_port_field_type =
3306         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3307     cnat_nfv9_template_info.add_dslite_session_outside_ip_port_field_size =
3308         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3309
3310      cnat_nfv9_template_info.add_dslite_session_dest_ip_addr_field_type =
3311          clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3312      cnat_nfv9_template_info.add_dslite_session_dest_ip_addr_field_size =
3313          clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3314  
3315      cnat_nfv9_template_info.add_dslite_session_dest_port_field_type =
3316          clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3317      cnat_nfv9_template_info.add_dslite_session_dest_port_field_size =
3318          clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3319
3320     cnat_nfv9_template_info.add_dslite_session_protocol_field_type =
3321         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3322     cnat_nfv9_template_info.add_dslite_session_protocol_field_size =
3323         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3324
3325     /*
3326      * Ds-lite session delete template 
3327      */
3328     cnat_nfv9_template_info.del_dslite_session_template_id =
3329         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_SESSION_TEMPLATE_ID);
3330     cnat_nfv9_template_info.del_dslite_session_field_count =
3331         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_SESSION_FIELD_COUNT);
3332
3333     cnat_nfv9_template_info.del_dslite_session_inside_vrf_id_field_type =
3334         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3335     cnat_nfv9_template_info.del_dslite_session_inside_vrf_id_field_size =
3336         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3337
3338     cnat_nfv9_template_info.del_dslite_session_inside_ip_addr_field_type =
3339         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3340     cnat_nfv9_template_info.del_dslite_session_inside_ip_addr_field_size =
3341         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3342
3343     cnat_nfv9_template_info.del_dslite_session_inside_ipv6_addr_field_type =
3344       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3345     cnat_nfv9_template_info.del_dslite_session_inside_ipv6_addr_field_size =
3346       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3347     
3348     cnat_nfv9_template_info.del_dslite_session_inside_ip_port_field_type =
3349         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3350     cnat_nfv9_template_info.del_dslite_session_inside_ip_port_field_size =
3351         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3352
3353     cnat_nfv9_template_info.del_dslite_session_dest_ip_addr_field_type =
3354         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3355     cnat_nfv9_template_info.del_dslite_session_dest_ip_addr_field_size =
3356         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3357
3358     cnat_nfv9_template_info.del_dslite_session_dest_port_field_type =
3359         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3360     cnat_nfv9_template_info.del_dslite_session_dest_port_field_size =
3361         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3362    
3363     cnat_nfv9_template_info.del_dslite_session_protocol_field_type =
3364         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3365     cnat_nfv9_template_info.del_dslite_session_protocol_field_size =
3366         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3367
3368     /* Create add bulk template */
3369     cnat_nfv9_template_info.bulk_add_template_id =
3370         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_ADD_TEMPLATE_ID);
3371     cnat_nfv9_template_info.bulk_add_field_count =
3372         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_ADD_FIELD_COUNT);
3373
3374     cnat_nfv9_template_info.bulk_add_inside_vrf_id_field_type =
3375         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3376     cnat_nfv9_template_info.bulk_add_inside_vrf_id_field_size =
3377         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3378
3379     cnat_nfv9_template_info.bulk_add_outside_vrf_id_field_type =
3380         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3381     cnat_nfv9_template_info.bulk_add_outside_vrf_id_field_size =
3382         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3383
3384     cnat_nfv9_template_info.bulk_add_inside_ip_addr_field_type =
3385         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3386     cnat_nfv9_template_info.bulk_add_inside_ip_addr_field_size =
3387         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3388
3389     cnat_nfv9_template_info.bulk_add_outside_ip_addr_field_type =
3390         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3391     cnat_nfv9_template_info.bulk_add_outside_ip_addr_field_size =
3392         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3393
3394     cnat_nfv9_template_info.bulk_add_outside_start_port_field_type =
3395         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3396     cnat_nfv9_template_info.bulk_add_outside_start_port_field_size =
3397         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3398
3399     cnat_nfv9_template_info.bulk_add_outside_end_port_field_type =
3400         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_TYPE);
3401     cnat_nfv9_template_info.bulk_add_outside_end_port_field_size =
3402         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_SIZE);
3403
3404     /*
3405      * Create the bulk delete Template
3406      */
3407     cnat_nfv9_template_info.bulk_del_template_id =
3408         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_DEL_TEMPLATE_ID);
3409     cnat_nfv9_template_info.bulk_del_field_count =
3410         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_DEL_FIELD_COUNT);
3411
3412     cnat_nfv9_template_info.bulk_del_inside_vrf_id_field_type =
3413         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3414     cnat_nfv9_template_info.bulk_del_inside_vrf_id_field_size =
3415         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3416
3417     cnat_nfv9_template_info.bulk_del_inside_ip_addr_field_type =
3418         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3419     cnat_nfv9_template_info.bulk_del_inside_ip_addr_field_size =
3420         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3421
3422     cnat_nfv9_template_info.bulk_del_outside_start_port_field_type =
3423         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3424     cnat_nfv9_template_info.bulk_del_outside_start_port_field_size =
3425         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3426
3427     /*
3428      * Ds-lite bulk add template
3429      */
3430     cnat_nfv9_template_info.bulk_dslite_add_template_id =
3431         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_ADD_TEMPLATE_ID);
3432     cnat_nfv9_template_info.bulk_dslite_add_field_count =
3433         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_ADD_FIELD_COUNT);
3434
3435     cnat_nfv9_template_info.bulk_dslite_add_inside_vrf_id_field_type =
3436         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3437     cnat_nfv9_template_info.bulk_dslite_add_inside_vrf_id_field_size =
3438         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3439
3440     cnat_nfv9_template_info.bulk_dslite_add_outside_vrf_id_field_type =
3441         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3442     cnat_nfv9_template_info.bulk_dslite_add_outside_vrf_id_field_size =
3443         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3444
3445     cnat_nfv9_template_info.bulk_dslite_add_inside_ip_addr_field_type =
3446         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3447     cnat_nfv9_template_info.bulk_dslite_add_inside_ip_addr_field_size =
3448         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3449
3450     cnat_nfv9_template_info.bulk_dslite_add_inside_ipv6_addr_field_type =
3451       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3452     cnat_nfv9_template_info.bulk_dslite_add_inside_ipv6_addr_field_size =
3453       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3454
3455     cnat_nfv9_template_info.bulk_dslite_add_outside_ip_addr_field_type =
3456         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3457     cnat_nfv9_template_info.bulk_dslite_add_outside_ip_addr_field_size =
3458         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3459
3460     cnat_nfv9_template_info.bulk_dslite_add_outside_start_port_field_type =
3461         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3462     cnat_nfv9_template_info.bulk_dslite_add_outside_start_port_field_size =
3463         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3464
3465     cnat_nfv9_template_info.bulk_dslite_add_outside_end_port_field_type =
3466         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_TYPE);
3467     cnat_nfv9_template_info.bulk_dslite_add_outside_end_port_field_size =
3468         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_SIZE);
3469
3470     /*
3471      * Ds-lite bulk delete template
3472      */
3473
3474     cnat_nfv9_template_info.bulk_dslite_del_template_id =
3475         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_DEL_TEMPLATE_ID);
3476     cnat_nfv9_template_info.bulk_dslite_del_field_count =
3477         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_DEL_FIELD_COUNT);
3478
3479     cnat_nfv9_template_info.bulk_dslite_del_inside_vrf_id_field_type =
3480         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3481     cnat_nfv9_template_info.bulk_dslite_del_inside_vrf_id_field_size =
3482         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3483
3484     cnat_nfv9_template_info.bulk_dslite_del_inside_ip_addr_field_type =
3485         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3486     cnat_nfv9_template_info.bulk_dslite_del_inside_ip_addr_field_size =
3487         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3488
3489     cnat_nfv9_template_info.bulk_dslite_del_inside_ipv6_addr_field_type =
3490       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3491     cnat_nfv9_template_info.bulk_dslite_del_inside_ipv6_addr_field_size =
3492       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3493
3494     cnat_nfv9_template_info.bulk_dslite_del_outside_start_port_field_type =
3495         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3496     cnat_nfv9_template_info.bulk_dslite_del_outside_start_port_field_size =
3497         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3498
3499 #endif /* NO_BULK_LOGGING */
3500
3501     /*
3502      * Ingress vrfid - name mapping  
3503      */ 
3504     CNAT_NFV9_OPTION_TEMPLATE.flowset_id =
3505         clib_host_to_net_u16(CNAT_NFV9_OPTION_TEMPLATE_FLOWSET_ID);
3506     CNAT_NFV9_OPTION_TEMPLATE.length =
3507         clib_host_to_net_u16(CNAT_NFV9_OPTION_TEMPLATE_LENGTH);
3508
3509     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_template_id =
3510         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_ID_NAME_TEMPLATE_ID);
3511     /* currently no scope field supported */
3512     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_scope_len = 0;
3513     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_option_len =
3514         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_ID_NAME_OPTION_LEN);
3515     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfid_option_type =
3516         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3517     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfid_option_len =
3518         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3519     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfname_option_type =
3520         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_NAME_FIELD_TYPE);
3521     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfname_option_len =
3522         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_NAME_FIELD_SIZE);
3523
3524     /*
3525      * Set the padding (which was added to make the size of template 
3526      * multiple of 4) to zero
3527      */
3528     CNAT_NFV9_OPTION_TEMPLATE.padding1 = 0;
3529 }
3530
3531 /*
3532  * one time function
3533  * has to be called at the init time
3534  */
3535 void cnat_nfv9_logging_init()
3536 {
3537     if (!cnat_nfv9_global_info.cnat_nfv9_init_done) {
3538         cnat_nfv9_template_init();
3539
3540         /* Pre allocate for NFV9_SERVER_POOL_SIZE. Will be good 
3541          * enough for most deployments 
3542          */
3543         pool_alloc(nfv9_server_info_pool, NFV9_SERVER_POOL_SIZE);
3544         int i;
3545         nfv9_server_info_t *server __attribute__((unused));
3546         for(i = 0; i < NFV9_SERVER_POOL_SIZE; i++) {
3547             pool_get(nfv9_server_info_pool, server);
3548         }
3549
3550         for(i = 0; i < NFV9_SERVER_POOL_SIZE; i++) {
3551             pool_put(nfv9_server_info_pool, nfv9_server_info_pool + i);
3552         }
3553
3554         memset(&cnat_nfv9_global_info, 0 , sizeof(cnat_nfv9_global_info_t));    
3555         ASSERT(cnat_nfv9_global_info.cnat_nfv9_disp_node_index != (u16)~0);
3556
3557         cnat_nfv9_global_info.cnat_nfv9_global_collector_index = EMPTY;
3558         cnat_nfv9_global_info.cnat_nfv9_init_done = 1;
3559
3560         /*
3561          * src id is set to infra IPv4 address + octeon core number
3562          */
3563         nfv9_src_id = my_instance_number;
3564     }
3565 }