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