1 /* *------------------------------------------------------------------
2 * cnat_cli_handler.c - CLI handler definitions
4 * Copyright (c) 2007-2015 Cisco and/or its affiliates.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *------------------------------------------------------------------
19 #include <vlib/vlib.h>
20 #include <vnet/vnet.h>
21 #include <vppinfra/vec.h>
22 #include <vppinfra/bitmap.h>
23 #include <vppinfra/hash.h>
24 #include <vppinfra/pool.h>
25 #include <vppinfra/clib.h>
26 #include <vppinfra/error.h>
29 #include "cnat_config.h"
30 #include "cnat_global.h"
32 #include "cnat_logging.h"
33 #include "cnat_syslog.h"
34 #include "cnat_config_api.h"
35 #include "cnat_show_api.h"
36 #include "cnat_show_response.h"
38 #include <arpa/inet.h>
40 u32 show_debug_level = 0;
43 cnat_get_vrfmap_nfv9_logging_index (u32 i_vrf_id)
45 cnat_nfv9_logging_info_t *my_nfv9_logging_info = 0;
46 u32 logging_index = EMPTY;
49 * Start with global logging index if available
51 if (cnat_nfv9_global_info.cnat_nfv9_init_done) {
52 logging_index = cnat_nfv9_global_info.cnat_nfv9_global_collector_index;
54 pool_foreach (my_nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
55 if (my_nfv9_logging_info->i_vrf_id == i_vrf_id) {
56 logging_index = my_nfv9_logging_info -
57 cnat_nfv9_logging_info_pool;
62 return (logging_index);
66 cnat_get_vrfmap_syslog_logging_index (u32 i_vrf_id)
68 cnat_syslog_logging_info_t *my_syslog_info = NULL;
69 u32 logging_index = EMPTY;
72 * Start with global logging index if available
74 if(PREDICT_TRUE(cnat_syslog_global_info.cnat_syslog_init_done)) {
76 pool_foreach (my_syslog_info, cnat_syslog_logging_info_pool, ({
77 if (my_syslog_info->i_vrf_id == i_vrf_id) {
78 logging_index = my_syslog_info -
79 cnat_syslog_logging_info_pool;
84 return (logging_index);
88 cnat_set_vrf_params_with_default(cnat_vrfmap_t *my_vrfmap, u32 i_vrf, u32 i_vrf_id)
91 my_vrfmap->status = S_WAO;
93 my_vrfmap->i_vrf = i_vrf;
94 my_vrfmap->i_vrf_id = i_vrf_id;
96 my_vrfmap->o_vrf = INVALID_UIDX;
97 my_vrfmap->o_vrf_id = INVALID_VRFID;
99 #ifndef NO_BULK_LOGGING
100 BULKSIZE_FROM_VRFMAP(my_vrfmap) = BULK_ALLOC_SIZE_NONE;
101 #endif /* #ifndef NO_BULK_LOGGING */
102 my_vrfmap->tcp_mss = V4_TCP_MSS_NOT_CONFIGURED_VALUE;
103 my_vrfmap->frag_tout = CNAT_IPV4_FRAG_TIMEOUT_DEF;
104 my_vrfmap->port_limit = V4_DEF_VRF_MAX_PORTS;
105 my_vrfmap->nfv9_logging_index =
106 cnat_get_vrfmap_nfv9_logging_index(i_vrf_id);
107 my_vrfmap->syslog_logging_index =
108 cnat_get_vrfmap_syslog_logging_index(i_vrf_id);
110 /* Copy logging policy from nfv9 info. */
111 if(my_vrfmap->nfv9_logging_index != EMPTY) {
112 cnat_nfv9_logging_info_t *nfv9_logging_info =
113 cnat_nfv9_logging_info_pool + my_vrfmap->nfv9_logging_index;
114 my_vrfmap->nf_logging_policy = nfv9_logging_info->logging_policy;
116 if(my_vrfmap->syslog_logging_index != EMPTY) {
117 cnat_syslog_logging_info_t *syslog_logging_info =
118 cnat_syslog_logging_info_pool + my_vrfmap->syslog_logging_index;
119 my_vrfmap->syslog_logging_policy = syslog_logging_info->logging_policy;
122 printf("Initializing params in cnat_set_vrf_params_with_default\n"
123 "my_vrfmap->status = %u\n"
124 "my_vrfmap->tcp_mss = %u\n"
125 "my_vrfmap->i_vrf = %u\n"
126 "my_vrfmap->i_vrf_id = %u\n"
127 "my_vrfmap->o_vrf = %u\n"
128 "my_vrfmap->o_vrf_id = %u\n"
129 "my_vrfmap->bulk_size = %u\n"
130 "my_vrfmap->nfv9_logging_index = %u\n"
131 "my_vrfmap->syslog_logging_index = %u\n"
132 "my_vrfmap->frag_tout = %u\n"
133 "my_vrfmap->port_limit = %u\n"
134 "my_vrfmap->nf_logging_policy = %u\n"
135 "my_vrfmap->syslog_logging_policy = %u\n",
142 my_vrfmap->bulk_size,
143 my_vrfmap->nfv9_logging_index,
144 my_vrfmap->syslog_logging_index,
145 my_vrfmap->frag_tout,
146 my_vrfmap->port_limit,
147 my_vrfmap->nf_logging_policy,
148 my_vrfmap->syslog_logging_policy);
152 /* config command handlers */
153 void cnat_nat44_add_vrf_map_t_handler(spp_api_cnat_v4_add_vrf_map_t *mp,
156 void cnat_table_entry_fill_map(u32 start_addr, u32 end_addr,
157 cnat_portmap_v2_t **port_map_holder);
158 u32 start_addr, end_addr;
159 u32 pm_len __attribute__((unused));
160 cnat_vrfmap_t *my_vrfmap = 0;
161 cnat_portmap_v2_t *pm = 0;
163 u32 ivrf_id, ovrf_id;
167 start_addr = mp->start_addr[0];
168 end_addr = mp->end_addr[0];
171 ovrf_id = mp->o_vrf_id;
172 ivrf_id = mp->i_vrf_id;
174 #if DEBUG_NOT_COMMENTED
175 vlib_cli_output(vm, "%s: saddr[0x%x], eaddr[0x%x], i_vrf[0x%x], o_vrf[0x%x], "
176 "ovrf_id[0x%x], ivrf_id[0x%x]\n", __func__, start_addr, end_addr,
177 i_vrf, o_vrf, ovrf_id, ivrf_id);
179 if (start_addr > end_addr) {
180 vlib_cli_output(vm, "Add VRF Map failed start addr 0x%x > end addr 0x%x\n",
181 start_addr, end_addr);
184 if ((end_addr - start_addr) > CNAT_MAX_ADDR_POOL_SIZE) {
185 vlib_cli_output(vm, "Add VRF Map failed start addr 0x%x - end addr "
186 "0x%x range > 65536\n", start_addr, end_addr);
189 my_vrfmap_index = vrf_map_array[i_vrf];
191 if (my_vrfmap_index != VRF_MAP_ENTRY_EMPTY) {
193 my_vrfmap = cnat_map_by_vrf + my_vrfmap_index;
195 my_vrfmap->o_vrf = o_vrf;
196 my_vrfmap->i_vrf_id = ivrf_id;
197 my_vrfmap->o_vrf_id = ovrf_id;
202 pool_get(cnat_map_by_vrf, my_vrfmap);
203 memset(my_vrfmap, 0, sizeof(*my_vrfmap));
204 /* waiting for outside vrf */
205 cnat_set_vrf_params_with_default(my_vrfmap, i_vrf, ivrf_id);
206 my_vrfmap->i_vrf = i_vrf;
207 my_vrfmap->o_vrf = o_vrf;
208 my_vrfmap->i_vrf_id = ivrf_id;
209 my_vrfmap->o_vrf_id = ovrf_id;
210 #ifndef NO_BULK_LOGGING
211 BULKSIZE_FROM_VRFMAP(my_vrfmap) = BULK_ALLOC_SIZE_NONE;
212 #endif /* #ifndef NO_BULK_LOGGING */
214 my_vrfmap->tcp_mss = V4_TCP_MSS_NOT_CONFIGURED_VALUE;
215 my_vrfmap->status = S_WA;
216 my_vrfmap->frag_tout = 0; /* currently setting it to 0 */
217 my_vrfmap->port_limit = V4_DEF_VRF_MAX_PORTS;
218 vrf_map_array[i_vrf] = (my_vrfmap - cnat_map_by_vrf);
220 pm = my_vrfmap->portmap_list;
221 pm_len = vec_len(pm);
222 for(i=0; i < 1 ; i++) {
223 start_addr = mp->start_addr[i];
224 end_addr = mp->end_addr[i];
225 if((start_addr == 0) || (end_addr == 0))
228 cnat_table_entry_fill_map(start_addr, end_addr,
229 &(my_vrfmap->portmap_list));
231 my_vrfmap->status = S_RUN;
232 vlib_cli_output(vm, "Address Pool Config Successful !!\n");
236 void cnat_nat44_set_protocol_timeout_value(u16 active,
237 u16 init, u8 *proto, u8 reset, vlib_main_t *vm)
239 if (!strncmp((char *) proto, "tcp", 3)) {
240 tcp_initial_setup_timeout = (reset) ? V4_DEF_TCP_IS_TO : init;
241 tcp_active_timeout = (reset) ? V4_DEF_TCP_AS_TO : active;
243 } else if (!strncmp((char *) proto, "udp", 3)) {
244 udp_init_session_timeout = (reset) ? V4_DEF_UDP_IS_TO : init;
245 udp_act_session_timeout = (reset) ? V4_DEF_UDP_AS_TO : active;
247 } else if (!strncmp((char *) proto, "icmp", 4)) {
248 icmp_session_timeout = (reset) ? V4_DEF_ICMP_S_TO : active;
251 vlib_cli_output(vm, "Error !! Unsupported protocol %s\n", proto);
259 /* Show command handlers */
260 void cnat_nat44_handle_show_stats(vlib_main_t *vm)
264 cnat_vrfmap_t *my_vrfmap =0;
265 cnat_portmap_v2_t *pm =0, *my_pm = 0;
268 void cnat_nfv9_show_collector
269 (vlib_main_t *vm, cnat_nfv9_logging_info_t *my_nfv9_logging_info);
271 /* active translations */
272 h = pool_header(cnat_main_db);
273 free = vec_len(h->free_indices);
274 used = vec_len(cnat_main_db) - free;
276 vlib_cli_output(vm, "vCGN NAT44 Statistics :\n");
277 vlib_cli_output(vm, "\tActive Translations : %u\n",
278 NAT44_COMMON_STATS.active_translations);
279 vlib_cli_output(vm, "\tTotal free address : %u\n", free);
280 vlib_cli_output(vm, "\tTotal used address : %u\n", used);
281 vlib_cli_output(vm, "\ti2o drops due to port limit exceeded : %lu\n",
282 in2out_drops_port_limit_exceeded);
283 vlib_cli_output(vm, "\ti2o drops due to system limit reached : %lu\n",
284 in2out_drops_system_limit_reached);
285 vlib_cli_output(vm, "\ti2o drops due to resource depletion : %lu\n",
286 in2out_drops_resource_depletion);
287 vlib_cli_output(vm, "\ti2o drops due to no translations : %lu\n",
288 NAT44_COMMON_STATS.no_translation_entry_drops);
290 vlib_cli_output(vm, "\tPool address usage:\n");
291 vlib_cli_output(vm, "\t-------------------------------------------------\n");
292 vlib_cli_output(vm, "\tExternal Address \tPorts Used\n");
293 vlib_cli_output(vm, "\t-------------------------------------------------\n");
296 pool_foreach (my_vrfmap, cnat_map_by_vrf, ({
297 pm = my_vrfmap->portmap_list;
298 pm_len = vec_len(pm);
299 for (i = 0; i < pm_len; i++) {
303 /* maximum of 200 addresses to be returned */
305 ip.s_addr = ntohl(my_pm->ipv4_address);
306 vlib_cli_output(vm, "\t%s \t\t%u\n", inet_ntoa(ip), my_pm->inuse);
314 void cnat_nat44_handle_show_config(vlib_main_t *vm)
316 cnat_vrfmap_t * my_vrfmap;
317 cnat_portmap_v2_t *pm = 0;
318 cnat_portmap_v2_t *my_pm = 0;
320 struct in_addr ip_addr;
322 cnat_nfv9_logging_info_t *my_nfv9_logging_info,
323 *global_nfv9_logging_info = 0;
324 void cnat_nfv9_show_collector
325 (vlib_main_t *vm, cnat_nfv9_logging_info_t *my_nfv9_logging_info);
327 vlib_cli_output(vm, "vCGN NAT44 Config:\n");
328 vlib_cli_output(vm, "\tPort Limit : %u\n", cnat_main_db_max_ports_per_user);
329 vlib_cli_output(vm, "\ttotal address pool : %u\n", total_address_pool_allocated);
330 vlib_cli_output(vm, "\tdynamic port start range : %u\n", cnat_static_port_range);
332 pool_foreach(my_vrfmap, cnat_map_by_vrf, ({
333 vlib_cli_output(vm, "\ti-intf-index : 0x%x\n", my_vrfmap->i_vrf);
334 vlib_cli_output(vm, "\to-intf-index : 0x%x\n", my_vrfmap->o_vrf);
336 memset(status_str, 0x00, sizeof(status_str));
337 switch(my_vrfmap->status) {
338 case S_WAO: memcpy(status_str, "S_WAO", 5); break;
339 case S_WA: memcpy(status_str, "S_WA", 4); break;
340 case S_WO: memcpy(status_str, "S_WO", 4); break;
341 case S_RUN: memcpy(status_str, "S_RUN", 5); break;
342 case S_DEL: memcpy(status_str, "S_DEL", 5); break;
343 default: memcpy(status_str, "Invalid state", 13);
347 "\tvrf map table status : %s\n", status_str);
349 pm = my_vrfmap->portmap_list;
350 pm_len = vec_len(pm);
352 ip_addr.s_addr = clib_net_to_host_u32(my_pm->ipv4_address);
354 "\tStart Address : %s\n", inet_ntoa(ip_addr));
355 my_pm = pm + (pm_len - 1);
356 ip_addr.s_addr = clib_net_to_host_u32(my_pm->ipv4_address);
358 "\tEnd Address : %s\n", inet_ntoa(ip_addr));
362 "\ttcp init timeout : %u sec\n", tcp_initial_setup_timeout);
364 "\ttcp active timeout : %u sec\n", tcp_active_timeout);
366 "\tudp init timeout : %u sec\n", udp_init_session_timeout);
368 "\tudp active timeout : %u sec\n", udp_act_session_timeout);
370 "\ticmp session timeout: %u sec\n", icmp_session_timeout);
373 if (cnat_nfv9_global_info.cnat_nfv9_global_collector_index != EMPTY) {
374 vlib_cli_output(vm,"\nGloabal NFV9 Collector :");
375 global_nfv9_logging_info = cnat_nfv9_logging_info_pool +
376 cnat_nfv9_global_info.cnat_nfv9_global_collector_index;
377 cnat_nfv9_show_collector(vm, global_nfv9_logging_info);
381 vlib_cli_output(vm, "\nNFV9 Collector :");
382 if (cnat_nfv9_logging_info_pool !=NULL) {
383 pool_foreach (my_nfv9_logging_info, cnat_nfv9_logging_info_pool, ({
384 if (my_nfv9_logging_info != global_nfv9_logging_info) {
385 cnat_nfv9_show_collector(vm, my_nfv9_logging_info);
386 vlib_cli_output(vm, "\n");
390 vlib_cli_output(vm, "\n");
397 * Check if the request flag matches the entry flags and
400 * entry_flag_ptr is an output parameter - it returns the flags
401 * corresponding to the translation entry
403 static u8 cnat_v4_show_verify_display_entry (
405 cnat_main_db_entry_t *db,
408 u8 display_entry = 0;
411 * This should never happen
413 if (!entry_flag_ptr) {
414 return (display_entry);
419 if ((db->flags & CNAT_DB_FLAG_STATIC_PORT)
420 &&(db->flags & CNAT_DB_FLAG_ALG_ENTRY)) {
421 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_STATIC;
422 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_ALG;
423 } else if (db->flags & CNAT_DB_FLAG_STATIC_PORT) {
424 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_STATIC;
425 } else if ((db->flags & CNAT_DB_FLAG_ALG_ENTRY) ||
426 (db->flags & CNAT_DB_FLAG_PPTP_GRE_ENTRY)) {
427 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_ALG;
428 } else if (db->flags & CNAT_DB_FLAG_PCPI) {
429 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_PCPI_DYNAMIC;
430 } else if (db->flags & CNAT_DB_FLAG_PCPE) {
431 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_PCPE_DYNAMIC;
433 *entry_flag_ptr |= CNAT_TRANSLATION_ENTRY_DYNAMIC;
436 if (request_flag == CNAT_TRANSLATION_ENTRY_ALL) {
440 * Check if the request_flag is STATIC or ALG
441 * and the entry is STATIC or ALG as well
443 if ((request_flag & CNAT_TRANSLATION_ENTRY_STATIC) &&
444 (*entry_flag_ptr & CNAT_TRANSLATION_ENTRY_STATIC)) {
448 if ((request_flag & CNAT_TRANSLATION_ENTRY_ALG) &&
449 (*entry_flag_ptr & CNAT_TRANSLATION_ENTRY_ALG)) {
453 if ((request_flag & CNAT_TRANSLATION_ENTRY_PCPI_DYNAMIC) &&
454 (*entry_flag_ptr & CNAT_TRANSLATION_ENTRY_PCPI_DYNAMIC)) {
458 if ((request_flag & CNAT_TRANSLATION_ENTRY_PCPE_DYNAMIC) &&
459 (*entry_flag_ptr & CNAT_TRANSLATION_ENTRY_PCPE_DYNAMIC)) {
464 * For dynamic entry case, check if flags field is 0
466 if ((request_flag & CNAT_TRANSLATION_ENTRY_DYNAMIC) &&
467 (*entry_flag_ptr & CNAT_TRANSLATION_ENTRY_DYNAMIC)) {
472 if (PREDICT_FALSE(show_debug_level > 2)) {
473 PLATFORM_DEBUG_PRINT("Entry (0x%x, %d) -> (0x%x, %d) request_flag 0x%x, entry_flag 0x%x, display_entry %d\n", db->in2out_key.k.ipv4, db->in2out_key.k.port, db->out2in_key.k.ipv4, db->out2in_key.k.port, request_flag, *entry_flag_ptr, display_entry);
476 return (display_entry);
478 void cnat_v4_show_inside_entry_req_t_handler
479 (spp_api_cnat_v4_show_inside_entry_req_t *mp, vlib_main_t * vm)
481 cnat_user_db_entry_t *udb = NULL;
482 cnat_main_db_entry_t *db = NULL;
483 cnat_db_key_bucket_t u_ki, ki;
486 u16 start_port, end_port, port;
487 u16 request_flag = 0;
492 cnat_v4_show_translation_entry *entry_list;
493 cnat_v4_show_translation_entry entry[PLATFORM_MAX_TRANSLATION_ENTRIES];
497 ki.k.k.ipv4 = mp->ipv4_addr;
498 ki.k.k.vrf = mp->vrf_id;
499 start_port = mp->start_port;
500 end_port = mp->end_port;
501 //memset(flag_str,0x00,11);
502 //strncpy(flag_str,"NA",2);
504 vlib_cli_output(vm, "## proto %d, inside-addr 0x%x, start_port %u, "
505 "end_port %u, vrf 0x%x, flag 0x%x\n",
514 proto = mp->protocol;
515 ki.k.k.vrf |= ((u16)proto << CNAT_PRO_SHIFT);
517 all = mp->all_entries; /* for no port range case */
518 request_flag = mp->flags; /* for all, alg, static entries case */
522 * check if the address is belonging to this core
527 * first we check if the user exists in the udb, if he is not then
528 * it does not make sense to check the main db for translations
530 u_ki.k.k.vrf = ki.k.k.vrf & CNAT_VRF_MASK;
531 u_ki.k.k.ipv4 = ki.k.k.ipv4;
534 if (PREDICT_FALSE(show_debug_level > 0)) {
535 vlib_cli_output(vm, "\nI_TRANS_CORE %d: IPv4 0x%x, VRF 0x%x, "
536 "start_port %d, end_port %d",
537 my_instance_number, ki.k.k.ipv4,
538 ki.k.k.vrf, start_port, end_port);
541 udb = cnat_user_db_lookup_entry(&u_ki);
543 if (PREDICT_FALSE(show_debug_level > 0)) {
544 vlib_cli_output(vm, "\nReturning %d entries",
552 if (PREDICT_FALSE(show_debug_level > 0)) {
553 PLATFORM_DEBUG_PRINT("\nI_TRANS: Printing ALL\n");
557 * get the head of list of translation entries for that user
560 head = udb->translation_list_head_index;
561 db = cnat_main_db + head;
563 while (num_entries < PLATFORM_MAX_TRANSLATION_ENTRIES) {
565 if (((db->in2out_key.k.vrf & CNAT_PRO_MASK) >> CNAT_PRO_SHIFT)
571 spp_api_cnat_v4_show_verify_display_entry(request_flag, db,
575 entry_list->ipv4_addr =
576 spp_host_to_net_byte_order_32(db->out2in_key.k.ipv4);
577 entry_list->cnat_port =
578 spp_host_to_net_byte_order_16(db->out2in_key.k.port);
579 entry_list->src_port =
580 spp_host_to_net_byte_order_16(db->in2out_key.k.port);
582 entry_list->protocol = proto;
584 /* incase of gre - in2out is not accounted */
585 if(proto != CNAT_PPTP) {
587 entry_list->in2out_packets =
588 spp_host_to_net_byte_order_32(db->in2out_pkts);
590 entry_list->in2out_packets = 0;
592 entry_list->out2in_packets =
593 spp_host_to_net_byte_order_32(db->out2in_pkts);
596 spp_host_to_net_byte_order_16(entry_flag);
599 entry_list = entry_list + 1;
602 db = cnat_main_db + db->user_ports.next;
604 * its a circular list, so if we have reached the head again
605 * all the entries for that user have been read
607 if (db == (cnat_main_db + head)) {
611 resp->num_entries = num_entries;
614 if (PREDICT_FALSE(show_debug_level > 0)) {
615 vlib_cli_output(vm, "\nI_TRANS: Printing range %d .. %d\n",
616 start_port, end_port);
619 * port range is specified so for each port calculate the hash and
620 * check if the entry is present in main db
624 while ((!done) && (num_entries < PLATFORM_MAX_TRANSLATION_ENTRIES)) {
627 if (port >= end_port) {
632 CNAT_V4_GET_HASH(ki.k.key64,
634 CNAT_MAIN_HASH_MASK);
635 index = cnat_in2out_hash[ki.bucket].next;
636 if (PREDICT_TRUE(index == EMPTY)) {
641 db = cnat_main_db + index;
642 if (db->in2out_key.key64 == ki.k.key64) {
645 index = db->in2out_hash.next;
646 } while (index != EMPTY);
648 if (index == EMPTY) {
653 cnat_v4_show_verify_display_entry(request_flag, db,
657 entry_list->ipv4_addr =
658 clib_host_to_net_u32(db->out2in_key.k.ipv4);
659 entry_list->cnat_port =
660 clib_host_to_net_u16(db->out2in_key.k.port);
661 entry_list->src_port =
662 clib_host_to_net_u16(db->in2out_key.k.port);
664 entry_list->protocol = proto;
665 entry_list->nsessions = db->nsessions;
666 entry_list->flags = ((db->flags & CNAT_DB_FLAG_TCP_ACTIVE) ||
667 (db->flags & CNAT_DB_FLAG_UDP_ACTIVE)) ? 1:0;
668 /* incase of gre - in2out is not accounted */
669 if(proto != CNAT_PPTP) {
670 entry_list->in2out_packets =
671 clib_host_to_net_u32(db->in2out_pkts);
673 entry_list->in2out_packets = 0;
676 entry_list->out2in_packets =
677 clib_host_to_net_u32(db->out2in_pkts);
679 if (PREDICT_FALSE(show_debug_level > 3)) {
680 vlib_cli_output(vm, "\n1. Entry: Addr 0x%x, port %d, num_entries %d",
681 clib_net_to_host_u32(entry_list->ipv4_addr),
682 clib_net_to_host_u16(entry_list->cnat_port),
686 entry_list = entry_list + 1;
689 } /* if (index == EMPTY) */
693 if (PREDICT_FALSE(show_debug_level > 0)) {
695 vlib_cli_output(vm, "\nReturning %d entries\n",
705 memset(proto_str, 0x00, 10);
706 memset(transl_str, 0x00, 10);
708 if (proto == 1) strncpy((char *)proto_str, "udp", 3);
709 else if (proto == 2) strncpy((char *)proto_str, "tcp", 3);
710 else if (proto == 3) strncpy((char *)proto_str, "icmp", 4);
711 else strncpy((char *)proto_str, "unknown", 7);
713 if (request_flag == 0x04) strncpy((char *)transl_str, "Dynamic", 7);
714 else strncpy((char *)transl_str, "Unknown", 7); /* currently we are not supporting static/alg entries */
716 ip.s_addr = clib_net_to_host_u32(u_ki.k.k.ipv4);
718 vlib_cli_output (vm, "Inside-translation details\n");
719 vlib_cli_output (vm, "--------------------------\n");
721 vlib_cli_output (vm, "Inside interface index : 0x%x\n", u_ki.k.k.vrf);
722 vlib_cli_output (vm, "Inside address : %s\n", inet_ntoa(ip));
723 vlib_cli_output (vm, "Start port : %u\n", start_port);
724 vlib_cli_output (vm, "End port : %u\n", end_port);
726 vlib_cli_output (vm, "--------------------------------------------------------------------------------------"
727 "-----------------------\n");
728 vlib_cli_output (vm, "Outside Protocol Inside Outside Translation"
729 " I2O O2I Flag Num\n");
730 vlib_cli_output (vm, "Address Src Port Src Port Type "
731 " Pkts Pkts Sessions\n");
732 vlib_cli_output (vm, "--------------------------------------------------------------------------------------"
733 "-----------------------\n");
735 while ((num_entries) && (entry_list) && (i < 50)) {
737 ip.s_addr = entry_list->ipv4_addr;
738 memset(flag_str,0x00,11);
739 if((proto == 1) || (proto == 2)) {
740 if(entry_list->flags == 1) {
741 strncpy((char *)flag_str,"Active",6);
744 strncpy((char *) flag_str,"Non Active",10);
747 strncpy((char *) flag_str, "NA", 2);
749 vlib_cli_output(vm, "%s %10s %11u %12u %13s %10u %10u %14s %6u\n",
750 inet_ntoa(ip), proto_str,
751 clib_net_to_host_u16(entry_list->src_port),
752 clib_net_to_host_u16(entry_list->cnat_port),
754 clib_net_to_host_u32(entry_list->in2out_packets),
755 clib_net_to_host_u32(entry_list->out2in_packets),
757 entry_list->nsessions);
765 void cnat_v4_show_outside_entry_req_t_handler
766 (spp_api_cnat_v4_show_outside_entry_req_t *mp, vlib_main_t *vm)
768 cnat_main_db_entry_t *db = NULL;
769 cnat_db_key_bucket_t ko;
772 u16 start_port, end_port, port;
773 u16 request_flag = 0;
777 cnat_v4_show_translation_entry *entry_list;
778 cnat_v4_show_translation_entry entry[PLATFORM_MAX_TRANSLATION_ENTRIES];
783 ko.k.k.ipv4 = mp->ipv4_addr;
784 ko.k.k.vrf = mp->vrf_id;
785 start_port = mp->start_port;
786 end_port = mp->end_port;
788 proto = mp->protocol;
789 request_flag = mp->flags;
791 ko.k.k.vrf |= ((u16)proto << CNAT_PRO_SHIFT);
795 if (PREDICT_FALSE(show_debug_level > 0)) {
796 vlib_cli_output(vm, "\nO_TRANS_CORE %d: IPv4 0x%x, VRF 0x%x, "
797 "start_port %d, end_port %d", my_instance_number,
798 ko.k.k.ipv4, ko.k.k.vrf, start_port, end_port);
802 * for each ip and port combination we need to scan the main db
803 * and check if the entry is present in main db
807 while ((!done) && (num_entries < PLATFORM_MAX_TRANSLATION_ENTRIES)) {
811 * If we have reached the end_port, we are DONE
813 if (port >= end_port) {
819 CNAT_V4_GET_HASH(ko.k.key64,
821 CNAT_MAIN_HASH_MASK);
823 index = cnat_out2in_hash[ko.bucket].next;
824 if (PREDICT_TRUE(index == EMPTY)) {
829 db = cnat_main_db + index;
830 if (db->out2in_key.key64 == ko.k.key64) {
833 index = db->out2in_hash.next;
834 } while (index != EMPTY);
836 if (index == EMPTY) {
840 cnat_v4_show_verify_display_entry(request_flag, db,
844 entry_list->ipv4_addr =
845 clib_host_to_net_u32(db->in2out_key.k.ipv4);
846 entry_list->cnat_port =
847 clib_host_to_net_u16(db->out2in_key.k.port);
848 entry_list->src_port =
849 clib_host_to_net_u16(db->in2out_key.k.port);
850 entry_list->protocol = proto;
851 entry_list->nsessions = db->nsessions;
852 entry_list->flags = ((db->flags & CNAT_DB_FLAG_TCP_ACTIVE) ||
853 (db->flags & CNAT_DB_FLAG_UDP_ACTIVE)) ? 1:0;
854 /* incase of gre - in2out is not accounted */
855 if(proto != CNAT_PPTP) {
856 entry_list->in2out_packets =
857 clib_host_to_net_u32(db->in2out_pkts);
859 entry_list->in2out_packets = 0 ;
861 entry_list->out2in_packets =
862 clib_host_to_net_u32(db->out2in_pkts);
865 clib_host_to_net_u16(entry_flag);
867 entry_list = entry_list + 1;
873 if (num_entries == 0) {
874 /* No point proceeding further */
878 if (PREDICT_FALSE(show_debug_level > 0)) {
880 vlib_cli_output(vm, "\nO_TRANS: Core %d returning %d entries",
890 memset(proto_str, 0x00, 10);
891 memset(transl_str, 0x00, 10);
893 if (proto == 1) strncpy((char *) proto_str, "udp", 3);
894 else if (proto == 2) strncpy((char *) proto_str, "tcp", 3);
895 else if (proto == 3) strncpy((char *) proto_str, "icmp", 4);
896 else strncpy((char *) proto_str, "unknown", 7);
898 if (request_flag == 0x04) strncpy((char *) transl_str, "Dynamic", 7);
899 else strncpy((char *)transl_str, "Unknown", 7); /* currently we are not supporting static/alg entries */
901 ip.s_addr = clib_net_to_host_u32(ko.k.k.ipv4);
903 vlib_cli_output (vm, "Outside-translation details\n");
904 vlib_cli_output (vm, "--------------------------\n");
906 vlib_cli_output (vm, "Outside interface index : 0x%x\n", (ko.k.k.vrf & CNAT_VRF_MASK));
907 vlib_cli_output (vm, "Outside address : %s\n", inet_ntoa(ip));
908 vlib_cli_output (vm, "Start port : %u\n", start_port);
909 vlib_cli_output (vm, "End port : %u\n", end_port);
911 vlib_cli_output (vm, "--------------------------------------------------------------------------------------"
912 "-----------------------\n");
913 vlib_cli_output (vm, "Inside Protocol Outside Inside Translation"
914 " I2O O2I Flag Num\n");
915 vlib_cli_output (vm, "Address Dst Port Dst Port Type "
916 " Pkts Pkts Sessions\n");
917 vlib_cli_output (vm, "--------------------------------------------------------------------------------------"
918 "-----------------------\n");
920 while ((num_entries) && (entry_list) && (i < 50)) {
921 ip.s_addr = entry_list->ipv4_addr;
922 memset(flag_str,0x00,11);
923 if((proto == 1) || (proto == 2)) {
924 if(entry_list->flags == 1) {
925 strncpy((char *) flag_str,"Active",6);
928 strncpy((char *) flag_str,"Non Active",10);
931 strncpy((char *) flag_str, "NA", 2);
933 vlib_cli_output(vm, "%s %10s %11u %12u %13s %10u %10u %14s %6u\n",
934 inet_ntoa(ip), proto_str,
935 clib_net_to_host_u16(entry_list->cnat_port),
936 clib_net_to_host_u16(entry_list->src_port),
938 clib_net_to_host_u32(entry_list->in2out_packets),
939 clib_net_to_host_u32(entry_list->out2in_packets),
941 entry_list->nsessions);