Initial commit of vpp code.
[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 inline 
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 inline
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 inline
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 inline
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 inline
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 inline
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 inline 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 inline
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 inline
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 inline
855 void cnat_nfv9_record_create (
856         cnat_nfv9_logging_info_t *nfv9_logging_info, u16 cur_record)
857 {
858     int byte_diff = 0;
859     u16 last_record = nfv9_logging_info->last_record;
860
861     if(last_record != 0 && last_record != cur_record) {
862         u16 orig_length, new_length;
863
864         orig_length = nfv9_logging_info->record_length[last_record];
865         new_length  = cnat_nfv9_pad_end_of_record_length(orig_length);
866
867         /*
868          * The padding bytes are required after the last record
869          * Ensure length of last record accounts for padding bytes
870          */
871         nfv9_logging_info->dataflow_header->dataflow_length =
872             clib_host_to_net_u16(new_length);
873
874         /*
875          * Since we are working on the del record, set add record to 0
876          */
877         nfv9_logging_info->record[last_record] = 0;
878
879         nfv9_logging_info->record_length[last_record] = 0;
880
881         nfv9_logging_info->last_record = 0;
882     }
883
884     nfv9_logging_info->last_record = cur_record;
885
886     /*
887      * The padding bytes are required after the last record
888      * Ensure that we skip over the padding bytes
889      */
890     nfv9_logging_info->dataflow_header = (nfv9_dataflow_record_header_t *)
891         cnat_nfv9_add_end_of_record_padding(nfv9_logging_info->next_data_ptr);
892     /*
893      * Get the difference 
894      */       
895     byte_diff = cnat_nfv9_pad_added_to_an_addr(
896                         (u8 *)nfv9_logging_info->dataflow_header,
897                         nfv9_logging_info->next_data_ptr); 
898     if(byte_diff > 0) {
899         /*
900          * Update the packet length to account for the pad bytes
901          */
902         nfv9_logging_info->pkt_length += byte_diff;           
903         u8 *pkt_ptr =  nfv9_logging_info->next_data_ptr;
904
905         /*
906          * Blindly copy 3 bytes of data to Zero to avoid for loops
907          * We have sufficient padding bytes for safety and we won't
908          * go over buffer limits
909          */
910         *pkt_ptr++ =  0;
911         *pkt_ptr++ =  0;
912         *pkt_ptr++ =  0;
913     }
914     /*
915      * Initialize the template_id and the length of the add record
916      */
917     nfv9_logging_info->dataflow_header->dataflow_template_id =
918         clib_host_to_net_u16(cnat_template_id[cur_record]);
919
920     nfv9_logging_info->record[cur_record]  =
921         (u8 *) (nfv9_logging_info->dataflow_header + 1);
922
923     nfv9_logging_info->record_length[cur_record] =
924         CNAT_NFV9_DATAFLOW_RECORD_HEADER_LENGTH;
925
926     /*
927      * Update the length of the total NFV9 record
928      */
929     nfv9_logging_info->pkt_length +=
930     CNAT_NFV9_DATAFLOW_RECORD_HEADER_LENGTH;
931
932     /*
933      * Set the data pointer beyond the dataflow header field
934      */
935     nfv9_logging_info->next_data_ptr =
936         (u8 *) (nfv9_logging_info->dataflow_header + 1);
937
938 }
939
940 static void cnat_nfv9_insert_add_record(
941         cnat_nfv9_logging_info_t *nfv9_logging_info,
942         cnat_main_db_entry_t *db,
943         cnat_vrfmap_t *vrfmap)
944 {
945     u16 my_proto_mask;
946     u8 my_protocol;
947     nfv9_add_record_t nfv9_logging_add_record;
948     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_ADD_RECORD] == NULL)) {
949         cnat_nfv9_record_create(nfv9_logging_info, NAT44_ADD_RECORD);
950     }
951
952    /*
953     * We should definitely have add_record now, no need to sanitize
954     */
955
956     nfv9_logging_add_record.inside_vrf_id =
957         clib_host_to_net_u32(vrfmap->i_vrf_id);
958
959     nfv9_logging_add_record.outside_vrf_id =
960         clib_host_to_net_u32(vrfmap->o_vrf_id);
961
962     nfv9_logging_add_record.inside_ip_addr =
963         clib_host_to_net_u32(db->in2out_key.k.ipv4);
964     nfv9_logging_add_record.outside_ip_addr =
965         clib_host_to_net_u32(db->out2in_key.k.ipv4);
966
967     nfv9_logging_add_record.inside_ip_port =
968         clib_host_to_net_u16(db->in2out_key.k.port);
969     nfv9_logging_add_record.outside_ip_port =
970         clib_host_to_net_u16(db->out2in_key.k.port);
971
972     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
973     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
974                 ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
975                 ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
976
977     nfv9_logging_add_record.protocol = my_protocol;
978
979     memcpy(nfv9_logging_info->record[NAT44_ADD_RECORD], 
980             &nfv9_logging_add_record, CNAT_NFV9_ADD_RECORD_LENGTH);
981
982     nfv9_logging_info->record_length[NAT44_ADD_RECORD] 
983             += CNAT_NFV9_ADD_RECORD_LENGTH;
984
985     nfv9_logging_info->pkt_length += CNAT_NFV9_ADD_RECORD_LENGTH;
986
987     nfv9_logging_info->record[NAT44_ADD_RECORD] 
988                       += CNAT_NFV9_ADD_RECORD_LENGTH;
989     nfv9_logging_info->next_data_ptr = 
990                       nfv9_logging_info->record[NAT44_ADD_RECORD];
991
992     nfv9_logging_info->dataflow_header->dataflow_length =
993         clib_host_to_net_u32(
994         nfv9_logging_info->record_length[NAT44_ADD_RECORD]);
995
996 }
997
998
999 static void cnat_nfv9_ds_lite_insert_add_record(
1000         cnat_nfv9_logging_info_t *nfv9_logging_info,
1001         cnat_main_db_entry_t *db,
1002         dslite_table_entry_t *dslite_entry)
1003 {
1004
1005     nfv9_ds_lite_add_record_t   nfv9_logging_add_record = {0};
1006     cnat_user_db_entry_t        *udb = NULL;
1007     u16     my_proto_mask;
1008     u8      my_protocol;
1009
1010     udb = cnat_user_db + db->user_index; 
1011     if (PREDICT_FALSE(!udb)) {
1012         return;
1013     }
1014     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_ADD_RECORD] == NULL)) {
1015         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_ADD_RECORD);
1016     }
1017     /*
1018      * We should definitely have add_record now, no need to sanitize
1019      */
1020     nfv9_logging_add_record.inside_vrf_id =
1021                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
1022     nfv9_logging_add_record.outside_vrf_id = 
1023                     clib_host_to_net_u32(dslite_entry->o_vrf_id);
1024
1025 #ifdef DSLITE_USER_IPV4
1026     nfv9_logging_add_record.inside_ip_addr = 
1027                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
1028 #else
1029     /*
1030      * Inside ipv4 address is sent as 0.0.0.0 for ds-lite case as 
1031      * ipv6 is user here. 
1032      */
1033     nfv9_logging_add_record.inside_ip_addr = 0; 
1034 #endif
1035
1036     nfv9_logging_add_record.inside_v6_src_addr[0] = 
1037                     clib_host_to_net_u32(udb->ipv6[0]);
1038     nfv9_logging_add_record.inside_v6_src_addr[1] = 
1039                     clib_host_to_net_u32(udb->ipv6[1]);
1040     nfv9_logging_add_record.inside_v6_src_addr[2] = 
1041                     clib_host_to_net_u32(udb->ipv6[2]);
1042     nfv9_logging_add_record.inside_v6_src_addr[3] = 
1043                     clib_host_to_net_u32(udb->ipv6[3]);
1044
1045     nfv9_logging_add_record.outside_ip_addr = 
1046                     clib_host_to_net_u32(db->out2in_key.k.ipv4);
1047
1048     nfv9_logging_add_record.inside_ip_port = 
1049                     clib_host_to_net_u16(db->in2out_key.k.port);
1050     nfv9_logging_add_record.outside_ip_port = 
1051                     clib_host_to_net_u16(db->out2in_key.k.port);
1052
1053     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
1054
1055     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1056                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1057                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
1058     nfv9_logging_add_record.protocol = my_protocol;
1059
1060     memcpy(nfv9_logging_info->record[DS_LITE_ADD_RECORD], 
1061             &nfv9_logging_add_record, CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH);
1062
1063     nfv9_logging_info->record_length[DS_LITE_ADD_RECORD] 
1064                                   += CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH;
1065
1066     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH;
1067     nfv9_logging_info->total_record_count += 1;
1068
1069     nfv9_logging_info->record[DS_LITE_ADD_RECORD] 
1070                       += CNAT_NFV9_DS_LITE_ADD_RECORD_LENGTH;
1071     nfv9_logging_info->next_data_ptr = 
1072                          nfv9_logging_info->record[DS_LITE_ADD_RECORD];
1073
1074     nfv9_logging_info->dataflow_header->dataflow_length =
1075         clib_host_to_net_u32(
1076         nfv9_logging_info->record_length[DS_LITE_ADD_RECORD]);
1077 }
1078
1079
1080 static void cnat_nfv9_ds_lite_insert_del_record(
1081         cnat_nfv9_logging_info_t *nfv9_logging_info,
1082         cnat_main_db_entry_t *db,
1083         dslite_table_entry_t *dslite_entry)
1084 {
1085
1086     nfv9_ds_lite_del_record_t   nfv9_logging_del_record = {0};
1087     cnat_user_db_entry_t        *udb = NULL;
1088     u16     my_proto_mask;
1089     u8      my_protocol;
1090
1091     udb = cnat_user_db + db->user_index; 
1092     if (PREDICT_FALSE(!udb)) {
1093         return;
1094     }
1095     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_DEL_RECORD] == NULL)) {
1096         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_DEL_RECORD);
1097     }
1098     /*
1099      * We should definitely have a del record now.
1100      * No need to sanitize
1101      */
1102     nfv9_logging_del_record.inside_vrf_id = 
1103                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
1104
1105 #ifdef DSLITE_USER_IPV4
1106     nfv9_logging_del_record.inside_ip_addr = 
1107                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
1108 #else
1109     /*
1110      * Inside ipv4 address is sent as 0.0.0.0 for ds-lite case as 
1111      * ipv6 is user here. 
1112      */
1113     nfv9_logging_del_record.inside_ip_addr = 0;
1114 #endif
1115
1116     nfv9_logging_del_record.inside_v6_src_addr[0] = 
1117                     clib_host_to_net_u32(udb->ipv6[0]);
1118     nfv9_logging_del_record.inside_v6_src_addr[1] = 
1119                     clib_host_to_net_u32(udb->ipv6[1]);
1120     nfv9_logging_del_record.inside_v6_src_addr[2] = 
1121                     clib_host_to_net_u32(udb->ipv6[2]);
1122     nfv9_logging_del_record.inside_v6_src_addr[3] = 
1123                     clib_host_to_net_u32(udb->ipv6[3]);
1124
1125     nfv9_logging_del_record.inside_ip_port = 
1126                     clib_host_to_net_u16(db->in2out_key.k.port);
1127
1128     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
1129
1130     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1131                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1132                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
1133     nfv9_logging_del_record.protocol = my_protocol;
1134
1135     memcpy(nfv9_logging_info->record[DS_LITE_DEL_RECORD], 
1136             &nfv9_logging_del_record, CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH);
1137
1138     nfv9_logging_info->record_length[DS_LITE_DEL_RECORD] += 
1139                              CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH;
1140
1141     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH;
1142     nfv9_logging_info->total_record_count += 1;
1143
1144     nfv9_logging_info->record[DS_LITE_DEL_RECORD] 
1145                                 += CNAT_NFV9_DS_LITE_DEL_RECORD_LENGTH;
1146     nfv9_logging_info->next_data_ptr = 
1147             nfv9_logging_info->record[DS_LITE_DEL_RECORD];
1148
1149     nfv9_logging_info->dataflow_header->dataflow_length =
1150         clib_host_to_net_u32(
1151            nfv9_logging_info->record_length[DS_LITE_DEL_RECORD]);
1152 }
1153
1154 #ifndef NO_BULK_LOGGING
1155 static void cnat_nfv9_insert_bulk_add_record(
1156         cnat_nfv9_logging_info_t *nfv9_logging_info,
1157         cnat_main_db_entry_t *db,
1158         cnat_vrfmap_t *vrfmap,
1159         int bulk_alloc_start_port)
1160 {
1161     nfv9_bulk_add_record_t nfv9_logging_bulk_add_record;
1162     bulk_alloc_size_t bulk_size = BULKSIZE_FROM_VRFMAP(vrfmap);
1163     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_BULK_ADD_RECORD] == NULL)) {
1164         cnat_nfv9_record_create(nfv9_logging_info, NAT44_BULK_ADD_RECORD);
1165     }
1166
1167    /*
1168     * We should definitely have add_record now, no need to sanitize
1169     */
1170
1171     nfv9_logging_bulk_add_record.inside_vrf_id =
1172         clib_host_to_net_u32(vrfmap->i_vrf_id);
1173     nfv9_logging_bulk_add_record.outside_vrf_id =
1174         clib_host_to_net_u32(vrfmap->o_vrf_id);
1175
1176     nfv9_logging_bulk_add_record.inside_ip_addr =
1177         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1178     nfv9_logging_bulk_add_record.outside_ip_addr =
1179         clib_host_to_net_u32(db->out2in_key.k.ipv4);
1180
1181     nfv9_logging_bulk_add_record.outside_ip_port_start =
1182         clib_host_to_net_u16(bulk_alloc_start_port);
1183     nfv9_logging_bulk_add_record.outside_ip_port_end =
1184         clib_host_to_net_u16(bulk_alloc_start_port + bulk_size -1);
1185
1186     memcpy(nfv9_logging_info->record[NAT44_BULK_ADD_RECORD], 
1187             &nfv9_logging_bulk_add_record, CNAT_NFV9_BULK_ADD_RECORD_LENGTH);
1188
1189     nfv9_logging_info->record_length[NAT44_BULK_ADD_RECORD] 
1190             += CNAT_NFV9_BULK_ADD_RECORD_LENGTH;
1191
1192     nfv9_logging_info->pkt_length += CNAT_NFV9_BULK_ADD_RECORD_LENGTH;
1193
1194     nfv9_logging_info->record[NAT44_BULK_ADD_RECORD] 
1195                       += CNAT_NFV9_BULK_ADD_RECORD_LENGTH;
1196     nfv9_logging_info->next_data_ptr = 
1197                       nfv9_logging_info->record[NAT44_BULK_ADD_RECORD];
1198
1199     nfv9_logging_info->dataflow_header->dataflow_length =
1200         clib_host_to_net_u32(
1201         nfv9_logging_info->record_length[NAT44_BULK_ADD_RECORD]);
1202
1203 }
1204
1205
1206 static void cnat_nfv9_ds_lite_insert_bulk_add_record(
1207         cnat_nfv9_logging_info_t *nfv9_logging_info,
1208         cnat_main_db_entry_t *db,
1209         dslite_table_entry_t *dslite_entry,
1210         int bulk_alloc_start_port)
1211 {
1212
1213     nfv9_ds_lite_bulk_add_record_t  nfv9_logging_bulk_add_record = {0};
1214     cnat_user_db_entry_t            *udb = NULL;
1215     bulk_alloc_size_t               bulk_size = BULKSIZE_FROM_VRFMAP(dslite_entry);
1216
1217     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD] == NULL)) {
1218         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_BULK_ADD_RECORD);
1219     }
1220     udb = cnat_user_db + db->user_index; 
1221     if (PREDICT_FALSE(!udb)) {
1222         return;
1223     }
1224     /*
1225      * We should definitely have add_record now, no need to sanitize
1226      */
1227
1228     nfv9_logging_bulk_add_record.inside_vrf_id =
1229         clib_host_to_net_u32(dslite_entry->i_vrf_id);
1230     nfv9_logging_bulk_add_record.outside_vrf_id =
1231         clib_host_to_net_u32(dslite_entry->o_vrf_id);
1232
1233 #ifdef DSLITE_USER_IPV4
1234     nfv9_logging_bulk_add_record.inside_ip_addr =
1235         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1236 #else
1237     /*
1238      * Inside ipv4 address is sent as 0.0.0.0 for ds-lite case as 
1239      * ipv6 is user here. 
1240      */
1241     nfv9_logging_bulk_add_record.inside_ip_addr = 0;
1242 #endif
1243
1244     nfv9_logging_bulk_add_record.inside_v6_src_addr[0] = 
1245                     clib_host_to_net_u32(udb->ipv6[0]);
1246     nfv9_logging_bulk_add_record.inside_v6_src_addr[1] = 
1247                     clib_host_to_net_u32(udb->ipv6[1]);
1248     nfv9_logging_bulk_add_record.inside_v6_src_addr[2] = 
1249                     clib_host_to_net_u32(udb->ipv6[2]);
1250     nfv9_logging_bulk_add_record.inside_v6_src_addr[3] = 
1251                     clib_host_to_net_u32(udb->ipv6[3]);
1252
1253     nfv9_logging_bulk_add_record.outside_ip_addr =
1254         clib_host_to_net_u32(db->out2in_key.k.ipv4);
1255
1256     nfv9_logging_bulk_add_record.outside_ip_port_start =
1257         clib_host_to_net_u16(bulk_alloc_start_port);
1258     nfv9_logging_bulk_add_record.outside_ip_port_end =
1259         clib_host_to_net_u16(bulk_alloc_start_port + bulk_size -1);
1260
1261     memcpy(nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD], 
1262             &nfv9_logging_bulk_add_record, CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH);
1263
1264     nfv9_logging_info->record_length[DS_LITE_BULK_ADD_RECORD] 
1265             += CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH;
1266
1267     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH;
1268     nfv9_logging_info->total_record_count += 1;
1269     nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD] 
1270                       += CNAT_NFV9_DS_LITE_BULK_ADD_RECORD_LENGTH;
1271     nfv9_logging_info->next_data_ptr = 
1272                       nfv9_logging_info->record[DS_LITE_BULK_ADD_RECORD];
1273     nfv9_logging_info->dataflow_header->dataflow_length =
1274         clib_host_to_net_u32(
1275         nfv9_logging_info->record_length[DS_LITE_BULK_ADD_RECORD]);
1276 }
1277
1278
1279 static void cnat_nfv9_ds_lite_insert_bulk_del_record(
1280         cnat_nfv9_logging_info_t *nfv9_logging_info,
1281         cnat_main_db_entry_t *db,
1282         dslite_table_entry_t *dslite_entry,
1283         int bulk_alloc_start_port)
1284 {
1285
1286     nfv9_ds_lite_bulk_del_record_t nfv9_logging_bulk_del_record = {0};
1287     cnat_user_db_entry_t           *udb = NULL;
1288
1289     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD] == NULL)) {
1290         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_BULK_DEL_RECORD);
1291     }
1292     udb = cnat_user_db + db->user_index; 
1293     if (PREDICT_FALSE(!udb)) {
1294         return;
1295     }
1296     /*
1297      * We should definitely have add_record now, no need to sanitize
1298      */
1299
1300     nfv9_logging_bulk_del_record.inside_vrf_id =
1301         clib_host_to_net_u32(dslite_entry->i_vrf_id);
1302
1303 #ifdef DSLITE_USER_IPV4
1304     nfv9_logging_bulk_del_record.inside_ip_addr =
1305         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1306 #else
1307     nfv9_logging_bulk_del_record.inside_ip_addr =
1308         clib_host_to_net_u32(0);
1309 #endif
1310
1311     nfv9_logging_bulk_del_record.inside_v6_src_addr[0] = 
1312         clib_host_to_net_u32(udb->ipv6[0]);
1313     nfv9_logging_bulk_del_record.inside_v6_src_addr[1] = 
1314         clib_host_to_net_u32(udb->ipv6[1]);
1315     nfv9_logging_bulk_del_record.inside_v6_src_addr[2] = 
1316         clib_host_to_net_u32(udb->ipv6[2]);
1317     nfv9_logging_bulk_del_record.inside_v6_src_addr[3] = 
1318         clib_host_to_net_u32(udb->ipv6[3]);
1319
1320     nfv9_logging_bulk_del_record.outside_ip_port_start =
1321         clib_host_to_net_u16(bulk_alloc_start_port);
1322
1323     memcpy(nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD], 
1324         &nfv9_logging_bulk_del_record, 
1325         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH);
1326     nfv9_logging_info->record_length[DS_LITE_BULK_DEL_RECORD] += 
1327         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH;
1328     nfv9_logging_info->pkt_length += 
1329         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH;
1330     nfv9_logging_info->total_record_count += 1;
1331     nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD] += 
1332         CNAT_NFV9_DS_LITE_BULK_DEL_RECORD_LENGTH;
1333     nfv9_logging_info->next_data_ptr = 
1334         nfv9_logging_info->record[DS_LITE_BULK_DEL_RECORD];
1335     nfv9_logging_info->dataflow_header->dataflow_length =
1336         clib_host_to_net_u32(
1337         nfv9_logging_info->record_length[DS_LITE_BULK_DEL_RECORD]);
1338 }
1339 #endif /* #ifndef NO_BULK_LOGGING */
1340
1341 static void cnat_nfv9_insert_del_record(
1342         cnat_nfv9_logging_info_t *nfv9_logging_info,
1343         cnat_main_db_entry_t *db,
1344         cnat_vrfmap_t *vrfmap)
1345 {
1346     u16 my_proto_mask;
1347     u8 my_protocol;
1348     nfv9_del_record_t nfv9_logging_del_record;
1349
1350     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_DEL_RECORD] == NULL)) {
1351         cnat_nfv9_record_create(nfv9_logging_info, NAT44_DEL_RECORD);
1352     }
1353
1354    /*
1355     * We should definitely have add_record now, no need to sanitize
1356     */
1357
1358     nfv9_logging_del_record.inside_vrf_id =
1359         clib_host_to_net_u32(vrfmap->i_vrf_id);
1360
1361     nfv9_logging_del_record.inside_ip_addr =
1362         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1363
1364     nfv9_logging_del_record.inside_ip_port =
1365         clib_host_to_net_u16(db->in2out_key.k.port);
1366
1367     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
1368     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1369                 ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1370                 ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
1371
1372     nfv9_logging_del_record.protocol = my_protocol;
1373
1374     memcpy(nfv9_logging_info->record[NAT44_DEL_RECORD], 
1375             &nfv9_logging_del_record, CNAT_NFV9_DEL_RECORD_LENGTH);
1376
1377     nfv9_logging_info->record_length[NAT44_DEL_RECORD] 
1378             += CNAT_NFV9_DEL_RECORD_LENGTH;
1379
1380     nfv9_logging_info->pkt_length += CNAT_NFV9_DEL_RECORD_LENGTH;
1381
1382     nfv9_logging_info->record[NAT44_DEL_RECORD] 
1383                       += CNAT_NFV9_DEL_RECORD_LENGTH;
1384     nfv9_logging_info->next_data_ptr = 
1385                       nfv9_logging_info->record[NAT44_DEL_RECORD];
1386
1387     nfv9_logging_info->dataflow_header->dataflow_length =
1388         clib_host_to_net_u32(
1389         nfv9_logging_info->record_length[NAT44_DEL_RECORD]);
1390
1391 }
1392
1393 #ifndef NO_BULK_LOGGING
1394 static void cnat_nfv9_insert_bulk_del_record(
1395         cnat_nfv9_logging_info_t *nfv9_logging_info,
1396         cnat_main_db_entry_t *db,
1397         cnat_vrfmap_t *vrfmap,
1398         int bulk_alloc_start_port)
1399 {
1400     nfv9_bulk_del_record_t nfv9_logging_bulk_del_record;
1401     if (PREDICT_FALSE(nfv9_logging_info->record[NAT44_BULK_DEL_RECORD] == NULL)) {
1402         cnat_nfv9_record_create(nfv9_logging_info, NAT44_BULK_DEL_RECORD);
1403     }
1404
1405    /*
1406     * We should definitely have add_record now, no need to sanitize
1407     */
1408
1409     nfv9_logging_bulk_del_record.inside_vrf_id =
1410         clib_host_to_net_u32(vrfmap->i_vrf_id);
1411
1412     nfv9_logging_bulk_del_record.inside_ip_addr =
1413         clib_host_to_net_u32(db->in2out_key.k.ipv4);
1414
1415     nfv9_logging_bulk_del_record.outside_ip_port_start =
1416         clib_host_to_net_u16(bulk_alloc_start_port);
1417
1418     memcpy(nfv9_logging_info->record[NAT44_BULK_DEL_RECORD], 
1419             &nfv9_logging_bulk_del_record, CNAT_NFV9_BULK_DEL_RECORD_LENGTH);
1420
1421     nfv9_logging_info->record_length[NAT44_BULK_DEL_RECORD] 
1422             += CNAT_NFV9_BULK_DEL_RECORD_LENGTH;
1423
1424     nfv9_logging_info->pkt_length += CNAT_NFV9_BULK_DEL_RECORD_LENGTH;
1425
1426     nfv9_logging_info->record[NAT44_BULK_DEL_RECORD] 
1427                       += CNAT_NFV9_BULK_DEL_RECORD_LENGTH;
1428     nfv9_logging_info->next_data_ptr = 
1429                       nfv9_logging_info->record[NAT44_BULK_DEL_RECORD];
1430
1431     nfv9_logging_info->dataflow_header->dataflow_length =
1432         clib_host_to_net_u32(
1433         nfv9_logging_info->record_length[NAT44_BULK_DEL_RECORD]);
1434
1435 }
1436
1437 #endif /* #ifndef NO_BULK_LOGGING */
1438 /*
1439  * edt: * * cnat_nfv9_log_mapping_create
1440  *
1441  * Tries to log a creation of mapping record
1442  *
1443  * Argument: cnat_main_db_entry_t *db
1444  * Main DB entry being created
1445  *
1446  * Argument: cnat_vrfmap_t *vrfmap
1447  * VRF Map for the Main DB entry being created
1448  */
1449 void cnat_nfv9_log_mapping_create (cnat_main_db_entry_t *db,
1450                                    cnat_vrfmap_t *vrfmap
1451 #ifndef NO_BULK_LOGGING
1452                        , int bulk_alloc
1453 #endif
1454                        )
1455 {
1456     cnat_nfv9_logging_info_t *nfv9_logging_info = 0; 
1457     vlib_main_t * vm = vlib_get_main();
1458
1459     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
1460
1461         //vlib_cli_output(vm, "\n1. Log Mapping failed");
1462         /*
1463          * No logging configured, silently return
1464          */
1465         return;
1466     }
1467
1468     if (cnat_nfv9_logging_info_pool == NULL) {
1469         vlib_cli_output(vm, "%s: info_pool pointer is NULL !!!!\n", __func__);
1470         return;
1471     }
1472     nfv9_logging_info = 
1473         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
1474
1475     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1476         cnat_nfv9_create_logging_context(nfv9_logging_info,
1477                                          cnat_nfv9_template_add_default);
1478
1479         /*
1480          * If still empty, return after increasing the count
1481          */
1482         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1483             //vlib_cli_output(vm, "\n2. Log Mapping failed");
1484             return;
1485         }
1486         
1487     }
1488
1489 #ifndef NO_BULK_LOGGING
1490     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
1491         cnat_nfv9_insert_bulk_add_record(nfv9_logging_info, db, vrfmap,
1492             bulk_alloc);
1493     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
1494         return; /* No logging required.. bulk port usage */
1495     else /* Individual logging .. fall back to old method */
1496 #endif
1497     cnat_nfv9_insert_add_record(nfv9_logging_info, db, vrfmap);
1498
1499     nfv9_logging_info->total_record_count += 1;
1500
1501     /*
1502      * If we have exceeded the packet length, let us send the
1503      * packet now.  There is buffer of additional bytes beyond
1504      * max_pkt_length to ensure that the last add/delete record
1505      * can be stored safely.
1506      */
1507     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
1508             nfv9_logging_info->max_length_minus_max_record_size)) {
1509             cnat_nfv9_send_pkt(nfv9_logging_info);
1510     }
1511 }
1512
1513 /*
1514  * edt: * * cnat_nfv9_log_mapping_delete
1515  *
1516  * Tries to log a deletion of mapping record
1517  *
1518  * Argument: cnat_main_db_entry_t *db
1519  * Main DB entry being deleted
1520  *
1521  * Argument: cnat_vrfmap_t *vrfmap
1522  * VRF Map for the Main DB entry being deleted
1523  */
1524 void cnat_nfv9_log_mapping_delete (cnat_main_db_entry_t * db,
1525                               cnat_vrfmap_t *vrfmap
1526 #ifndef NO_BULK_LOGGING
1527                               , int bulk_alloc
1528 #endif
1529                               )
1530 {
1531     cnat_nfv9_logging_info_t *nfv9_logging_info = 0; 
1532
1533     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
1534         //vlib_cli_output(vm, "\n3. Log Mapping failed");
1535         /*
1536          * No logging configured, silently return
1537          */
1538         return;
1539     }
1540
1541     nfv9_logging_info = 
1542         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
1543
1544     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1545         cnat_nfv9_create_logging_context(nfv9_logging_info,
1546                                          cnat_nfv9_template_add_default);
1547
1548         /*
1549          * If still empty, return after increasing the count
1550          */
1551         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1552             //vlib_cli_output(vm, "\n4. Log Mapping failed");
1553             return;
1554         }
1555     }
1556 #ifndef NO_BULK_LOGGING
1557     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
1558         cnat_nfv9_insert_bulk_del_record(nfv9_logging_info, db, vrfmap,
1559             bulk_alloc);
1560     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
1561         return; /* No logging required.. bulk port usage */
1562     else /* Individual logging .. fall back to old method */
1563 #endif
1564     cnat_nfv9_insert_del_record(nfv9_logging_info, db, vrfmap);
1565
1566     nfv9_logging_info->total_record_count += 1;
1567
1568     /*
1569      * If we have exceeded the packet length, let us send the
1570      * packet now.  There is buffer of additional bytes beyond
1571      * max_pkt_length to ensure that the last add/delete record
1572      * can be stored safely.
1573      */
1574     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
1575         nfv9_logging_info->max_length_minus_max_record_size)) {
1576             cnat_nfv9_send_pkt(nfv9_logging_info);
1577     }
1578 }
1579
1580
1581 /* NAT64 Related routines */
1582
1583 /*
1584  * edt: * * cnat_nfv9_bib_mapping_create
1585  *
1586  * Tries to log a creation of Bib mapping record
1587  *
1588  * Argument: nat64_bib_entry_t *db
1589  * BIB DB entry being created
1590  *
1591  * Argument: nat64_table_entry_t *nat64_entry
1592  * NAT64 Instance where this BIB belongs 
1593  */
1594 void cnat_nfv9_bib_mapping_create (nat64_bib_entry_t *db,
1595                        nat64_table_entry_t *nat64_entry)
1596 {
1597     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1598     u16 my_proto_mask;
1599     u8 my_protocol;
1600     nfv9_nat64_add_bib_record_t nfv9_logging_add_record;
1601
1602     if (PREDICT_FALSE(nat64_entry->logging_index == EMPTY)) {
1603         /*
1604          * No logging configured, silently return
1605          */
1606         return;
1607     }
1608
1609     nfv9_logging_info =
1610         cnat_nfv9_logging_info_pool + nat64_entry->logging_index;
1611
1612
1613     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1614         cnat_nfv9_create_logging_context(nfv9_logging_info,
1615                                         cnat_nfv9_template_add_default);
1616
1617         /*
1618          * If still empty, return after increasing the count
1619          */
1620         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1621             return;
1622         }
1623     }
1624
1625     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_ADD_BIB_RECORD] == NULL)){
1626         cnat_nfv9_record_create(nfv9_logging_info,NAT64_ADD_BIB_RECORD);
1627     }
1628
1629
1630     nfv9_logging_add_record.inside_v6_src_addr[0] = 
1631             clib_host_to_net_u32(db->v6_in_key.ipv6[0]);
1632     nfv9_logging_add_record.inside_v6_src_addr[1] = 
1633             clib_host_to_net_u32(db->v6_in_key.ipv6[1]);
1634     nfv9_logging_add_record.inside_v6_src_addr[2] = 
1635             clib_host_to_net_u32(db->v6_in_key.ipv6[2]);
1636     nfv9_logging_add_record.inside_v6_src_addr[3] = 
1637             clib_host_to_net_u32(db->v6_in_key.ipv6[3]);
1638
1639
1640     nfv9_logging_add_record.outside_v4_src_addr =
1641             clib_host_to_net_u32(db->v4_out_key.k.ipv4);
1642
1643     nfv9_logging_add_record.inside_src_port =
1644             clib_host_to_net_u16(db->v6_in_key.port);
1645     nfv9_logging_add_record.outside_src_port =
1646             clib_host_to_net_u16(db->v4_out_key.k.port);
1647
1648     my_proto_mask = db->v6_in_key.vrf & CNAT_PRO_MASK;
1649
1650     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1651            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1652            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
1653     nfv9_logging_add_record.protocol = my_protocol;
1654
1655
1656     memcpy(nfv9_logging_info->record[NAT64_ADD_BIB_RECORD], 
1657             &nfv9_logging_add_record, CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH);
1658
1659     nfv9_logging_info->record_length[NAT64_ADD_BIB_RECORD] += 
1660                          CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH;
1661     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH;
1662     nfv9_logging_info->total_record_count += 1;
1663
1664     nfv9_logging_info->record[NAT64_ADD_BIB_RECORD] 
1665                            += CNAT_NFV9_NAT64_ADD_BIB_RECORD_LENGTH;
1666
1667     nfv9_logging_info->next_data_ptr = 
1668                       nfv9_logging_info->record[NAT64_ADD_BIB_RECORD];
1669
1670     nfv9_logging_info->dataflow_header->dataflow_length =
1671     clib_host_to_net_u32(
1672             nfv9_logging_info->record_length[NAT64_ADD_BIB_RECORD]);
1673
1674     /*
1675      * If we have exceeded the packet length, let us send the
1676      * packet now.  There is buffer of additional bytes beyond
1677      * max_pkt_length to ensure that the last add/delete record
1678      * can be stored safely.
1679      */
1680     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
1681         nfv9_logging_info->max_length_minus_max_record_size)) {
1682         cnat_nfv9_send_pkt(nfv9_logging_info);
1683     }
1684 }
1685
1686
1687 /*
1688  * edt: * * cnat_nfv9_session_mapping_create
1689  *
1690  * Tries to log a creation of Bib mapping record
1691  *
1692  * Argument: nat64_bib_entry_t *bdb
1693  * BIB DB entry for the session that is created
1694  *
1695  * Argument: nat64_session_entry_t *sdb
1696  * Session DB entry being created
1697  * 
1698  * Argument: nat64_table_entry_t *nat64_entry
1699  * NAT64 Instance where this BIB and Session belongs 
1700  */
1701 void cnat_nfv9_session_mapping_create (nat64_bib_entry_t *bdb,
1702                        nat64_session_entry_t *sdb,
1703                        nat64_table_entry_t *nat64_entry_ptr)
1704 {
1705     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1706     u16 my_proto_mask;
1707     u8 my_protocol;
1708     u32 dest_v6[4];
1709     nfv9_nat64_add_session_record_t nfv9_logging_add_record;
1710     u8            *ipv6_addr_ptr;
1711     u8            *ipv4_addr_ptr;
1712
1713
1714     if (PREDICT_FALSE(nat64_entry_ptr->logging_index == EMPTY)) {
1715         /*
1716          * No logging configured, silently return
1717          */
1718         return;
1719     }
1720
1721     nfv9_logging_info =
1722         cnat_nfv9_logging_info_pool + nat64_entry_ptr->logging_index;
1723
1724
1725     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1726         cnat_nfv9_create_logging_context(nfv9_logging_info,
1727                                         cnat_nfv9_template_add_default);
1728
1729         /*
1730          * If still empty, return after increasing the count
1731          */
1732         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)){
1733             return;
1734         }
1735     }
1736
1737     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD] 
1738                                                   == NULL)){
1739         cnat_nfv9_record_create(nfv9_logging_info, NAT64_ADD_SESSION_RECORD);
1740     }
1741
1742
1743     nfv9_logging_add_record.inside_v6_src_addr[0] =
1744             clib_host_to_net_u32(bdb->v6_in_key.ipv6[0]);
1745     nfv9_logging_add_record.inside_v6_src_addr[1] =
1746             clib_host_to_net_u32(bdb->v6_in_key.ipv6[1]);
1747     nfv9_logging_add_record.inside_v6_src_addr[2] =
1748             clib_host_to_net_u32(bdb->v6_in_key.ipv6[2]);
1749     nfv9_logging_add_record.inside_v6_src_addr[3] =
1750             clib_host_to_net_u32(bdb->v6_in_key.ipv6[3]);
1751
1752
1753     nfv9_logging_add_record.outside_v4_src_addr =
1754             clib_host_to_net_u32(bdb->v4_out_key.k.ipv4);
1755
1756
1757     nfv9_logging_add_record.outside_v4_dest_addr =
1758           clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
1759
1760     /* Need to create the V6 address using prefix */
1761     dest_v6[0] = nat64_entry_ptr->v6_prefix[0];
1762     dest_v6[1] = nat64_entry_ptr->v6_prefix[1];
1763     dest_v6[2] = nat64_entry_ptr->v6_prefix[2];
1764     dest_v6[3] = nat64_entry_ptr->v6_prefix[3];
1765
1766     ipv6_addr_ptr = (u8 *) (&(dest_v6[0]));
1767     ipv4_addr_ptr = (u8 *) (&(sdb->v4_dest_key.k.ipv4));
1768
1769     *(ipv6_addr_ptr + nat64_entry_ptr->octet0_position) = *(ipv4_addr_ptr);
1770     *(ipv6_addr_ptr + nat64_entry_ptr->octet1_position) = *(ipv4_addr_ptr + 1);
1771     *(ipv6_addr_ptr + nat64_entry_ptr->octet2_position) = *(ipv4_addr_ptr + 2);
1772     *(ipv6_addr_ptr + nat64_entry_ptr->octet3_position) = *(ipv4_addr_ptr + 3);
1773
1774     nfv9_logging_add_record.inside_v6_dest_addr[0] =
1775           clib_host_to_net_u32(dest_v6[0]);
1776     nfv9_logging_add_record.inside_v6_dest_addr[1] =
1777           clib_host_to_net_u32(dest_v6[1]);
1778     nfv9_logging_add_record.inside_v6_dest_addr[2] =
1779           clib_host_to_net_u32(dest_v6[2]);
1780     nfv9_logging_add_record.inside_v6_dest_addr[3] =
1781           clib_host_to_net_u32(dest_v6[3]);
1782
1783     nfv9_logging_add_record.outside_v4_dest_addr =
1784           clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
1785
1786     nfv9_logging_add_record.inside_src_port =
1787             clib_host_to_net_u16(bdb->v6_in_key.port);
1788     nfv9_logging_add_record.outside_src_port =
1789             clib_host_to_net_u16(bdb->v4_out_key.k.port);
1790
1791     nfv9_logging_add_record.dest_port =
1792             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
1793
1794
1795     my_proto_mask = bdb->v6_in_key.vrf & CNAT_PRO_MASK;
1796
1797     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1798            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1799            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
1800     nfv9_logging_add_record.protocol = my_protocol;
1801
1802
1803     memcpy(nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD],
1804        &nfv9_logging_add_record, CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH);
1805
1806     nfv9_logging_info->record_length[NAT64_ADD_SESSION_RECORD] +=
1807                          CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH;
1808     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH;
1809     nfv9_logging_info->total_record_count += 1;
1810
1811     nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD]
1812                            += CNAT_NFV9_NAT64_ADD_SESSION_RECORD_LENGTH;
1813
1814     nfv9_logging_info->next_data_ptr =
1815                       nfv9_logging_info->record[NAT64_ADD_SESSION_RECORD];
1816
1817     nfv9_logging_info->dataflow_header->dataflow_length =
1818     clib_host_to_net_u32(
1819             nfv9_logging_info->record_length[NAT64_ADD_SESSION_RECORD]);
1820
1821     /*
1822      * If we have exceeded the packet length, let us send the
1823      * packet now.  There is buffer of additional bytes beyond
1824      * max_pkt_length to ensure that the last add/delete record
1825      * can be stored safely.
1826      */
1827     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
1828         nfv9_logging_info->max_length_minus_max_record_size)) {
1829         cnat_nfv9_send_pkt(nfv9_logging_info);
1830     }
1831 }
1832
1833
1834 /*
1835  * edt: * * cnat_nfv9_bib_mapping_delete
1836  *
1837  * Tries to log a deletion of Bib mapping record
1838  *
1839  * Argument: nat64_bib_entry_t *db
1840  * BIB DB entry being created
1841  *
1842  * Argument: nat64_table_entry_t *nat64_entry
1843  * NAT64 Instance where this BIB belongs 
1844  */
1845 void cnat_nfv9_bib_mapping_delete (nat64_bib_entry_t *db,
1846                        nat64_table_entry_t *nat64_entry)
1847 {
1848     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1849     u16 my_proto_mask;
1850     u8 my_protocol;
1851     nfv9_nat64_del_bib_record_t nfv9_logging_del_record;
1852     if (PREDICT_FALSE(nat64_entry->logging_index == EMPTY)) {
1853         /*
1854          * No logging configured, silently return
1855          */
1856         return;
1857     }
1858
1859     nfv9_logging_info =
1860         cnat_nfv9_logging_info_pool + nat64_entry->logging_index;
1861
1862
1863     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1864         cnat_nfv9_create_logging_context(nfv9_logging_info,
1865                                          cnat_nfv9_template_add_default);
1866
1867         /*
1868          * If still empty, return after increasing the count
1869          */
1870         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)){
1871             return;
1872         }
1873     }
1874
1875     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_DEL_BIB_RECORD] == NULL)){
1876         cnat_nfv9_record_create(nfv9_logging_info,NAT64_DEL_BIB_RECORD);
1877     }
1878
1879
1880     nfv9_logging_del_record.inside_v6_src_addr[0] =
1881             clib_host_to_net_u32(db->v6_in_key.ipv6[0]);
1882     nfv9_logging_del_record.inside_v6_src_addr[1] =
1883             clib_host_to_net_u32(db->v6_in_key.ipv6[1]);
1884     nfv9_logging_del_record.inside_v6_src_addr[2] =
1885             clib_host_to_net_u32(db->v6_in_key.ipv6[2]);
1886     nfv9_logging_del_record.inside_v6_src_addr[3] =
1887             clib_host_to_net_u32(db->v6_in_key.ipv6[3]);
1888
1889
1890     nfv9_logging_del_record.inside_src_port =
1891             clib_host_to_net_u16(db->v6_in_key.port);
1892
1893     my_proto_mask = db->v6_in_key.vrf & CNAT_PRO_MASK;
1894
1895     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
1896            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
1897            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
1898     nfv9_logging_del_record.protocol = my_protocol;
1899
1900
1901     memcpy(nfv9_logging_info->record[NAT64_DEL_BIB_RECORD],
1902             &nfv9_logging_del_record, CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH);
1903
1904     nfv9_logging_info->record_length[NAT64_DEL_BIB_RECORD] +=
1905                          CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH;
1906     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH;
1907     nfv9_logging_info->total_record_count += 1;
1908
1909     nfv9_logging_info->record[NAT64_DEL_BIB_RECORD]
1910                            += CNAT_NFV9_NAT64_DEL_BIB_RECORD_LENGTH;
1911
1912     nfv9_logging_info->next_data_ptr =
1913                       nfv9_logging_info->record[NAT64_DEL_BIB_RECORD];
1914
1915     nfv9_logging_info->dataflow_header->dataflow_length =
1916     clib_host_to_net_u32(
1917             nfv9_logging_info->record_length[NAT64_DEL_BIB_RECORD]);
1918
1919     /*
1920      * If we have exceeded the packet length, let us send the
1921      * packet now.  There is buffer of additional bytes beyond
1922      * max_pkt_length to ensure that the last add/delete record
1923      * can be stored safely.
1924      */
1925     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
1926         nfv9_logging_info->max_length_minus_max_record_size)) {
1927         cnat_nfv9_send_pkt(nfv9_logging_info);
1928     }
1929 }
1930
1931
1932 /*
1933  * edt: * * cnat_nfv9_session_mapping_delete
1934  *
1935  * Tries to log a deletion of Bib mapping record
1936  *
1937  * Argument: nat64_bib_entry_t *bdb
1938  * BIB DB entry for the session that is created
1939  *
1940  * Argument: nat64_session_entry_t *sdb
1941  * Session DB entry being created
1942  * 
1943  * Argument: nat64_table_entry_t *nat64_entry
1944  * NAT64 Instance where this BIB and Session belongs 
1945  */
1946 void cnat_nfv9_session_mapping_delete (nat64_bib_entry_t *bdb,
1947                        nat64_session_entry_t *sdb,
1948                        nat64_table_entry_t *nat64_entry_ptr)
1949 {
1950     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
1951     u16 my_proto_mask;
1952     u8 my_protocol;
1953     u32 dest_v6[4];
1954     nfv9_nat64_del_session_record_t nfv9_logging_del_record;
1955     u8            *ipv6_addr_ptr;
1956     u8            *ipv4_addr_ptr;
1957
1958     if (PREDICT_FALSE(nat64_entry_ptr->logging_index == EMPTY)) {
1959         /*
1960          * No logging configured, silently return
1961          */
1962         return;
1963     }
1964
1965     nfv9_logging_info =
1966         cnat_nfv9_logging_info_pool + nat64_entry_ptr->logging_index;
1967
1968
1969     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
1970         cnat_nfv9_create_logging_context(nfv9_logging_info,
1971                                         cnat_nfv9_template_add_default);
1972
1973         /*
1974          * If still empty, return after increasing the count
1975          */
1976         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)){
1977             return;
1978         }
1979     }
1980
1981     if (PREDICT_FALSE(nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD]
1982                                                   == NULL)){
1983         cnat_nfv9_record_create(nfv9_logging_info, NAT64_DEL_SESSION_RECORD);
1984     }
1985
1986
1987     nfv9_logging_del_record.inside_v6_src_addr[0] =
1988             clib_host_to_net_u32(bdb->v6_in_key.ipv6[0]);
1989     nfv9_logging_del_record.inside_v6_src_addr[1] =
1990             clib_host_to_net_u32(bdb->v6_in_key.ipv6[1]);
1991     nfv9_logging_del_record.inside_v6_src_addr[2] =
1992             clib_host_to_net_u32(bdb->v6_in_key.ipv6[2]);
1993     nfv9_logging_del_record.inside_v6_src_addr[3] =
1994             clib_host_to_net_u32(bdb->v6_in_key.ipv6[3]);
1995
1996     /* Need to create the V6 address using prefix */
1997     dest_v6[0] = nat64_entry_ptr->v6_prefix[0];
1998     dest_v6[1] = nat64_entry_ptr->v6_prefix[1];
1999     dest_v6[2] = nat64_entry_ptr->v6_prefix[2];
2000     dest_v6[3] = nat64_entry_ptr->v6_prefix[3];
2001
2002     ipv6_addr_ptr = (u8 *) (&(dest_v6[0]));
2003     ipv4_addr_ptr = (u8 *) (&(sdb->v4_dest_key.k.ipv4));
2004
2005     *(ipv6_addr_ptr + nat64_entry_ptr->octet0_position) = *(ipv4_addr_ptr);
2006     *(ipv6_addr_ptr + nat64_entry_ptr->octet1_position) = *(ipv4_addr_ptr + 1);
2007     *(ipv6_addr_ptr + nat64_entry_ptr->octet2_position) = *(ipv4_addr_ptr + 2);
2008     *(ipv6_addr_ptr + nat64_entry_ptr->octet3_position) = *(ipv4_addr_ptr + 3);
2009
2010     nfv9_logging_del_record.inside_v6_dest_addr[0] =
2011           clib_host_to_net_u32(dest_v6[0]);
2012     nfv9_logging_del_record.inside_v6_dest_addr[1] =
2013           clib_host_to_net_u32(dest_v6[1]);
2014     nfv9_logging_del_record.inside_v6_dest_addr[2] =
2015           clib_host_to_net_u32(dest_v6[2]);
2016     nfv9_logging_del_record.inside_v6_dest_addr[3] =
2017           clib_host_to_net_u32(dest_v6[3]);
2018
2019     nfv9_logging_del_record.inside_src_port =
2020             clib_host_to_net_u16(bdb->v6_in_key.port);
2021
2022     nfv9_logging_del_record.dest_port =
2023             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2024
2025
2026     my_proto_mask = bdb->v6_in_key.vrf & CNAT_PRO_MASK;
2027
2028     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2029            ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2030            ((my_proto_mask == CNAT_ICMP) ? IPV6_PROTO_ICMPV6 : 0)));
2031     nfv9_logging_del_record.protocol = my_protocol;
2032
2033     memcpy(nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD],
2034        &nfv9_logging_del_record, CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH);
2035
2036     nfv9_logging_info->record_length[NAT64_DEL_SESSION_RECORD] +=
2037                          CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH;
2038     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH;
2039     nfv9_logging_info->total_record_count += 1;
2040
2041     nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD]
2042                            += CNAT_NFV9_NAT64_DEL_SESSION_RECORD_LENGTH;
2043
2044     nfv9_logging_info->next_data_ptr =
2045                       nfv9_logging_info->record[NAT64_DEL_SESSION_RECORD];
2046
2047     nfv9_logging_info->dataflow_header->dataflow_length =
2048     clib_host_to_net_u32(
2049             nfv9_logging_info->record_length[NAT64_DEL_SESSION_RECORD]);
2050
2051     /*
2052      * If we have exceeded the packet length, let us send the
2053      * packet now.  There is buffer of additional bytes beyond
2054      * max_pkt_length to ensure that the last add/delete record
2055      * can be stored safely.
2056      */
2057     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2058         nfv9_logging_info->max_length_minus_max_record_size)) {
2059         cnat_nfv9_send_pkt(nfv9_logging_info);
2060     }
2061 }
2062
2063 /*
2064  * edt: * * cnat_nfv9_nat44_log_session_create
2065  *
2066  * Tries to log a creation of mapping record (session based)
2067  *
2068  * Argument: cnat_main_db_entry_t *db
2069  * Main DB entry being created
2070  * Arugment: cnat_session_entry_t *sdb
2071  * Session DB entry if the destination is not the first dest
2072  * Argument: cnat_vrfmap_t *vrfmap
2073  * VRF Map for the Main DB entry being created
2074  */
2075
2076 void cnat_nfv9_nat44_log_session_create(cnat_main_db_entry_t *db,
2077                 cnat_session_entry_t *sdb,
2078                 cnat_vrfmap_t *vrfmap)
2079 {
2080     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
2081     u16 my_proto_mask;
2082     u8 my_protocol;
2083     nfv9_add_session_record_t nfv9_logging_add_session_record;
2084
2085     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
2086         //vlib_cli_output(vm,"\n1. Log Mapping failed");
2087         /*
2088          * No logging configured, silently return
2089          */
2090         return;
2091     }
2092
2093     nfv9_logging_info =
2094         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
2095
2096     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2097         cnat_nfv9_create_logging_context(nfv9_logging_info,
2098                     cnat_nfv9_template_add_default);
2099
2100         /*
2101          * If still empty, return after increasing the count
2102          */
2103         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2104             //vlib_cli_output(vm,"\n2. Log Mapping failed");
2105             return;
2106         }
2107     }
2108
2109     if(PREDICT_FALSE(nfv9_logging_info->record[
2110             NAT44_ADD_SESSION_RECORD] == NULL)) {
2111         cnat_nfv9_record_create(nfv9_logging_info, NAT44_ADD_SESSION_RECORD);
2112     }
2113
2114     /*
2115      * We should definitely have add_record now, no need to sanitize
2116      */
2117     nfv9_logging_add_session_record.inside_vrf_id =
2118             clib_host_to_net_u32(vrfmap->i_vrf_id);
2119     nfv9_logging_add_session_record.outside_vrf_id =
2120             clib_host_to_net_u32(vrfmap->o_vrf_id);
2121
2122     nfv9_logging_add_session_record.inside_ip_addr =
2123             clib_host_to_net_u32(db->in2out_key.k.ipv4);
2124     nfv9_logging_add_session_record.outside_ip_addr =
2125         clib_host_to_net_u32(db->out2in_key.k.ipv4);
2126
2127     /* If sdb is null, it is assumed that logging is being done
2128      * for the first destination which is held in the main db
2129
2130      * itself
2131      */
2132     if(PREDICT_TRUE(sdb == NULL)) {
2133         nfv9_logging_add_session_record.dest_ip_addr =
2134             clib_host_to_net_u32(db->dst_ipv4);
2135         nfv9_logging_add_session_record.dest_port =
2136             clib_host_to_net_u16(db->dst_port);
2137     } else {
2138         nfv9_logging_add_session_record.dest_ip_addr =
2139             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2140         nfv9_logging_add_session_record.dest_port =
2141             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2142     }
2143
2144     nfv9_logging_add_session_record.inside_ip_port =
2145             clib_host_to_net_u16(db->in2out_key.k.port);
2146     nfv9_logging_add_session_record.outside_ip_port =
2147             clib_host_to_net_u16(db->out2in_key.k.port);
2148
2149
2150     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2151
2152     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2153             ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2154             ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
2155     nfv9_logging_add_session_record.protocol = my_protocol;
2156
2157     memcpy(nfv9_logging_info->record[NAT44_ADD_SESSION_RECORD],
2158             &nfv9_logging_add_session_record,
2159             CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH);
2160
2161     nfv9_logging_info->record_length[NAT44_ADD_SESSION_RECORD]
2162             += CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH;
2163     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH;
2164     nfv9_logging_info->total_record_count += 1;
2165
2166
2167     nfv9_logging_info->record[NAT44_ADD_SESSION_RECORD]
2168             += CNAT_NFV9_NAT44_ADD_SESSION_RECORD_LENGTH;
2169
2170     nfv9_logging_info->next_data_ptr =
2171             nfv9_logging_info->record[NAT44_ADD_SESSION_RECORD];
2172
2173     nfv9_logging_info->dataflow_header->dataflow_length =
2174         clib_host_to_net_u32(
2175     nfv9_logging_info->record_length[NAT44_ADD_SESSION_RECORD]);
2176
2177     /*
2178      * If we have exceeded the packet length, let us send the
2179      * packet now.  There is buffer of additional bytes beyond
2180      * max_pkt_length to ensure that the last add/delete record
2181      * can be stored safely.
2182      */
2183     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2184         nfv9_logging_info->max_length_minus_max_record_size)) {
2185         cnat_nfv9_send_pkt(nfv9_logging_info);
2186     }
2187 }
2188
2189 /*
2190  * edt: * * cnat_nfv9_nat44_log_session_delete
2191  *
2192  * Tries to log a deletion of mapping record (session based)
2193  *
2194  * Argument: cnat_main_db_entry_t *db
2195  * Main DB entry being created
2196  * Arugment: cnat_session_entry_t *sdb
2197  * Session DB entry if the destination is not the first dest
2198  * Argument: cnat_vrfmap_t *vrfmap
2199  * VRF Map for the Main DB entry being deleted
2200  */
2201
2202 void cnat_nfv9_nat44_log_session_delete(cnat_main_db_entry_t *db,
2203                 cnat_session_entry_t *sdb,
2204                 cnat_vrfmap_t *vrfmap)
2205 {
2206     cnat_nfv9_logging_info_t *nfv9_logging_info = 0;
2207     u16 my_proto_mask;
2208     u8 my_protocol;
2209     nfv9_del_session_record_t nfv9_logging_del_session_record;
2210
2211     if (PREDICT_FALSE(vrfmap->nfv9_logging_index == EMPTY)) {
2212         //vlib_cli_output(vm, "\n1. Log Mapping failed");
2213         /*
2214          * No logging configured, silently return
2215          */
2216         return;
2217     }
2218
2219     nfv9_logging_info =
2220         cnat_nfv9_logging_info_pool + vrfmap->nfv9_logging_index;
2221
2222     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2223         cnat_nfv9_create_logging_context(nfv9_logging_info,
2224                     cnat_nfv9_template_add_default);
2225
2226         /*
2227          * If still empty, return after increasing the count
2228          */
2229         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2230             //vlib_cli_output(vm, "\n2. Log Mapping failed");
2231             return;
2232         }
2233     }
2234
2235     if(PREDICT_FALSE(nfv9_logging_info->record[
2236             NAT44_DEL_SESSION_RECORD] == NULL)) {
2237         cnat_nfv9_record_create(nfv9_logging_info, NAT44_DEL_SESSION_RECORD);
2238     }
2239
2240     /*
2241      * We should definitely have add_record now, no need to sanitize
2242      */
2243     nfv9_logging_del_session_record.inside_vrf_id =
2244             clib_host_to_net_u32(vrfmap->i_vrf_id);
2245
2246     nfv9_logging_del_session_record.inside_ip_addr =
2247             clib_host_to_net_u32(db->in2out_key.k.ipv4);
2248
2249     /* If sdb is null, it is assumed that logging is being done
2250      * for the first destination which is held in the main db
2251      * itself
2252      */
2253     if(PREDICT_TRUE(sdb == NULL)) {
2254         nfv9_logging_del_session_record.dest_ip_addr =
2255             clib_host_to_net_u32(db->dst_ipv4);
2256         nfv9_logging_del_session_record.dest_port =
2257             clib_host_to_net_u16(db->dst_port);
2258     } else {
2259         nfv9_logging_del_session_record.dest_ip_addr =
2260             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2261         nfv9_logging_del_session_record.dest_port =
2262             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2263     }
2264
2265     nfv9_logging_del_session_record.inside_ip_port =
2266             clib_host_to_net_u16(db->in2out_key.k.port);
2267
2268     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2269     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2270             ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2271             ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : GRE_PROT)));
2272
2273     nfv9_logging_del_session_record.protocol = my_protocol;
2274
2275     memcpy(nfv9_logging_info->record[NAT44_DEL_SESSION_RECORD],
2276             &nfv9_logging_del_session_record,
2277             CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH);
2278
2279     nfv9_logging_info->record_length[NAT44_DEL_SESSION_RECORD]
2280             += CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH;
2281     nfv9_logging_info->pkt_length += CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH;
2282     nfv9_logging_info->total_record_count += 1;
2283
2284     nfv9_logging_info->record[NAT44_DEL_SESSION_RECORD]
2285             += CNAT_NFV9_NAT44_DEL_SESSION_RECORD_LENGTH;
2286
2287     nfv9_logging_info->next_data_ptr =
2288             nfv9_logging_info->record[NAT44_DEL_SESSION_RECORD];
2289
2290     nfv9_logging_info->dataflow_header->dataflow_length =
2291         clib_host_to_net_u32(
2292     nfv9_logging_info->record_length[NAT44_DEL_SESSION_RECORD]);
2293
2294     /*
2295      * If we have exceeded the packet length, let us send the
2296      * packet now.  There is buffer of additional bytes beyond
2297      * max_pkt_length to ensure that the last add/delete record
2298      * can be stored safely.
2299      */
2300     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2301         nfv9_logging_info->max_length_minus_max_record_size)) {
2302         cnat_nfv9_send_pkt(nfv9_logging_info);
2303     }
2304 }
2305
2306 /*
2307  * DS-Lite APIs for netflow logging
2308  */
2309
2310 /*
2311  * edt: * * cnat_nfv9_ds_lite_mapping_create
2312  *
2313  * Tries to log a creation of mapping record
2314  *
2315  * Argument: cnat_main_db_entry_t *db
2316  * Main DB entry being created
2317  *
2318  * Argument: dslite_table_entry_t *dslite_entry
2319  * ds-lite instance for the Main DB entry being created
2320  */
2321 void cnat_nfv9_ds_lite_mapping_create(cnat_main_db_entry_t *db,
2322                         dslite_table_entry_t *dslite_entry
2323 #ifndef NO_BULK_LOGGING
2324                         , int bulk_alloc
2325 #endif
2326                        )
2327 {
2328     
2329     cnat_nfv9_logging_info_t    *nfv9_logging_info = NULL; 
2330
2331     if (PREDICT_FALSE(!(db && dslite_entry))) {
2332         return;
2333     }
2334     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2335         /*
2336          * no logging configured, silently return
2337          */
2338         return;
2339     }
2340
2341     nfv9_logging_info = 
2342         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2343     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2344         cnat_nfv9_create_logging_context(nfv9_logging_info,
2345                                         cnat_nfv9_template_add_default);
2346         /*
2347          * If still empty, return after increasing the count
2348          */
2349         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2350             return;
2351         }
2352     }
2353 #ifndef NO_BULK_LOGGING
2354     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
2355         cnat_nfv9_ds_lite_insert_bulk_add_record(nfv9_logging_info, 
2356                 db, dslite_entry, bulk_alloc);
2357     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
2358         return; /* No logging required.. bulk port usage */
2359     else  /* Individual logging .. fall back to old method */
2360 #endif /*NO_BULK_LOGGING*/
2361     cnat_nfv9_ds_lite_insert_add_record(nfv9_logging_info, db, dslite_entry);
2362     /*
2363      * If we have exceeded the packet length, let us send the
2364      * packet now.  There is buffer of additional bytes beyond
2365      * max_pkt_length to ensure that the last add/delete record
2366      * can be stored safely.
2367      */
2368     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
2369         nfv9_logging_info->max_length_minus_max_record_size)) {
2370         cnat_nfv9_send_pkt(nfv9_logging_info);
2371     }
2372 }
2373
2374 /*
2375  * edt: * * cnat_nfv9_ds_lite_mapping_delete
2376  *
2377  * Tries to log a deletion of mapping record
2378  *
2379  * Argument: cnat_main_db_entry_t *db
2380  * Main DB entry being deleted
2381  *
2382  * Argument: dslite_table_entry_t *dslite_entry
2383  * ds-lite instance for the Main DB entry being deleted
2384  */
2385 void cnat_nfv9_ds_lite_mapping_delete(cnat_main_db_entry_t *db,
2386                            dslite_table_entry_t *dslite_entry
2387 #ifndef NO_BULK_LOGGING
2388                            , int bulk_alloc
2389 #endif
2390                               )
2391 {
2392
2393     cnat_nfv9_logging_info_t    *nfv9_logging_info = NULL; 
2394     if (PREDICT_FALSE(!(db && dslite_entry))) {
2395         return;
2396     }
2397     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2398         /*
2399          * No logging configured, silently return
2400          */
2401         return;
2402     }
2403     nfv9_logging_info = 
2404         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2405
2406
2407     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2408         cnat_nfv9_create_logging_context(nfv9_logging_info,
2409                                          cnat_nfv9_template_add_default);
2410         /*
2411          * If still empty, return after increasing the count
2412          */
2413         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2414             return;
2415         }
2416     }
2417 #ifndef NO_BULK_LOGGING
2418     if(bulk_alloc > 0) { /* new bulk alloc - use bulk add template */
2419         cnat_nfv9_ds_lite_insert_bulk_del_record(nfv9_logging_info, 
2420                     db, dslite_entry, bulk_alloc);
2421     } else if(bulk_alloc == CACHE_ALLOC_NO_LOG_REQUIRED)
2422         return; /* No logging required.. bulk port usage */
2423     else  /* Individual logging .. fall back to old method */
2424 #endif /*NO_BULK_LOGGING*/
2425     cnat_nfv9_ds_lite_insert_del_record(nfv9_logging_info, db, dslite_entry);
2426     /*
2427      * If we have exceeded the packet length, let us send the
2428      * packet now.  There is buffer of additional bytes beyond
2429      * max_pkt_length to ensure that the last add/delete record
2430      * can be stored safely.
2431      */
2432     if (PREDICT_FALSE(nfv9_logging_info->pkt_length > 
2433         nfv9_logging_info->max_length_minus_max_record_size)) {
2434         cnat_nfv9_send_pkt(nfv9_logging_info);
2435     }
2436 }
2437
2438 /*
2439  * edt: * * cnat_nfv9_dslite_log_session_create
2440  *
2441  * Tries to log a creation of mapping record (session based)
2442  * Argument: cnat_main_db_entry_t *db
2443  * Main DB entry being created
2444  * Arugment: cnat_session_entry_t *sdb
2445  * Session DB entry if the destination is not the first dest
2446  * Argument: dslite_table_entry_t *dslite_entry,
2447  * dslite table entry for dslite instance
2448  */
2449
2450 void cnat_nfv9_ds_lite_log_session_create(
2451                 cnat_main_db_entry_t *db,
2452                 dslite_table_entry_t *dslite_entry,
2453                 cnat_session_entry_t *sdb)
2454 {
2455
2456     nfv9_ds_lite_add_session_record_t   nfv9_logging_add_record ;
2457     cnat_user_db_entry_t        *udb = NULL;
2458     u16     my_proto_mask;
2459     u8      my_protocol;
2460     cnat_nfv9_logging_info_t  *nfv9_logging_info = 0;
2461
2462     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2463         /*
2464          * no logging configured, silently return
2465          */
2466         return;
2467     }
2468
2469     nfv9_logging_info =
2470         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2471     udb = cnat_user_db + db->user_index;
2472
2473     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2474         cnat_nfv9_create_logging_context(nfv9_logging_info,
2475                     cnat_nfv9_template_add_default);
2476
2477         /*
2478          * If still empty, return after increasing the count
2479          */
2480         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2481             return;
2482         }
2483     }
2484
2485     udb = cnat_user_db + db->user_index;
2486     if (PREDICT_FALSE(!udb)) {
2487          return;
2488     }
2489     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD] == NULL)) {
2490         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_ADD_SESSION_RECORD);
2491     }
2492     /*
2493      * We should definitely have add_record now, no need to sanitize
2494      */
2495     nfv9_logging_add_record.inside_vrf_id =
2496                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
2497     nfv9_logging_add_record.outside_vrf_id =
2498                     clib_host_to_net_u32(dslite_entry->o_vrf_id);
2499
2500     nfv9_logging_add_record.inside_ip_addr =
2501                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
2502
2503     nfv9_logging_add_record.inside_v6_src_addr[0] =
2504                     clib_host_to_net_u32(udb->ipv6[0]);
2505     nfv9_logging_add_record.inside_v6_src_addr[1] =
2506                     clib_host_to_net_u32(udb->ipv6[1]);
2507     nfv9_logging_add_record.inside_v6_src_addr[2] =
2508                     clib_host_to_net_u32(udb->ipv6[2]);
2509     nfv9_logging_add_record.inside_v6_src_addr[3] =
2510                     clib_host_to_net_u32(udb->ipv6[3]);
2511
2512     nfv9_logging_add_record.outside_ip_addr =
2513                     clib_host_to_net_u32(db->out2in_key.k.ipv4);
2514
2515     nfv9_logging_add_record.inside_ip_port =
2516                     clib_host_to_net_u16(db->in2out_key.k.port);
2517     nfv9_logging_add_record.outside_ip_port =
2518                     clib_host_to_net_u16(db->out2in_key.k.port);
2519
2520     /* If sdb is null, it is assumed that logging is being done
2521      * for the first destination which is held in the main db
2522
2523      * itself
2524      */
2525     if(PREDICT_TRUE(sdb == NULL)) {
2526         nfv9_logging_add_record.dest_ip_addr =
2527             clib_host_to_net_u32(db->dst_ipv4);
2528         nfv9_logging_add_record.dest_port =
2529             clib_host_to_net_u16(db->dst_port);
2530     } else {
2531         nfv9_logging_add_record.dest_ip_addr =
2532             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2533         nfv9_logging_add_record.dest_port =
2534             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2535     }
2536
2537
2538     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2539
2540     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2541                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2542                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
2543     nfv9_logging_add_record.protocol = my_protocol;
2544
2545     memcpy(nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD],
2546             &nfv9_logging_add_record, CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH);
2547
2548     nfv9_logging_info->record_length[DS_LITE_ADD_SESSION_RECORD]
2549                                   += CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH;
2550
2551     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH;
2552     nfv9_logging_info->total_record_count += 1;
2553
2554     nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD]
2555                       += CNAT_NFV9_DS_LITE_ADD_SESSION_RECORD_LENGTH;
2556     nfv9_logging_info->next_data_ptr =
2557                          nfv9_logging_info->record[DS_LITE_ADD_SESSION_RECORD];
2558
2559     nfv9_logging_info->dataflow_header->dataflow_length =
2560         clib_host_to_net_u32(
2561         nfv9_logging_info->record_length[DS_LITE_ADD_SESSION_RECORD]);
2562
2563     /*
2564      * If we have exceeded the packet length, let us send the
2565      * packet now.  There is buffer of additional bytes beyond
2566      * max_pkt_length to ensure that the last add/delete record
2567      * can be stored safely.
2568      */
2569     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2570         nfv9_logging_info->max_length_minus_max_record_size)) {
2571         cnat_nfv9_send_pkt(nfv9_logging_info);
2572     }
2573
2574 }
2575
2576 /*
2577  * edt: * * cnat_nfv9_dslite_log_session_delete
2578  *
2579  * Tries to log a creation of mapping record (session based)
2580  * Argument: cnat_main_db_entry_t *db
2581  * Main DB entry being created
2582  * Arugment: cnat_session_entry_t *sdb
2583  * Session DB entry if the destination is not the first dest
2584  * Argument: dslite_table_entry_t *dslite_entry,
2585  * dslite table entry for dslite instance
2586  */
2587
2588 void cnat_nfv9_ds_lite_log_session_delete(
2589                 cnat_main_db_entry_t *db,
2590                 dslite_table_entry_t *dslite_entry,
2591                 cnat_session_entry_t *sdb)
2592 {
2593
2594     nfv9_ds_lite_del_session_record_t   nfv9_logging_add_record = {0};
2595     cnat_user_db_entry_t        *udb = NULL;
2596     u16     my_proto_mask;
2597     u8      my_protocol;
2598     cnat_nfv9_logging_info_t  *nfv9_logging_info = NULL;
2599
2600     if (PREDICT_FALSE(dslite_entry->nfv9_logging_index == EMPTY)) {
2601         /*
2602          * no logging configured, silently return
2603          */
2604         return;
2605     }
2606
2607     nfv9_logging_info =
2608         cnat_nfv9_logging_info_pool + dslite_entry->nfv9_logging_index;
2609     udb = cnat_user_db + db->user_index;
2610
2611     if (PREDICT_FALSE(!udb)) {
2612         return;
2613     }
2614
2615     if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2616         cnat_nfv9_create_logging_context(nfv9_logging_info,
2617                     cnat_nfv9_template_add_default);
2618
2619         /*
2620          * If still empty, return after increasing the count
2621          */
2622         if (PREDICT_FALSE(nfv9_logging_info->current_logging_context == NULL)) {
2623             return;
2624         }
2625     }
2626
2627     if (PREDICT_FALSE(nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD] == NULL)) {
2628         cnat_nfv9_record_create(nfv9_logging_info, DS_LITE_DEL_SESSION_RECORD);
2629     }
2630     /*
2631      * We should definitely have add_record now, no need to sanitize
2632      */
2633     nfv9_logging_add_record.inside_vrf_id =
2634                     clib_host_to_net_u32(dslite_entry->i_vrf_id);
2635
2636     nfv9_logging_add_record.inside_ip_addr =
2637                     clib_host_to_net_u32(db->in2out_key.k.ipv4);
2638
2639     nfv9_logging_add_record.inside_v6_src_addr[0] =
2640                     clib_host_to_net_u32(udb->ipv6[0]);
2641     nfv9_logging_add_record.inside_v6_src_addr[1] =
2642                     clib_host_to_net_u32(udb->ipv6[1]);
2643     nfv9_logging_add_record.inside_v6_src_addr[2] =
2644                     clib_host_to_net_u32(udb->ipv6[2]);
2645     nfv9_logging_add_record.inside_v6_src_addr[3] =
2646                     clib_host_to_net_u32(udb->ipv6[3]);
2647
2648     nfv9_logging_add_record.inside_ip_port =
2649                     clib_host_to_net_u16(db->in2out_key.k.port);
2650
2651     /* If sdb is null, it is assumed that logging is being done
2652      * for the first destination which is held in the main db
2653      * itself
2654      */
2655     if(PREDICT_TRUE(sdb == NULL)) {
2656         nfv9_logging_add_record.dest_ip_addr =
2657             clib_host_to_net_u32(db->dst_ipv4);
2658         nfv9_logging_add_record.dest_port = 
2659             clib_host_to_net_u16(db->dst_port);
2660     } else {
2661         nfv9_logging_add_record.dest_ip_addr =
2662             clib_host_to_net_u32(sdb->v4_dest_key.k.ipv4);
2663         nfv9_logging_add_record.dest_port =
2664             clib_host_to_net_u16(sdb->v4_dest_key.k.port);
2665     }
2666
2667
2668     my_proto_mask = db->in2out_key.k.vrf & CNAT_PRO_MASK;
2669
2670     my_protocol = ((my_proto_mask == CNAT_UDP) ? UDP_PROT :
2671                    ((my_proto_mask == CNAT_TCP) ? TCP_PROT :
2672                    ((my_proto_mask == CNAT_ICMP) ? ICMP_PROT : 0)));
2673     nfv9_logging_add_record.protocol = my_protocol;
2674     
2675     memcpy(nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD],
2676             &nfv9_logging_add_record, CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH);
2677
2678     nfv9_logging_info->record_length[DS_LITE_DEL_SESSION_RECORD]
2679                                   += CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH;
2680
2681     nfv9_logging_info->pkt_length += CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH;
2682     nfv9_logging_info->total_record_count += 1;
2683
2684     nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD]
2685                       += CNAT_NFV9_DS_LITE_DEL_SESSION_RECORD_LENGTH;
2686     nfv9_logging_info->next_data_ptr = 
2687                          nfv9_logging_info->record[DS_LITE_DEL_SESSION_RECORD];
2688
2689     nfv9_logging_info->dataflow_header->dataflow_length =
2690         clib_host_to_net_u32(
2691         nfv9_logging_info->record_length[DS_LITE_DEL_SESSION_RECORD]);
2692
2693     /*
2694      * If we have exceeded the packet length, let us send the
2695      * packet now.  There is buffer of additional bytes beyond
2696      * max_pkt_length to ensure that the last add/delete record
2697      * can be stored safely.
2698      */
2699     if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2700         nfv9_logging_info->max_length_minus_max_record_size)) {
2701         cnat_nfv9_send_pkt(nfv9_logging_info);
2702     }
2703
2704 }
2705
2706
2707 /*
2708  * netflow logging API for ingress vrf_id to name mapping
2709  */
2710
2711 /*
2712  * edt: * * handle_vrfid_name_mapping
2713  * It will search for valid natflow entry in netflow pool,
2714  * once found one, will send all vrfid name mapping info
2715  * using that entry
2716  */
2717
2718
2719 inline
2720 void handle_vrfid_name_mapping(void)
2721 {
2722     cnat_nfv9_logging_info_t    *nfv9_logging_info = NULL;
2723
2724     pool_foreach (nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
2725         if(PREDICT_FALSE(nfv9_logging_info == NULL)) {
2726             continue;
2727         }
2728         nfv9_server_info_t *server =  nfv9_server_info_pool + 
2729             nfv9_logging_info->server_index;
2730         if(server->template_sent == TEMPLATE_SENT_TRUE) {
2731             cnat_nfv9_ingress_vrfid_name_mapping_create(nfv9_logging_info);
2732             server->template_sent = TEMPLATE_SENT_FALSE;
2733         }
2734     }));
2735 }
2736
2737 /*
2738  * edt: * * cnat_nfv9_ingress_vrfid_name_mapping_create
2739  * 
2740  * Tries to log vrfid-name mapping record
2741  * Argument: netflow pointer
2742  */
2743
2744
2745 void cnat_nfv9_ingress_vrfid_name_mapping_create(
2746                 cnat_nfv9_logging_info_t *nfv9_logging_info)
2747 {
2748     u16 index = 0;
2749
2750     for (index = 0; index < MAX_VRFID; index++) {
2751         if(vrfid_name_map[index].ref_count == 0) {
2752             continue;
2753         }
2754         if (PREDICT_FALSE(
2755                     nfv9_logging_info->current_logging_context == NULL)) {
2756             cnat_nfv9_create_logging_context(nfv9_logging_info,
2757                     cnat_nfv9_template_add_default);
2758         }
2759         cnat_nfv9_insert_ingress_vrfid_name_record(
2760                 nfv9_logging_info,index);
2761         if (PREDICT_FALSE(nfv9_logging_info->pkt_length >
2762                     nfv9_logging_info->max_length_minus_max_record_size) ||
2763                     PREDICT_FALSE(index == MAX_VRFID - 1)) {
2764             if (PREDICT_TRUE(nfv9_logging_info->current_logging_context
2765                         != NULL)) {
2766                 cnat_nfv9_send_pkt(nfv9_logging_info);
2767             }
2768         }
2769     }/*for()*/
2770     return;
2771 }
2772
2773 static void cnat_nfv9_insert_ingress_vrfid_name_record(
2774         cnat_nfv9_logging_info_t *nfv9_logging_info, u16 index)
2775 {
2776     nfv9_ingress_vrfid_name_record_t  nfv9_ingress_vrfid_name_record = {0};
2777  
2778     if (PREDICT_FALSE(
2779             nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD] == NULL)) {
2780         cnat_nfv9_record_create(nfv9_logging_info, INGRESS_VRF_ID_NAME_RECORD);
2781     }
2782     nfv9_ingress_vrfid_name_record.ingress_vrf_id = 
2783                     clib_host_to_net_u32(vrfid_name_map[index].vrf_id);
2784
2785     memcpy(nfv9_ingress_vrfid_name_record.ingress_vrf_name,
2786             vrfid_name_map[index].vrf_name, NFV9_VRF_NAME_LEN);
2787
2788     memcpy(nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD], 
2789             &nfv9_ingress_vrfid_name_record, 
2790             CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH);
2791
2792     nfv9_logging_info->record_length[INGRESS_VRF_ID_NAME_RECORD] 
2793             += CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH;
2794
2795     nfv9_logging_info->pkt_length += 
2796             CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH;
2797
2798     nfv9_logging_info->total_record_count += 1;
2799
2800     nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD] 
2801             += CNAT_NFV9_INGRESS_VRFID_NAME_RECORD_LENGTH;
2802
2803     nfv9_logging_info->next_data_ptr = 
2804             nfv9_logging_info->record[INGRESS_VRF_ID_NAME_RECORD];
2805
2806     nfv9_logging_info->dataflow_header->dataflow_length =
2807         clib_host_to_net_u32(
2808         nfv9_logging_info->record_length[INGRESS_VRF_ID_NAME_RECORD]);
2809     return;
2810 }
2811 /*
2812  * edt: * * cnat_log_timer_handler
2813  *
2814  * Timer handler for sending any pending NFV9 record
2815  *
2816  * Argument: spp_timer_t * timer_p
2817  * Timer handler structure
2818  */
2819 void handle_pending_nfv9_pkts()
2820 {
2821     vlib_node_t *output_node;
2822     vlib_main_t * vm = vlib_get_main();
2823     cnat_nfv9_logging_info_t *my_nfv9_logging_info = 0;
2824     u32 current_timestamp = cnat_nfv9_get_sys_up_time_in_ms();
2825     u32 current_unix_time_in_seconds = cnat_nfv9_get_unix_time_in_seconds();
2826     
2827     output_node =  vlib_get_node_by_name (vm, (u8 *) "ip4-lookup");
2828
2829     pool_foreach (my_nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
2830         nfv9_server_info_t *server =  nfv9_server_info_pool + 
2831                                       my_nfv9_logging_info->server_index;
2832         if (my_nfv9_logging_info->queued_logging_context ||
2833             (my_nfv9_logging_info->current_logging_context &&
2834              (current_timestamp - 
2835               my_nfv9_logging_info->current_logging_context_timestamp) 
2836              > 1000)) {
2837             /*
2838              * If there is a current logging context and timestamp
2839              * indicates it is pending for long, send it out
2840              * Also if there is a queued context send it out as well
2841               */
2842               vlib_cli_output(vm, "\nNFV9_TIMER: queued %p, curr %p",
2843                                my_nfv9_logging_info->queued_logging_context, 
2844                                my_nfv9_logging_info->current_logging_context);
2845
2846
2847               cnat_nfv9_send_pkt_always_success(my_nfv9_logging_info,
2848                                               output_node);
2849         } else {
2850             /*
2851              * If the last_template_sent_time is too far back in time
2852              * send the template even if there is no NFv9 records to send
2853              */
2854             if ((my_nfv9_logging_info->queued_logging_context == NULL) &&
2855                  (my_nfv9_logging_info->current_logging_context == NULL) &&
2856                  ((current_unix_time_in_seconds -
2857                  server->last_template_sent_time) >
2858                  server->timeout_rate)) {
2859                  cnat_nfv9_create_logging_context(my_nfv9_logging_info,
2860                                                  cnat_nfv9_template_add_always);
2861                  if (PREDICT_TRUE(my_nfv9_logging_info->current_logging_context
2862                                   != NULL)) {
2863                      cnat_nfv9_send_pkt(my_nfv9_logging_info);
2864                  }
2865             }
2866         }
2867     }));
2868 }
2869
2870 /*
2871  * Code to initialize NFV9 Template.  This is done when a NFV9 is enabled
2872  * It is done only once and later used when sending NFV9 template records.
2873  */
2874 static void
2875 cnat_nfv9_template_init (void)
2876 {
2877     cnat_nfv9_template_info.flowset_id =
2878         clib_host_to_net_u16(CNAT_NFV9_TEMPLATE_FLOWSET_ID);
2879     cnat_nfv9_template_info.length =
2880         clib_host_to_net_u16(CNAT_NFV9_TEMPLATE_LENGTH - 
2881                         CNAT_NFV9_OPTION_TEMPLATE_LENGTH);
2882     /*
2883      * Create the add Template
2884      */
2885     cnat_nfv9_template_info.add_template_id =
2886         clib_host_to_net_u16(CNAT_NFV9_ADD_TEMPLATE_ID);
2887     cnat_nfv9_template_info.add_field_count =
2888         clib_host_to_net_u16(CNAT_NFV9_ADD_FIELD_COUNT);
2889
2890     cnat_nfv9_template_info.add_inside_vrf_id_field_type =
2891         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
2892     cnat_nfv9_template_info.add_inside_vrf_id_field_size =
2893         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
2894
2895     cnat_nfv9_template_info.add_outside_vrf_id_field_type =
2896         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
2897     cnat_nfv9_template_info.add_outside_vrf_id_field_size =
2898         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
2899
2900     cnat_nfv9_template_info.add_inside_ip_addr_field_type =
2901         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
2902     cnat_nfv9_template_info.add_inside_ip_addr_field_size =
2903         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
2904
2905     cnat_nfv9_template_info.add_outside_ip_addr_field_type =
2906         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
2907     cnat_nfv9_template_info.add_outside_ip_addr_field_size =
2908         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
2909
2910     cnat_nfv9_template_info.add_inside_ip_port_field_type =
2911         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
2912     cnat_nfv9_template_info.add_inside_ip_port_field_size =
2913         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
2914
2915     cnat_nfv9_template_info.add_outside_ip_port_field_type =
2916         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
2917     cnat_nfv9_template_info.add_outside_ip_port_field_size =
2918         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
2919
2920     cnat_nfv9_template_info.add_protocol_field_type = 
2921         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
2922     cnat_nfv9_template_info.add_protocol_field_size =
2923         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
2924
2925     /*
2926      * Create the delete Template
2927      */
2928     cnat_nfv9_template_info.del_template_id =
2929         clib_host_to_net_u16(CNAT_NFV9_DEL_TEMPLATE_ID);
2930     cnat_nfv9_template_info.del_field_count =
2931         clib_host_to_net_u16(CNAT_NFV9_DEL_FIELD_COUNT);
2932
2933     cnat_nfv9_template_info.del_inside_vrf_id_field_type =
2934         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
2935     cnat_nfv9_template_info.del_inside_vrf_id_field_size =
2936         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
2937
2938     cnat_nfv9_template_info.del_inside_ip_addr_field_type =
2939         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
2940     cnat_nfv9_template_info.del_inside_ip_addr_field_size =
2941         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
2942
2943     cnat_nfv9_template_info.del_inside_ip_port_field_type =
2944         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
2945     cnat_nfv9_template_info.del_inside_ip_port_field_size =
2946         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
2947
2948     cnat_nfv9_template_info.del_protocol_field_type =
2949         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
2950     cnat_nfv9_template_info.del_protocol_field_size =
2951         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
2952
2953
2954     /* Create NAT64 BIB Add template */
2955 #if 0
2956     cnat_nfv9_template_info.nat64_add_bib_template_id =
2957         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_BIB_TEMPLATE_ID);
2958     cnat_nfv9_template_info.nat64_add_bib_field_count =
2959         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_BIB_FIELD_COUNT);
2960
2961
2962     cnat_nfv9_template_info.nat64_add_bib_inside_ipv6_addr_field_type =
2963       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
2964     cnat_nfv9_template_info.nat64_add_bib_inside_ipv6_addr_field_size =
2965       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
2966
2967     cnat_nfv9_template_info.nat64_add_bib_outside_ip_addr_field_type =
2968         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
2969     cnat_nfv9_template_info.nat64_add_bib_outside_ip_addr_field_size =
2970         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
2971
2972     cnat_nfv9_template_info.nat64_add_bib_inside_ip_port_field_type =
2973       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
2974     cnat_nfv9_template_info.nat64_add_bib_inside_ip_port_field_size =
2975       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
2976
2977     cnat_nfv9_template_info.nat64_add_bib_outside_ip_port_field_type =
2978         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
2979     cnat_nfv9_template_info.nat64_add_bib_outside_ip_port_field_size =
2980         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
2981
2982     cnat_nfv9_template_info.nat64_add_bib_protocol_field_type =
2983         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
2984     cnat_nfv9_template_info.nat64_add_bib_protocol_field_size =
2985         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
2986
2987  
2988     /* NAT64 BIB Delete */
2989     cnat_nfv9_template_info.nat64_del_bib_template_id =
2990         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_BIB_TEMPLATE_ID);
2991     cnat_nfv9_template_info.nat64_del_bib_field_count =
2992         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_BIB_FIELD_COUNT);
2993
2994     cnat_nfv9_template_info.nat64_del_bib_inside_ip_addr_field_type =
2995       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
2996     cnat_nfv9_template_info.nat64_del_bib_inside_ip_addr_field_size =
2997       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
2998
2999     cnat_nfv9_template_info.nat64_del_bib_inside_ip_port_field_type =
3000       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3001     cnat_nfv9_template_info.nat64_del_bib_inside_ip_port_field_size =
3002       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3003
3004     cnat_nfv9_template_info.nat64_del_bib_protocol_field_type =
3005         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3006     cnat_nfv9_template_info.nat64_del_bib_protocol_field_size =
3007         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3008
3009
3010     /* NAt64 SESSION ADD */
3011
3012     cnat_nfv9_template_info.nat64_add_session_template_id =
3013         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_SESSION_TEMPLATE_ID);
3014     cnat_nfv9_template_info.nat64_add_session_field_count =
3015         clib_host_to_net_u16(CNAT_NFV9_NAT64_ADD_SESSION_FIELD_COUNT);
3016
3017
3018     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_src_addr_field_type =
3019       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3020     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_src_addr_field_size =
3021       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3022
3023     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_addr_field_type =
3024         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3025     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_addr_field_size =
3026         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3027
3028
3029     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_dst_addr_field_type =
3030       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_TYPE);
3031     cnat_nfv9_template_info.nat64_add_session_inside_ipv6_dst_addr_field_size =
3032       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_SIZE);
3033
3034
3035     cnat_nfv9_template_info.nat64_add_session_outside_ip_dst_addr_field_type =
3036       clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_DST_ADDR_FIELD_TYPE);
3037     cnat_nfv9_template_info.nat64_add_session_outside_ip_dst_addr_field_size =
3038       clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_DST_ADDR_FIELD_SIZE);
3039
3040     cnat_nfv9_template_info.nat64_add_session_inside_ip_src_port_field_type =
3041       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3042     cnat_nfv9_template_info.nat64_add_session_inside_ip_src_port_field_size =
3043       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3044
3045
3046     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_port_field_type =
3047         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3048     cnat_nfv9_template_info.nat64_add_session_outside_ip_src_port_field_size =
3049         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3050    
3051
3052     cnat_nfv9_template_info.nat64_add_session_ip_dest_port_field_type =
3053       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3054     cnat_nfv9_template_info.nat64_add_session_ip_dest_port_field_size =
3055       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3056  
3057     cnat_nfv9_template_info.nat64_add_session_protocol_field_type =
3058         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3059     cnat_nfv9_template_info.nat64_add_session_protocol_field_size =
3060         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3061
3062
3063
3064     /* Session Delete */
3065     cnat_nfv9_template_info.nat64_del_session_template_id =
3066         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_SESSION_TEMPLATE_ID);
3067     cnat_nfv9_template_info.nat64_del_session_field_count =
3068         clib_host_to_net_u16(CNAT_NFV9_NAT64_DEL_SESSION_FIELD_COUNT);
3069
3070     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_addr_field_type =
3071       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3072     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_addr_field_size =
3073       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3074
3075     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_addr_field_type =
3076       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_TYPE);
3077     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_addr_field_size =
3078       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_DST_ADDR_FIELD_SIZE);
3079
3080     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_port_field_type =
3081       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3082     cnat_nfv9_template_info.nat64_del_session_inside_ip_src_port_field_size =
3083       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3084
3085     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_port_field_type =
3086       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3087     cnat_nfv9_template_info.nat64_del_session_inside_ip_dst_port_field_size =
3088       clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3089
3090     cnat_nfv9_template_info.nat64_del_session_protocol_field_type =
3091         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3092     cnat_nfv9_template_info.nat64_del_session_protocol_field_size =
3093         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3094 #endif
3095     /*
3096      * Create the nat44 session add Template
3097      */
3098     cnat_nfv9_template_info.nat44_session_add_template_id =
3099         clib_host_to_net_u16(CNAT_NFV9_NAT44_ADD_SESSION_TEMPLATE_ID);
3100     cnat_nfv9_template_info.nat44_session_add_field_count =
3101         clib_host_to_net_u16(CNAT_NFV9_NAT44_ADD_SESSION_FIELD_COUNT);
3102
3103     cnat_nfv9_template_info.nat44_session_add_inside_vrf_id_field_type =
3104         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3105     cnat_nfv9_template_info.nat44_session_add_inside_vrf_id_field_size =
3106         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3107
3108     cnat_nfv9_template_info.nat44_session_add_outside_vrf_id_field_type =
3109         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3110     cnat_nfv9_template_info.nat44_session_add_outside_vrf_id_field_size =
3111         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3112
3113     cnat_nfv9_template_info.nat44_session_add_inside_ip_addr_field_type =
3114         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3115     cnat_nfv9_template_info.nat44_session_add_inside_ip_addr_field_size =
3116         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3117
3118     cnat_nfv9_template_info.nat44_session_add_outside_ip_addr_field_type =
3119         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3120     cnat_nfv9_template_info.nat44_session_add_outside_ip_addr_field_size =
3121         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3122
3123     cnat_nfv9_template_info.nat44_session_add_inside_ip_port_field_type =
3124         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3125     cnat_nfv9_template_info.nat44_session_add_inside_ip_port_field_size =
3126         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3127
3128     cnat_nfv9_template_info.nat44_session_add_outside_ip_port_field_type =
3129         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3130    cnat_nfv9_template_info.nat44_session_add_outside_ip_port_field_size =
3131         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3132
3133     cnat_nfv9_template_info.nat44_session_add_dest_ip_addr_field_type =
3134         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3135     cnat_nfv9_template_info.nat44_session_add_dest_ip_addr_field_size =
3136         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3137
3138     cnat_nfv9_template_info.nat44_session_add_dest_port_field_type =
3139         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3140     cnat_nfv9_template_info.nat44_session_add_dest_port_field_size =
3141         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3142
3143     cnat_nfv9_template_info.nat44_session_add_protocol_field_type =
3144         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3145     cnat_nfv9_template_info.nat44_session_add_protocol_field_size =
3146         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3147
3148     /*
3149      * Create the nat44 session del Template
3150      */
3151     cnat_nfv9_template_info.nat44_session_del_template_id =
3152         clib_host_to_net_u16(CNAT_NFV9_NAT44_DEL_SESSION_TEMPLATE_ID);
3153     cnat_nfv9_template_info.nat44_session_del_field_count =
3154         clib_host_to_net_u16(CNAT_NFV9_NAT44_DEL_SESSION_FIELD_COUNT);
3155
3156     cnat_nfv9_template_info.nat44_session_del_inside_vrf_id_field_type =
3157         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3158     cnat_nfv9_template_info.nat44_session_del_inside_vrf_id_field_size =
3159         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3160
3161     cnat_nfv9_template_info.nat44_session_del_inside_ip_addr_field_type =
3162         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3163     cnat_nfv9_template_info.nat44_session_del_inside_ip_addr_field_size =
3164         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3165
3166     cnat_nfv9_template_info.nat44_session_del_dest_ip_addr_field_type =
3167         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3168     cnat_nfv9_template_info.nat44_session_del_dest_ip_addr_field_size =
3169         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3170
3171     cnat_nfv9_template_info.nat44_session_del_inside_ip_port_field_type =
3172         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3173     cnat_nfv9_template_info.nat44_session_del_inside_ip_port_field_size =
3174         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3175
3176     cnat_nfv9_template_info.nat44_session_del_dest_port_field_type =
3177         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3178     cnat_nfv9_template_info.nat44_session_del_dest_port_field_size =
3179         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3180
3181     cnat_nfv9_template_info.nat44_session_del_protocol_field_type =
3182         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3183     cnat_nfv9_template_info.nat44_session_del_protocol_field_size =
3184         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3185     /*
3186      * Ds-lite add template
3187      */
3188 #if 0
3189     cnat_nfv9_template_info.add_dslite_template_id =
3190         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_TEMPLATE_ID);
3191     cnat_nfv9_template_info.add_dslite_field_count =
3192         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_FIELD_COUNT);
3193
3194     cnat_nfv9_template_info.add_dslite_inside_vrf_id_field_type =
3195         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3196     cnat_nfv9_template_info.add_dslite_inside_vrf_id_field_size =
3197         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3198
3199     cnat_nfv9_template_info.add_dslite_outside_vrf_id_field_type =
3200         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3201     cnat_nfv9_template_info.add_dslite_outside_vrf_id_field_size =
3202         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3203
3204     cnat_nfv9_template_info.add_dslite_inside_ip_addr_field_type =
3205         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3206     cnat_nfv9_template_info.add_dslite_inside_ip_addr_field_size =
3207         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3208
3209     cnat_nfv9_template_info.add_dslite_inside_ipv6_addr_field_type =
3210       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3211     cnat_nfv9_template_info.add_dslite_inside_ipv6_addr_field_size =
3212       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3213
3214     cnat_nfv9_template_info.add_dslite_outside_ip_addr_field_type =
3215         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3216     cnat_nfv9_template_info.add_dslite_outside_ip_addr_field_size =
3217         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3218
3219     cnat_nfv9_template_info.add_dslite_inside_ip_port_field_type =
3220         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3221     cnat_nfv9_template_info.add_dslite_inside_ip_port_field_size =
3222         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3223
3224     cnat_nfv9_template_info.add_dslite_outside_ip_port_field_type =
3225         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3226     cnat_nfv9_template_info.add_dslite_outside_ip_port_field_size =
3227         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3228
3229     cnat_nfv9_template_info.add_dslite_protocol_field_type = 
3230         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3231     cnat_nfv9_template_info.add_dslite_protocol_field_size =
3232         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3233
3234     /*
3235      * Ds-lite delete template 
3236      */
3237     cnat_nfv9_template_info.del_dslite_template_id =
3238         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_TEMPLATE_ID);
3239     cnat_nfv9_template_info.del_dslite_field_count =
3240         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_FIELD_COUNT);
3241
3242     cnat_nfv9_template_info.del_dslite_inside_vrf_id_field_type =
3243         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3244     cnat_nfv9_template_info.del_dslite_inside_vrf_id_field_size =
3245         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3246
3247     cnat_nfv9_template_info.del_dslite_inside_ip_addr_field_type =
3248         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3249     cnat_nfv9_template_info.del_dslite_inside_ip_addr_field_size =
3250         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3251
3252     cnat_nfv9_template_info.del_dslite_inside_ipv6_addr_field_type =
3253       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3254     cnat_nfv9_template_info.del_dslite_inside_ipv6_addr_field_size =
3255       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3256
3257     cnat_nfv9_template_info.del_dslite_inside_ip_port_field_type =
3258         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3259     cnat_nfv9_template_info.del_dslite_inside_ip_port_field_size =
3260         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3261
3262     cnat_nfv9_template_info.del_dslite_protocol_field_type =
3263         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3264     cnat_nfv9_template_info.del_dslite_protocol_field_size =
3265         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3266
3267     /*
3268      * Ds-lite session add template
3269      */
3270
3271     cnat_nfv9_template_info.add_dslite_session_template_id =
3272         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_SESSION_TEMPLATE_ID);
3273     cnat_nfv9_template_info.add_dslite_session_field_count =
3274         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_ADD_SESSION_FIELD_COUNT);
3275
3276     cnat_nfv9_template_info.add_dslite_session_inside_vrf_id_field_type =
3277         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3278     cnat_nfv9_template_info.add_dslite_session_inside_vrf_id_field_size =
3279         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3280
3281     cnat_nfv9_template_info.add_dslite_session_outside_vrf_id_field_type =
3282         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3283     cnat_nfv9_template_info.add_dslite_session_outside_vrf_id_field_size =
3284         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3285
3286     cnat_nfv9_template_info.add_dslite_session_inside_ip_addr_field_type =
3287         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3288     cnat_nfv9_template_info.add_dslite_session_inside_ip_addr_field_size =
3289         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3290
3291     cnat_nfv9_template_info.add_dslite_session_inside_ipv6_addr_field_type =
3292       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3293     cnat_nfv9_template_info.add_dslite_session_inside_ipv6_addr_field_size =
3294       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3295
3296     cnat_nfv9_template_info.add_dslite_session_outside_ip_addr_field_type =
3297         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3298     cnat_nfv9_template_info.add_dslite_session_outside_ip_addr_field_size =
3299         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3300
3301     cnat_nfv9_template_info.add_dslite_session_inside_ip_port_field_type =
3302         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3303     cnat_nfv9_template_info.add_dslite_session_inside_ip_port_field_size =
3304         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3305
3306     cnat_nfv9_template_info.add_dslite_session_outside_ip_port_field_type =
3307         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_TYPE);
3308     cnat_nfv9_template_info.add_dslite_session_outside_ip_port_field_size =
3309         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_FIELD_SIZE);
3310
3311      cnat_nfv9_template_info.add_dslite_session_dest_ip_addr_field_type =
3312          clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3313      cnat_nfv9_template_info.add_dslite_session_dest_ip_addr_field_size =
3314          clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3315  
3316      cnat_nfv9_template_info.add_dslite_session_dest_port_field_type =
3317          clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3318      cnat_nfv9_template_info.add_dslite_session_dest_port_field_size =
3319          clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3320
3321     cnat_nfv9_template_info.add_dslite_session_protocol_field_type =
3322         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3323     cnat_nfv9_template_info.add_dslite_session_protocol_field_size =
3324         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3325
3326     /*
3327      * Ds-lite session delete template 
3328      */
3329     cnat_nfv9_template_info.del_dslite_session_template_id =
3330         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_SESSION_TEMPLATE_ID);
3331     cnat_nfv9_template_info.del_dslite_session_field_count =
3332         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_DEL_SESSION_FIELD_COUNT);
3333
3334     cnat_nfv9_template_info.del_dslite_session_inside_vrf_id_field_type =
3335         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3336     cnat_nfv9_template_info.del_dslite_session_inside_vrf_id_field_size =
3337         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3338
3339     cnat_nfv9_template_info.del_dslite_session_inside_ip_addr_field_type =
3340         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3341     cnat_nfv9_template_info.del_dslite_session_inside_ip_addr_field_size =
3342         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3343
3344     cnat_nfv9_template_info.del_dslite_session_inside_ipv6_addr_field_type =
3345       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3346     cnat_nfv9_template_info.del_dslite_session_inside_ipv6_addr_field_size =
3347       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3348     
3349     cnat_nfv9_template_info.del_dslite_session_inside_ip_port_field_type =
3350         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_TYPE);
3351     cnat_nfv9_template_info.del_dslite_session_inside_ip_port_field_size =
3352         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_PORT_FIELD_SIZE);
3353
3354     cnat_nfv9_template_info.del_dslite_session_dest_ip_addr_field_type =
3355         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_TYPE);
3356     cnat_nfv9_template_info.del_dslite_session_dest_ip_addr_field_size =
3357         clib_host_to_net_u16(CNAT_NFV9_DESTINATION_IP_ADDR_FIELD_SIZE);
3358
3359     cnat_nfv9_template_info.del_dslite_session_dest_port_field_type =
3360         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_TYPE);
3361     cnat_nfv9_template_info.del_dslite_session_dest_port_field_size =
3362         clib_host_to_net_u16(CNAT_NFV9_INSIDE_DST_PORT_FIELD_SIZE);
3363    
3364     cnat_nfv9_template_info.del_dslite_session_protocol_field_type =
3365         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_TYPE);
3366     cnat_nfv9_template_info.del_dslite_session_protocol_field_size =
3367         clib_host_to_net_u16(CNAT_NFV9_PROTOCOL_FIELD_SIZE);
3368
3369     /* Create add bulk template */
3370     cnat_nfv9_template_info.bulk_add_template_id =
3371         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_ADD_TEMPLATE_ID);
3372     cnat_nfv9_template_info.bulk_add_field_count =
3373         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_ADD_FIELD_COUNT);
3374
3375     cnat_nfv9_template_info.bulk_add_inside_vrf_id_field_type =
3376         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3377     cnat_nfv9_template_info.bulk_add_inside_vrf_id_field_size =
3378         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3379
3380     cnat_nfv9_template_info.bulk_add_outside_vrf_id_field_type =
3381         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3382     cnat_nfv9_template_info.bulk_add_outside_vrf_id_field_size =
3383         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3384
3385     cnat_nfv9_template_info.bulk_add_inside_ip_addr_field_type =
3386         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3387     cnat_nfv9_template_info.bulk_add_inside_ip_addr_field_size =
3388         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3389
3390     cnat_nfv9_template_info.bulk_add_outside_ip_addr_field_type =
3391         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3392     cnat_nfv9_template_info.bulk_add_outside_ip_addr_field_size =
3393         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3394
3395     cnat_nfv9_template_info.bulk_add_outside_start_port_field_type =
3396         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3397     cnat_nfv9_template_info.bulk_add_outside_start_port_field_size =
3398         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3399
3400     cnat_nfv9_template_info.bulk_add_outside_end_port_field_type =
3401         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_TYPE);
3402     cnat_nfv9_template_info.bulk_add_outside_end_port_field_size =
3403         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_SIZE);
3404
3405     /*
3406      * Create the bulk delete Template
3407      */
3408     cnat_nfv9_template_info.bulk_del_template_id =
3409         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_DEL_TEMPLATE_ID);
3410     cnat_nfv9_template_info.bulk_del_field_count =
3411         clib_host_to_net_u16(CNAT_NFV9_NAT44_BULK_DEL_FIELD_COUNT);
3412
3413     cnat_nfv9_template_info.bulk_del_inside_vrf_id_field_type =
3414         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3415     cnat_nfv9_template_info.bulk_del_inside_vrf_id_field_size =
3416         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3417
3418     cnat_nfv9_template_info.bulk_del_inside_ip_addr_field_type =
3419         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3420     cnat_nfv9_template_info.bulk_del_inside_ip_addr_field_size =
3421         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3422
3423     cnat_nfv9_template_info.bulk_del_outside_start_port_field_type =
3424         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3425     cnat_nfv9_template_info.bulk_del_outside_start_port_field_size =
3426         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3427
3428     /*
3429      * Ds-lite bulk add template
3430      */
3431     cnat_nfv9_template_info.bulk_dslite_add_template_id =
3432         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_ADD_TEMPLATE_ID);
3433     cnat_nfv9_template_info.bulk_dslite_add_field_count =
3434         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_ADD_FIELD_COUNT);
3435
3436     cnat_nfv9_template_info.bulk_dslite_add_inside_vrf_id_field_type =
3437         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3438     cnat_nfv9_template_info.bulk_dslite_add_inside_vrf_id_field_size =
3439         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3440
3441     cnat_nfv9_template_info.bulk_dslite_add_outside_vrf_id_field_type =
3442         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_TYPE);
3443     cnat_nfv9_template_info.bulk_dslite_add_outside_vrf_id_field_size =
3444         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_VRFID_FIELD_SIZE);
3445
3446     cnat_nfv9_template_info.bulk_dslite_add_inside_ip_addr_field_type =
3447         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3448     cnat_nfv9_template_info.bulk_dslite_add_inside_ip_addr_field_size =
3449         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3450
3451     cnat_nfv9_template_info.bulk_dslite_add_inside_ipv6_addr_field_type =
3452       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3453     cnat_nfv9_template_info.bulk_dslite_add_inside_ipv6_addr_field_size =
3454       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3455
3456     cnat_nfv9_template_info.bulk_dslite_add_outside_ip_addr_field_type =
3457         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_TYPE);
3458     cnat_nfv9_template_info.bulk_dslite_add_outside_ip_addr_field_size =
3459         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_ADDR_FIELD_SIZE);
3460
3461     cnat_nfv9_template_info.bulk_dslite_add_outside_start_port_field_type =
3462         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3463     cnat_nfv9_template_info.bulk_dslite_add_outside_start_port_field_size =
3464         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3465
3466     cnat_nfv9_template_info.bulk_dslite_add_outside_end_port_field_type =
3467         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_TYPE);
3468     cnat_nfv9_template_info.bulk_dslite_add_outside_end_port_field_size =
3469         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_END_FIELD_SIZE);
3470
3471     /*
3472      * Ds-lite bulk delete template
3473      */
3474
3475     cnat_nfv9_template_info.bulk_dslite_del_template_id =
3476         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_DEL_TEMPLATE_ID);
3477     cnat_nfv9_template_info.bulk_dslite_del_field_count =
3478         clib_host_to_net_u16(CNAT_NFV9_DS_LITE_BULK_DEL_FIELD_COUNT);
3479
3480     cnat_nfv9_template_info.bulk_dslite_del_inside_vrf_id_field_type =
3481         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3482     cnat_nfv9_template_info.bulk_dslite_del_inside_vrf_id_field_size =
3483         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3484
3485     cnat_nfv9_template_info.bulk_dslite_del_inside_ip_addr_field_type =
3486         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_TYPE);
3487     cnat_nfv9_template_info.bulk_dslite_del_inside_ip_addr_field_size =
3488         clib_host_to_net_u16(CNAT_NFV9_INSIDE_IP_ADDR_FIELD_SIZE);
3489
3490     cnat_nfv9_template_info.bulk_dslite_del_inside_ipv6_addr_field_type =
3491       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_TYPE);
3492     cnat_nfv9_template_info.bulk_dslite_del_inside_ipv6_addr_field_size =
3493       clib_host_to_net_u16(CNAT_NFV9_INSIDE_IPV6_SRC_ADDR_FIELD_SIZE);
3494
3495     cnat_nfv9_template_info.bulk_dslite_del_outside_start_port_field_type =
3496         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_TYPE);
3497     cnat_nfv9_template_info.bulk_dslite_del_outside_start_port_field_size =
3498         clib_host_to_net_u16(CNAT_NFV9_OUTSIDE_IP_PORT_START_FIELD_SIZE);
3499
3500 #endif /* NO_BULK_LOGGING */
3501
3502     /*
3503      * Ingress vrfid - name mapping  
3504      */ 
3505     CNAT_NFV9_OPTION_TEMPLATE.flowset_id =
3506         clib_host_to_net_u16(CNAT_NFV9_OPTION_TEMPLATE_FLOWSET_ID);
3507     CNAT_NFV9_OPTION_TEMPLATE.length =
3508         clib_host_to_net_u16(CNAT_NFV9_OPTION_TEMPLATE_LENGTH);
3509
3510     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_template_id =
3511         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_ID_NAME_TEMPLATE_ID);
3512     /* currently no scope field supported */
3513     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_scope_len = 0;
3514     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_option_len =
3515         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_ID_NAME_OPTION_LEN);
3516     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfid_option_type =
3517         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_TYPE);
3518     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfid_option_len =
3519         clib_host_to_net_u16(CNAT_NFV9_INSIDE_VRFID_FIELD_SIZE);
3520     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfname_option_type =
3521         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_NAME_FIELD_TYPE);
3522     CNAT_NFV9_OPTION_TEMPLATE.ingress_vrfid_name_map_vrfname_option_len =
3523         clib_host_to_net_u16(CNAT_NFV9_INGRESS_VRF_NAME_FIELD_SIZE);
3524
3525     /*
3526      * Set the padding (which was added to make the size of template 
3527      * multiple of 4) to zero
3528      */
3529     CNAT_NFV9_OPTION_TEMPLATE.padding1 = 0;
3530 }
3531
3532 /*
3533  * one time function
3534  * has to be called at the init time
3535  */
3536 void cnat_nfv9_logging_init()
3537 {
3538     if (!cnat_nfv9_global_info.cnat_nfv9_init_done) {
3539         cnat_nfv9_template_init();
3540
3541         /* Pre allocate for NFV9_SERVER_POOL_SIZE. Will be good 
3542          * enough for most deployments 
3543          */
3544         pool_alloc(nfv9_server_info_pool, NFV9_SERVER_POOL_SIZE);
3545         int i;
3546         nfv9_server_info_t *server __attribute__((unused));
3547         for(i = 0; i < NFV9_SERVER_POOL_SIZE; i++) {
3548             pool_get(nfv9_server_info_pool, server);
3549         }
3550
3551         for(i = 0; i < NFV9_SERVER_POOL_SIZE; i++) {
3552             pool_put(nfv9_server_info_pool, nfv9_server_info_pool + i);
3553         }
3554
3555         memset(&cnat_nfv9_global_info, 0 , sizeof(cnat_nfv9_global_info_t));    
3556         ASSERT(cnat_nfv9_global_info.cnat_nfv9_disp_node_index != (u16)~0);
3557
3558         cnat_nfv9_global_info.cnat_nfv9_global_collector_index = EMPTY;
3559         cnat_nfv9_global_info.cnat_nfv9_init_done = 1;
3560
3561         /*
3562          * src id is set to infra IPv4 address + octeon core number
3563          */
3564         nfv9_src_id = my_instance_number;
3565     }
3566 }