[l2l3 stack] implements new nd state machine & nd buffering
[samplevnf.git] / VNFs / vCGNAPT / pipeline / pipeline_cgnapt_be.c
index 9a05a4d..ba324e9 100644 (file)
@@ -80,6 +80,9 @@
 /* To maintain all cgnapt pipeline pointers used for all stats */
 struct pipeline_cgnapt *all_pipeline_cgnapt[128];
 uint8_t n_cgnapt_pipeline;
+struct pipeline_cgnapt *global_pnat;
+
+uint64_t arp_pkts_mask;
 
 /* To know egress or ingress port */
 static uint8_t cgnapt_in_port_egress_prv[PIPELINE_MAX_PORT_IN];
@@ -101,7 +104,8 @@ struct rte_ct_cnxn_tracker *cgnat_cnxn_tracker;
 /***** Common Port Allocation declarations *****/
 
 struct rte_ring *port_alloc_ring[MAX_CGNAPT_SETS] = { NULL, NULL, NULL, NULL,
-                                               NULL, NULL, NULL, NULL };
+                                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                                NULL, NULL, NULL, NULL};
 const char *napt_port_alloc_ring_name[MAX_CGNAPT_SETS] = {
        "NAPT_PORT_ALLOC_0 ",
        "NAPT_PORT_ALLOC_1 ",
@@ -110,7 +114,15 @@ const char *napt_port_alloc_ring_name[MAX_CGNAPT_SETS] = {
        "NAPT_PORT_ALLOC_4 ",
        "NAPT_PORT_ALLOC_5 ",
        "NAPT_PORT_ALLOC_6 ",
-       "NAPT_PORT_ALLOC_7 "
+       "NAPT_PORT_ALLOC_7 ",
+       "NAPT_PORT_ALLOC_8 ",
+       "NAPT_PORT_ALLOC_9 ",
+       "NAPT_PORT_ALLOC_10 ",
+       "NAPT_PORT_ALLOC_11 ",
+       "NAPT_PORT_ALLOC_12 ",
+       "NAPT_PORT_ALLOC_13 ",
+       "NAPT_PORT_ALLOC_14 ",
+       "NAPT_PORT_ALLOC_16 "
 };
 
 int vnf_set_count = -1;
@@ -131,6 +143,7 @@ struct rte_hash_parameters napt_common_table_hash_params = {
 };
 
 /***** ARP local cache *****/
+
 uint8_t link_hw_laddr_valid[MAX_NUM_LOCAL_MAC_ADDRESS] = {
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0
@@ -169,7 +182,6 @@ static uint32_t local_get_nh_ipv4(
        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);
@@ -180,10 +192,6 @@ static uint32_t local_get_nh_ipv6(
        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,
@@ -211,34 +219,9 @@ uint64_t nextPowerOf2(uint64_t n)
        return n;
 }
 
-/**
- * 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)
+void remove_local_cache(uint8_t port)
 {
-       return link_hw_laddr_valid[out_port];
+       link_hw_laddr_valid[port] = 0;
 }
 
 /**
@@ -291,26 +274,7 @@ 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;
-               }
-       }
+       return;
 }
 
 
@@ -372,45 +336,6 @@ static uint32_t local_get_nh_ipv6(
 }
 
 
-/**
- * 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
@@ -901,6 +826,33 @@ void sw_checksum(struct rte_mbuf *pkt, enum PKT_TYPE ver)
        }
 }
 
+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)
+{
+
+if (CGNAPT_DEBUG > 2) {
+       printf("MAC Found ip 0x%x, port %d - %02x:%02x:%02x:%02x:%02x:%02x  \n",
+       dest_address, port_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 (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]);
+}
+
+if (CGNAPT_DEBUG > 4)
+       print_pkt(pkt);
+}
+
 static uint8_t check_arp_icmp(
        struct rte_mbuf *pkt,
        uint64_t pkt_mask,
@@ -916,7 +868,7 @@ 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;
 
@@ -1669,7 +1621,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)
@@ -2160,11 +2111,35 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        }
 
                        *outport_id = p_nat->outport_id[dest_if];
-                       int ret;
-                       ret = get_dest_mac_addr_port(dest_address,
-                               &dest_if, &hw_addr);
+                       struct arp_entry_data *ret_arp_data;
+                       ret_arp_data = get_dest_mac_addr_port(dest_address,
+                               &dest_if, (struct ether_addr *)eth_dest);
+
+                       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;
+                       }
+
+                       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,
+                                                &hw_addr, *outport_id);
+                               }
 
-                       if (ret == ARP_FOUND) {
                                memcpy(eth_dest, &hw_addr,
                                        sizeof(struct ether_addr));
                                memcpy(eth_src, get_link_hw_addr(dest_if),
@@ -2199,23 +2174,22 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                        print_pkt(pkts[pkt_index]);
                                #endif
 
-                       } else{
-                               if (ret == ARP_NOT_FOUND) {
-                                       /* Commented code may be required
-                                        * for future use, Please keep it */
-                                       //request_arp(*outport_id, nhip,
-                                       //      p_nat->p.p);
-                                       printf("%s: ARP Not Found, nhip: %x, "
-                                       "outport_id: %d\n", __func__, nhip,
-                                       *outport_id);
-                               }
+                       } else 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++;
 
-                               p_nat->invalid_packets |= pkt_mask;
-                               p_nat->naptDroppedPktCount++;
-                               #ifdef CGNAPT_DEBUGGING
-                               p_nat->naptDroppedPktCount4++;
-                               #endif
-                               continue;
+                                       #ifdef CGNAPT_DEBUGGING
+                                       p_nat->naptDroppedPktCount4++;
+                                       #endif
+                                       continue;
+                               } else {
+                                       arp_queue_unresolved_packet(ret_arp_data,
+                                               pkts[pkt_index]);
+                                       continue;
+                               }
                        }
 
                        #ifdef CGNAPT_DBG_PRNT
@@ -2287,74 +2261,61 @@ 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_nd_data = get_dest_mac_address_ipv6_port((uint8_t *)
+                                &dst_addr[0], &dest_if,
+                                &hw_addr, &nh_ipv6[0]);
+                       *outport_id = p_nat->outport_id[dest_if];
 
-                       ret = local_get_nh_ipv6((uint8_t *)&dst_addr[0],
-                               &dest_if, &nh_ipv6[0], p_nat);
+                       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 (!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;
+                               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
@@ -2387,61 +2348,78 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                };
 
                                *outport_id = p_nat->outport_id[dest_if];
-                               int ret;
-                               ret = get_dest_mac_addr_port(dest_address,
-                                       &dest_if, &hw_addr);
+                               struct arp_entry_data *ret_arp_data;
+                               ret_arp_data = get_dest_mac_addr_port(dest_address,
+                                       &dest_if, (struct ether_addr *)eth_dest);
+
+                               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;
+                               }
+
+                               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,
+                                                        &hw_addr, *outport_id);
+                                       }
 
-                               if (ret == ARP_FOUND) {
                                        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("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_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",
+                                       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
+                                       }
+                                       #endif
 
-                               #ifdef CGNAPT_DBG_PRNT
-                               if (CGNAPT_DEBUG > 2) {
-                               printf("Dest MAC after - "
-                               "%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                       #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
+                                       }
+                                       #endif
 
-                               #ifdef CGNAPT_DBG_PRNT
-                               if (CGNAPT_DEBUG > 4)
-                                       print_pkt(pkts[pkt_index]);
-                               #endif
+                                       #ifdef CGNAPT_DBG_PRNT
+                                       if (CGNAPT_DEBUG > 4)
+                                               print_pkt(pkts[pkt_index]);
+                                       #endif
 
-                               } else {
-                                       if (ret == ARP_NOT_FOUND) {
-                                       printf("%s: ARP Not Found, nhip: %x, "
-                                       "outport_id: %d\n", __func__, nhip,
-                                       *outport_id);
-                                       }
-                                               //request_arp(*outport_id,
-                                               //      nhip, p_nat->p.p);
-                               p_nat->invalid_packets |= pkt_mask;
-                               p_nat->naptDroppedPktCount++;
-                               #ifdef CGNAPT_DEBUGGING
-                               p_nat->naptDroppedPktCount4++;
-                               #endif
-                               continue;
-                       }
+                               } else if (ret_arp_data->status == INCOMPLETE ||
+                                       ret_arp_data->status == PROBE) {
+                                       arp_queue_unresolved_packet(ret_arp_data,
+                                               pkts[pkt_index]);
+                                       continue;
+                               }
 
                        if (*protocol == IP_PROTOCOL_ICMP) {
                                // Query ID reverse translation done here
@@ -2465,12 +2443,12 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
 
                p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkts[pkt_index], pkt_type);
                        else
-               #endif
                                sw_checksum(pkts[pkt_index], pkt_type);
+               #endif
        }
 
        if (p_nat->invalid_packets) {
@@ -2538,7 +2516,7 @@ static int cgnapt_in_port_ah_ipv4_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)
                printf("cgnapt_key hit fn: %" PRIu32 "\n", n_pkts);
@@ -2558,6 +2536,7 @@ static int cgnapt_in_port_ah_ipv4_prv(struct rte_pipeline *rte_p,
 
        if (unlikely(p_nat->valid_packets == 0)) {
                /* no suitable packet for lookup */
+               printf("no suitable valid packets\n");
                rte_pipeline_ah_packet_drop(rte_p, p_nat->invalid_packets);
                return p_nat->valid_packets;
        }
@@ -2597,6 +2576,11 @@ static int cgnapt_in_port_ah_ipv4_prv(struct rte_pipeline *rte_p,
        for (; i < n_pkts; i++)
                pkt_work_cgnapt_ipv4_prv(pkts, i, arg, p_nat);
 
+       if (arp_pkts_mask) {
+               p_nat->valid_packets &= ~(arp_pkts_mask);
+               rte_pipeline_ah_packet_hijack(rte_p, arp_pkts_mask);
+       }
+
        if (p_nat->invalid_packets) {
                /* get rid of invalid packets */
                rte_pipeline_ah_packet_drop(rte_p, p_nat->invalid_packets);
@@ -2673,7 +2657,7 @@ static int cgnapt_in_port_ah_ipv4_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)
                printf("cgnapt_key hit fn: %" PRIu32 "\n", n_pkts);
@@ -2692,6 +2676,7 @@ static int cgnapt_in_port_ah_ipv4_pub(struct rte_pipeline *rte_p,
        p_nat->valid_packets &= ~(p_nat->invalid_packets);
 
        if (unlikely(p_nat->valid_packets == 0)) {
+               printf("no valid packets in pub\n");
                /* no suitable packet for lookup */
                rte_pipeline_ah_packet_drop(rte_p, p_nat->invalid_packets);
                return p_nat->valid_packets;
@@ -2732,6 +2717,11 @@ static int cgnapt_in_port_ah_ipv4_pub(struct rte_pipeline *rte_p,
        for (; i < n_pkts; i++)
                pkt_work_cgnapt_ipv4_pub(pkts, i, arg, p_nat);
 
+       if (arp_pkts_mask) {
+               rte_pipeline_ah_packet_hijack(rte_p, arp_pkts_mask);
+               p_nat->valid_packets &= ~(arp_pkts_mask);
+       }
+
        if (p_nat->invalid_packets) {
                /* get rid of invalid packets */
                rte_pipeline_ah_packet_drop(rte_p, p_nat->invalid_packets);
@@ -3697,6 +3687,7 @@ pkt_work_cgnapt_key_ipv4_pub(
  *  A pointer to main CGNAPT structure
  *
  */
+uint64_t last_update;
 void
 pkt_work_cgnapt_ipv4_prv(
        struct rte_mbuf **pkts,
@@ -3840,54 +3831,32 @@ pkt_work_cgnapt_ipv4_prv(
                #endif
                return;
        }
-
+       last_update = rte_rdtsc();
        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);
-       }
-
+       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);
        *outport_id = p_nat->outport_id[dest_if];
 
-       #ifdef CGNAPT_DBG_PRNT
-       if (CGNAPT_DEBUG > 2)
-               printf("Egress: \tphy_port:%d\t get_prv_to_pub():%d "
-                               "\tout_port:%d\n", pkt->port, dest_if,
-                               *outport_id);
-       #endif
+       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);
 
-       if (local_dest_mac_present(dest_if)) {
-               memcpy(eth_dest,
-                               get_local_link_hw_addr(dest_if),
-                               sizeof(struct ether_addr));
-               memcpy(eth_src, get_link_hw_addr(dest_if),
-                               sizeof(struct ether_addr));
+               }
        } else {
-               int ret;
-               ret = get_dest_mac_addr_port(dest_address, &dest_if, &hw_addr);
 
-               if (unlikely(ret != ARP_FOUND)) {
+               if (unlikely(ret_arp_data == NULL)) {
 
-                       if (unlikely(ret == ARP_NOT_FOUND)) {
-                               //request_arp(*outport_id, nhip, p_nat->p.p);
-                               printf("%s: ARP Not Found, nhip: %x, "
-                               "outport_id: %d\n", __func__, nhip,
-                               *outport_id);
-                       }
+                       #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;
@@ -3897,41 +3866,26 @@ pkt_work_cgnapt_ipv4_prv(
                        p_nat->naptDroppedPktCount4++;
                        #endif
                        return;
-
                }
 
-               #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));
-
-               link_hw_laddr_valid[dest_if] = 1;
-               memcpy(&link_hw_laddr[dest_if], &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));
        }
 
        {
@@ -4080,12 +4034,12 @@ pkt_work_cgnapt_ipv4_prv(
 
        p_nat->naptedPktCount++;
 
-       #ifdef HW_CHECKSUM_REQ
+       #ifdef CHECKSUM_REQ
                if (p_nat->hw_checksum_reqd)
                        hw_checksum(pkt, pkt_type);
                else
-       #endif
                        sw_checksum(pkt, pkt_type);
+       #endif
 
 }
 
@@ -4225,55 +4179,36 @@ pkt_work_cgnapt_ipv4_pub(
                        #endif
                        return;
                }
+       }
 
        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);
+       *outport_id = p_nat->outport_id[dest_if];
 
-       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 (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 (dest_if == INVALID_DESTIF) {
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount6++;
-                       #endif
-                       return;
+               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);
                }
 
-               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("Ingress: \tphy_port:%d\t get_pub_to_prv():%d "
-                       "\tout_port%d\n", pkt->port, dest_if, *outport_id);
-               #endif
-       }
-
-       if (local_dest_mac_present(dest_if)) {
-               memcpy(eth_dest,
-                                get_local_link_hw_addr(dest_if),
-                                sizeof(struct ether_addr));
-               memcpy(eth_src, get_link_hw_addr(dest_if),
-                                sizeof(struct ether_addr));
        } else {
-               int ret;
-               ret = get_dest_mac_addr_port(dest_address, &dest_if, &hw_addr);
 
-               if (unlikely(ret != ARP_FOUND)) {
+               if (unlikely(ret_arp_data == NULL)) {
 
-                       if (unlikely(ret == ARP_NOT_FOUND)) {
-                               /* Commented code may be required for debug
-                                * and future use, Please keep it */
-                               //request_arp(*outport_id, nhip, p_nat->p.p);
-                               printf("%s: ARP Not Found, nhip: %x, "
-                               "outport_id: %d\n", __func__, nhip,
-                               *outport_id);
+                       /* 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;
@@ -4285,42 +4220,24 @@ pkt_work_cgnapt_ipv4_pub(
                        return;
 
                }
-               #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));
-
-               link_hw_laddr_valid[dest_if] = 1;
-               memcpy(&link_hw_laddr[dest_if], &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));
        }
 
        {
@@ -4457,7 +4374,7 @@ pkt_work_cgnapt_ipv4_pub(
                if (ct_position < 0){
                        p_nat->invalid_packets |= pkt_mask;
 
-                        p_nat->naptDroppedPktCount++;
+                       p_nat->naptDroppedPktCount++;
                        return;
                }
                        #ifdef ALGDBG
@@ -4490,12 +4407,12 @@ pkt_work_cgnapt_ipv4_pub(
 
        p_nat->naptedPktCount++;
 
-       #ifdef HW_CHECKSUM_REQ
+       #ifdef CHECKSUM_REQ
                if (p_nat->hw_checksum_reqd)
                        hw_checksum(pkt, pkt_type);
                else
-       #endif
                        sw_checksum(pkt, pkt_type);
+       #endif
 }
 
 
@@ -4699,101 +4616,63 @@ pkt4_work_cgnapt_ipv4_prv(
                                #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 |= 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 "
-                       "get_prv_to_pub():%d \tout_port:%d\n",
-                                pkt->port, dest_if, *outport_id);
-               #endif
-               }
+               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);
+                       update_nhip_access(dest_if);
+
+                       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 (local_dest_mac_present(dest_if)) {
-                       memcpy(eth_dest,
-                                        get_local_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
-                       memcpy(eth_src,
-                                        get_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
                } else {
-               int ret;
-               ret = get_dest_mac_addr_port(dest_address, &dest_if, &hw_addr);
 
-               if (unlikely(ret != ARP_FOUND)) {
+                       if (unlikely(ret_arp_data == NULL)) {
 
-                       if (unlikely(ret == ARP_NOT_FOUND)) {
+                               #ifdef CGNAPT_DEBUGGING
                                printf("%s: ARP Not Found, nhip: %x, "
                                "outport_id: %d\n", __func__, nhip,
                                *outport_id);
-                               //request_arp(*outport_id, nhip, p_nat->p.p);
-                       }
-
-                       /* Drop the pkt */
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
+                               #endif
 
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount4++;
-                       #endif
-                       continue;
+                               /* Drop the pkt */
+                               p_nat->invalid_packets |= pkt_mask;
+                               p_nat->naptDroppedPktCount++;
 
-               }
-                       #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
+                               p_nat->naptDroppedPktCount4++;
+                               #endif
+                               continue;
 
-                               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));
 
-                       link_hw_laddr_valid[dest_if] = 1;
-                       memcpy(&link_hw_laddr[dest_if], &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
+                                       continue;
+                               } else {
+                                       arp_pkts_mask |= pkt_mask;
+                                       arp_queue_unresolved_packet(ret_arp_data, pkt);
+                                       continue;
+                               }
                        }
-                       #endif
-
-                       memcpy(eth_src,
-                                        get_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
                }
 
                {
@@ -4949,12 +4828,12 @@ pkt4_work_cgnapt_ipv4_prv(
 
                p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkt, pkt_type);
                        else
-               #endif
                                sw_checksum(pkt, pkt_type);
+               #endif
        }
 }
 
@@ -5041,7 +4920,7 @@ pkt4_work_cgnapt_ipv4_pub(
                                #ifdef CGNAPT_DEBUGGING
                                p_nat->naptDroppedPktCount3++;
                                #endif
-
+                               printf("causing p_nat->naptDroppedPktCount3\n");
                                continue;
                        }
 
@@ -5105,54 +4984,32 @@ pkt4_work_cgnapt_ipv4_pub(
                                #endif
                                continue;
                        }
-
-                       dest_address = entry->data.u.prv_ip;
-       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;
                }
+               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);
+               *outport_id = p_nat->outport_id[dest_if];
 
-               do_local_nh_ipv4_cache(dest_if, p_nat);
-       }
-
-                       *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);
 
-                       #ifdef CGNAPT_DBG_PRNT
-                       if (CGNAPT_DEBUG > 2)
-                               printf("Ingress: \tphy_port:%d\t "
-                               "get_pub_to_prv():%d \tout_port%d\n",
-                                        pkt->port, dest_if,
-                                        *outport_id);
-                       #endif
+               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 (local_dest_mac_present(dest_if)) {
-                       memcpy(eth_dest,
-                                        get_local_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
-                       memcpy(eth_src,
-                                        get_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
-               } else {
-               int ret;
-               ret = get_dest_mac_addr_port(dest_address, &dest_if, &hw_addr);
+       } else {
 
-               if (unlikely(ret != ARP_FOUND)) {
+               if (unlikely(ret_arp_data == NULL)) {
 
-                       if (unlikely(ret == ARP_NOT_FOUND)) {
-                               printf("%s: ARP Not Found, nhip: %x, "
-                               "outport_id: %d\n", __func__, nhip,
-                               *outport_id);
-                               //request_arp(*outport_id, nhip, p_nat->p.p);
-                       }
+                       #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;
@@ -5162,47 +5019,26 @@ pkt4_work_cgnapt_ipv4_pub(
                        p_nat->naptDroppedPktCount4++;
                        #endif
                        continue;
-
                }
-                       #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));
-
-                       link_hw_laddr_valid[dest_if] = 1;
-                       memcpy(&link_hw_laddr[dest_if],
-                                        &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
+                               continue;
+                       } else {
+                               arp_pkts_mask |= pkt_mask;
+                               arp_queue_unresolved_packet(ret_arp_data, pkt);
+                               continue;
                        }
-                       #endif
-
-                       memcpy(eth_src,
-                                        get_link_hw_addr(dest_if),
-                                        sizeof(struct ether_addr));
                }
+       }
 
                {
                        /* Ingress */
@@ -5369,12 +5205,12 @@ pkt4_work_cgnapt_ipv4_pub(
 
                p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkt, pkt_type);
                        else
-               #endif
                                sw_checksum(pkt, pkt_type);
+               #endif
        }
 }
 
@@ -6150,7 +5986,6 @@ pkt_work_cgnapt_ipv6_prv(
        __rte_unused void *arg,
        struct pipeline_cgnapt *p_nat)
 {
-
        /* index into hash table entries */
        int hash_table_entry = p_nat->lkup_indx[pkt_num];
 
@@ -6302,23 +6137,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)
@@ -6341,24 +6159,30 @@ pkt_work_cgnapt_ipv6_prv(
        }
        #endif
 
-       if (local_dest_mac_present(dest_if)) {
-               memcpy(eth_dest,
-                               get_local_link_hw_addr(dest_if),
-                               sizeof(struct ether_addr));
-               memcpy(eth_src, get_link_hw_addr(dest_if),
-                               sizeof(struct ether_addr));
+       struct arp_entry_data *ret_arp_data;
+       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);
+               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 {
-               int ret;
-               ret = get_dest_mac_addr_port(dest_address, &dest_if, &hw_addr);
 
-               if (unlikely(ret != ARP_FOUND)) {
+               if (unlikely(ret_arp_data == NULL)) {
 
-                       if (unlikely(ret == ARP_NOT_FOUND)) {
-                               printf("%s: ARP Not Found, nhip: %x, "
-                               "outport_id: %d\n", __func__, nhip,
-                               *outport_id);
-                               //request_arp(*outport_id, nhip, p_nat->p.p);
-                       }
+                       #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;
@@ -6368,37 +6192,25 @@ pkt_work_cgnapt_ipv6_prv(
                        p_nat->naptDroppedPktCount4++;
                        #endif
                        return;
-
-               }
-               #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));
        }
 
        {
@@ -6419,12 +6231,12 @@ pkt_work_cgnapt_ipv6_prv(
 
        p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkt, pkt_type);
                        else
-               #endif
                                sw_checksum(pkt, pkt_type);
+               #endif
 }
 
 
@@ -6520,91 +6332,70 @@ pkt_work_cgnapt_ipv6_pub(
                        #endif
                        return;
                }
-
-               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];
        }
+       memcpy(&dest_addr_ipv6[0], &entry->data.u.prv_ipv6[0], 16);
+       uint8_t nhipv6[16];
 
-       #ifdef CGNAPT_DEBUGGING
-       static int static_count;
+       memset(nh_ipv6, 0, 16);
+       struct nd_entry_data *ret_nd_data = NULL;
+       ret_nd_data = get_dest_mac_address_ipv6_port(
+                &dest_addr_ipv6[0],
+                &dest_if,
+                (struct ether_addr *)eth_dest,
+                &nh_ipv6[0]);
 
-       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
+       *outport_id = p_nat->outport_id[dest_if];
 
-       memset(nh_ipv6, 0, 16);
-       if (get_dest_mac_address_ipv6_port(
-               &dest_addr_ipv6[0],
-               &dest_if,
-               &hw_addr,
-               &nh_ipv6[0])) {
+       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 */
        {
 
@@ -6638,12 +6429,12 @@ pkt_work_cgnapt_ipv6_pub(
 
        p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkt, pkt_type);
                        else
-               #endif
                                sw_checksum(pkt, pkt_type);
+               #endif
 }
 
 
@@ -6825,23 +6616,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"
@@ -6865,67 +6639,63 @@ pkt4_work_cgnapt_ipv6_prv(
 
                memset(nh_ipv6, 0, 16);
 
-               {
-               int ret;
-               ret = get_dest_mac_addr_port(dest_address, &dest_if, &hw_addr);
+       {
+               struct arp_entry_data *ret_arp_data;
+               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 (unlikely(ret != ARP_FOUND)) {
+               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_NOT_FOUND)) {
-                               /* Commented code may be required for debug
-                                * and future use, Please keep it */
-                               //request_arp(*outport_id, nhip, p_nat->p.p);
-                               printf("%s: ARP Not Found, nhip: %x, "
-                               "outport_id: %d\n", __func__, nhip,
-                               *outport_id);
-                       }
+                       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);
 
-                       /* Drop the pkt */
-                       p_nat->invalid_packets |= pkt_mask;
-                       p_nat->naptDroppedPktCount++;
+                       }
+               } else {
 
-                       #ifdef CGNAPT_DEBUGGING
-                       p_nat->naptDroppedPktCount4++;
-                       #endif
-                       continue;
+                       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
 
-                       #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]
-                                       );
+                               /* Drop the pkt */
+                               p_nat->invalid_packets |= pkt_mask;
+                               p_nat->naptDroppedPktCount++;
 
-                               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]);
+                               #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));
                }
+       }
 
                {
                        /* Egress */
@@ -6945,12 +6715,12 @@ pkt4_work_cgnapt_ipv6_prv(
 
                p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkt, pkt_type);
                        else
-               #endif
                                sw_checksum(pkt, pkt_type);
+               #endif
        }
 }
 
@@ -7041,8 +6811,7 @@ pkt4_work_cgnapt_ipv6_pub(
                uint8_t dest_addr_ipv6[16];
                uint8_t nh_ipv6[16];
                uint32_t dest_if = INVALID_DESTIF;
-               /* Ingress */
-               {
+               { /*start of Ingress */
 
                        if (unlikely(protocol == IP_PROTOCOL_UDP
                                && rte_be_to_cpu_16(*src_port) == 53)) {
@@ -7057,27 +6826,7 @@ 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
                static int static_count;
@@ -7092,53 +6841,65 @@ 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;
+               ret_nd_data = get_dest_mac_address_ipv6_port
+                               (&dest_addr_ipv6[0], &dest_if,
+                               (struct ether_addr *)eth_dest, &nh_ipv6[0]);
 
-                               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]);
+               *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)) {
+
+                               #ifdef CGNAPT_DEBUGGING
+                               printf("%s: NHIP Not Found "
+                               "outport_id: %d\n", __func__,
+                               *outport_id);
+                               #endif
 
-                       memcpy(eth_dest, &hw_addr, sizeof(struct ether_addr));
+                               /* 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
+                               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;
                }
 
                {
-                       /* Ingress */
+               /* start of Ingress */
 
                        convert_ipv4_to_ipv6(pkt, &ipv4_hdr);
 
@@ -7166,17 +6927,17 @@ pkt4_work_cgnapt_ipv6_pub(
                        #endif
 
                        p_nat->inaptedPktCount++;
-               }
+               } /* end of ingress */
 
                p_nat->naptedPktCount++;
 
-               #ifdef HW_CHECKSUM_REQ
+               #ifdef CHECKSUM_REQ
                        if (p_nat->hw_checksum_reqd)
                                hw_checksum(pkt, pkt_type);
                        else
-               #endif
                                sw_checksum(pkt, pkt_type);
-       }
+               #endif
+       } /* end of for loop */
 }
 
 /**
@@ -7208,6 +6969,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)
@@ -7226,6 +6988,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);
@@ -7321,6 +7088,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)
@@ -7339,6 +7107,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);
@@ -7882,12 +7655,11 @@ pkt_miss_cgnapt(struct pipeline_cgnapt_entry_key *key,
                                        printf("Add Dynamic NAT entry failed "
                                        "in pkt!!!\n");
                                #endif
-               } else {
+                       } else {
                                #ifdef CGNAPT_DEBUGGING
                                p_nat->missedpktcount11++;
                                #endif
-               }
-
+                       }
                }
 
        } else if (!is_phy_port_privte(phy_port)) {
@@ -8380,7 +8152,6 @@ pipeline_cgnapt_parse_args(struct pipeline_cgnapt *p,
        return 0;
 
 }
-
 /**
  * Function to initialize the pipeline
  *
@@ -8408,6 +8179,7 @@ static void *pipeline_cgnapt_init(struct pipeline_params *params, void *arg)
        size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_cgnapt));
        p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
        p_nat = (struct pipeline_cgnapt *)p;
+       global_pnat = p_nat;
        if (p == NULL)
                return NULL;
 
@@ -9251,11 +9023,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) {