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