Merge changes from PROX-v041
[samplevnf.git] / VNFs / vCGNAPT / pipeline / pipeline_cgnapt_be.c
index 2fbc71d..a1779aa 100644 (file)
@@ -64,6 +64,7 @@
 #include "vnf_common.h"
 #include "lib_sip_alg.h"
 #include "lib_icmpv6.h"
+#include "gateway.h"
 
 #include "pipeline_common_fe.h"
 #ifdef CT_CGNAT
@@ -83,7 +84,7 @@ uint8_t n_cgnapt_pipeline;
 struct pipeline_cgnapt *global_pnat;
 
 uint64_t arp_pkts_mask;
-extern struct arp_entry_data *arp_data_ptr[16];
+
 /* To know egress or ingress port */
 static uint8_t cgnapt_in_port_egress_prv[PIPELINE_MAX_PORT_IN];
 static uint8_t cgnapt_prv_que_port_index[PIPELINE_MAX_PORT_IN];
@@ -177,25 +178,6 @@ uint8_t well_known_prefix[16] = {
        0x00, 0x00, 0x00, 0x00
 };
 
-static uint32_t local_get_nh_ipv4(
-       uint32_t ip,
-       uint32_t *port,
-       uint32_t *nhip,
-       struct pipeline_cgnapt *p_nat);
-static void do_local_nh_ipv4_cache(
-       uint32_t dest_if,
-       struct pipeline_cgnapt *p_nat);
-
-static uint32_t local_get_nh_ipv6(
-       uint8_t *ip,
-       uint32_t *port,
-       uint8_t nhip[],
-       struct pipeline_cgnapt *p_nat);
-
-static void do_local_nh_ipv6_cache(
-       uint32_t dest_if,
-       struct pipeline_cgnapt *p_nat);
-
 static uint8_t check_arp_icmp(
        struct rte_mbuf *pkt,
        uint64_t pkt_mask,
@@ -223,211 +205,6 @@ uint64_t nextPowerOf2(uint64_t n)
        return n;
 }
 
-void remove_local_cache(uint8_t port)
-{
-       link_hw_laddr_valid[port] = 0;
-}
-
-/**
- * Function to get MAC addr of local link
- *
- * @params out_port
- *  Physical port number
- *
- * @return
- *  Outport Link MAC addr
- */
-
-//struct ether_addr *get_local_link_hw_addr(uint8_t out_port)
-//{
-//     return &link_hw_laddr[out_port];
-//}
-
-/**
- * Function to get MAC addr from array instead of hash table
- *
- * @params out_port
- *  Physical port number
- *
- * @return
- *  Outport Link MAC addr
- */
-
-uint8_t local_dest_mac_present(uint8_t out_port)
-{
-       return link_hw_laddr_valid[out_port];
-}
-
-/**
- * Function to get IPv4-IP NH from thread local array
- *
- * @params ip
- *  IPv4 - IP
- * @params port
- *  NH port number
- * @params nhip
- *  NHIP of IPv4 type
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- * @return
- *  1 on success, 0 for failure
- */
-
-static uint32_t local_get_nh_ipv4(
-       uint32_t ip,
-       uint32_t *port,
-       uint32_t *nhip,
-       struct pipeline_cgnapt *p_nat)
-{
-       int i;
-       for (i = 0; i < p_nat->local_lib_arp_route_ent_cnt; i++) {
-               if (((p_nat->local_lib_arp_route_table[i].ip &
-                       p_nat->local_lib_arp_route_table[i].mask) ==
-                       (ip & p_nat->local_lib_arp_route_table[i].mask))) {
-                       *port = p_nat->local_lib_arp_route_table[i].port;
-
-                       *nhip = p_nat->local_lib_arp_route_table[i].nh;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/**
- * Function to make local copy for NH of type IPv4
- *
- * @params dest_if
- *  Physical port number
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- */
-
-static void do_local_nh_ipv4_cache(
-       uint32_t dest_if,
-       struct pipeline_cgnapt *p_nat)
-{
-
-       /* Search for the entry and do local copy */
-       int i;
-
-       for (i = 0; i < MAX_ARP_RT_ENTRY; i++) {
-               if (lib_arp_route_table[i].port == dest_if) {
-
-                       struct lib_arp_route_table_entry *lentry =
-                               &p_nat->local_lib_arp_route_table
-                                       [p_nat->local_lib_arp_route_ent_cnt];
-
-                       lentry->ip   = lib_arp_route_table[i].ip;
-                       lentry->mask = lib_arp_route_table[i].mask;
-                       lentry->port = lib_arp_route_table[i].port;
-                       lentry->nh   = lib_arp_route_table[i].nh;
-
-                       p_nat->local_lib_arp_route_ent_cnt++;
-                                               break;
-               }
-       }
-}
-
-
-/**
- * Function to get IPv6-IP NH from thread local array
- *
- * @params ip
- *  Pointer to starting addr of IPv6
- * @params port
- *  NH port number
- * @params nhip
- *  NHIP of IPv6 type
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- * @return
- *  1 on success, 0 for failure
- */
-
-static uint32_t local_get_nh_ipv6(
-       uint8_t *ip,
-       uint32_t *port,
-       uint8_t nhip[],
-       struct pipeline_cgnapt *p_nat)
-{
-       int i = 0;
-       uint8_t netmask_ipv6[16];
-       uint8_t k = 0, l = 0, depthflags = 0, depthflags1 = 0;
-
-       for (i = 0; i < p_nat->local_lib_nd_route_ent_cnt; i++) {
-
-               convert_prefixlen_to_netmask_ipv6(
-                       p_nat->local_lib_nd_route_table[i].depth,
-                       netmask_ipv6);
-
-               for (k = 0; k < 16; k++)
-                       if (p_nat->local_lib_nd_route_table[i].ipv6[k] &
-                                       netmask_ipv6[k])
-                               depthflags++;
-
-               for (l = 0; l < 16; l++)
-                       if (ip[l] & netmask_ipv6[l])
-                               depthflags1++;
-
-               int j = 0;
-               if (depthflags == depthflags1) {
-                       *port = p_nat->local_lib_nd_route_table[i].port;
-
-                       for (j = 0; j < 16; j++)
-                               nhip[j] = p_nat->local_lib_nd_route_table[i].
-                                               nhipv6[j];
-                       return 1;
-               }
-
-               depthflags = 0;
-               depthflags1 = 0;
-                       }
-                       return 0;
-}
-
-
-/**
- * Function to make local copy for NH of type IPv6
- *
- * @params dest_if
- *  Physical port number
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- */
-
-static void do_local_nh_ipv6_cache(
-       uint32_t dest_if,
-       struct pipeline_cgnapt *p_nat)
-{
-               /* Search for the entry and do local copy */
-       int i, l;
-       for (i = 0; i < MAX_ND_RT_ENTRY; i++) {
-
-               if (lib_nd_route_table[i].port == dest_if) {
-
-                       struct lib_nd_route_table_entry *lentry =
-                               &p_nat->local_lib_nd_route_table
-                                       [p_nat->local_lib_nd_route_ent_cnt];
-
-                       for (l = 0; l < 16; l++) {
-                               lentry->ipv6[l]   =
-                                       lib_nd_route_table[i].ipv6[l];
-                               lentry->nhipv6[l] =
-                                       lib_nd_route_table[i].nhipv6[l];
-                       }
-                       lentry->depth = lib_nd_route_table[i].depth;
-                       lentry->port  = lib_nd_route_table[i].port;
-
-                       p_nat->local_lib_nd_route_ent_cnt++;
-                       break;
-                       } //if
-               } //for
-}
-
 #ifdef SIP_ALG
 /* Commented code may be required for future usage, Please keep it*/
 #if 0
@@ -754,7 +531,7 @@ void hw_checksum(struct rte_mbuf *pkt, enum PKT_TYPE ver)
                prot_offset = PROT_OFST_IP4 + temp;
                break;
        default:
-               printf("hw_checksum: pkt version is invalid\n");
+                   printf("hw_checksum: pkt version is invalid\n");
        }
        protocol = (uint8_t *) RTE_MBUF_METADATA_UINT8_PTR(pkt,
                         prot_offset);
@@ -802,7 +579,9 @@ void hw_checksum(struct rte_mbuf *pkt, enum PKT_TYPE ver)
                break;
 
        default:
-               printf("hw_checksum() : Neither TCP or UDP pkt\n");
+        #ifdef CGNAPT_DEBUGGING
+                   printf("hw_checksum() : Neither TCP or UDP pkt\n");
+  #endif
                break;
        }
 }
@@ -860,7 +639,7 @@ void sw_checksum(struct rte_mbuf *pkt, enum PKT_TYPE ver)
                prot_offset = PROT_OFST_IP4 + temp;
                break;
        default:
-               printf("sw_checksum: pkt version is invalid\n");
+                    printf("sw_checksum: pkt version is invalid\n");
        }
        protocol = (uint8_t *) RTE_MBUF_METADATA_UINT8_PTR(pkt,
                         prot_offset);
@@ -913,12 +692,14 @@ void sw_checksum(struct rte_mbuf *pkt, enum PKT_TYPE ver)
                break;
 
        default:
-               printf("sw_checksum() : Neither TCP or UDP pkt\n");
+        #ifdef CGNAPT_DEBUGGING
+                   printf("sw_checksum() : Neither TCP or UDP pkt\n");
+               #endif
                break;
        }
 }
 
-void print_pkt_info(uint8_t *eth_dest, struct ether_addr *hw_addr, 
+void print_pkt_info(uint8_t *eth_dest, struct ether_addr *hw_addr,
                uint32_t dest_address, uint32_t port_id, struct rte_mbuf *pkt)
 {
 
@@ -960,7 +741,6 @@ static uint8_t check_arp_icmp(
 
        /* ARP outport number */
        uint16_t out_port = p_nat->p.n_ports_out - 1;
-       printf("check_arp_icmp called*****\n");
        uint8_t *protocol;
        uint32_t prot_offset;
 
@@ -1140,8 +920,10 @@ int napt_port_alloc_init(struct pipeline_cgnapt *p_nat)
        uint32_t vnf_set_num = p_nat->vnf_set;
        /*uint32_t vnf_set_num = get_vnf_set_num(p_nat->pipeline_num); */
 
-       printf("VNF set number for CGNAPT %d is %d.\n", p_nat->pipeline_num,
-                        vnf_set_num);
+       #ifdef CGNAPT_DBG_PRNT
+            printf("VNF set number for CGNAPT %d is %d.\n", p_nat->pipeline_num,
+             vnf_set_num);
+       #endif
        if (vnf_set_num == 0xFF) {
                printf("VNF set number for CGNAPT %d is invalid %d.\n",
                                 p_nat->pipeline_num, vnf_set_num);
@@ -1713,7 +1495,6 @@ void print_common_table(void)
  * @return
  *  int that is not checked by caller
  */
-
 static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                 struct rte_mbuf **pkts,
                                 uint32_t n_pkts, void *arg)
@@ -2166,7 +1947,7 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                uint8_t nh_ipv6[16];
                uint32_t nhip = 0;
 
-               uint32_t dest_if = 0xff;
+               uint32_t dest_if = INVALID_DESTIF;
                uint32_t ret;
 
                uint16_t *outport_id =
@@ -2179,53 +1960,56 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        && rte_be_to_cpu_16(*dst_port) == 53) {
                        p_nat->invalid_packets |= 1LLU << pkt_index;
                        p_nat->naptDroppedPktCount++;
-                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                        p_nat->naptDroppedPktCount6++;
-                       #endif
+#endif
                        continue;
                        }
 
                        dest_address = rte_bswap32(*dst_addr);
-                       ret = local_get_nh_ipv4(dest_address, &dest_if,
-                                       &nhip, p_nat);
-                       if (!ret) {
-                               dest_if = get_prv_to_pub_port(&dest_address,
-                                               IP_VERSION_4);
-                               if (dest_if == INVALID_DESTIF) {
-                                       p_nat->invalid_packets |=
-                                               1LLU << pkt_index;
-                                       p_nat->naptDroppedPktCount++;
-                                       #ifdef CGNAPT_DEBUGGING
-                                       p_nat->naptDroppedPktCount6++;
-                                       #endif
-                                       continue;
-                               }
-                               do_local_nh_ipv4_cache(dest_if, p_nat);
-                       }
-
-                       *outport_id = p_nat->outport_id[dest_if];
-                       struct arp_entry_data *ret_arp_data;
-                       ret_arp_data = get_dest_mac_addr_port(dest_address,
-                               &dest_if, (struct ether_addr *)&hw_addr);
+                       /* Gateway Proc Starts */
 
-                       if (unlikely(ret_arp_data == NULL)) {
+                       struct arp_entry_data *ret_arp_data = NULL;
+                       uint32_t src_phy_port = *src_port;
 
-                               printf("%s: NHIP Not Found, nhip: %x, "
-                               "outport_id: %d\n", __func__, nhip,
-                               *outport_id);
+                       gw_get_nh_port_ipv4(dest_address,
+                                       &dest_if, &nhip);
 
-                               /* Drop the pkt */
-                               p_nat->invalid_packets |= pkt_mask;
+                       if (dest_if == INVALID_DESTIF) {
+                               p_nat->invalid_packets |=
+                                       1LLU << pkt_index;
                                p_nat->naptDroppedPktCount++;
-
-                               #ifdef CGNAPT_DEBUGGING
-                               p_nat->naptDroppedPktCount4++;
-                               #endif
+#ifdef CGNAPT_DEBUGGING
+                               p_nat->naptDroppedPktCount6++;
+#endif
                                continue;
                        }
 
+               *outport_id = p_nat->outport_id[dest_if];
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if, &hw_addr);
+
+               if (unlikely(ret_arp_data == NULL)) {
+
+                       #ifdef CGNAPT_DEBUGGING
+                       printf("%s: NHIP Not Found, nhip: %x, "
+                       "outport_id: %d\n", __func__, nhip,
+                       *outport_id);
+                       #endif
+                       /* Drop the pkt */
+                       p_nat->invalid_packets |= pkt_mask;
+                       p_nat->naptDroppedPktCount++;
+
+                       #ifdef CGNAPT_DEBUGGING
+                       p_nat->naptDroppedPktCount4++;
+                       #endif
+                       continue;
+               }
+
+               /* Gateway Proc Ends */
+
                        if (ret_arp_data->status == COMPLETE) {
-                               
+
                                if (ret_arp_data->num_pkts) {
                                        p_nat->naptedPktCount += ret_arp_data->num_pkts;
                                        arp_send_buffered_pkts(ret_arp_data,
@@ -2266,7 +2050,7 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                        print_pkt(pkts[pkt_index]);
                                #endif
 
-                       } else if (ret_arp_data->status == INCOMPLETE || 
+                       } else if (ret_arp_data->status == INCOMPLETE ||
                                ret_arp_data->status == PROBE) {
                                if (ret_arp_data->num_pkts >= NUM_DESC) {
                                        /* Drop the pkt */
@@ -2353,74 +2137,68 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        memcpy((uint8_t *) &dst_addr[0],
                                         &entry->data.u.prv_ipv6[0], 16);
                        memset(nh_ipv6, 0, 16);
+                       struct nd_entry_data *ret_nd_data = NULL;
 
-                       ret = local_get_nh_ipv6((uint8_t *)&dst_addr[0],
-                               &dest_if, &nh_ipv6[0], p_nat);
+                       dest_if = INVALID_DESTIF;
 
-                       if (!ret) {
-                               dest_if = get_prv_to_pub_port(
-                                               &dst_addr[0],
-                                               IP_VERSION_6);
-                               if (dest_if == INVALID_DESTIF) {
-                                       p_nat->invalid_packets |=
-                                               1LLU << pkt_index;
+                       uint32_t src_phy_port = pkts[pkt_index]->port;
+
+                       gw_get_nh_port_ipv6((uint8_t *) &dst_addr[0],
+                                       &dest_if, &nh_ipv6[0]);
+
+                       ret_nd_data = get_dest_mac_addr_ipv6(&nh_ipv6[0],
+                                       dest_if, &hw_addr);
+                       *outport_id = p_nat->outport_id[dest_if];
+
+                       if (nd_cache_dest_mac_present(dest_if)) {
+                               ether_addr_copy(get_link_hw_addr(dest_if),
+                                               (struct ether_addr *)eth_src);
+                               update_nhip_access(dest_if);
+
+                               if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                                       p_nat->naptedPktCount += ret_nd_data->num_pkts;
+                                       nd_send_buffered_pkts(ret_nd_data,
+                                                       (struct ether_addr *)eth_dest,
+                                                       *outport_id);
+                               }
+                       } else {
+                               if (unlikely(ret_nd_data == NULL)) {
+
+                                       #ifdef CGNAPT_DEBUGGING
+                                       printf("%s: NHIP Not Found, "
+                                       "outport_id: %d\n", __func__,
+                                       *outport_id);
+                                       #endif
+
+                                       /* Drop the pkt */
+                                       p_nat->invalid_packets |= pkt_mask;
                                        p_nat->naptDroppedPktCount++;
+
                                        #ifdef CGNAPT_DEBUGGING
-                                       p_nat->naptDroppedPktCount6++;
+                                       p_nat->naptDroppedPktCount4++;
                                        #endif
                                        continue;
                                }
-                               do_local_nh_ipv6_cache(dest_if, p_nat);
-                       }
-                       *outport_id = p_nat->outport_id[dest_if];
-
-                       if (get_dest_mac_address_ipv6_port((uint8_t *)
-                               &dst_addr[0], &dest_if,
-                               &hw_addr, &nh_ipv6[0])){
-
-                               #ifdef CGNAPT_DBG_PRNT
-                               if (CGNAPT_DEBUG > 2) {
-                               printf("MAC found for ip 0x%x, port %d - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               dest_address, *outport_id,
-                               hw_addr.addr_bytes[0],
-                               hw_addr.addr_bytes[1], hw_addr.addr_bytes[2],
-                               hw_addr.addr_bytes[3], hw_addr.addr_bytes[4],
-                               hw_addr.addr_bytes[5]);
 
-                               printf("Dest MAC before - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2],
-                               eth_dest[3], eth_dest[4], eth_dest[5]);
+                               if (ret_nd_data->status == INCOMPLETE ||
+                                       ret_nd_data->status == PROBE) {
+                                       if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                               /* Drop the pkt */
+                                               p_nat->invalid_packets |= pkt_mask;
+                                               p_nat->naptDroppedPktCount++;
+
+                                               #ifdef CGNAPT_DEBUGGING
+                                               p_nat->naptDroppedPktCount4++;
+                                               #endif
+                                               continue;
+                                       } else {
+                                               arp_pkts_mask |= pkt_mask;
+                                               nd_queue_unresolved_packet(ret_nd_data,
+                                                        pkts[pkt_index]);
+                                               continue;
+                                       }
                                }
-                               #endif
-                                       memcpy(eth_dest, &hw_addr,
-                                               sizeof(struct ether_addr));
-                                       memcpy(eth_src, get_link_hw_addr(
-                                               dest_if),
-                                               sizeof(struct ether_addr));
-
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                               printf("Dest MAC after - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2],
-                               eth_dest[3], eth_dest[4], eth_dest[5]);
-                       }
-                       #endif
-
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 4)
-                               print_pkt(pkts[pkt_index]);
-                       #endif
-                       } else {
 
-                               p_nat->invalid_packets |= pkt_mask;
-                               p_nat->naptDroppedPktCount++;
-                               #ifdef CGNAPT_DEBUGGING
-                               p_nat->naptDroppedPktCount4++;
-                               #endif
-                               continue;
                        }
 
                        #ifdef NAT_ONLY_CONFIG_REQ
@@ -2435,44 +2213,49 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        } else {
                                *dst_addr = rte_bswap32(entry->data.u.prv_ip);
                                dest_address = entry->data.u.prv_ip;
-                               ret = local_get_nh_ipv4(dest_address, &dest_if,
-                                       &nhip, p_nat);
-                               if (!ret) {
-                                       dest_if = get_pub_to_prv_port(
-                                               &dest_address, IP_VERSION_4);
+                               /* Gateway Proc Starts */
+
+                               struct arp_entry_data *ret_arp_data = NULL;
+                               dest_if = INVALID_DESTIF;
+                               uint32_t src_phy_port = *src_port;
+
+                               gw_get_nh_port_ipv4(dest_address,
+                                               &dest_if, &nhip);
+
                                if (dest_if == INVALID_DESTIF) {
                                        p_nat->invalid_packets |=
                                                1LLU << pkt_index;
                                        p_nat->naptDroppedPktCount++;
-                                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                                        p_nat->naptDroppedPktCount6++;
-                                       #endif
+#endif
                                        continue;
                                }
-                                       do_local_nh_ipv4_cache(dest_if, p_nat);
-                               };
 
                                *outport_id = p_nat->outport_id[dest_if];
-                               struct arp_entry_data *ret_arp_data;
-                               ret_arp_data = get_dest_mac_addr_port(dest_address,
-                                       &dest_if, (struct ether_addr *)&hw_addr);
+
+                               ret_arp_data = get_dest_mac_addr_ipv4(nhip,
+                                               dest_if, (struct ether_addr *)&hw_addr);
 
                                if (unlikely(ret_arp_data == NULL)) {
 
+#ifdef CGNAPT_DEBUGGING
                                        printf("%s: NHIP Not Found, nhip: %x, "
-                                       "outport_id: %d\n", __func__, nhip,
-                                       *outport_id);
-
+                                                       "outport_id: %d\n", __func__, nhip,
+                                                       *outport_id);
+#endif
                                        /* Drop the pkt */
                                        p_nat->invalid_packets |= pkt_mask;
                                        p_nat->naptDroppedPktCount++;
 
-                                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                                        p_nat->naptDroppedPktCount4++;
-                                       #endif
+#endif
                                        continue;
                                }
 
+                               /* Gateway Proc Ends */
+
                                if (ret_arp_data->status == COMPLETE) {
 
                                        if (ret_arp_data->num_pkts) {
@@ -2492,9 +2275,9 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                        printf("MAC found for ip 0x%x, port %d - "
                                        "%02x:%02x:%02x:%02x:%02x:%02x\n",
                                        dest_address, *outport_id,
-                                       hw_addr.addr_bytes[0], hw_addr.addr_bytes[1],
-                                       hw_addr.addr_bytes[2], hw_addr.addr_bytes[3],
-                                       hw_addr.addr_bytes[4], hw_addr.addr_bytes[5]);
+                                       hw_addr.addr_bytes[0], hw_addr.addr_bytes[1],
+                                       hw_addr.addr_bytes[2], hw_addr.addr_bytes[3],
+                                       hw_addr.addr_bytes[4], hw_addr.addr_bytes[5]);
 
                                        printf("Dest MAC before - "
                                        "%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -2517,7 +2300,7 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                                print_pkt(pkts[pkt_index]);
                                        #endif
 
-                               } else if (ret_arp_data->status == INCOMPLETE || 
+                               } else if (ret_arp_data->status == INCOMPLETE ||
                                        ret_arp_data->status == PROBE) {
                                        arp_queue_unresolved_packet(ret_arp_data,
                                                pkts[pkt_index]);
@@ -2673,9 +2456,6 @@ static int cgnapt_in_port_ah_ipv4_prv(struct rte_pipeline *rte_p,
                                                [p_nat->lkup_indx[j]]);
        }
 
-       //prefetch();
-
-
        for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)
                pkt4_work_cgnapt_ipv4_prv(pkts, i, arg, p_nat);
 
@@ -3814,7 +3594,7 @@ pkt_work_cgnapt_ipv4_prv(
 
        uint8_t protocol = RTE_MBUF_METADATA_UINT8(pkt, PROT_OFST_IP4);
 
-       uint32_t dest_if = 0xff;        /* Added for Multiport */
+       uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
        uint16_t *outport_id =
                RTE_MBUF_METADATA_UINT16_PTR(pkt, cgnapt_meta_offset);
 
@@ -3915,6 +3695,12 @@ pkt_work_cgnapt_ipv4_prv(
                src_port = RTE_MBUF_METADATA_UINT16_PTR(pkt, src_port_offset);
                dst_port = RTE_MBUF_METADATA_UINT16_PTR(pkt, dst_port_offset);
        break;
+       default: /* KW fix: unknown is treated as TCP/UDP */
+               src_port_offset = SRC_PRT_OFST_IP4_TCP;
+               dst_port_offset = DST_PRT_OFST_IP4_TCP;
+               src_port = RTE_MBUF_METADATA_UINT16_PTR(pkt, src_port_offset);
+               dst_port = RTE_MBUF_METADATA_UINT16_PTR(pkt, dst_port_offset);
+       break;
        }
 
        uint8_t *eth_dest = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
@@ -3923,7 +3709,6 @@ pkt_work_cgnapt_ipv4_prv(
        if (entry->data.ttl == NAPT_ENTRY_STALE)
                entry->data.ttl = NAPT_ENTRY_VALID;
 
-       struct ether_addr hw_addr;
        uint32_t dest_address = 0;
 
        /* Egress */
@@ -3941,27 +3726,34 @@ pkt_work_cgnapt_ipv4_prv(
        dest_address = rte_bswap32(*dst_addr);
        uint32_t nhip = 0;
        struct arp_entry_data *ret_arp_data = NULL;
-       ret_arp_data = get_dest_mac_addr_port(dest_address, &dest_if, (struct ether_addr *)eth_dest);
+
+       uint32_t src_phy_port = *src_port;
+
+       gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                       (struct ether_addr *)eth_dest);
+
        *outport_id = p_nat->outport_id[dest_if];
 
        if (arp_cache_dest_mac_present(dest_if)) {
                ether_addr_copy(get_link_hw_addr(dest_if),(struct ether_addr *)eth_src);
-               arp_data_ptr[dest_if]->n_last_update = time(NULL);
-
+               update_nhip_access(dest_if);
                if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
-                       printf("sending buffered packets\n");
                        p_nat->naptedPktCount += ret_arp_data->num_pkts;
                        arp_send_buffered_pkts(ret_arp_data,
-                                (struct ether_addr *)eth_dest, *outport_id);
+                                       (struct ether_addr *)eth_dest, *outport_id);
 
                }
        } else {
 
                if (unlikely(ret_arp_data == NULL)) {
 
+                       #ifdef CGNAPT_DEBUGGING
                        printf("%s: NHIP Not Found, nhip:%x , "
                        "outport_id: %d\n", __func__, nhip,
                        *outport_id);
+                       #endif
 
                        /* Drop the pkt */
                        p_nat->invalid_packets |= pkt_mask;
@@ -3973,7 +3765,7 @@ pkt_work_cgnapt_ipv4_prv(
                        return;
                }
 
-               if (ret_arp_data->status == INCOMPLETE || 
+               if (ret_arp_data->status == INCOMPLETE ||
                           ret_arp_data->status == PROBE) {
                                if (ret_arp_data->num_pkts >= NUM_DESC) {
                                        /* Drop the pkt */
@@ -4183,7 +3975,7 @@ pkt_work_cgnapt_ipv4_pub(
 
        uint8_t protocol = RTE_MBUF_METADATA_UINT8(pkt, PROT_OFST_IP4);
 
-       uint32_t dest_if = 0xff;        /* Added for Multiport */
+       uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
        uint16_t *outport_id =
                RTE_MBUF_METADATA_UINT16_PTR(pkt, cgnapt_meta_offset);
 
@@ -4266,7 +4058,6 @@ pkt_work_cgnapt_ipv4_pub(
        if (entry->data.ttl == NAPT_ENTRY_STALE)
                entry->data.ttl = NAPT_ENTRY_VALID;
 
-       struct ether_addr hw_addr;
        uint32_t dest_address = 0;
 
        /* Multiport Changes */
@@ -4288,15 +4079,20 @@ pkt_work_cgnapt_ipv4_pub(
 
        dest_address = entry->data.u.prv_ip;
        struct arp_entry_data *ret_arp_data = NULL;
-       ret_arp_data = get_dest_mac_addr_port(dest_address, &dest_if, (struct ether_addr *)eth_dest);
+
+       uint32_t src_phy_port = *src_port;
+
+       gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                       (struct ether_addr *)eth_dest);
        *outport_id = p_nat->outport_id[dest_if];
 
        if (arp_cache_dest_mac_present(dest_if)) {
                ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src);
-               arp_data_ptr[dest_if]->n_last_update = time(NULL);
+               update_nhip_access(dest_if);
 
                if (ret_arp_data && ret_arp_data->num_pkts) {
-                       printf("sending buffered packets\n");
                        p_nat->naptedPktCount += ret_arp_data->num_pkts;
                        arp_send_buffered_pkts(ret_arp_data,
                                 (struct ether_addr *)eth_dest, *outport_id);
@@ -4308,9 +4104,12 @@ pkt_work_cgnapt_ipv4_pub(
 
                        /* Commented code may be required for debug
                         * and future use, Please keep it */
+
+                       #ifdef CGNAPT_DEBUGGING
                        printf("%s: NHIP Not Found, nhip: %x, "
                        "outport_id: %d\n", __func__, nhip,
                        *outport_id);
+                       #endif
 
                        /* Drop the pkt */
                        p_nat->invalid_packets |= pkt_mask;
@@ -4323,7 +4122,7 @@ pkt_work_cgnapt_ipv4_pub(
 
                }
 
-               if (ret_arp_data->status == INCOMPLETE || 
+               if (ret_arp_data->status == INCOMPLETE ||
                        ret_arp_data->status == PROBE) {
                        if (ret_arp_data->num_pkts >= NUM_DESC) {
                                /* Drop the pkt */
@@ -4538,7 +4337,7 @@ pkt4_work_cgnapt_ipv4_prv(
        __rte_unused void *arg,
        struct pipeline_cgnapt *p_nat)
 {
-       uint32_t dest_if = 0xff;        /* Added for Multiport */
+       uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
        struct rte_mbuf *pkt;
        uint8_t i;
        uint8_t pkt_num;
@@ -4688,6 +4487,14 @@ pkt4_work_cgnapt_ipv4_prv(
                        dst_port = RTE_MBUF_METADATA_UINT16_PTR(pkt,
                                        dst_port_offset);
                break;
+               default: /* KW fix: unknown is treated as TCP/UDP */
+                       src_port_offset = SRC_PRT_OFST_IP4_TCP;
+                       dst_port_offset = DST_PRT_OFST_IP4_TCP;
+                       src_port = RTE_MBUF_METADATA_UINT16_PTR(pkt,
+                                       src_port_offset);
+                       dst_port = RTE_MBUF_METADATA_UINT16_PTR(pkt,
+                                       dst_port_offset);
+               break;
                }
 
 
@@ -4699,7 +4506,6 @@ pkt4_work_cgnapt_ipv4_prv(
                if (entry->data.ttl == NAPT_ENTRY_STALE)
                        entry->data.ttl = NAPT_ENTRY_VALID;
 
-               struct ether_addr hw_addr;
                uint32_t dest_address = 0;
                /*Multiport Changes */
                uint32_t nhip = 0;
@@ -4723,14 +4529,21 @@ pkt4_work_cgnapt_ipv4_prv(
                dest_address = rte_bswap32(*dst_addr);
                struct arp_entry_data *ret_arp_data = NULL;
                uint64_t start, end;
-               ret_arp_data = get_dest_mac_addr_port(dest_address, &dest_if, (struct ether_addr *)eth_dest);
-               *outport_id = p_nat->outport_id[dest_if];
-               if (arp_cache_dest_mac_present(dest_if)) {
-                       ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src);
-                       arp_data_ptr[dest_if]->n_last_update = time(NULL);
-               
+               uint32_t src_phy_port = *src_port;
+
+               gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                               (struct ether_addr *)eth_dest);
+
+               *outport_id = p_nat->outport_id[dest_if];
+
+               if (arp_cache_dest_mac_present(dest_if)) {
+                       ether_addr_copy(get_link_hw_addr(dest_if),
+                                (struct ether_addr *)eth_src);
+                       update_nhip_access(dest_if);
+
                        if (ret_arp_data && ret_arp_data->num_pkts) {
-                               printf("sending buffered packets\n");
                                p_nat->naptedPktCount += ret_arp_data->num_pkts;
                                arp_send_buffered_pkts(ret_arp_data,
                                         (struct ether_addr *)eth_dest, *outport_id);
@@ -4740,9 +4553,11 @@ pkt4_work_cgnapt_ipv4_prv(
 
                        if (unlikely(ret_arp_data == NULL)) {
 
+                               #ifdef CGNAPT_DEBUGGING
                                printf("%s: ARP Not Found, nhip: %x, "
                                "outport_id: %d\n", __func__, nhip,
                                *outport_id);
+                               #endif
 
                                /* Drop the pkt */
                                p_nat->invalid_packets |= pkt_mask;
@@ -4755,7 +4570,7 @@ pkt4_work_cgnapt_ipv4_prv(
 
                        }
 
-                       if (ret_arp_data->status == INCOMPLETE || 
+                       if (ret_arp_data->status == INCOMPLETE ||
                                ret_arp_data->status == PROBE) {
                                if (ret_arp_data->num_pkts >= NUM_DESC) {
                                        /* Drop the pkt */
@@ -4976,7 +4791,7 @@ pkt4_work_cgnapt_ipv4_pub(
 
                uint8_t protocol = RTE_MBUF_METADATA_UINT8(pkt, PROT_OFST_IP4);
 
-               uint32_t dest_if = 0xff;        /* Added for Multiport */
+               uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
                uint16_t *outport_id =
                        RTE_MBUF_METADATA_UINT16_PTR(pkt, cgnapt_meta_offset);
 
@@ -5019,7 +4834,6 @@ pkt4_work_cgnapt_ipv4_pub(
                                #ifdef CGNAPT_DEBUGGING
                                p_nat->naptDroppedPktCount3++;
                                #endif
-                               printf("causing p_nat->naptDroppedPktCount3\n");
                                continue;
                        }
 
@@ -5066,7 +4880,6 @@ pkt4_work_cgnapt_ipv4_pub(
                if (entry->data.ttl == NAPT_ENTRY_STALE)
                        entry->data.ttl = NAPT_ENTRY_VALID;
 
-               struct ether_addr hw_addr;
                uint32_t dest_address = 0;
                /* Multiport Changes */
                uint32_t nhip = 0;
@@ -5086,27 +4899,35 @@ pkt4_work_cgnapt_ipv4_pub(
                }
                dest_address = entry->data.u.prv_ip;
                struct arp_entry_data *ret_arp_data = NULL;
-               ret_arp_data = get_dest_mac_addr_port(dest_address, &dest_if, (struct ether_addr *)eth_dest);
+               uint32_t src_phy_port = *src_port;
+
+               gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                               (struct ether_addr *)eth_dest);
+
                *outport_id = p_nat->outport_id[dest_if];
 
-       if (arp_cache_dest_mac_present(dest_if)) {
-               ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src);
-               arp_data_ptr[dest_if]->n_last_update = time(NULL);
-               
-               if (ret_arp_data && ret_arp_data->num_pkts) {
-                       printf("sending buffered packets\n");
-                       p_nat->naptedPktCount += ret_arp_data->num_pkts;
-                       arp_send_buffered_pkts(ret_arp_data,
-                                (struct ether_addr *)eth_dest, *outport_id);
-               }
+               if (arp_cache_dest_mac_present(dest_if)) {
+                       ether_addr_copy(get_link_hw_addr(dest_if),
+                                       (struct ether_addr *)eth_src);
+                       update_nhip_access(dest_if);
 
-       } else {
+                       if (ret_arp_data && ret_arp_data->num_pkts) {
+                               p_nat->naptedPktCount += ret_arp_data->num_pkts;
+                               arp_send_buffered_pkts(ret_arp_data,
+                                               (struct ether_addr *)eth_dest, *outport_id);
+                       }
 
-               if (unlikely(ret_arp_data == NULL)) {
+               } else {
 
+                       if (unlikely(ret_arp_data == NULL)) {
+
+                       #ifdef CGNAPT_DEBUGGING
                        printf("%s: NHIP Not Found, nhip: %x, "
                        "outport_id: %d\n", __func__, nhip,
                        *outport_id);
+                       #endif
 
                        /* Drop the pkt */
                        p_nat->invalid_packets |= pkt_mask;
@@ -5118,7 +4939,7 @@ pkt4_work_cgnapt_ipv4_pub(
                        continue;
                }
 
-               if (ret_arp_data->status == INCOMPLETE || 
+               if (ret_arp_data->status == INCOMPLETE ||
                        ret_arp_data->status == PROBE) {
                        if (ret_arp_data->num_pkts >= NUM_DESC) {
                                /* Drop the pkt */
@@ -6151,7 +5972,6 @@ pkt_work_cgnapt_ipv6_prv(
 
        struct ipv6_hdr ipv6_hdr;
 
-       struct ether_addr hw_addr;
        uint32_t dest_address = 0;
        uint32_t nhip = 0;
        /* Egress */
@@ -6234,23 +6054,6 @@ pkt_work_cgnapt_ipv6_prv(
                dest_address = rte_bswap32(*dst_addr);
                /*Multiport Changes */
        uint32_t nhip = 0;
-       uint32_t ret;
-       ret = local_get_nh_ipv4(dest_address, &dest_if, &nhip, p_nat);
-       if (!ret) {
-               dest_if = get_prv_to_pub_port(&dest_address, IP_VERSION_4);
-
-               if (dest_if == INVALID_DESTIF) {
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount6++;
-                       #endif
-                       return;
-               }
-
-               do_local_nh_ipv4_cache(dest_if, p_nat);
-       }
-               *outport_id = p_nat->outport_id[dest_if];
 
                #ifdef CGNAPT_DBG_PRNT
                if (CGNAPT_DEBUG > 2)
@@ -6273,18 +6076,37 @@ pkt_work_cgnapt_ipv6_prv(
        }
        #endif
 
-       if (local_dest_mac_present(dest_if)) {
-               memcpy(eth_src, get_link_hw_addr(dest_if),
-                               sizeof(struct ether_addr));
+       struct arp_entry_data *ret_arp_data;
+
+       uint32_t src_phy_port = *src_port;
+
+       gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                       (struct ether_addr *)eth_dest);
+
+       *outport_id = p_nat->outport_id[dest_if];
+
+       if (arp_cache_dest_mac_present(dest_if)) {
+               ether_addr_copy(get_link_hw_addr(dest_if),
+                       (struct ether_addr *)eth_src);
+               update_nhip_access(dest_if);
+
+               if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+                       p_nat->naptedPktCount += ret_arp_data->num_pkts;
+                       arp_send_buffered_pkts(ret_arp_data,
+                                (struct ether_addr *)eth_dest, *outport_id);
+
+               }
        } else {
-               struct arp_entry_data *ret_arp_data;
-               ret_arp_data = get_dest_mac_addr_port(dest_address, &dest_if, (struct ether_addr *)&hw_addr);
 
                if (unlikely(ret_arp_data == NULL)) {
 
-                       printf("%s: NHIP Not Found, nhip: %x, "
+                       #ifdef CGNAPT_DEBUGGING
+                       printf("%s: NHIP Not Found, nhip:%x , "
                        "outport_id: %d\n", __func__, nhip,
                        *outport_id);
+                       #endif
 
                        /* Drop the pkt */
                        p_nat->invalid_packets |= pkt_mask;
@@ -6296,42 +6118,22 @@ pkt_work_cgnapt_ipv6_prv(
                        return;
                }
 
-               if (ret_arp_data->status == COMPLETE) {
-
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                       printf("MAC found for ip 0x%x, port %d - %02x:%02x: "
-                       "%02x:%02x:%02x:%02x\n", dest_address,
-                       *outport_id,
-                       hw_addr.addr_bytes[0], hw_addr.addr_bytes[1],
-                       hw_addr.addr_bytes[2], hw_addr.addr_bytes[3],
-                       hw_addr.addr_bytes[4], hw_addr.addr_bytes[5]);
-
-                       printf("Dest MAC before - %02x:%02x:%02x:%02x: "
-                       "%02x:%02x\n", eth_dest[0], eth_dest[1],
-                       eth_dest[2], eth_dest[3],
-                       eth_dest[4], eth_dest[5]);
-                       }
-                       #endif
-
-                       //memcpy(eth_dest, &hw_addr, sizeof(struct ether_addr));
+               if (ret_arp_data->status == INCOMPLETE ||
+                          ret_arp_data->status == PROBE) {
+                       if (ret_arp_data->num_pkts >= NUM_DESC) {
+                               /* Drop the pkt */
+                               p_nat->invalid_packets |= pkt_mask;
+                               p_nat->naptDroppedPktCount++;
 
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                               printf("Dest MAC after - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2], eth_dest[3],
-                               eth_dest[4], eth_dest[5]);
+                               #ifdef CGNAPT_DEBUGGING
+                               p_nat->naptDroppedPktCount4++;
+                               #endif
+                               return;
+                       } else {
+                               arp_pkts_mask |= pkt_mask;
+                               arp_queue_unresolved_packet(ret_arp_data, pkt);
+                               return;
                        }
-                       #endif
-
-                       memcpy(eth_src, get_link_hw_addr(dest_if),
-                                sizeof(struct ether_addr));
-               } else if (ret_arp_data->status == INCOMPLETE || 
-                       ret_arp_data->status == PROBE) {
-                       arp_queue_unresolved_packet(ret_arp_data,
-                               pkt);
-                       return;
                }
        }
 
@@ -6454,91 +6256,75 @@ pkt_work_cgnapt_ipv6_pub(
                        #endif
                        return;
                }
+       }
+       memcpy(&dest_addr_ipv6[0], &entry->data.u.prv_ipv6[0], 16);
+       uint8_t nhipv6[16];
 
-               memcpy(&dest_addr_ipv6[0], &entry->data.u.prv_ipv6[0], 16);
-               uint8_t nhipv6[16];
-               int ret;
-               ret = local_get_nh_ipv6(&dest_addr_ipv6[0], &dest_if,
-                               &nhipv6[0], p_nat);
-               if (!ret) {
-                       dest_if = get_prv_to_pub_port((uint32_t *)
-                                       &dest_addr_ipv6[0],
-                                       IP_VERSION_6);
-
-               if (dest_if == INVALID_DESTIF) {
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount6++;
-                       #endif
-                       return;
-               }
+       memset(nh_ipv6, 0, 16);
+       struct nd_entry_data *ret_nd_data = NULL;
 
-                       do_local_nh_ipv6_cache(dest_if, p_nat);
-               }
-               *outport_id = p_nat->outport_id[dest_if];
-       }
+       dest_if = INVALID_DESTIF;
 
-       #ifdef CGNAPT_DEBUGGING
-       static int static_count;
+       uint32_t src_phy_port = pkt->port;
 
-       if (static_count++ < 10) {
-               print_pkt(pkt);
-               my_print_entry(entry);
-               printf("dest-offset:%d\n", DST_ADR_OFST_IP4);
-               printf("dest_add:%x\n", entry->data.u.prv_ip);
-               printf("DST_ADR_OFST_IP6:%d\n", DST_ADR_OFST_IP6);
-       }
-       #endif
+       gw_get_nh_port_ipv6((uint8_t *) &dest_addr_ipv6[0],
+                       &dest_if, &nh_ipv6[0]);
 
-       memset(nh_ipv6, 0, 16);
-       if (get_dest_mac_address_ipv6_port(
-               &dest_addr_ipv6[0],
-               &dest_if,
-               &hw_addr,
-               &nh_ipv6[0])) {
+       ret_nd_data = get_dest_mac_addr_ipv6(&nh_ipv6[0],
+                       dest_if, (struct ether_addr *)eth_dest);
+
+       *outport_id = p_nat->outport_id[dest_if];
+
+       if (nd_cache_dest_mac_present(dest_if)) {
+               ether_addr_copy(get_link_hw_addr(dest_if),
+                       (struct ether_addr *)eth_src);
+               update_nhip_access(dest_if);
+
+               if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                       p_nat->naptedPktCount += ret_nd_data->num_pkts;
+                       nd_send_buffered_pkts(ret_nd_data,
+                                (struct ether_addr *)eth_dest, *outport_id);
 
-               #ifdef CGNAPT_DBG_PRNT
-               if (CGNAPT_DEBUG > 2) {
-                       printf("MAC found for ip 0x%x, port %d - "
-                       "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       *((uint32_t *)dest_addr_ipv6 + 12),
-                       *outport_id,
-                       hw_addr.addr_bytes[0],
-                       hw_addr.addr_bytes[1], hw_addr.addr_bytes[2],
-                       hw_addr.addr_bytes[3], hw_addr.addr_bytes[4],
-                       hw_addr.addr_bytes[5]);
-
-                       printf("Dest MAC before - "
-                       "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       eth_dest[0], eth_dest[1], eth_dest[2],
-                       eth_dest[3], eth_dest[4], eth_dest[5]);
                }
-               #endif
+       } else {
+               if (unlikely(ret_nd_data == NULL)) {
 
-               memcpy(eth_dest, &hw_addr, sizeof(struct ether_addr));
+                       #ifdef CGNAPT_DEBUGGING
+                       printf("%s: NHIP Not Found, "
+                       "outport_id: %d\n", __func__,
+                       *outport_id);
+                       #endif
 
-               #ifdef CGNAPT_DBG_PRNT
-               if (CGNAPT_DEBUG > 2) {
-                       printf("Dest MAC after - "
-                       "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       eth_dest[0], eth_dest[1], eth_dest[2], eth_dest[3],
-                       eth_dest[4], eth_dest[5]);
+                       /* Drop the pkt */
+                       p_nat->invalid_packets |= pkt_mask;
+                       p_nat->naptDroppedPktCount++;
+
+                       #ifdef CGNAPT_DEBUGGING
+                       p_nat->naptDroppedPktCount4++;
+                       #endif
+                       return;
                }
-               #endif
 
-               memcpy(eth_src, get_link_hw_addr(dest_if),
-                                sizeof(struct ether_addr));
-       } else {
-               p_nat->invalid_packets |= pkt_mask;
-               p_nat->naptDroppedPktCount++;
+               if (ret_nd_data->status == INCOMPLETE ||
+                          ret_nd_data->status == PROBE) {
+                       if (ret_nd_data->num_pkts >= NUM_DESC) {
+                               /* Drop the pkt */
+                               p_nat->invalid_packets |= pkt_mask;
+                               p_nat->naptDroppedPktCount++;
 
-               #ifdef CGNAPT_DEBUGGING
-               p_nat->naptDroppedPktCount4++;
-               #endif
+                               #ifdef CGNAPT_DEBUGGING
+                               p_nat->naptDroppedPktCount4++;
+                               #endif
+                               return;
+                       } else {
+                               arp_pkts_mask |= pkt_mask;
+                               nd_queue_unresolved_packet(ret_nd_data, pkt);
+                               return;
+                       }
+               }
 
-               return;
        }
+
        /* Ingress */
        {
 
@@ -6675,7 +6461,6 @@ pkt4_work_cgnapt_ipv6_prv(
                p_nat->entries[pkt_num] = &(entry->head);
 
                struct ipv6_hdr ipv6_hdr;
-               struct ether_addr hw_addr;
                uint32_t dest_address = 0;
                uint8_t nh_ipv6[16];
                uint32_t nhip = 0;
@@ -6759,23 +6544,6 @@ pkt4_work_cgnapt_ipv6_prv(
                        dest_address = rte_bswap32(*dst_addr);
        uint32_t nhip;
        uint32_t ret;
-       ret = local_get_nh_ipv4(dest_address, &dest_if, &nhip, p_nat);
-       if (!ret) {
-               dest_if = get_prv_to_pub_port(&dest_address, IP_VERSION_4);
-
-               if (dest_if == INVALID_DESTIF) {
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount6++;
-                       #endif
-                       continue;
-               }
-
-               do_local_nh_ipv4_cache(dest_if, p_nat);
-       }
-               *outport_id = p_nat->outport_id[dest_if];
-
                #ifdef CGNAPT_DBG_PRNT
                        if (CGNAPT_DEBUG > 2)
                                printf("Egress: \tphy_port:%d\t"
@@ -6801,64 +6569,62 @@ pkt4_work_cgnapt_ipv6_prv(
 
        {
                struct arp_entry_data *ret_arp_data;
-               ret_arp_data = get_dest_mac_addr_port(dest_address, &dest_if, (struct ether_addr *)&hw_addr);
+               uint32_t src_phy_port = *src_port;
 
-               if (unlikely(ret_arp_data == NULL)) {
+               gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
 
-                       printf("%s: NHIP Not Found, nhip: %x, "
-                       "outport_id: %d\n", __func__, nhip,
-                       *outport_id);
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                               (struct ether_addr *)eth_dest);
+               *outport_id = p_nat->outport_id[dest_if];
 
-                       /* Drop the pkt */
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
+               if (arp_cache_dest_mac_present(dest_if)) {
+                       ether_addr_copy(get_link_hw_addr(dest_if),
+                               (struct ether_addr *)eth_src);
+                       update_nhip_access(dest_if);
+                       if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+                               p_nat->naptedPktCount += ret_arp_data->num_pkts;
+                               arp_send_buffered_pkts(ret_arp_data,
+                                        (struct ether_addr *)eth_dest, *outport_id);
 
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount4++;
-                       #endif
-                       continue;
-               }
+                       }
+               } else {
 
-               if (ret_arp_data->status == COMPLETE) {
+                       if (unlikely(ret_arp_data == NULL)) {
 
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                               printf("MAC found for ip 0x%x, port %d - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               dest_address, *outport_id,
-                                        hw_addr.addr_bytes[0],
-                                        hw_addr.addr_bytes[1],
-                                        hw_addr.addr_bytes[2],
-                                        hw_addr.addr_bytes[3],
-                                        hw_addr.addr_bytes[4],
-                                        hw_addr.addr_bytes[5]
-                                       );
+                               #ifdef CGNAPT_DEBUGGING
+                               printf("%s: NHIP Not Found, nhip:%x , "
+                               "outport_id: %d\n", __func__, nhip,
+                               *outport_id);
+                               #endif
 
-                               printf("Dest MAC before - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2],
-                               eth_dest[3], eth_dest[4], eth_dest[5]);
+                               /* Drop the pkt */
+                               p_nat->invalid_packets |= pkt_mask;
+                               p_nat->naptDroppedPktCount++;
+
+                               #ifdef CGNAPT_DEBUGGING
+                               p_nat->naptDroppedPktCount4++;
+                               #endif
+                               return;
                        }
-                       #endif
 
-                       //memcpy(eth_dest, &hw_addr, sizeof(struct ether_addr));
+                       if (ret_arp_data->status == INCOMPLETE ||
+                          ret_arp_data->status == PROBE) {
+                               if (ret_arp_data->num_pkts >= NUM_DESC) {
+                                       /* Drop the pkt */
+                                       p_nat->invalid_packets |= pkt_mask;
+                                       p_nat->naptDroppedPktCount++;
 
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                               printf("Dest MAC after - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2],
-                               eth_dest[3], eth_dest[4], eth_dest[5]);
+                                       #ifdef CGNAPT_DEBUGGING
+                                       p_nat->naptDroppedPktCount4++;
+                                       #endif
+                                       return;
+                               } else {
+                                       arp_pkts_mask |= pkt_mask;
+                                       arp_queue_unresolved_packet(ret_arp_data, pkt);
+                                       return;
+                               }
                        }
-                       #endif
 
-                       memcpy(eth_src, get_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
-               } else if (ret_arp_data->status == INCOMPLETE || 
-                       ret_arp_data->status == PROBE) {
-                       arp_queue_unresolved_packet(ret_arp_data,
-                               pkt);
-                       continue;
                }
        }
 
@@ -6991,26 +6757,6 @@ pkt4_work_cgnapt_ipv6_pub(
                        memcpy(&dest_addr_ipv6[0], &entry->data.u.prv_ipv6[0],
                                         16);
                        uint8_t nhipv6[16];
-                       int ret;
-                       ret = local_get_nh_ipv6(&dest_addr_ipv6[0], &dest_if,
-                               &nhipv6[0], p_nat);
-                       if (!ret) {
-                               dest_if = get_prv_to_pub_port((uint32_t *)
-                                       &dest_addr_ipv6[0], IP_VERSION_6);
-
-                               if (dest_if == INVALID_DESTIF) {
-                                       p_nat->invalid_packets |= pkt_mask;
-                                       p_nat->naptDroppedPktCount++;
-                                       #ifdef CGNAPT_DEBUGGING
-                                       p_nat->naptDroppedPktCount6++;
-                                       #endif
-                                       return;
-                               }
-
-                               do_local_nh_ipv6_cache(dest_if, p_nat);
-                       }
-
-                       *outport_id = p_nat->outport_id[dest_if];
                }/* end of ingress */
 
                #ifdef CGNAPT_DEBUGGING
@@ -7026,49 +6772,66 @@ pkt4_work_cgnapt_ipv6_pub(
                #endif
 
                memset(nh_ipv6, 0, 16);
-               if (get_dest_mac_address_ipv6
-                       (&dest_addr_ipv6[0], &dest_if,
-                        &hw_addr, &nh_ipv6[0])) {
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                               printf("MAC found for ip 0x%x, port %d - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               *((uint32_t *)dest_addr_ipv6 + 12),
-                               *outport_id,
-                               hw_addr.addr_bytes[0], hw_addr.addr_bytes[1],
-                               hw_addr.addr_bytes[2], hw_addr.addr_bytes[3],
-                               hw_addr.addr_bytes[4], hw_addr.addr_bytes[5]);
+               struct nd_entry_data *ret_nd_data = NULL;
+               dest_if = INVALID_DESTIF;
 
-                               printf("Dest MAC before - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2],
-                               eth_dest[3], eth_dest[4], eth_dest[5]);
+               uint32_t src_phy_port = pkt->port;
+
+               gw_get_nh_port_ipv6((uint8_t *) &dest_addr_ipv6[0],
+                               &dest_if, &nh_ipv6[0]);
+
+               ret_nd_data = get_dest_mac_addr_ipv6(&nh_ipv6[0],
+                               dest_if, (struct ether_addr *)eth_dest);
+               *outport_id = p_nat->outport_id[dest_if];
+
+               if (nd_cache_dest_mac_present(dest_if)) {
+                       ether_addr_copy(get_link_hw_addr(dest_if),
+                               (struct ether_addr *)eth_src);
+                       update_nhip_access(dest_if);
+
+                       if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                               p_nat->naptedPktCount += ret_nd_data->num_pkts;
+                               nd_send_buffered_pkts(ret_nd_data,
+                                (struct ether_addr *)eth_dest, *outport_id);
                        }
-                       #endif
+               } else {
+                       if (unlikely(ret_nd_data == NULL)) {
 
-                       memcpy(eth_dest, &hw_addr, sizeof(struct ether_addr));
+                               #ifdef CGNAPT_DEBUGGING
+                               printf("%s: NHIP Not Found "
+                               "outport_id: %d\n", __func__,
+                               *outport_id);
+                               #endif
 
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2) {
-                               printf("Dest MAC after - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                               eth_dest[0], eth_dest[1], eth_dest[2],
-                               eth_dest[3], eth_dest[4], eth_dest[5]);
+                               /* Drop the pkt */
+                               p_nat->invalid_packets |= pkt_mask;
+                               p_nat->naptDroppedPktCount++;
+
+                               #ifdef CGNAPT_DEBUGGING
+                               p_nat->naptDroppedPktCount4++;
+                               #endif
+                               continue;
                        }
-                       #endif
 
-                       memcpy(eth_src,
-                                        get_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
-               } else {
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
+                       if (ret_nd_data->status == INCOMPLETE ||
+                                  ret_nd_data->status == PROBE) {
 
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount4++;
-                       #endif
+                               if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                       /* Drop the pkt */
+                                       p_nat->invalid_packets |= pkt_mask;
+                                       p_nat->naptDroppedPktCount++;
+
+                                       #ifdef CGNAPT_DEBUGGING
+                                       p_nat->naptDroppedPktCount4++;
+                                       #endif
+                                       continue;
+                               } else {
+                                       arp_pkts_mask |= pkt_mask;
+                                       nd_queue_unresolved_packet(ret_nd_data, pkt);
+                                       continue;
+                               }
+                       }
 
-                       continue;
                }
 
                {
@@ -7142,6 +6905,7 @@ static int cgnapt_in_port_ah_ipv6_prv(struct rte_pipeline *rte_p,
        p_nat->pkt_burst_cnt = 0;       /* for dynamic napt */
        p_nat->valid_packets = rte_p->pkts_mask;        /*n_pkts; */
        p_nat->invalid_packets = 0;
+       arp_pkts_mask = 0;
 
        #ifdef CGNAPT_DBG_PRNT
        if (CGNAPT_DEBUG > 1)
@@ -7160,6 +6924,11 @@ static int cgnapt_in_port_ah_ipv6_prv(struct rte_pipeline *rte_p,
 
        p_nat->valid_packets &= ~(p_nat->invalid_packets);
 
+       if (arp_pkts_mask) {
+               p_nat->valid_packets &= ~(arp_pkts_mask);
+               rte_pipeline_ah_packet_hijack(rte_p, arp_pkts_mask);
+       }
+
        if (unlikely(p_nat->valid_packets == 0)) {
                /* no suitable packet for lookup */
                rte_pipeline_ah_packet_drop(rte_p, p_nat->invalid_packets);
@@ -7255,6 +7024,7 @@ static int cgnapt_in_port_ah_ipv6_pub(struct rte_pipeline *rte_p,
        p_nat->pkt_burst_cnt = 0;       /* for dynamic napt */
        p_nat->valid_packets = rte_p->pkts_mask;        /*n_pkts; */
        p_nat->invalid_packets = 0;
+       arp_pkts_mask = 0;
 
        #ifdef CGNAPT_DBG_PRNT
        if (CGNAPT_DEBUG > 1)
@@ -7273,6 +7043,11 @@ static int cgnapt_in_port_ah_ipv6_pub(struct rte_pipeline *rte_p,
 
        p_nat->valid_packets &= ~(p_nat->invalid_packets);
 
+       if (arp_pkts_mask) {
+               p_nat->valid_packets &= ~(arp_pkts_mask);
+               rte_pipeline_ah_packet_hijack(rte_p, arp_pkts_mask);
+       }
+
        if (unlikely(p_nat->valid_packets == 0)) {
                /* no suitable packet for lookup */
                rte_pipeline_ah_packet_drop(rte_p, p_nat->invalid_packets);
@@ -8346,7 +8121,7 @@ static void *pipeline_cgnapt_init(struct pipeline_params *params, void *arg)
 
        all_pipeline_cgnapt[n_cgnapt_pipeline++] = p_nat;
 
-       strcpy(p->name, params->name);
+       strncpy(p->name, params->name,PIPELINE_NAME_SIZE);
        p->log_level = params->log_level;
 
        PLOG(p, HIGH, "CG-NAPT");
@@ -8374,7 +8149,7 @@ static void *pipeline_cgnapt_init(struct pipeline_params *params, void *arg)
        p_nat->hw_checksum_reqd = 0;
        p_nat->pub_ip_port_set = NULL;
        p_nat->pub_ip_count = 0;
-       p_nat->traffic_type = TRAFFIC_TYPE_MIX;
+       p_nat->traffic_type = TRAFFIC_TYPE_IPV4;
        p_nat->vnf_set = 0xff;
 
        /* For every init it should be reset */
@@ -9022,7 +8797,6 @@ void *pipeline_cgnapt_msg_req_entry_add_handler(struct pipeline *p, void *msg)
 
         printf("PhyPort %d, ttl %u,", rx_port, ttl);
         printf("entry_type %d\n", type);
-
         #ifdef NAT_ONLY_CONFIG_REQ
        if (nat_only_config_flag) {
                if (!p_nat->is_static_cgnapt) {
@@ -9050,9 +8824,10 @@ void *pipeline_cgnapt_msg_req_entry_add_handler(struct pipeline *p, void *msg)
                                return msg;
                }
 
+  #ifdef CGNAPT_DBG_PRNT
                printf("Success - pipeline_cgnapt_msg_req_entry_addm_handler");
                printf("added %d rule pairs.\n", count);
-
+  #endif
                return msg;
        }
         #endif
@@ -9083,9 +8858,10 @@ void *pipeline_cgnapt_msg_req_entry_add_handler(struct pipeline *p, void *msg)
        }
 
 
+  #ifdef CGNAPT_DBG_PRNT
         printf("\nSuccess - pipeline_cgnapt_msg_req_entry_add_handler "
                "added\n");
-
+  #endif
        return msg;
 }
 
@@ -9184,11 +8960,6 @@ pipeline_cgnapt_msg_req_entry_addm_pair(
        }
        #endif
 
-       //if (CGNAPT_DEBUG > 2)
-               //printf("key.ip %x, key.port %d", key.ip, key.port);
-               //printf("key.pid %d, in_type %d,", key.pid, type);
-               //printf("entry_type %d\n", entry.data.type);
-
        int32_t position = rte_hash_add_key(napt_common_table, &key);
 
        if (position < 0) {
@@ -9274,7 +9045,6 @@ void *pipeline_cgnapt_msg_req_entry_addm_handler(struct pipeline *p, void *msg)
        printf("PhyPort %d, ttl %u, NumUe %d,", rx_port, ttl, max_ue);
        printf("mPrvPort %d, mPubPort %d,", max_src_port, max_dest_port);
        printf("entry_type %d\n", type);
-
        #ifdef NAT_ONLY_CONFIG_REQ
        if (nat_only_config_flag) {
                if (!p_nat->is_static_cgnapt) {
@@ -9315,8 +9085,10 @@ void *pipeline_cgnapt_msg_req_entry_addm_handler(struct pipeline *p, void *msg)
                        dest_ip++;
                }
 
+  #ifdef CGNAPT_DBG_PRNT
                printf("Success - pipeline_cgnapt_msg_req_entry_addm_handler");
                printf("added %d rule pairs.\n", count);
+  #endif
 
                return msg;
        }
@@ -9367,9 +9139,10 @@ void *pipeline_cgnapt_msg_req_entry_addm_handler(struct pipeline *p, void *msg)
                }
        }
 
+ #ifdef CGNAPT_DBG_PRNT
        printf("\nSuccess - pipeline_cgnapt_msg_req_entry_addm_handler added");
        printf("%d rule pairs.\n", count);
-
+ #endif
        return msg;
 }
 
@@ -10710,9 +10483,9 @@ void *pipeline_cgnapt_msg_req_ver_handler(__rte_unused struct pipeline *p,
  * Function to show CGNAPT stats
  *
  */
-void all_cgnapt_stats(void)
+void all_cgnapt_stats(char *buf)
 {
-       int i;
+       int i, len = 0;
        struct pipeline_cgnapt *p_nat;
        uint64_t receivedPktCount = 0;
        uint64_t missedPktCount = 0;
@@ -10722,7 +10495,7 @@ void all_cgnapt_stats(void)
        uint64_t enaptedPktCount = 0;
        uint64_t arpicmpPktCount = 0;
 
-       printf("\nCG-NAPT Packet Stats:\n");
+       len += sprintf(buf + len, "\nCG-NAPT Packet Stats:\n");
        for (i = 0; i < n_cgnapt_pipeline; i++) {
                p_nat = all_pipeline_cgnapt[i];
 
@@ -10734,6 +10507,16 @@ void all_cgnapt_stats(void)
                enaptedPktCount         += p_nat->enaptedPktCount;
                arpicmpPktCount         += p_nat->arpicmpPktCount;
 
+               len += sprintf(buf + len, "pipeline %d stats:\n", p_nat->pipeline_num);
+               len += sprintf(buf + len, "Received %" PRIu64 ",", p_nat->receivedPktCount);
+               len += sprintf(buf + len, "Missed %" PRIu64 ",", p_nat->missedPktCount);
+               len += sprintf(buf + len, "Dropped %" PRIu64 ",",  p_nat->naptDroppedPktCount);
+               len += sprintf(buf + len, "Translated %" PRIu64 ",", p_nat->naptedPktCount);
+               len += sprintf(buf + len, "ingress %" PRIu64 ",",  p_nat->inaptedPktCount);
+               len += sprintf(buf + len, "egress %" PRIu64 "\n", p_nat->enaptedPktCount);
+               len += sprintf(buf + len, "arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
+
+               printf("\nCG-NAPT Packet Stats:\n");
                printf("pipeline %d stats:\n", p_nat->pipeline_num);
                printf("Received %" PRIu64 ",", p_nat->receivedPktCount);
                printf("Missed %" PRIu64 ",", p_nat->missedPktCount);
@@ -10744,33 +10527,34 @@ void all_cgnapt_stats(void)
                printf("arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
 
 
+
                #ifdef CGNAPT_DEBUGGING
-               printf("\n Drop detail 1:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 1:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount1);
-               printf("\n Drop detail 2:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 2:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount2);
-               printf("\n Drop detail 3:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 3:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount3);
-               printf("\n Drop detail 4:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 4:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount4);
-               printf("\n Drop detail 5:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 5:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount5);
-               printf("\n Drop detail 6:%" PRIu64 "",
+               len += sprintf(buf + len, "\n Drop detail 6:%" PRIu64 "",
                                p_nat->naptDroppedPktCount6);
 
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount1,
                                p_nat->missedpktcount2);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount3,
                                p_nat->missedpktcount4);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount5,
                                p_nat->missedpktcount6);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount7,
                                p_nat->missedpktcount8);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount9,
                                p_nat->missedpktcount10);
 
@@ -10778,6 +10562,15 @@ void all_cgnapt_stats(void)
 
        }
 
+       len += sprintf(buf + len, "\nTotal pipeline stats:\n");
+       len += sprintf(buf + len, "Received %" PRIu64 ",", receivedPktCount);
+       len += sprintf(buf + len, "Missed %" PRIu64 ",", missedPktCount);
+       len += sprintf(buf + len, "Dropped %" PRIu64 ",",  naptDroppedPktCount);
+       len += sprintf(buf + len, "Translated %" PRIu64 ",", naptedPktCount);
+       len += sprintf(buf + len, "ingress %" PRIu64 ",",  inaptedPktCount);
+       len += sprintf(buf + len, "egress %" PRIu64 "\n", enaptedPktCount);
+       len += sprintf(buf + len, "arpicmp pkts %" PRIu64 "\n", arpicmpPktCount);
+
        printf("\nTotal pipeline stats:\n");
        printf("Received %" PRIu64 ",", receivedPktCount);
        printf("Missed %" PRIu64 ",", missedPktCount);
@@ -10786,24 +10579,27 @@ void all_cgnapt_stats(void)
        printf("ingress %" PRIu64 ",",  inaptedPktCount);
        printf("egress %" PRIu64 "\n", enaptedPktCount);
        printf("arpicmp pkts %" PRIu64 "\n", arpicmpPktCount);
+
+       if (!rest_api_supported())
+               printf("%s\n", buf);
 }
 
-void all_cgnapt_clear_stats(void)
+void all_cgnapt_clear_stats(char *buf)
 {
-       int i;
+       int i, len = 0;
        struct pipeline_cgnapt *p_nat;
-               printf("\nCG-NAPT Packet Stats:\n");
+               len += sprintf(buf + len, "\nCG-NAPT Packet Stats:\n");
        for (i = 0; i < n_cgnapt_pipeline; i++) {
                p_nat = all_pipeline_cgnapt[i];
 
-               printf("pipeline %d stats:\n", p_nat->pipeline_num);
-               printf("Received %" PRIu64 ",", p_nat->receivedPktCount);
-               printf("Missed %" PRIu64 ",", p_nat->missedPktCount);
-               printf("Dropped %" PRIu64 ",",  p_nat->naptDroppedPktCount);
-               printf("Translated %" PRIu64 ",", p_nat->naptedPktCount);
-               printf("ingress %" PRIu64 ",",  p_nat->inaptedPktCount);
-               printf("egress %" PRIu64 "\n", p_nat->enaptedPktCount);
-               printf("arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
+               len += sprintf(buf + len, "pipeline %d stats:\n", p_nat->pipeline_num);
+               len += sprintf(buf + len, "Received %" PRIu64 ",", p_nat->receivedPktCount);
+               len += sprintf(buf + len, "Missed %" PRIu64 ",", p_nat->missedPktCount);
+               len += sprintf(buf + len, "Dropped %" PRIu64 ",",  p_nat->naptDroppedPktCount);
+               len += sprintf(buf + len, "Translated %" PRIu64 ",", p_nat->naptedPktCount);
+               len += sprintf(buf + len, "ingress %" PRIu64 ",",  p_nat->inaptedPktCount);
+               len += sprintf(buf + len, "egress %" PRIu64 "\n", p_nat->enaptedPktCount);
+               len += sprintf(buf + len, "arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
 
                p_nat->receivedPktCount = 0;
                p_nat->missedPktCount = 0;
@@ -10814,38 +10610,41 @@ void all_cgnapt_clear_stats(void)
                p_nat->arpicmpPktCount = 0;
 
                #ifdef CGNAPT_DEBUGGING
-               printf("\n Drop detail 1:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 1:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount1);
-               printf("\n Drop detail 2:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 2:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount2);
-               printf("\n Drop detail 3:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 3:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount3);
-               printf("\n Drop detail 4:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 4:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount4);
-               printf("\n Drop detail 5:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 5:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount5);
-               printf("\n Drop detail 6:%" PRIu64 "",
+               len += sprintf(buf + len, "\n Drop detail 6:%" PRIu64 "",
                                p_nat->naptDroppedPktCount6);
 
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount1,
                                p_nat->missedpktcount2);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount3,
                                p_nat->missedpktcount4);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount5,
                                p_nat->missedpktcount6);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount7,
                                p_nat->missedpktcount8);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount9,
                                p_nat->missedpktcount10);
 
                #endif
 
        }
+
+       if (!rest_api_supported())
+               printf("%s\n", buf);
 }
 
 /**