[l2l3 stack] implements new nd state machine & nd buffering 13/35913/6
authorVishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
Wed, 7 Jun 2017 21:23:22 +0000 (02:53 +0530)
committerVishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
Tue, 18 Jul 2017 07:40:56 +0000 (13:10 +0530)
JIRA: SAMPLEVNF-32

This patch implements
  ~New nd state machine implementing new states
   like INCOMPLETE, COMPLETE, PROBE, STALE.
  ~Implementing nd buffering, when nd is unresolved.
  ~Integratig the new changes with vCGNAPT
  ~Integrating the new changes with vACL
  ~Integrating the new changes with vFW.
  ~Adding locks to synchronize against multiple VNF threads

Change-Id: Iaee4f4599ca3016ebb50ee2d9133fd8c39c5cd04
Signed-off-by: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
16 files changed:
VNFs/vACL/init.c
VNFs/vACL/pipeline/pipeline_acl_be.c
VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.c
VNFs/vFW/pipeline/pipeline_vfw_be.c
common/VIL/l2l3_stack/interface.h
common/VIL/l2l3_stack/l3fwd_lpm6.c
common/VIL/l2l3_stack/lib_arp.c
common/VIL/l2l3_stack/lib_arp.h
common/VIL/l2l3_stack/lib_icmpv6.c
common/VIL/l2l3_stack/lib_icmpv6.h
common/VIL/pipeline_arpicmp/pipeline_arpicmp.c
common/VIL/pipeline_arpicmp/pipeline_arpicmp_be.h
common/VIL/pipeline_common/pipeline_common_fe.c
common/VIL/pipeline_txrx/pipeline_txrx_be.c
common/vnf_common/config_parse.c
common/vnf_common/vnf_common.c

index 42a1e43..71dd50e 100644 (file)
@@ -1299,11 +1299,13 @@ int app_init(struct app_params *app)
        app_init_pipelines(app);
        app_init_threads(app);
 
+       #ifdef L3_STACK_SUPPORT
         l3fwd_init();
         create_arp_table();
         create_nd_table();
         populate_lpm_routes();
         print_interface_details();
+       #endif
 
        return 0;
 }
index b9386e6..3a9005f 100644 (file)
@@ -166,30 +166,6 @@ uint32_t local_get_nh_ipv4(uint32_t ip,
        return 0;
 }
 
-static void do_local_nh_ipv4_cache(uint32_t dest_if, struct pipeline_acl *p_acl)
-{
-
-       /* 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_acl->local_lib_arp_route_table
-                               [p_acl->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_acl->local_lib_arp_route_ent_cnt++;
-                       break;
-               }
-       }
-}
-
 static uint32_t local_get_nh_ipv6(uint8_t *ip,
                                  uint32_t *port,
                                  uint8_t nhip[], struct pipeline_acl *p_acl)
@@ -239,32 +215,6 @@ static uint32_t local_get_nh_ipv6(uint8_t *ip,
         }
         return 0;
 }
-void do_local_nh_ipv6_cache(uint32_t dest_if, struct pipeline_acl *p_acl)
-{
-       /* 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_acl->local_lib_nd_route_table
-                           [p_acl->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_acl->local_lib_nd_route_ent_cnt++;
-                       break;
-               }               /* if */
-       }                       /* for */
-}
 
 static uint8_t check_arp_icmp(struct rte_mbuf *pkt,
                              uint64_t pkt_mask, struct pipeline_acl *p_acl)
@@ -925,9 +875,9 @@ pkt_work_acl_key(struct rte_pipeline *p,
                            (dest_address, &dest_if, (struct ether_addr *) eth_dest);
                        *port_out_id = p_acl->port_out_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);
-
+                               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)) {
                                        printf("sending buffered packets\n");
                                        arp_send_buffered_pkts(ret_arp_data,
@@ -936,7 +886,7 @@ pkt_work_acl_key(struct rte_pipeline *p,
                                }
                        } else {
                                if (unlikely(ret_arp_data == NULL)) {
-
+                                       if (ACL_DEBUG)
                                        printf("%s: NHIP Not Found, "
                                        "outport_id: %d\n", __func__,
                                        *port_out_id);
@@ -964,7 +914,8 @@ pkt_work_acl_key(struct rte_pipeline *p,
                                                continue;
                                        } else {
                                                arp_pkts_mask |= pkt_mask;
-                                               arp_queue_unresolved_packet(ret_arp_data, pkt);
+                                               arp_queue_unresolved_packet(ret_arp_data,
+                                                                        pkt);
                                                continue;
                                        }
                                }
@@ -1026,105 +977,60 @@ pkt_work_acl_key(struct rte_pipeline *p,
                        }
                        memcpy(dest_address, *dst_addr, sizeof(dest_address));
                        memset(nhip, 0, sizeof(nhip));
-                       ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
-                                               &nhip[0], p_acl);
-
-                       if (is_phy_port_privte(phy_port)) {
-                               if (!ret) {
-                                       dest_if = get_prv_to_pub_port((
-                                                                      uint32_t
-                                                                      *)
-                                             &dest_address[0], IP_VERSION_6);
-                                       do_local_nh_ipv6_cache(dest_if, p_acl);
-                                       *port_out_id =
-                                           p_acl->port_out_id[dest_if];
-                               }
-                               //              port = ACL_PUB_PORT_ID;
 
+                       struct nd_entry_data *ret_nd_data = NULL;
+                       ret_nd_data = get_dest_mac_address_ipv6_port
+                           (dest_address, &dest_if, &hw_addr, &nhip[0]);
+                       *port_out_id = p_acl->port_out_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)) {
+                                       printf("sending buffered packets\n");
+                                       p_acl->counters->tpkts_processed +=
+                                                ret_nd_data->num_pkts;
+                                       nd_send_buffered_pkts(ret_nd_data,
+                                       (struct ether_addr *)eth_dest, *port_out_id);
+                               }
                        } else {
-                               if (!ret) {
-                                       dest_if = get_pub_to_prv_port((
-                                                                      uint32_t
-                                                                      *)
-                                             &dest_address[0], IP_VERSION_6);
-                                       do_local_nh_ipv6_cache(dest_if, p_acl);
-                                       *port_out_id =
-                                           p_acl->port_out_id[dest_if];
+                               if (unlikely(ret_nd_data == NULL)) {
+                                       if (ACL_DEBUG)
+                                               printf("ACL before drop pkt_mask  "
+                                               "%lu, pkt_num %d\n", pkts_mask, pos);
+                                       pkts_mask &= ~(1LLU << pos);
+                                       if (ACL_DEBUG)
+                                               printf("ACL after drop pkt_mask  "
+                                               "%lu, pkt_num %d\n", pkts_mask, pos);
+                                       p_acl->counters->pkts_drop++;
+                                       continue;
                                }
-//               port = ACL_PRV_PORT_ID;
-
-                       }
 
-                       if (get_dest_mac_address_ipv6_port
-                           (dest_address, &dest_if, &hw_addr, &nhip[0])) {
-                               if (ACL_DEBUG) {
-                                       printf("MAC found for  port %d - "
-                                       " %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                            phy_port, 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]);
-                               }
-                               memcpy(eth_dest, &hw_addr,
-                                      sizeof(struct ether_addr));
-                               if (ACL_DEBUG) {
-                                       printf("PktP %p, dest_macP %p\n", pkt,
-                                              eth_dest);
-                                       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 (ret_nd_data->status == INCOMPLETE ||
+                                       ret_nd_data->status == PROBE) {
+                                       if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                               /* Drop the pkt */
+                                               if (ACL_DEBUG)
+                                                       printf("ACL before drop pkt_mask  "
+                                                       "%lu, pkt_num %d\n", pkts_mask, pos);
+                                               pkts_mask &= ~(1LLU << pos);
+                                               if (ACL_DEBUG)
+                                                       printf("ACL after drop pkt_mask  "
+                                                       "%lu, pkt_num %d\n", pkts_mask, pos);
+                                               p_acl->counters->pkts_drop++;
+                                               continue;
+                                       } else {
+                                               arp_pkts_mask |= pkt_mask;
+                                               nd_queue_unresolved_packet(ret_nd_data,
+                                                                                pkt);
+                                               continue;
+                                       }
                                }
-                               if (is_phy_port_privte(phy_port))
-                                       memcpy(eth_src,
-                                              get_link_hw_addr(dest_if),
-                                              sizeof(struct ether_addr));
-                               else
-                                       memcpy(eth_src,
-                                              get_link_hw_addr(dest_if),
-                                              sizeof(struct ether_addr));
 
-/* memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]), */
-/*                sizeof(struct ether_addr)); */
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
                        }
 
-                       else {
-
-#if 0
-                       /* Request next neighbor for Ipv6 is yet to be done. */
-                               if (*nhip != 0) {
-                                       if (ACL_DEBUG)
-                                               printf
-                                   ("ACL requesting ARP for ip %x, port %d\n",
-                                                    dest_address, phy_port);
-
-                       /* request_arp(p_acl->links_map[phy_port], *nhip); */
-                               }
-#endif
-                               /* Drop packet by changing the mask */
-                               if (ACL_DEBUG)
-                                       printf("ACL before drop pkt_mask  "
-                                                       "%lu, pkt_num %d\n",
-                                            pkts_mask, pos);
-                               pkts_mask &= ~(1LLU << pos);
-                               if (ACL_DEBUG)
-                                       printf("ACL after drop pkt_mask  "
-                                                       "%lu, pkt_num %d\n",
-                                            pkts_mask, pos);
-                               p_acl->counters->pkts_drop++;
-                       }
-               }
+               } /* if (hdr_chk == IPv6_HDR_VERSION) */
 
        }
 
@@ -1645,44 +1551,16 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p,
                                                                       nhip));
                        uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
                        *nhip = 0;
-                       if (is_phy_port_privte(phy_port)) {
-                               dest_address = rte_bswap32(*dst_addr);
-                               ret =
-                                   local_get_nh_ipv4(dest_address, &dest_if,
-                                                     nhip, p_acl);
-                               if (!ret) {
-                                       dest_if =
-                                           get_prv_to_pub_port(&dest_address,
-                                                               IP_VERSION_4);
-                                       do_local_nh_ipv4_cache(dest_if, p_acl);
-                               }
-                               *port_out_id = p_acl->port_out_id[dest_if];
-                       }
-                       /* port = ACL_PUB_PORT_ID; */
-                       else {
-                               dest_address = rte_bswap32(*dst_addr);
-
-                               ret = local_get_nh_ipv4(dest_address, &dest_if,
-                                                       nhip, p_acl);
-                               if (!ret) {
-                                       dest_if =
-                                           get_pub_to_prv_port(&dest_address,
-                                                               IP_VERSION_4);
-                                       do_local_nh_ipv4_cache(dest_if, p_acl);
-                               };
-                               *port_out_id = p_acl->port_out_id[dest_if];
-                       }
-                       /* port = ACL_PRV_PORT_ID; */
-
+                       dest_address = rte_bswap32(*dst_addr);
                        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);
                        *port_out_id = p_acl->port_out_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);
-
+                               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)) {
                                        printf("sending buffered packets\n");
                                        arp_send_buffered_pkts(ret_arp_data,
@@ -1692,6 +1570,7 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p,
                        } else {
                                if (unlikely(ret_arp_data == NULL)) {
 
+                                       if (ACL_DEBUG)
                                        printf("%s: NHIP Not Found, "
                                        "outport_id: %d\n", __func__,
                                        *port_out_id);
@@ -1833,17 +1712,6 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p,
 
                        else {
 
-#if 0
-                       /* Request next neighbor for Ipv6 is yet to be done. */
-                               if (*nhip != 0) {
-                                       if (ACL_DEBUG)
-                                               printf
-                                   ("ACL requesting ARP for ip %x, port %d\n",
-                                                    dest_address, phy_port);
-
-                       /* request_arp(p_acl->links_map[phy_port], *nhip); */
-                               }
-#endif
                                /* Drop packet by changing the mask */
                                if (ACL_DEBUG)
                                        printf("ACL before drop pkt_mask "
@@ -2331,151 +2199,6 @@ pkt_work_acl_ipv6_key(struct rte_pipeline *p,
                uint8_t hdr_chk =
                    RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
                hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-#if 0
-               if (hdr_chk == IPv4_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv4[pos];
-                       uint16_t phy_port = entry->head.port_id;
-                       uint32_t *port_out_id =
-                           RTE_MBUF_METADATA_UINT32_PTR(pkt,
-                                                        META_DATA_OFFSET +
-                                                        offsetof(struct
-                                                         mbuf_acl_meta_data,
-                                                                 output_port));
-                       /*  *port_out_id = p_acl->links_map[phy_port]; */
-                       if (is_phy_port_privte(phy_port))
-                               *port_out_id = ACL_PUB_PORT_ID;
-                       else
-                               *port_out_id = ACL_PRV_PORT_ID;
-                       if (ACL_DEBUG)
-                               printf
-                                   ("phy_port = %i,links_map[phy_port] = %i\n",
-                                    phy_port, p_acl->links_map[phy_port]);
-
-       /* header room + eth hdr size + dst_adr offset in ip header */
-                       uint32_t dst_addr_offset =
-                           MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
-                       uint32_t *dst_addr =
-                           RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
-                       uint8_t *eth_dest =
-                           RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
-                       uint8_t *eth_src =
-                           RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
-                       struct ether_addr hw_addr;
-                       uint32_t dest_address = rte_bswap32(*dst_addr);
-                       uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
-                                                             META_DATA_OFFSET
-                                                                     +
-                                                                     offsetof
-                                                                     (struct
-                                                      mbuf_acl_meta_data,
-                                                                      nhip));
-                       uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
-                       *nhip = 0;
-                       if (is_phy_port_privte(phy_port)) {
-                               dest_address = rte_bswap32(*dst_addr);
-                               ret =
-                                   local_get_nh_ipv4(dest_address, &dest_if,
-                                                     nhip, p_acl);
-                               if (!ret) {
-                                       dest_if =
-                                           get_prv_to_pub_port(&dest_address,
-                                                               IP_VERSION_4);
-                                       do_local_nh_ipv4_cache(dest_if, p_acl);
-                               }
-                               *port_out_id = p_acl->port_out_id[dest_if];
-                       }
-                       /* port = ACL_PUB_PORT_ID; */
-                       else {
-                               dest_address = rte_bswap32(*dst_addr);
-
-                               ret = local_get_nh_ipv4(dest_address, &dest_if,
-                                                       nhip, p_acl);
-                               if (!ret) {
-                                       dest_if =
-                                           get_pub_to_prv_port(&dest_address,
-                                                               IP_VERSION_4);
-                                       do_local_nh_ipv4_cache(dest_if, p_acl);
-                               };
-                               *port_out_id = p_acl->port_out_id[dest_if];
-                       }
-                       /* port = ACL_PRV_PORT_ID; */
-
-                       if (get_dest_mac_addr_port
-                           (dest_address, &dest_if, &hw_addr)) {
-                               if (ACL_DEBUG) {
-                                       printf("MAC found for ip 0x%x, port "
-                                       " %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                            dest_address, phy_port,
-                                            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]);
-                               }
-
-                               memcpy(eth_dest, &hw_addr,
-                                      sizeof(struct ether_addr));
-                               if (ACL_DEBUG) {
-                                       printf("PktP %p, dest_macP %p\n", pkt,
-                                              eth_dest);
-                                       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 (is_phy_port_privte(phy_port))
-                                       memcpy(eth_src,
-                                              get_link_hw_addr(dest_if),
-                                              sizeof(struct ether_addr));
-                               else
-                                       memcpy(eth_src,
-                                              get_link_hw_addr(dest_if),
-                                              sizeof(struct ether_addr));
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
-                       }
-
-                       else {
-                               if (*nhip != 0) {
-
-                                       if (ACL_DEBUG)
-
-                                               printf("ACL requesting ARP for "
-                                                       " ip %x, port %d\n",
-                                                    dest_address, phy_port);
-                                       if (is_phy_port_privte(phy_port))
-                                               request_arp(dest_if, *nhip);
-
-                                       else
-                                               request_arp(dest_if, *nhip);
-
-                       /*  request_arp(p_acl->links_map[phy_port], *nhip); */
-                               }
-                               /* Drop packet by changing the mask */
-                               if (ACL_DEBUG)
-                                       printf("ACL before drop pkt_mask  "
-                                               "%lu, pkt_num %d\n",
-                                            pkts_mask, pos);
-                               pkts_mask &= ~(1LLU << pos);
-                               if (ACL_DEBUG)
-                                       printf("ACL after drop pkt_mask  "
-                                               "%lu, pkt_num %d\n",
-                                            pkts_mask, pos);
-                               p_acl->counters->pkts_drop++;
-                       }
-               }
-#endif
 
                if (hdr_chk == IPv6_HDR_VERSION) {
 
@@ -2531,109 +2254,62 @@ pkt_work_acl_ipv6_key(struct rte_pipeline *p,
                        }
                        memcpy(dest_address, *dst_addr, sizeof(dest_address));
                        memset(nhip, 0, sizeof(nhip));
-                       ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
-                                               &nhip[0], p_acl);
-
-                       if (is_phy_port_privte(phy_port)) {
-                               if (!ret) {
-                                       dest_if = get_prv_to_pub_port((
-                                                                      uint32_t
-                                                                      *)
-                                             &dest_address[0], IP_VERSION_6);
-                                       do_local_nh_ipv6_cache(dest_if, p_acl);
-                               }
-                               //          port = ACL_PUB_PORT_ID;
-                                       *port_out_id =
-                                           p_acl->port_out_id[dest_if];
+                       struct nd_entry_data *ret_nd_data = NULL;
+                       ret_nd_data = get_dest_mac_address_ipv6_port
+                           (dest_address, &dest_if, &hw_addr, &nhip[0]);
+                       *port_out_id = p_acl->port_out_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)) {
+                                       printf("sending buffered packets\n");
+                                       p_acl->counters->tpkts_processed +=
+                                                ret_nd_data->num_pkts;
+                                       nd_send_buffered_pkts(ret_nd_data,
+                                       (struct ether_addr *)eth_dest, *port_out_id);
+                               }
                        } else {
-                               if (!ret) {
-                                       dest_if = get_pub_to_prv_port((
-                                                                      uint32_t
-                                                                      *)
-                                             &dest_address[0], IP_VERSION_6);
-                                       do_local_nh_ipv6_cache(dest_if, p_acl);
+                               if (unlikely(ret_nd_data == NULL)) {
+                                       if (ACL_DEBUG)
+                                               printf("ACL before drop pkt_mask  "
+                                               "%lu, pkt_num %d\n", pkts_mask, pos);
+                                       pkts_mask &= ~(1LLU << pos);
+                                       if (ACL_DEBUG)
+                                               printf("ACL after drop pkt_mask  "
+                                               "%lu, pkt_num %d\n", pkts_mask, pos);
+                                       p_acl->counters->pkts_drop++;
+                                       continue;
                                }
-                               //           port = ACL_PRV_PORT_ID;
-                                       *port_out_id =
-                                           p_acl->port_out_id[dest_if];
-
-                       }
 
-                       if (get_dest_mac_address_ipv6_port
-                           (dest_address, &dest_if, &hw_addr, &nhip[0])) {
-                               if (ACL_DEBUG) {
-                                       printf("MAC found for  port %d  "
-                                       "- %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                            phy_port, 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]);
-                               }
-                               memcpy(eth_dest, &hw_addr,
-                                      sizeof(struct ether_addr));
-                               if (ACL_DEBUG) {
-                                       printf("PktP %p, dest_macP %p\n", pkt,
-                                              eth_dest);
-                                       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 (ret_nd_data->status == INCOMPLETE ||
+                                       ret_nd_data->status == PROBE) {
+                                       if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                               /* Drop the pkt */
+                                               if (ACL_DEBUG)
+                                                       printf("ACL before drop pkt_mask  "
+                                                       "%lu, pkt_num %d\n", pkts_mask, pos);
+                                               pkts_mask &= ~(1LLU << pos);
+                                               if (ACL_DEBUG)
+                                                       printf("ACL after drop pkt_mask  "
+                                                       "%lu, pkt_num %d\n", pkts_mask, pos);
+                                               p_acl->counters->pkts_drop++;
+                                               continue;
+                                       } else {
+                                               arp_pkts_mask |= pkt_mask;
+                                               nd_queue_unresolved_packet(ret_nd_data,
+                                                                                pkt);
+                                               continue;
+                                       }
                                }
-                               if (is_phy_port_privte(phy_port))
-                                       memcpy(eth_src,
-                                              get_link_hw_addr(dest_if),
-                                              sizeof(struct ether_addr));
-                               else
-                                       memcpy(eth_src,
-                                              get_link_hw_addr(dest_if),
-                                              sizeof(struct ether_addr));
 
-               /*
-                * memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]),
-                * sizeof(struct ether_addr));
-                */
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
                        }
 
-                       else {
-
-#if 0
-                       /* Request next neighbor for Ipv6 is yet to be done. */
-                       if (*nhip != 0) {
-                       if (ACL_DEBUG)
-                               printf
-                                   ("ACL requesting ARP for ip %x, port %d\n",
-                                                    dest_address, phy_port);
-
-                       /* request_arp(p_acl->links_map[phy_port], *nhip); */
-                               }
-#endif
-                               /* Drop packet by changing the mask */
-                               if (ACL_DEBUG)
-                                       printf("ACL before drop pkt_mask "
-                                               " %lu, pkt_num %d\n",
-                                            pkts_mask, pos);
-                               pkts_mask &= ~(1LLU << pos);
-                               if (ACL_DEBUG)
-                                       printf("ACL after drop pkt_mask "
-                                               " %lu, pkt_num %d\n",
-                                            pkts_mask, pos);
-                               p_acl->counters->pkts_drop++;
-                       }
                }
 
-       }
+       } /* end of for loop */
 
        pkts_drop_mask = keep_mask & ~pkts_mask;
        rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
index 2fbc71d..ba324e9 100644 (file)
@@ -83,7 +83,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];
@@ -192,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,
@@ -228,36 +224,6 @@ 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
  *
@@ -308,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;
 }
 
 
@@ -389,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
@@ -918,7 +826,7 @@ void sw_checksum(struct rte_mbuf *pkt, enum PKT_TYPE ver)
        }
 }
 
-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)
 {
 
@@ -1713,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)
@@ -2206,14 +2113,15 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        *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);
+                               &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++;
@@ -2225,7 +2133,7 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        }
 
                        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 +2174,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 +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
@@ -2455,13 +2350,15 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                *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);
+                                       &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;
@@ -2492,9 +2389,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 +2414,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 +2570,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);
 
@@ -3941,15 +3835,14 @@ 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);
+       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);
-
+               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);
@@ -3959,9 +3852,11 @@ pkt_work_cgnapt_ipv4_prv(
 
                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 +3868,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 */
@@ -4288,15 +4183,15 @@ 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);
+       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);
+               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 +4203,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 +4221,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 */
@@ -4723,14 +4621,15 @@ 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);
+               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);
-               
+                       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 +4639,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 +4656,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 */
@@ -5086,15 +4987,15 @@ 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);
+               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);
-               
+               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);
@@ -5104,9 +5005,11 @@ pkt4_work_cgnapt_ipv4_pub(
 
                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 +5021,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 */
@@ -6234,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)
@@ -6273,18 +6159,30 @@ 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;
+       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 {
-               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 +6194,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 +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 */
        {
 
@@ -6759,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"
@@ -6801,64 +6641,59 @@ 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);
+               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_data == NULL)) {
+               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);
 
-                       printf("%s: NHIP 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)) {
 
-               if (ret_arp_data->status == COMPLETE) {
+                               #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));
-               } else if (ret_arp_data->status == INCOMPLETE || 
-                       ret_arp_data->status == PROBE) {
-                       arp_queue_unresolved_packet(ret_arp_data,
-                               pkt);
-                       continue;
                }
        }
 
@@ -6991,26 +6826,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 +6841,61 @@ 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;
                }
 
                {
@@ -7142,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)
@@ -7160,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);
@@ -7255,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)
@@ -7273,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);
@@ -9184,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) {
index a654c3f..ea5d235 100644 (file)
@@ -68,7 +68,7 @@
 uint32_t timer_lcore;
 
 uint8_t firewall_flag = 1;
-uint8_t VFW_DEBUG;
+uint8_t VFW_DEBUG = 0;
 uint8_t cnxn_tracking_is_active = 1;
 /**
  * A structure defining the VFW pipeline input port per thread data.
@@ -176,32 +176,6 @@ __rte_cache_aligned;
   * TODO: look into "stub" table and see if that can be used
   * to avoid useless table lookup
   */
-/***** ARP local cache *****/
-#if 0
-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
-};
-
-static struct ether_addr link_hw_laddr[MAX_NUM_LOCAL_MAC_ADDRESS] = {
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-       {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
-};
-#endif
 uint64_t arp_pkts_mask;
 
 /* Start TSC measurement */
@@ -231,142 +205,6 @@ static inline void end_tsc_measure(
        }
 }
 
-//static struct ether_addr *get_local_link_hw_addr(uint8_t out_port)
-//{
-//       return &link_hw_laddr[out_port];
-//}
-#if 0
-static uint8_t local_dest_mac_present(uint8_t out_port)
-{
-       return link_hw_laddr_valid[out_port];
-}
-
-static uint32_t local_get_nh_ipv4(
-       uint32_t ip,
-       uint32_t *port,
-       uint32_t *nhip,
-       struct pipeline_vfw *vfw_pipe)
-{
-       int i;
-
-       for (i = 0; i < vfw_pipe->local_lib_arp_route_ent_cnt; i++) {
-              if (((vfw_pipe->local_lib_arp_route_table[i].ip &
-              vfw_pipe->local_lib_arp_route_table[i].mask) ==
-              (ip & vfw_pipe->local_lib_arp_route_table[i].mask))) {
-                     *port = vfw_pipe->local_lib_arp_route_table[i].port;
-
-                     *nhip = vfw_pipe->local_lib_arp_route_table[i].nh;
-                     return 1;
-              }
-       }
-       return 0;
-}
-
-static void do_local_nh_ipv4_cache(uint32_t dest_if,
-              struct pipeline_vfw *vfw_pipe)
-{
-
-       /* 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 =
-                            &vfw_pipe->
-                            local_lib_arp_route_table[vfw_pipe->
-                            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;
-
-                     vfw_pipe->local_lib_arp_route_ent_cnt++;
-                     break;
-              }
-       }
-}
-#endif
-static uint32_t local_get_nh_ipv6(
-       uint8_t *ip,
-       uint32_t *port,
-       uint8_t nhip[],
-        struct pipeline_vfw *vfw_pipe)
-{
-       uint8_t netmask_ipv6[IPV6_ADD_SIZE], netip_nd[IPV6_ADD_SIZE],
-              netip_in[IPV6_ADD_SIZE];
-       uint8_t i = 0, j = 0, k = 0, l = 0, depthflags = 0, depthflags1 = 0;
-       memset(netmask_ipv6, 0, sizeof(netmask_ipv6));
-       memset(netip_nd, 0, sizeof(netip_nd));
-       memset(netip_in, 0, sizeof(netip_in));
-
-       for (i = 0; i < vfw_pipe->local_lib_nd_route_ent_cnt; i++) {
-
-              convert_prefixlen_to_netmask_ipv6(
-                     vfw_pipe->local_lib_nd_route_table[i].depth,
-                     netmask_ipv6);
-
-              for (k = 0; k < IPV6_ADD_SIZE; k++)
-                     if (vfw_pipe->local_lib_nd_route_table[i].ipv6[k] &
-                                   netmask_ipv6[k]) {
-                            depthflags++;
-                            netip_nd[k] = vfw_pipe->
-                                   local_lib_nd_route_table[i].ipv6[k];
-                     }
-
-              for (l = 0; l < IPV6_ADD_SIZE; l++)
-                     if (ip[l] & netmask_ipv6[l]) {
-                            depthflags1++;
-                            netip_in[l] = ip[l];
-                     }
-
-
-              if ((depthflags == depthflags1) && (memcmp(netip_nd, netip_in,
-                                          sizeof(netip_nd)) == 0)) {
-
-                     *port = vfw_pipe->local_lib_nd_route_table[i].port;
-
-                     for (j = 0; j < IPV6_ADD_SIZE; j++)
-                            nhip[j] = vfw_pipe->
-                                   local_lib_nd_route_table[i].nhipv6[j];
-                     return 1;
-              }
-
-              depthflags = 0;
-              depthflags1 = 0;
-                     }
-                     return 0;
-}
-
-static void do_local_nh_ipv6_cache(uint32_t dest_if,
-              struct pipeline_vfw *vfw_pipe)
-{
-              /* 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 = &vfw_pipe->
-                            local_lib_nd_route_table[vfw_pipe->
-                            local_lib_nd_route_ent_cnt];
-
-                     for (l = 0; l < IPV6_ADD_SIZE; 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;
-
-                     vfw_pipe->local_lib_nd_route_ent_cnt++;
-                     break;
-                     } /* if */
-              } /* for */
-}
 /**
  * Print packet for debugging.
  *
@@ -929,85 +767,16 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
               uint32_t dest_address = rte_bswap32(ihdr->dst_addr);
               if (must_reverse)
                      rte_sp_exchange_mac_addresses(ehdr);
-#if 0
-              ret = local_get_nh_ipv4(dest_address, &dest_if,
-                            &nhip, vfw_pipe);
-              if (must_reverse) {
-                     rte_sp_exchange_mac_addresses(ehdr);
-                     if (is_phy_port_privte(phy_port)) {
-                            if (!ret) {
-                                   dest_if = get_pub_to_prv_port(
-                                                 &dest_address,
-                                                 IP_VERSION_4);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv4_cache(
-                                                 dest_if, vfw_pipe);
-                            }
-
-                     } else {
-                            if (!ret) {
-                                   dest_if = get_prv_to_pub_port(
-                                                 &dest_address,
-                                                 IP_VERSION_4);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv4_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-                     }
-              } else if (is_phy_port_privte(phy_port)) {
-                     if (!ret) {
-                            dest_if = get_prv_to_pub_port(&dest_address,
-                                          IP_VERSION_4);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv4_cache(dest_if, vfw_pipe);
-                     }
 
-              } else {
-                     if (!ret) {
-                            dest_if = get_pub_to_prv_port(&dest_address,
-                                          IP_VERSION_4);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv4_cache(dest_if, vfw_pipe);
-                     }
-
-              }
-              meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
-              if (local_dest_mac_present(dest_if)) {
-                     ether_addr_copy(get_local_link_hw_addr(dest_if),
-                                   &ehdr->d_addr);
-                     ether_addr_copy(get_link_hw_addr(dest_if),
-                                   &ehdr->s_addr);
-              } else {
-#endif
        struct arp_entry_data *ret_arp_data = NULL;
         ret_arp_data = get_dest_mac_addr_port(dest_address,
                        &dest_if, &ehdr->d_addr);
         meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
 
         if (arp_cache_dest_mac_present(dest_if)) {
-
                 ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
-                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");
                         arp_send_buffered_pkts(ret_arp_data,
                                  &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
 
@@ -1015,7 +784,7 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
 
                      } else {
                 if (unlikely(ret_arp_data == NULL)) {
-
+                       if (VFW_DEBUG)
                         printf("%s: NHIP Not Found, nhip:%x , "
                         "outport_id: %d\n", __func__, nhip,
                         vfw_pipe->outport_id[dest_if]);
@@ -1028,10 +797,9 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
                if (ret_arp_data->status == INCOMPLETE ||
                            ret_arp_data->status == PROBE) {
                                 if (ret_arp_data->num_pkts >= NUM_DESC) {
-                            /* ICMP req sent, drop packet by
-                             * changing the mask */
-                               vfw_pipe->counters->
-                                        pkts_drop_without_arp_entry++;
+                                       /* ICMP req sent, drop packet by
+                                               * changing the mask */
+                                       vfw_pipe->counters->pkts_drop_without_arp_entry++;
                                         continue;
                                 } else {
                                         arp_pkts_mask |= pkt_mask;
@@ -1096,92 +864,24 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
               if (must_reverse)
                      rte_sp_exchange_mac_addresses(ehdr);
 
-#if 0
-              ret = local_get_nh_ipv4(dest_address, &dest_if,
-                            &nhip, vfw_pipe);
-              if (must_reverse) {
-                     rte_sp_exchange_mac_addresses(ehdr);
-                     if (is_phy_port_privte(phy_port)) {
-                            if (!ret) {
-                                   dest_if = get_pub_to_prv_port(
-                                                 &dest_address,
-                                                 IP_VERSION_4);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv4_cache(
-                                                 dest_if, vfw_pipe);
-                            }
-
-                     } else {
-                            if (!ret) {
-                                   dest_if = get_prv_to_pub_port(
-                                                 &dest_address,
-                                                 IP_VERSION_4);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv4_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-                     }
-              } else if (is_phy_port_privte(phy_port)) {
-                     if (!ret) {
-                            dest_if = get_prv_to_pub_port(&dest_address,
-                                          IP_VERSION_4);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv4_cache(dest_if, vfw_pipe);
-                     }
-
-              } else {
-                     if (!ret) {
-                            dest_if = get_pub_to_prv_port(&dest_address,
-                                          IP_VERSION_4);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv4_cache(dest_if, vfw_pipe);
-                     }
-
-              }
-              meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
-              if (local_dest_mac_present(dest_if)) {
-                     ether_addr_copy(get_local_link_hw_addr(dest_if),
-                                   &ehdr->d_addr);
-                     ether_addr_copy(get_link_hw_addr(dest_if),
-                                   &ehdr->s_addr);
-              } else {
-#endif
        struct arp_entry_data *ret_arp_data = NULL;
                      ret_arp_data = get_dest_mac_addr_port(dest_address,
                                    &dest_if, &ehdr->d_addr);
-                       meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
+                       meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
+
         if (arp_cache_dest_mac_present(dest_if)) {
 
                 ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
-                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");
                         arp_send_buffered_pkts(ret_arp_data,
                                  &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
 
                             }
-
                      } else {
                 if (unlikely(ret_arp_data == NULL)) {
 
+                       if (VFW_DEBUG)
                         printf("%s: NHIP Not Found, nhip:%x , "
                         "outport_id: %d\n", __func__, nhip,
                         vfw_pipe->outport_id[dest_if]);
@@ -1193,10 +893,9 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
                if (ret_arp_data->status == INCOMPLETE ||
                            ret_arp_data->status == PROBE) {
                                 if (ret_arp_data->num_pkts >= NUM_DESC) {
-                            /* ICMP req sent, drop packet by
-                             * changing the mask */
-                                       vfw_pipe->counters->
-                                               pkts_drop_without_arp_entry++;
+                                       /* ICMP req sent, drop packet by
+                                               * changing the mask */
+                                       vfw_pipe->counters->pkts_drop_without_arp_entry++;
                                         return;
                                 } else {
                                         arp_pkts_mask |= pkt_mask;
@@ -1237,12 +936,10 @@ pkt4_work_vfw_arp_ipv6_packets(struct rte_mbuf **pkts,
               struct pipeline_vfw *vfw_pipe)
 {
        uint8_t nh_ipv6[IPV6_ADD_SIZE];
-       uint32_t ret;
        struct ether_addr hw_addr;
        struct mbuf_tcp_meta_data *meta_data_addr;
        struct ether_hdr *ehdr;
        struct rte_mbuf *pkt;
-       uint16_t phy_port;
        uint8_t i;
 
        for (i = 0; i < 4; i++) {
@@ -1256,7 +953,6 @@ pkt4_work_vfw_arp_ipv6_packets(struct rte_mbuf **pkts,
                      continue;
               int must_reverse = ((synproxy_reply_mask & pkt_mask) != 0);
 
-              phy_port = pkt->port;
               meta_data_addr = (struct mbuf_tcp_meta_data *)
                      RTE_MBUF_METADATA_UINT32_PTR(pkt, META_DATA_OFFSET);
               ehdr = rte_vfw_get_ether_addr(pkt);
@@ -1268,104 +964,49 @@ pkt4_work_vfw_arp_ipv6_packets(struct rte_mbuf **pkts,
               uint8_t dest_address[IPV6_ADD_SIZE];
 
               memset(nhip, 0, IPV6_ADD_SIZE);
-
-              rte_mov16(dest_address, ihdr->dst_addr);
-              ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
-                            &nhip[0], vfw_pipe);
-              if (must_reverse) {
+              if (must_reverse)
                      rte_sp_exchange_mac_addresses(ehdr);
-                     if (is_phy_port_privte(phy_port)) {
-                            if (!ret) {
-                                   dest_if = get_pub_to_prv_port(
-                                                 (uint32_t *)
-                                                 &dest_address[0],
-                                                 IP_VERSION_6);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv6_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-
-                     } else {
-                            if (!ret) {
-                                   dest_if = get_prv_to_pub_port(
-                                                 (uint32_t *)
-                                                 &dest_address[0],
-                                                 IP_VERSION_6);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv6_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-                     }
-
-              } else if (is_phy_port_privte(phy_port)) {
-                     if (!ret) {
-                            dest_if = get_prv_to_pub_port((uint32_t *)
-                                          &dest_address[0], IP_VERSION_6);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv6_cache(dest_if, vfw_pipe);
-                     }
-
-              } else {
-                     if (!ret) {
-                            dest_if = get_pub_to_prv_port((uint32_t *)
-                                          &dest_address[0], IP_VERSION_6);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-
-                            }
-                            do_local_nh_ipv6_cache(dest_if, vfw_pipe);
-                     }
-
-              }
-
-              meta_data_addr->output_port = vfw_pipe->outport_id[dest_if];
 
+              rte_mov16(dest_address, ihdr->dst_addr);
               memset(nh_ipv6, 0, IPV6_ADD_SIZE);
-              if (get_dest_mac_address_ipv6_port(
+              struct nd_entry_data *ret_nd_data = NULL;
+              ret_nd_data = get_dest_mac_address_ipv6_port(
                                    &dest_address[0],
                                    &dest_if,
                                    &hw_addr,
-                                   &nh_ipv6[0])) {
-                     ether_addr_copy(&hw_addr, &ehdr->d_addr);
-                     ether_addr_copy(get_link_hw_addr(dest_if),
-                                   &ehdr->s_addr);
+                                   &nh_ipv6[0]);
 
-                     if (vfw_debug >= DEBUG_LEVEL_4) {
-                            char buf[HW_ADDR_SIZE];
-
-                            ether_format_addr(buf, sizeof(buf),
-                                          &hw_addr);
-                            printf("MAC found for  dest_if %d: %s, ",
-                                          dest_if, buf);
-                            ether_format_addr(buf, sizeof(buf),
-                                          &ehdr->s_addr);
-                            printf("new eth hdr src: %s, ", buf);
-                            ether_format_addr(buf, sizeof(buf),
-                                          &ehdr->d_addr);
-                            printf("new eth hdr dst: %s\n", buf);
-                     }
+               meta_data_addr->output_port = vfw_pipe->
+                                    outport_id[dest_if];
+              if (nd_cache_dest_mac_present(dest_if)) {
+                    ether_addr_copy(get_link_hw_addr(dest_if),
+                                   &ehdr->s_addr);
+                   update_nhip_access(dest_if);
 
+                    if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                        nd_send_buffered_pkts(ret_nd_data,
+                               &ehdr->d_addr, meta_data_addr->output_port);
+                    }
               } else {
-                     printf("deleting ipv6\n");
-                     *pkts_mask &= ~pkt_mask;
-                     /*Next Neighbor is not yet implemented
-                      * for ipv6.*/
-                     vfw_pipe->counters->
-                            pkts_drop_without_arp_entry++;
+                    if (unlikely(ret_nd_data == NULL)) {
+                         *pkts_mask &= ~pkt_mask;
+                         vfw_pipe->counters->
+                               pkts_drop_without_arp_entry++;
+                          continue;
+                    }
+                   if (ret_nd_data->status == INCOMPLETE ||
+                         ret_nd_data->status == PROBE) {
+                         if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                /* Drop the pkt */
+                                *pkts_mask &= ~pkt_mask;
+                               vfw_pipe->counters->pkts_drop_without_arp_entry++;
+                               continue;
+                          } else {
+                                arp_pkts_mask |= pkt_mask;
+                                nd_queue_unresolved_packet(ret_nd_data, pkt);
+                                continue;
+                          }
+                    }
               }
 
        }
@@ -1399,12 +1040,10 @@ pkt_work_vfw_arp_ipv6_packets(struct rte_mbuf *pkts,
               struct pipeline_vfw *vfw_pipe)
 {
        uint8_t nh_ipv6[IPV6_ADD_SIZE];
-       uint32_t ret;
        struct ether_addr hw_addr;
        struct mbuf_tcp_meta_data *meta_data_addr;
        struct ether_hdr *ehdr;
        struct rte_mbuf *pkt;
-       uint16_t phy_port;
 
        uint32_t dest_if = INVALID_DESTIF;
        /* bitmask representing only this packet */
@@ -1416,7 +1055,6 @@ pkt_work_vfw_arp_ipv6_packets(struct rte_mbuf *pkts,
 
               int must_reverse = ((synproxy_reply_mask & pkt_mask) != 0);
 
-              phy_port = pkt->port;
               meta_data_addr = (struct mbuf_tcp_meta_data *)
                      RTE_MBUF_METADATA_UINT32_PTR(pkt, META_DATA_OFFSET);
               ehdr = rte_vfw_get_ether_addr(pkt);
@@ -1428,104 +1066,47 @@ pkt_work_vfw_arp_ipv6_packets(struct rte_mbuf *pkts,
               uint8_t dest_address[IPV6_ADD_SIZE];
 
               memset(nhip, 0, IPV6_ADD_SIZE);
-
-              rte_mov16(dest_address, ihdr->dst_addr);
-              ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
-                            &nhip[0], vfw_pipe);
-              if (must_reverse) {
+              if (must_reverse)
                      rte_sp_exchange_mac_addresses(ehdr);
-                     if (is_phy_port_privte(phy_port)) {
-                            if (!ret) {
-                                   dest_if = get_pub_to_prv_port(
-                                                 (uint32_t *)
-                                                 &dest_address[0],
-                                                 IP_VERSION_6);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv6_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-
-                     } else {
-                            if (!ret) {
-                                   dest_if = get_prv_to_pub_port(
-                                                 (uint32_t *)
-                                                 &dest_address[0],
-                                                 IP_VERSION_6);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          *pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv6_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-                     }
-
-              } else if (is_phy_port_privte(phy_port)) {
-                     if (!ret) {
-                            dest_if = get_prv_to_pub_port((uint32_t *)
-                                          &dest_address[0], IP_VERSION_6);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv6_cache(dest_if, vfw_pipe);
-                     }
-
-              } else {
-                     if (!ret) {
-                            dest_if = get_pub_to_prv_port((uint32_t *)
-                                          &dest_address[0], IP_VERSION_6);
-                            if (dest_if == INVALID_DESTIF) {
-                                   *pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-
-                            }
-                            do_local_nh_ipv6_cache(dest_if, vfw_pipe);
-                     }
-
-              }
-
-              meta_data_addr->output_port = vfw_pipe->outport_id[dest_if];
-
+              rte_mov16(dest_address, ihdr->dst_addr);
               memset(nh_ipv6, 0, IPV6_ADD_SIZE);
-              if (get_dest_mac_address_ipv6_port(
+              struct nd_entry_data *ret_nd_data = NULL;
+              ret_nd_data = get_dest_mac_address_ipv6_port(
                                    &dest_address[0],
                                    &dest_if,
                                    &hw_addr,
-                                   &nh_ipv6[0])) {
-                     ether_addr_copy(&hw_addr, &ehdr->d_addr);
+                                   &nh_ipv6[0]);
+             meta_data_addr->output_port = vfw_pipe->
+                                    outport_id[dest_if];
+              if (nd_cache_dest_mac_present(dest_if)) {
                      ether_addr_copy(get_link_hw_addr(dest_if),
                                    &ehdr->s_addr);
+                   update_nhip_access(dest_if);
 
-                     if (vfw_debug >= DEBUG_LEVEL_4) {
-                            char buf[HW_ADDR_SIZE];
-
-                            ether_format_addr(buf, sizeof(buf),
-                                          &hw_addr);
-                            printf("MAC found for  dest_if %d: %s, ",
-                                          dest_if, buf);
-                            ether_format_addr(buf, sizeof(buf),
-                                          &ehdr->s_addr);
-                            printf("new eth hdr src: %s, ", buf);
-                            ether_format_addr(buf, sizeof(buf),
-                                          &ehdr->d_addr);
-                            printf("new eth hdr dst: %s\n", buf);
+                    if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                        nd_send_buffered_pkts(ret_nd_data,
+                               &ehdr->d_addr, meta_data_addr->output_port);
                      }
-
               } else {
-                     printf("deleting ipv6\n");
-                     *pkts_mask &= ~pkt_mask;
-                     /*Next Neighbor is not yet implemented
-                      * for ipv6.*/
-                     vfw_pipe->counters->
-                            pkts_drop_without_arp_entry++;
+                    if (unlikely(ret_nd_data == NULL)) {
+                        *pkts_mask &= ~pkt_mask;
+                       vfw_pipe->counters->
+                               pkts_drop_without_arp_entry++;
+                        return;
+                    }
+                   if (ret_nd_data->status == INCOMPLETE ||
+                          ret_nd_data->status == PROBE) {
+                          if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                /* Drop the pkt */
+                                *pkts_mask &= ~pkt_mask;
+                               vfw_pipe->counters->pkts_drop_without_arp_entry++;
+                                return;
+                          } else {
+                                arp_pkts_mask |= pkt_mask;
+                                nd_queue_unresolved_packet(ret_nd_data, pkt);
+                                return;
+                          }
+                    }
               }
 
        }
@@ -1588,85 +1169,16 @@ rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
               uint32_t dest_address = rte_bswap32(ihdr->dst_addr);
               if (must_reverse)
                      rte_sp_exchange_mac_addresses(ehdr);
-#if 0
-              ret = local_get_nh_ipv4(dest_address, &dest_if,
-                            &nhip, vfw_pipe);
-              if (must_reverse) {
-                     rte_sp_exchange_mac_addresses(ehdr);
-                     if (is_phy_port_privte(phy_port)) {
-                            if (!ret) {
-                                   dest_if = get_pub_to_prv_port(
-                                                 &dest_address,
-                                                 IP_VERSION_4);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv4_cache(
-                                                 dest_if, vfw_pipe);
-                            }
-
-                     } else {
-                            if (!ret) {
-                                   dest_if = get_prv_to_pub_port(
-                                                 &dest_address,
-                                                 IP_VERSION_4);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv4_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-                     }
-              } else if (is_phy_port_privte(phy_port)) {
-                     if (!ret) {
-                            dest_if = get_prv_to_pub_port(&dest_address,
-                                          IP_VERSION_4);
-                            if (dest_if == INVALID_DESTIF) {
-                                   pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv4_cache(dest_if, vfw_pipe);
-                     }
-
-              } else {
-                     if (!ret) {
-                            dest_if = get_pub_to_prv_port(&dest_address,
-                                          IP_VERSION_4);
-                            if (dest_if == INVALID_DESTIF) {
-                                   pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv4_cache(dest_if, vfw_pipe);
-                     }
-
-              }
-              meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
-              if (local_dest_mac_present(dest_if)) {
-                     ether_addr_copy(get_local_link_hw_addr(dest_if),
-                                   &ehdr->d_addr);
-                     ether_addr_copy(get_link_hw_addr(dest_if),
-                                   &ehdr->s_addr);
-              } else {
-#endif
                struct arp_entry_data *ret_arp_data = NULL;
                      ret_arp_data = get_dest_mac_addr_port(dest_address,
                                    &dest_if, &ehdr->d_addr);
-               meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
+               meta_data_addr->output_port =  vfw_pipe->outport_id[dest_if];
         if (arp_cache_dest_mac_present(dest_if)) {
 
                 ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
-                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,
                                  &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
 
@@ -1675,6 +1187,7 @@ rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
                      } else {
                 if (unlikely(ret_arp_data == NULL)) {
 
+                       if (VFW_DEBUG)
                         printf("%s: NHIP Not Found, nhip:%x , "
                         "outport_id: %d\n", __func__, nhip,
                         vfw_pipe->outport_id[dest_if]);
@@ -1687,10 +1200,9 @@ rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
                if (ret_arp_data->status == INCOMPLETE ||
                            ret_arp_data->status == PROBE) {
                                 if (ret_arp_data->num_pkts >= NUM_DESC) {
-                     /* ICMP req sent, drop packet by
-                      * changing the mask */
-                                       vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
+                                       /* ICMP req sent, drop packet by
+                                               * changing the mask */
+                                       vfw_pipe->counters->pkts_drop_without_arp_entry++;
                                         continue;
                                 } else {
                                         arp_pkts_mask |= pkt_mask;
@@ -1759,106 +1271,52 @@ rte_vfw_arp_ipv6_packets(struct rte_mbuf **pkts,
               uint8_t dest_address[IPV6_ADD_SIZE];
 
               memset(nhip, 0, IPV6_ADD_SIZE);
-
-              rte_mov16(dest_address, ihdr->dst_addr);
-              ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
-                            &nhip[0], vfw_pipe);
-              if (must_reverse) {
+              if (must_reverse)
                      rte_sp_exchange_mac_addresses(ehdr);
-                     if (is_phy_port_privte(phy_port)) {
-                            if (!ret) {
-                                   dest_if = get_pub_to_prv_port(
-                                                 (uint32_t *)
-                                                 &dest_address[0],
-                                                 IP_VERSION_6);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv6_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-
-                     } else {
-                            if (!ret) {
-                                   dest_if = get_prv_to_pub_port(
-                                                 (uint32_t *)
-                                                 &dest_address[0],
-                                                 IP_VERSION_6);
-                                   if (dest_if == INVALID_DESTIF) {
-                                          pkts_mask &= ~pkt_mask;
-                                          vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                                   }
-                                   do_local_nh_ipv6_cache(dest_if,
-                                                 vfw_pipe);
-                            }
-                     }
-
-              } else if (is_phy_port_privte(phy_port)) {
-                     if (!ret) {
-                            dest_if = get_prv_to_pub_port((uint32_t *)
-                                          &dest_address[0], IP_VERSION_6);
-                            if (dest_if == INVALID_DESTIF) {
-                                   pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                            }
-                            do_local_nh_ipv6_cache(dest_if, vfw_pipe);
-                     }
-
-              } else {
-                     if (!ret) {
-                            dest_if = get_pub_to_prv_port((uint32_t *)
-                                          &dest_address[0], IP_VERSION_6);
-                            if (dest_if == INVALID_DESTIF) {
-                                   pkts_mask &= ~pkt_mask;
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-
-                            }
-                            do_local_nh_ipv6_cache(dest_if, vfw_pipe);
-                     }
-
-              }
-
-              meta_data_addr->output_port = vfw_pipe->outport_id[dest_if];
 
+              rte_mov16(dest_address, ihdr->dst_addr);
               memset(nh_ipv6, 0, IPV6_ADD_SIZE);
-              if (get_dest_mac_address_ipv6_port(
+              struct nd_entry_data *ret_nd_data = NULL;
+              ret_nd_data = get_dest_mac_address_ipv6_port(
                                    &dest_address[0],
                                    &dest_if,
                                    &hw_addr,
-                                   &nh_ipv6[0])) {
-                     ether_addr_copy(&hw_addr, &ehdr->d_addr);
+                                   &nh_ipv6[0]);
+
+             meta_data_addr->output_port = vfw_pipe->
+                                    outport_id[dest_if];
+              if (nd_cache_dest_mac_present(dest_if)) {
                      ether_addr_copy(get_link_hw_addr(dest_if),
                                    &ehdr->s_addr);
+                   update_nhip_access(dest_if);
 
-                     if (vfw_debug >= DEBUG_LEVEL_4) {
-                            char buf[HW_ADDR_SIZE];
-
-                            ether_format_addr(buf, sizeof(buf),
-                                          &hw_addr);
-                            printf("MAC found for  dest_if %d: %s, ",
-                                          dest_if, buf);
-                            ether_format_addr(buf, sizeof(buf),
-                                          &ehdr->s_addr);
-                            printf("new eth hdr src: %s, ", buf);
-                            ether_format_addr(buf, sizeof(buf),
-                                          &ehdr->d_addr);
-                            printf("new eth hdr dst: %s\n", buf);
+                    if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                        nd_send_buffered_pkts(ret_nd_data,
+                               &ehdr->d_addr, meta_data_addr->output_port);
                      }
 
               } else {
-                     printf("deleting ipv6\n");
+                    if (unlikely(ret_nd_data == NULL)) {
                      pkts_mask &= ~pkt_mask;
-                     /*Next Neighbor is not yet implemented
-                      * for ipv6.*/
-                     vfw_pipe->counters->
-                            pkts_drop_without_arp_entry++;
-              }
-
+                         vfw_pipe->counters->
+                               pkts_drop_without_arp_entry++;
+                          continue;
+                    }
+                   if (ret_nd_data->status == INCOMPLETE ||
+                          ret_nd_data->status == PROBE) {
+                          if (ret_nd_data->num_pkts >= NUM_DESC) {
+                                /* Drop the pkt */
+                               pkts_mask &= ~pkt_mask;
+                                vfw_pipe->counters->
+                                    pkts_drop_without_arp_entry++;
+                                continue;
+                          } else {
+                                arp_pkts_mask |= pkt_mask;
+                                nd_queue_unresolved_packet(ret_nd_data, pkt);
+                                continue;
+                          }
+                    }
+             }
 
        }
 
index f8d35cb..0f654fa 100644 (file)
 #define IFM_QUEUE_STAT_CNTRS   16
 #define IFM_TX_DEFAULT_Q       0
 #define IFM_RX_DEFAULT_Q       0
-#define IFM_RX_DESC_DEFAULT    512
+#define IFM_RX_DESC_DEFAULT    128
 #define IFM_TX_DESC_DEFAULT    512
 #define IFM_BURST_SIZE         32
 #define IFM_BURST_TX_WAIT_US   1
index 7aa7fb6..7d3cf4f 100644 (file)
@@ -705,7 +705,7 @@ int get_dest_mac_for_nexthop_ipv6(uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE],
        }
        tmp_nd_key.port_id = out_phy_port;
 
-       nd_data = retrieve_nd_entry(tmp_nd_key);
+       nd_data = retrieve_nd_entry(tmp_nd_key, DYNAMIC_ND);
        if (nd_data == NULL) {
                printf("ND entry is not found\n");
                return 0;
index 43d0c8e..0c59730 100644 (file)
@@ -54,7 +54,7 @@
 #define IP_VERSION_4 0x40
 #define IP_HDRLEN  0x05                /**< default IP header length == five 32-bits words. */
 #define IP_VHL_DEF (IP_VERSION_4 | IP_HDRLEN)
-
+#define MAX_POOL               32
 #define is_multicast_ipv4_addr(ipv4_addr) \
        (((rte_be_to_cpu_32((ipv4_addr)) >> 24) & 0x000000FF) == 0xE0)
 
@@ -63,6 +63,7 @@ extern uint32_t timer_lcore;
 extern int USE_RTM_LOCKS;
 uint32_t arp_timeout = ARP_TIMER_EXPIRY;
 uint32_t arp_buffer = ARP_BUF_DEFAULT;
+uint32_t nd_buffer = ARP_BUF_DEFAULT;
 
 /*ND IPV6 */
 #define INADDRSZ 4
@@ -73,6 +74,7 @@ static int my_inet_pton_ipv6(int af, const char *src, void *dst);
 static int inet_pton_ipv6(const char *src, unsigned char *dst);
 static int inet_pton_ipv4(const char *src, unsigned char *dst);
 static void local_arp_cache_init(void);
+struct ether_addr *get_nd_local_link_hw_addr(uint8_t out_port, uint8_t nhip[]);
 extern void convert_prefixlen_to_netmask_ipv6(uint32_t depth,
                                                                uint8_t netmask_ipv6[]);
 
@@ -108,7 +110,7 @@ struct rte_mempool *lib_arp_pktmbuf_tx_pool;
 struct rte_mempool *lib_nd_pktmbuf_tx_pool;
 
 struct rte_mbuf *lib_arp_pkt[MAX_PORTS];
-struct rte_mbuf *lib_nd_pkt;
+struct rte_mbuf *lib_nd_pkt[MAX_PORTS];
 
 uint8_t default_ether_addr[6] = { 0, 0, 0, 0, 1, 1 };
 uint8_t default_ip[4] = { 0, 0, 1, 1 };
@@ -127,32 +129,17 @@ uint8_t arp_cache_hw_laddr_valid[MAX_NUM_ARP_CACHE_MAC_ADDRESS] = {
         0, 0, 0, 0, 0, 0, 0, 0
 };
 
-void prefetch(void)
+/**
+ * handler lock.
+ */
+rte_rwlock_t arp_hash_handle_lock;
+rte_rwlock_t nd_hash_handle_lock;
+
+void update_nhip_access(uint8_t dest_if)
 {
-       rte_prefetch0(p_arp_data);
+       p_arp_data->update_tsc[dest_if] = rte_rdtsc();
 }
 
-struct arp_entry_data *arp_data_ptr[MAX_NUM_ARP_CACHE_MAC_ADDRESS];
-
-struct ether_addr arp_cache_hw_laddr[MAX_NUM_ARP_CACHE_MAC_ADDRESS] = {
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
-        {.addr_bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
-};
-
 /**
  * A structure defining the mbuf meta data for VFW.
  */
@@ -167,6 +154,11 @@ static struct arp_entry_data arp_entry_data_default = {
        .num_pkts = 0,
 };
 
+static struct nd_entry_data nd_entry_data_default = {
+       .status = COMPLETE,
+       .num_pkts = 0,
+};
+
 /**
  * memory pool for queued up user pkts.
  */
@@ -234,7 +226,8 @@ int timer_objs_mempool_count = 70000;
 #define MAX_NUM_ND_ENTRIES 64
 
 inline uint32_t get_nh(uint32_t, uint32_t *, struct ether_addr *addr);
-void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[]);
+void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[],
+        struct ether_addr *hw_addr);
 
 #define MAX_ARP_DATA_ENTRY_TABLE 7
 
@@ -334,41 +327,6 @@ struct lib_nd_route_table_entry lib_nd_route_table[MAX_ND_RT_ENTRY] = {
         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
 };
 
-struct lib_arp_route_table_entry lib_arp_route_table[MAX_ARP_RT_ENTRY] = {
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0},
-       {0, 0, 0, 0, 0}
-};
-
 void print_trace(void);
 
 uint32_t get_arp_buf(void)
@@ -376,11 +334,21 @@ uint32_t get_arp_buf(void)
        return arp_buffer;
 }
 
+uint32_t get_nd_buf(void)
+{
+       return nd_buffer;
+}
+
 uint8_t arp_cache_dest_mac_present(uint32_t out_port)
 {
         return p_arp_data->arp_cache_hw_laddr_valid[out_port];
 }
 
+uint8_t nd_cache_dest_mac_present(uint32_t out_port)
+{
+       return p_arp_data->nd_cache_hw_laddr_valid[out_port];
+}
+
 /* Obtain a backtrace and print it to stdout. */
 void print_trace(void)
 {
@@ -409,7 +377,9 @@ uint32_t get_nh(uint32_t ip, uint32_t *port, struct ether_addr *addr)
 
                        *port = p_arp_data->lib_arp_route_table[i].port;
                        if (arp_cache_dest_mac_present(*port))
-                               ether_addr_copy(get_local_link_hw_addr(*port, p_arp_data->lib_arp_route_table[i].nh), addr);
+                               ether_addr_copy(
+                               get_local_link_hw_addr(*port,
+                               p_arp_data->lib_arp_route_table[i].nh), addr);
                        return p_arp_data->lib_arp_route_table[i].nh;
                }
        }
@@ -418,7 +388,8 @@ uint32_t get_nh(uint32_t ip, uint32_t *port, struct ether_addr *addr)
 }
 
 /*ND IPv6 */
-void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[])
+void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[],
+struct ether_addr *hw_addr)
 {
        int i = 0;
        uint8_t netmask_ipv6[16], netip_nd[16], netip_in[16];
@@ -456,6 +427,11 @@ void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[])
                        for (j = 0; j < 16; j++)
                                nhipv6[j] = lib_nd_route_table[i].nhipv6[j];
 
+                       if (nd_cache_dest_mac_present(*port)) {
+                               ether_addr_copy(
+                               get_nd_local_link_hw_addr(*port, nhipv6),
+                               (struct ether_addr *)hw_addr);
+                       }
                        return;
                }
 
@@ -465,7 +441,7 @@ void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[])
                depthflags1 = 0;
        }
        if (NDIPV6_DEBUG)
-               printf("No NH - ip 0x%x, port %u\n", ipv6[0], *port);
+               printf("No NH - ip 0x%x, \n", ipv6[0]);
        lib_nd_no_nh_found++;
 }
 
@@ -477,7 +453,6 @@ struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
        uint32_t nhip = 0;
        uint8_t index;
 
-       //lib_arp_get_mac_req++;
        nhip = get_nh(ipaddr, phy_port, hw_addr);
        if (unlikely(nhip == 0)) {
                if (ARPICMP_DEBUG)
@@ -490,7 +465,6 @@ struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
         * & thus can be sent without having to retrieve
         */
        if (arp_cache_dest_mac_present(*phy_port)) {
-               //arp_data_ptr[*phy_port]->n_last_update = time(NULL);
                return &arp_entry_data_default;
        }
 
@@ -506,44 +480,45 @@ struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
        if (ret_arp_data == NULL) {
                if (ARPICMP_DEBUG && ipaddr)
                 {
-                       RTE_LOG(INFO, LIBARP,"ARPICMP no arp entry found for ip %x, port %u\n", ipaddr, *phy_port);
+                       RTE_LOG(INFO, LIBARP,"ARPICMP no arp entry found for ip %x,"
+                       " port %u\n", ipaddr, *phy_port);
                        print_arp_table();
                 }
                lib_arp_no_arp_entry_found++;
        } else if (ret_arp_data->status == COMPLETE) {
+               rte_rwlock_write_lock(&ret_arp_data->queue_lock);
                 ether_addr_copy(&ret_arp_data->eth_addr, hw_addr);
-               printf("Setting mac found for port:%d\n", *phy_port);
                p_arp_data->arp_cache_hw_laddr_valid[*phy_port] = 1;
-               arp_data_ptr[*phy_port] = ret_arp_data;
-               //memcpy(&arp_cache_hw_laddr[*phy_port], hw_addr,
-               //      sizeof(struct ether_addr));
                index = p_arp_data->arp_local_cache[*phy_port].num_nhip;
                p_arp_data->arp_local_cache[*phy_port].nhip[index] = nhip;
-               ether_addr_copy(hw_addr, &p_arp_data->arp_local_cache[*phy_port].link_hw_laddr[index]);
+               ether_addr_copy(hw_addr,
+                &p_arp_data->arp_local_cache[*phy_port].link_hw_laddr[index]);
                p_arp_data->arp_local_cache[*phy_port].num_nhip++;
+               rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
                lib_arp_arp_entry_found++;
-
                if (ARPICMP_DEBUG)
                        printf("%s: ARPICMP hwaddr found\n", __FUNCTION__);
         }
 
        if (ret_arp_data)
-               ret_arp_data->n_last_update = time(NULL);
+               p_arp_data->update_tsc[*phy_port] = rte_rdtsc();
 
         return ret_arp_data;
 }
 
-int get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
-                                        struct ether_addr *hw_addr, uint8_t nhipv6[])
+struct nd_entry_data *get_dest_mac_address_ipv6_port(uint8_t ipv6addr[],
+                        uint32_t *phy_port, struct ether_addr *hw_addr, uint8_t nhipv6[])
 {
        int i = 0, j = 0, flag = 0;
+       uint8_t index;
        lib_nd_get_mac_req++;
 
-       get_nh_ipv6(ipv6addr, phy_port, nhipv6);
+       get_nh_ipv6(ipv6addr, phy_port, nhipv6, hw_addr);
        for (j = 0; j < 16; j++) {
                if (nhipv6[j])
                        flag++;
        }
+
        if (flag == 0) {
                if (NDIPV6_DEBUG)
                        printf("NDIPV6 no nh found for ipv6 "
@@ -562,73 +537,41 @@ int get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
        struct nd_key_ipv6 tmp_nd_key;
        tmp_nd_key.port_id = *phy_port;
 
+       if (nd_cache_dest_mac_present(*phy_port)) {
+               return &nd_entry_data_default;
+       }
+
+
        for (i = 0; i < 16; i++)
                tmp_nd_key.ipv6[i] = nhipv6[i];
 
-       ret_nd_data = retrieve_nd_entry(tmp_nd_key);
+       ret_nd_data = retrieve_nd_entry(tmp_nd_key, DYNAMIC_ND);
        if (ret_nd_data == NULL) {
                if (NDIPV6_DEBUG) {
                        printf("NDIPV6 no nd entry found for ip %x, port %d\n",
                                                 ipv6addr[0], *phy_port);
                }
                lib_nd_no_arp_entry_found++;
-               return 0;
-       }
-       ether_addr_copy(&ret_nd_data->eth_addr, hw_addr);
-       lib_nd_nd_entry_found++;
-       return 1;
-}
-
-int get_dest_mac_address_ipv6(uint8_t ipv6addr[], uint32_t *phy_port,
-                                               struct ether_addr *hw_addr, uint8_t nhipv6[])
-{
-       int i = 0, j = 0, flag = 0;
-       lib_nd_get_mac_req++;
-
-       get_nh_ipv6(ipv6addr, phy_port, nhipv6);
-       for (j = 0; j < 16; j++) {
-               if (nhipv6[j]) {
-                       flag++;
-               }
-       }
-       if (flag == 0) {
-               if (NDIPV6_DEBUG && ipv6addr)
-                       RTE_LOG(INFO, LIBARP,
-                               "NDIPV6 no nh found for ipv6 %x, port %d\n",
-                               ipv6addr[0], *phy_port);
-               return 0;
-       }
-
-       struct nd_entry_data *ret_nd_data = NULL;
-       struct nd_key_ipv6 tmp_nd_key;
-       tmp_nd_key.port_id = *phy_port;
+               return NULL;
+       } else if (ret_nd_data->status == COMPLETE) {
+               rte_rwlock_write_lock(&ret_nd_data->queue_lock);
+               ether_addr_copy(&ret_nd_data->eth_addr, hw_addr);
+               p_arp_data->nd_cache_hw_laddr_valid[*phy_port] = 1;
+               index = p_arp_data->nd_local_cache[*phy_port].num_nhip;
+               rte_mov16(&p_arp_data->nd_local_cache[*phy_port].nhip[index][0],
+                                &nhipv6[0]);
+               ether_addr_copy(hw_addr,
+                       &p_arp_data->nd_local_cache[*phy_port].link_hw_laddr[index]);
+               p_arp_data->nd_local_cache[*phy_port].num_nhip++;
 
-       for (i = 0; i < 16; i++) {
-               tmp_nd_key.ipv6[i] = nhipv6[i];
+               lib_nd_nd_entry_found++;
+               rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
        }
 
-       ret_nd_data = retrieve_nd_entry(tmp_nd_key);
-       if (ret_nd_data == NULL) {
-               if (NDIPV6_DEBUG && ipv6addr) {
-                       RTE_LOG(INFO, LIBARP,
-                               "NDIPV6 no nd entry found for ip %x, port %d\n",
-                               ipv6addr[0], *phy_port);
-               }
-               if (flag != 0) {
-                       if (ARPICMP_DEBUG > 4)
-                               printf
-                                               ("Requesting ARP for ipv6 addr and port %d\n",
-                                                *phy_port);
-                       request_nd(&nhipv6[0], ifm_get_port(*phy_port));
+       if (ret_nd_data)
+               p_arp_data->update_tsc[*phy_port] = rte_rdtsc();
 
-               }
-
-               lib_nd_no_arp_entry_found++;
-               return 0;
-       }
-       ether_addr_copy(&ret_nd_data->eth_addr, hw_addr);
-       lib_nd_nd_entry_found++;
-       return 1;
+       return ret_nd_data;
 }
 
 /**
@@ -783,6 +726,91 @@ print_mbuf(const char *rx_tx, uint8_t portid, struct rte_mbuf *mbuf,
        fflush(stdout);
 }
 
+/**
+ * Add entry in ND table.
+ *
+ * @param nd_key
+ *      key.
+ * @param ret_nd_data
+ *      return nd entry from table.
+ *
+ */
+static int add_nd_data(struct nd_key_ipv6 *nd_key,
+                struct nd_entry_data *ret_nd_data)
+{
+        int ret;
+        struct nd_entry_data *tmp_nd_data = NULL;
+        rte_rwlock_write_lock(&nd_hash_handle_lock);
+        /* Check for value while locked */
+        ret = rte_hash_lookup_data(nd_hash_handle, nd_key, (void **)&tmp_nd_data);
+
+        if (ret == -ENOENT) {
+                /* entry not yet added, do so now */
+                ret = rte_hash_add_key_data(nd_hash_handle, nd_key, ret_nd_data);
+                if (ret) {
+                        /* We panic here because either:
+                         * ret == -EINVAL and a parameter got messed up, or
+                         * ret == -ENOSPC and the hash table isn't big enough
+                         */
+                        rte_panic("ND: Error on entry add for %s", rte_strerror(abs(ret)));
+                }
+        } else if (ret < 0) {
+                /* We panic here because ret == -EINVAL and a parameter got
+                 * messed up, or dpdk hash lib changed and this needs corrected */
+                rte_panic("ARP: Error on entry add for %s", rte_strerror(abs(ret)));
+        } else {
+                /* entry already exists */
+                ret = EEXIST;
+        }
+
+        rte_rwlock_write_unlock(&nd_hash_handle_lock);
+        return ret;
+}
+
+/**
+ * Add entry in ARP table.
+ *
+ * @param arp_key
+ *      key.
+ * @param ret_arp_data
+ *      return arp entry from table.
+ *
+ */
+static int add_arp_data(struct arp_key_ipv4 *arp_key,
+                struct arp_entry_data *ret_arp_data) {
+        int ret;
+        struct arp_entry_data *tmp_arp_data = NULL;
+        rte_rwlock_write_lock(&arp_hash_handle_lock);
+        /* Check for value while locked */
+        ret = rte_hash_lookup_data(arp_hash_handle, arp_key, (void **)&tmp_arp_data);
+
+        if (ret == -ENOENT) {
+                /* entry not yet added, do so now */
+                ret = rte_hash_add_key_data(arp_hash_handle, arp_key, ret_arp_data);
+                if (ret) {
+                        /* We panic here because either:
+                         * ret == -EINVAL and a parameter got messed up, or
+                         * ret == -ENOSPC and the hash table isn't big enough
+                         */
+                        rte_panic("ARP: Error on entry add for %s - %s",
+                                        inet_ntoa(*(struct in_addr *)&arp_key->ip),
+                                        rte_strerror(abs(ret)));
+                }
+        } else if (ret < 0) {
+                /* We panic here because ret == -EINVAL and a parameter got
+                 * messed up, or dpdk hash lib changed and this needs corrected */
+                rte_panic("ARP: Error on entry add for %s - %s",
+                                inet_ntoa(*(struct in_addr *)&arp_key->ip),
+                                rte_strerror(abs(ret)));
+        } else {
+                /* entry already exists */
+                ret = EEXIST;
+        }
+
+        rte_rwlock_write_unlock(&arp_hash_handle_lock);
+        return ret;
+}
+
 struct arp_entry_data *retrieve_arp_entry(struct arp_key_ipv4 arp_key, uint8_t mode)
 {
        struct arp_entry_data *ret_arp_data = NULL;
@@ -794,7 +822,8 @@ struct arp_entry_data *retrieve_arp_entry(struct arp_key_ipv4 arp_key, uint8_t m
                                                         (void **)&ret_arp_data);
        if (ret < 0 && (mode == DYNAMIC_ARP)) {
                if (ARPICMP_DEBUG)
-                       RTE_LOG(INFO, LIBARP, "ARP entry not found for ip 0x%x\n",arp_key.ip);
+                       RTE_LOG(INFO, LIBARP, "ARP entry not found for ip 0x%x\n",
+                               arp_key.ip);
 
                /* add INCOMPLETE arp entry */
                ret_arp_data = rte_malloc_socket(NULL, sizeof(struct arp_entry_data),
@@ -805,22 +834,36 @@ struct arp_entry_data *retrieve_arp_entry(struct arp_key_ipv4 arp_key, uint8_t m
                ret_arp_data->ip = arp_key.ip;
                ret_arp_data->mode = mode;
                ret_arp_data->num_pkts = 0;
-               ret_arp_data->buffered_pkt_list_head = NULL;
-               ret_arp_data->buffered_pkt_list_tail = NULL;
                rte_rwlock_init(&ret_arp_data->queue_lock);
                rte_rwlock_write_lock(&ret_arp_data->queue_lock);
 
+               /* attempt to add arp_entry to hash */
+               ret = add_arp_data(&arp_key, ret_arp_data);
+
+               if (ret == EEXIST) {
+                       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
+                       rte_free(ret_arp_data);
+                       /* Some other thread has 'beat' this thread in
+                               creation of arp_data, try again */
+                        return NULL;
+               }
+
                 if (rte_mempool_get(timer_mempool_arp,
                        (void **) &(ret_arp_data->timer) ) < 0) {
+                       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
                         RTE_LOG(INFO, LIBARP,"Error in getting timer alloc buf\n");
                         return NULL;
                 }
 
-               ret_arp_data->buf_pkts = (struct rte_mbuf **)rte_zmalloc_socket(
+               ret_arp_data->buf_pkts = (struct rte_mbuf **)rte_zmalloc_socket(
                                        NULL, sizeof(struct rte_mbuf *) * arp_buffer,
                                        RTE_CACHE_LINE_SIZE, rte_socket_id());
 
-               rte_hash_add_key_data(arp_hash_handle, &arp_key, ret_arp_data);
+               if (ret_arp_data->buf_pkts == NULL) {
+                       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
+                        RTE_LOG(INFO, LIBARP,"Could not allocate buf for queueing\n");
+                        return NULL;
+               }
 
                 rte_timer_init(ret_arp_data->timer);
                 struct arp_timer_key * callback_key =
@@ -829,7 +872,8 @@ struct arp_entry_data *retrieve_arp_entry(struct arp_key_ipv4 arp_key, uint8_t m
                 callback_key->port_id = arp_key.port_id;
                 callback_key->ip = arp_key.ip;
                 if(ARPICMP_DEBUG)
-                      RTE_LOG(INFO, LIBARP,"TIMER STARTED FOR %u seconds\n",ARP_TIMER_EXPIRY);
+                      RTE_LOG(INFO, LIBARP,"TIMER STARTED FOR %u seconds\n",
+                       ARP_TIMER_EXPIRY);
                 if(rte_timer_reset(ret_arp_data->timer,
                                         (PROBE_TIME * rte_get_tsc_hz() / 1000),
                                         SINGLE,timer_lcore,
@@ -842,30 +886,34 @@ struct arp_entry_data *retrieve_arp_entry(struct arp_key_ipv4 arp_key, uint8_t m
 
                /* send arp request */
                request_arp(arp_key.port_id, arp_key.ip);
+               rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
        } else {
                if (ret_arp_data &&
                 ret_arp_data->mode == DYNAMIC_ARP && ret_arp_data->status == STALE) {
+                       rte_rwlock_write_lock(&ret_arp_data->queue_lock);
                        ether_addr_copy(&null_ether_addr, &ret_arp_data->eth_addr);
                        ret_arp_data->status = PROBE;
-                       struct arp_timer_key * callback_key =
-                                (struct arp_timer_key*) rte_malloc(NULL,
-                                       sizeof(struct  arp_timer_key*),RTE_CACHE_LINE_SIZE);
-                       callback_key->port_id = arp_key.port_id;
-                       callback_key->ip = arp_key.ip;
-                       if(ARPICMP_DEBUG)
-                               RTE_LOG(INFO, LIBARP,"TIMER STARTED FOR %u seconds\n",ARP_TIMER_EXPIRY);
-                       if(rte_timer_reset(ret_arp_data->timer,
+                       struct arp_timer_key * callback_key =
+                               (struct arp_timer_key*) rte_malloc(NULL,
+                               sizeof(struct  arp_timer_key*),RTE_CACHE_LINE_SIZE);
+                       callback_key->port_id = arp_key.port_id;
+                       callback_key->ip = arp_key.ip;
+                       if(ARPICMP_DEBUG)
+                               RTE_LOG(INFO, LIBARP,"TIMER STARTED FOR %u"
+                                       " seconds\n",ARP_TIMER_EXPIRY);
+                       if(rte_timer_reset(ret_arp_data->timer,
                                         (arp_timeout * rte_get_tsc_hz()),
                                         SINGLE,timer_lcore,
                                         arp_timer_callback,
                                         callback_key) < 0)
-                        if(ARPICMP_DEBUG)
-                               RTE_LOG(INFO, LIBARP,"Err : Timer already running\n");
+                       if(ARPICMP_DEBUG)
+                               RTE_LOG(INFO, LIBARP,"Err : Timer already running\n");
 
-                       ret_arp_data->timer_key = callback_key;
+                       ret_arp_data->timer_key = callback_key;
 
                        /* send arp request */
                        request_arp(arp_key.port_id, arp_key.ip);
+                       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
                }
 
        }
@@ -873,7 +921,7 @@ struct arp_entry_data *retrieve_arp_entry(struct arp_key_ipv4 arp_key, uint8_t m
        return ret_arp_data;
 }
 
-struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key)
+struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key, uint8_t mode)
 {
        struct nd_entry_data *ret_nd_data = NULL;
        nd_key.filler1 = 0;
@@ -884,31 +932,109 @@ struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key)
        /*Find a nd IPv6 key-data pair in the hash table for ND IPv6 */
        int ret = rte_hash_lookup_data(nd_hash_handle, &nd_key,
                                                         (void **)&ret_nd_data);
-       if (ret < 0) {
-/*             RTE_LOG(INFO, LIBARP,"nd-hash: no lookup Entry Found - ret %d, EINVAL %d, ENOENT %d\n",
-                               ret, EINVAL, ENOENT);*/
-       } else {
-               if (ret_nd_data->mode == DYNAMIC_ND) {
-                       struct nd_timer_key callback_key;
-                       callback_key.port_id = ret_nd_data->port;
+       if (ret < 0 && (mode == DYNAMIC_ND)) {
+               if (ARPICMP_DEBUG)
+                       RTE_LOG(INFO, LIBARP, "ND entry not found for ip \n");
 
-                       for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
-                               callback_key.ipv6[i] = ret_nd_data->ipv6[i];
+               /* add INCOMPLETE arp entry */
+               ret_nd_data = rte_malloc_socket(NULL, sizeof(struct nd_entry_data),
+                               RTE_CACHE_LINE_SIZE, rte_socket_id());
+               ether_addr_copy(&null_ether_addr, &ret_nd_data->eth_addr);
+               ret_nd_data->status = INCOMPLETE;
+               ret_nd_data->port = nd_key.port_id;
+
+               for (i = 0; i < ND_IPV6_ADDR_SIZE; i++)
+                       ret_nd_data->ipv6[i] = nd_key.ipv6[i];
+               ret_nd_data->mode = mode;
+               ret_nd_data->num_pkts = 0;
+               rte_rwlock_init(&ret_nd_data->queue_lock);
+               rte_rwlock_write_lock(&ret_nd_data->queue_lock);
+
+               /* attempt to add arp_entry to hash */
+               ret = add_nd_data(&nd_key, ret_nd_data);
+
+               if (ret == EEXIST) {
+                       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+                       rte_free(ret_nd_data);
+                       /* Some other thread has 'beat' this thread in
+                               creation of arp_data, try again */
+                        return NULL;
+               }
+
+
+                if (rte_mempool_get(timer_mempool_arp,
+                       (void **) &(ret_nd_data->timer) ) < 0) {
+                        RTE_LOG(INFO, LIBARP,"Error in getting timer alloc buf\n");
+                       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+                        return NULL;
+                }
+
+               ret_nd_data->buf_pkts = (struct rte_mbuf **)rte_zmalloc_socket(
+                                       NULL, sizeof(struct rte_mbuf *) * nd_buffer,
+                                       RTE_CACHE_LINE_SIZE, rte_socket_id());
+
+               if (ret_nd_data->buf_pkts == NULL) {
+                       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+                        RTE_LOG(INFO, LIBARP,"Could not allocate buf for queueing\n");
+                        return NULL;
+               }
+
+                rte_timer_init(ret_nd_data->timer);
+                struct nd_timer_key * callback_key =
+                        (struct nd_timer_key*) rte_malloc(NULL,
+                               sizeof(struct  nd_timer_key*),RTE_CACHE_LINE_SIZE);
+                callback_key->port_id = nd_key.port_id;
+               for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
+                       callback_key->ipv6[i] = ret_nd_data->ipv6[i];
+               }
+
+               if(ARPICMP_DEBUG) {
+                       RTE_LOG(INFO, LIBARP,"TIMER STARTED FOR %u seconds\n",
+                       ARP_TIMER_EXPIRY);
+               }
 
+               if(rte_timer_reset(ret_nd_data->timer,
+                       (PROBE_TIME * rte_get_tsc_hz() / 1000),
+                       SINGLE,timer_lcore,
+                       nd_timer_callback,
+                       callback_key) < 0)
+               if(ARPICMP_DEBUG)
+                       RTE_LOG(INFO, LIBARP,"Err : Timer already running\n");
+
+                ret_nd_data->timer_key = callback_key;
+               /* send nd request */
+               request_nd(callback_key->ipv6, ifm_get_port(callback_key->port_id));
+               rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+       } else {
+               if (ret_nd_data &&
+                ret_nd_data->mode == DYNAMIC_ND && ret_nd_data->status == STALE) {
+                       rte_rwlock_write_lock(&ret_nd_data->queue_lock);
+                       ether_addr_copy(&null_ether_addr, &ret_nd_data->eth_addr);
+                       ret_nd_data->status = PROBE;
+                       struct nd_timer_key * callback_key =
+                        (struct nd_timer_key*) rte_malloc(NULL,
+                               sizeof(struct  nd_timer_key*),RTE_CACHE_LINE_SIZE);
+
+                       callback_key->port_id = nd_key.port_id;
+                       for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
+                               callback_key->ipv6[i] = ret_nd_data->ipv6[i];
                        }
 
                        if (rte_timer_reset
-                                       (ret_nd_data->timer,
-                                        (arp_timeout * rte_get_tsc_hz()), SINGLE,
-                                        timer_lcore, nd_timer_callback, &callback_key) < 0)
-                               if (ARPICMP_DEBUG)
-                                       RTE_LOG(INFO, LIBARP,
-                                               "Err : Timer already running\n");
+                               (ret_nd_data->timer,
+                                (arp_timeout * rte_get_tsc_hz()), SINGLE,
+                                timer_lcore, nd_timer_callback, callback_key) < 0)
+                       if (ARPICMP_DEBUG)
+                               RTE_LOG(INFO, LIBARP,
+                                       "Err : Timer already running\n");
+                       ret_nd_data->timer_key = callback_key;
+
+                       /* send nd request */
+                       request_nd(callback_key->ipv6, ifm_get_port(callback_key->port_id));
+                       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
                }
-               return ret_nd_data;
        }
-
-       return NULL;
+       return ret_nd_data;
 }
 
 static const char* arp_status[] = {"INCOMPLETE", "COMPLETE", "PROBE", "STALE"};
@@ -919,13 +1045,10 @@ void print_arp_table(void)
        void *next_data;
        uint32_t iter = 0;
 
-       printf
-                       ("------------------------ ARP CACHE -----------------------------------------\n");
-       printf
-                       ("----------------------------------------------------------------------------\n");
+       printf("------------------------ ARP CACHE ------------------------------------\n");
+       printf("-----------------------------------------------------------------------\n");
        printf("\tport  hw addr            status     ip addr\n");
-       printf
-                       ("----------------------------------------------------------------------------\n");
+       printf("-----------------------------------------------------------------------\n");
 
        while (rte_hash_iterate(arp_hash_handle, &next_key, &next_data, &iter)
                                 >= 0) {
@@ -934,8 +1057,8 @@ void print_arp_table(void)
                                (struct arp_entry_data *)next_data;
                struct arp_key_ipv4 tmp_arp_key;
                memcpy(&tmp_arp_key, next_key, sizeof(struct arp_key_ipv4));
-               printf
-                               ("\t%4d  %02X:%02X:%02X:%02X:%02X:%02X  %10s %d.%d.%d.%d\n",
+               printf("\t%4d  %02X:%02X:%02X:%02X:%02X:%02X"
+                       "  %10s %d.%d.%d.%d\n",
                                 tmp_arp_data->port, tmp_arp_data->eth_addr.addr_bytes[0],
                                 tmp_arp_data->eth_addr.addr_bytes[1],
                                 tmp_arp_data->eth_addr.addr_bytes[2],
@@ -956,11 +1079,12 @@ void print_arp_table(void)
                printf("0x%x    0x%x    %d       0x%x\n",
                                         p_arp_data->lib_arp_route_table[i].ip,
                                         p_arp_data->lib_arp_route_table[i].mask,
-                                        p_arp_data->lib_arp_route_table[i].port, p_arp_data->lib_arp_route_table[i].nh);
+                                        p_arp_data->lib_arp_route_table[i].port,
+                                        p_arp_data->lib_arp_route_table[i].nh);
        }
 
-       printf
-                       ("\nARP Stats: Total Queries %u, ok_NH %u, no_NH %u, ok_Entry %u, no_Entry %u, PopulateCall %u, Del %u, Dup %u\n",
+       printf("\nARP Stats: Total Queries %u, ok_NH %u, no_NH %u, ok_Entry %u,"
+               " no_Entry %u, PopulateCall %u, Del %u, Dup %u\n",
                         lib_arp_get_mac_req, lib_arp_nh_found, lib_arp_no_nh_found,
                         lib_arp_arp_entry_found, lib_arp_no_arp_entry_found,
                         lib_arp_populate_called, lib_arp_delete_called,
@@ -976,12 +1100,10 @@ void print_nd_table(void)
        void *next_data;
        uint32_t iter = 0;
        uint8_t ii = 0, j = 0, k = 0;
-       printf
-                       ("------------------------------------------------------------------------------------------------------\n");
+       printf("-----------------------------------------------------------------------\n");
        printf("\tport  hw addr            status         ip addr\n");
 
-       printf
-                       ("------------------------------------------------------------------------------------------------------\n");
+       printf("-----------------------------------------------------------------------\n");
        while (rte_hash_iterate(nd_hash_handle, &next_key, &next_data, &iter) >=
                                 0) {
 
@@ -997,8 +1119,7 @@ void print_nd_table(void)
                                         tmp_nd_data->eth_addr.addr_bytes[3],
                                         tmp_nd_data->eth_addr.addr_bytes[4],
                                         tmp_nd_data->eth_addr.addr_bytes[5],
-                                        tmp_nd_data->status ==
-                                        COMPLETE ? "COMPLETE" : "INCOMPLETE");
+                                        arp_status[tmp_nd_data->status]);
                printf("\t\t\t\t\t\t");
                for (ii = 0; ii < ND_IPV6_ADDR_SIZE; ii += 2) {
                        printf("%02X%02X ", tmp_nd_data->ipv6[ii],
@@ -1010,8 +1131,8 @@ void print_nd_table(void)
        uint32_t i = 0;
        printf("\n\nND IPV6 routing table has %d entries\n",
                                 nd_route_tbl_index);
-       printf
-                       ("\nIP_Address                                          Depth          Port                             NH_IP_Address\n");
+       printf("\nIP_Address                                            Depth");
+       printf("          Port                          NH_IP_Address\n");
        for (i = 0; i < nd_route_tbl_index; i++) {
                printf("\n");
 
@@ -1030,8 +1151,8 @@ void print_nd_table(void)
                                                 lib_nd_route_table[i].ipv6[k + 1]);
                }
        }
-       printf
-                       ("\nND IPV6 Stats: \nTotal Queries %u, ok_NH %u, no_NH %u, ok_Entry %u, no_Entry %u, PopulateCall %u, Del %u, Dup %u\n",
+       printf("\nND IPV6 Stats: \nTotal Queries %u, ok_NH %u,"
+               " no_NH %u, ok_Entry %u, no_Entry %u, PopulateCall %u, Del %u, Dup %u\n",
                         lib_nd_get_mac_req, lib_nd_nh_found, lib_nd_no_nh_found,
                         lib_nd_nd_entry_found, lib_nd_no_arp_entry_found,
                         lib_nd_populate_called, lib_nd_delete_called,
@@ -1053,10 +1174,8 @@ void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg)
                RTE_LOG(INFO, LIBARP,
                        "ARP Entry Deleted for IP :%d.%d.%d.%d , port %d\n",
                        (arp_key->ip >> 24),
-                       ((arp_key->ip & 0x00ff0000) >>
-                        16),
-                       ((arp_key->ip & 0x0000ff00) >>
-                        8),
+                       ((arp_key->ip & 0x00ff0000) >> 16),
+                       ((arp_key->ip & 0x0000ff00) >>  8),
                        ((arp_key->ip & 0x000000ff)),
                        arp_key->port_id);
        }
@@ -1065,80 +1184,65 @@ void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg)
 }
 
 /* ND IPv6 */
-void remove_nd_entry_ipv6(uint8_t ipv6addr[], uint8_t portid)
+void remove_nd_entry_ipv6(struct nd_entry_data *ret_nd_data, void *arg)
 {
        int i = 0;
-       struct nd_entry_data *ret_nd_data = NULL;
-       struct nd_key_ipv6 nd_key;
-       nd_key.port_id = portid;
-
-       for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
-               nd_key.ipv6[i] = ipv6addr[i];
-       }
-
-       nd_key.filler1 = 0;
-       nd_key.filler2 = 0;
-       nd_key.filler3 = 0;
+       struct nd_timer_key *timer_key = (struct nd_timer_key *)arg;
 
        lib_nd_delete_called++;
 
-       if (NDIPV6_DEBUG) {
-               RTE_LOG(INFO, LIBARP,
-                       "Deletes rte hash table nd entry for port %d ipv6=",
-                       nd_key.port_id);
-               for (i = 0; i < ND_IPV6_ADDR_SIZE; i += 2) {
-                       RTE_LOG(INFO, LIBARP, "%02X%02X ", nd_key.ipv6[i],
-                               nd_key.ipv6[i + 1]);
-               }
-       }
-       struct nd_timer_key callback_key;
-       callback_key.port_id = portid;
-
-       for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
-               callback_key.ipv6[i] = ipv6addr[i];
-
-       }
-       int ret = rte_hash_lookup_data(arp_hash_handle, &callback_key,
-                                                        (void **)&ret_nd_data);
-       if (ret < 0) {
-//              RTE_LOG(INFO, LIBARP,"arp-hash lookup failed ret %d, EINVAL %d, ENOENT %d\n", ret, EINVAL, ENOENT);
-       } else {
-               if (ret_nd_data->mode == DYNAMIC_ND) {
-                       rte_timer_stop(ret_nd_data->timer);
-                       rte_free(ret_nd_data->timer);
-               }
-       }
-       rte_hash_del_key(nd_hash_handle, &nd_key);
+        rte_timer_stop(ret_nd_data->timer);
+        rte_free(ret_nd_data->timer_key);
+        rte_free(ret_nd_data->buf_pkts);
+        ret_nd_data->buf_pkts = NULL;
+
+        if (NDIPV6_DEBUG) {
+                RTE_LOG(INFO, LIBARP,
+                        "Deletes rte hash table nd entry for port %d ipv6=",
+                        timer_key->port_id);
+                for (i = 0; i < ND_IPV6_ADDR_SIZE; i += 2) {
+                        RTE_LOG(INFO, LIBARP, "%02X%02X ", timer_key->ipv6[i],
+                                timer_key->ipv6[i + 1]);
+                }
+        }
+        rte_hash_del_key(nd_hash_handle, timer_key);
 }
 
 int
 arp_queue_unresolved_packet(struct arp_entry_data *ret_arp_data, struct rte_mbuf *pkt)
 {
+       rte_rwlock_write_lock(&ret_arp_data->queue_lock);
        if (ret_arp_data->num_pkts  == NUM_DESC) {
+               rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
                return 0;
        }
+
        ret_arp_data->buf_pkts[ret_arp_data->num_pkts++] = pkt;
+       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
        return 0;
 }
 
 void
-arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,struct ether_addr *hw_addr, uint8_t port_id)
+arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,
+       struct ether_addr *hw_addr, uint8_t port_id)
 {
        l2_phy_interface_t *port = ifm_get_port(port_id);
        struct rte_mbuf *pkt, *tmp;
        uint8_t *eth_dest, *eth_src;
        int i;
 
-       
+
        if (!hw_addr || !ret_arp_data)
                return;
 
+       rte_rwlock_write_lock(&ret_arp_data->queue_lock);
        for (i=0;i<(int)ret_arp_data->num_pkts;i++) {
                pkt = ret_arp_data->buf_pkts[i];
-               eth_dest = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
-               eth_src = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
 
-               memcpy(eth_dest, &hw_addr, sizeof(struct ether_addr));
+               eth_dest = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
+               eth_src = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
+
+               memcpy(eth_dest, hw_addr, sizeof(struct ether_addr));
                memcpy(eth_src, get_link_hw_addr(port_id),
                                 sizeof(struct ether_addr));
                port->transmit_single_pkt(port, pkt);
@@ -1146,8 +1250,50 @@ arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,struct ether_addr *hw
                rte_pktmbuf_free(tmp);
        }
        ret_arp_data->num_pkts = 0;
-       ret_arp_data->buffered_pkt_list_head = NULL;
+       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
+}
 
+int
+nd_queue_unresolved_packet(struct nd_entry_data *ret_nd_data, struct rte_mbuf *pkt)
+{
+       rte_rwlock_write_lock(&ret_nd_data->queue_lock);
+       if (ret_nd_data->num_pkts  == get_nd_buf()) {
+               rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+               return 0;
+       }
+
+       ret_nd_data->buf_pkts[ret_nd_data->num_pkts++] = pkt;
+       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+       return 0;
+}
+
+void
+nd_send_buffered_pkts(struct nd_entry_data *ret_nd_data,
+       struct ether_addr *hw_addr, uint8_t port_id)
+{
+       l2_phy_interface_t *port = ifm_get_port(port_id);
+       struct rte_mbuf *pkt, *tmp;
+       uint8_t *eth_dest, *eth_src;
+       int i;
+
+       if (!hw_addr || !ret_nd_data)
+               return;
+
+       rte_rwlock_write_lock(&ret_nd_data->queue_lock);
+       for (i=0;i<(int)ret_nd_data->num_pkts;i++) {
+               pkt = ret_nd_data->buf_pkts[i];
+               eth_dest = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
+               eth_src = RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
+
+               memcpy(eth_dest, hw_addr, sizeof(struct ether_addr));
+               memcpy(eth_src, get_link_hw_addr(port_id),
+                               sizeof(struct ether_addr));
+               port->transmit_single_pkt(port, pkt);
+               tmp = pkt;
+               rte_pktmbuf_free(tmp);
+       }
+       ret_nd_data->num_pkts = 0;
+       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
 }
 
 void
@@ -1171,14 +1317,13 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
 
        new_arp_data = retrieve_arp_entry(arp_key, mode);
        if (new_arp_data && ((new_arp_data->mode == STATIC_ARP
-                       && mode == DYNAMIC_ARP) || (new_arp_data->mode == DYNAMIC_ARP
-                       && mode == STATIC_ARP))) {
-                       if (ARPICMP_DEBUG)
-                               RTE_LOG(INFO, LIBARP,"populate_arp_entry: ARP entry already exists(%d %d)\n",
-                       new_arp_data->mode, mode);
-
-                       return;
-               }
+               && mode == DYNAMIC_ARP) || (new_arp_data->mode == DYNAMIC_ARP
+               && mode == STATIC_ARP))) {
+               if (ARPICMP_DEBUG)
+                       RTE_LOG(INFO, LIBARP,"populate_arp_entry: ARP entry "
+                               "already exists(%d %d)\n", new_arp_data->mode, mode);
+               return;
+       }
 
        if (mode == DYNAMIC_ARP) {
 
@@ -1196,6 +1341,7 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
                                        arp_key.port_id);
                        }
                        lib_arp_duplicate_found++;
+                       rte_rwlock_write_lock(&new_arp_data->queue_lock);
                        new_arp_data->retry_count = 0;  // Reset
                        if (new_arp_data->status == STALE) {
                                new_arp_data->status = PROBE;
@@ -1211,7 +1357,7 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
                                                new_arp_data->port);
                                }
                        }
-                       
+
                        if (rte_timer_reset(new_arp_data->timer,
                                                (arp_timeout * rte_get_tsc_hz()),
                                                SINGLE, timer_lcore,
@@ -1221,16 +1367,16 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
                                        RTE_LOG(INFO, LIBARP,
                                                "Err : Timer already running\n");
                        }
+                       rte_rwlock_write_unlock(&new_arp_data->queue_lock);
                        return;
                } else {
+                       rte_rwlock_write_lock(&new_arp_data->queue_lock);
                        ether_addr_copy(hw_addr, &new_arp_data->eth_addr);
                        if ((new_arp_data->status == INCOMPLETE) ||
                                (new_arp_data->status == PROBE)) {
                                new_arp_data->status = COMPLETE;
                                new_arp_data->mode = mode;
-                               new_arp_data->n_confirmed = time(NULL);
-                               //end_tsc[new_arp_data->port] = rte_rdtsc();
-                               //printf("confirmed val is %x %dms\n",new_arp_data->ip, (end_tsc[new_arp_data->port] - start_tsc[new_arp_data->port] + ticks_per_ms/2)/ticks_per_ms);
+                               new_arp_data->n_confirmed = rte_rdtsc();
                                new_arp_data->retry_count = 0;
                                if (rte_timer_reset(new_arp_data->timer,
                                                (arp_timeout * rte_get_tsc_hz()),
@@ -1242,6 +1388,7 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
                                                "Err : Timer already running\n");
                                }
                        }
+                       rte_rwlock_write_unlock(&new_arp_data->queue_lock);
                        return;
                }
        } else {
@@ -1269,12 +1416,16 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
                        new_arp_data->port = portid;
                        new_arp_data->ip = ipaddr;
                        new_arp_data->mode = mode;
-                       new_arp_data->buffered_pkt_list_head = NULL;
-                       new_arp_data->buffered_pkt_list_tail = NULL;
                        new_arp_data->num_pkts = 0;
-                       
-                       rte_hash_add_key_data(arp_hash_handle, &arp_key,
-                                                               new_arp_data);
+
+                       /* attempt to add arp_entry to hash */
+                       int ret;
+                       ret = add_arp_data(&arp_key, new_arp_data);
+                       if (ret) {
+                               /* Some other thread created an entry for this ip */
+                               rte_free(new_arp_data);
+                       }
+
                        if (ARPICMP_DEBUG) {
                                RTE_LOG(INFO, LIBARP,
                                        "arp_entry exists ip :%d.%d.%d.%d , port %d\n",
@@ -1314,21 +1465,24 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
  * Install key - data pair in Hash table - From Pipeline Configuration
  *
  */
-
 void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ipv6[],
                                         uint8_t portid, uint8_t mode)
 {
 
        /* need to lock here if multi-threaded */
        /* rte_hash_add_key_data is not thread safe */
-       uint8_t i;
+       uint8_t i, val = 0;
        struct nd_key_ipv6 nd_key;
        nd_key.port_id = portid;
 
-       for (i = 0; i < ND_IPV6_ADDR_SIZE; i++)
+       for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
                nd_key.ipv6[i] = ipv6[i];
+               val |= ipv6[i];
+       }
+
+       if (!val)
+               return;
 
-//      RTE_LOG(INFO, LIBARP,"\n");
        nd_key.filler1 = 0;
        nd_key.filler2 = 0;
        nd_key.filler3 = 0;
@@ -1336,11 +1490,18 @@ void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ipv6[],
        lib_nd_populate_called++;
 
        /* Validate if key-value pair already exists in the hash table for ND IPv6 */
-       struct nd_entry_data *new_nd_data = retrieve_nd_entry(nd_key);
+       struct nd_entry_data *new_nd_data = retrieve_nd_entry(nd_key, mode);
+       if (new_nd_data && ((new_nd_data->mode == STATIC_ND
+               && mode == DYNAMIC_ND) || (new_nd_data->mode == DYNAMIC_ND
+               && mode == STATIC_ND))) {
+               if (ARPICMP_DEBUG)
+               RTE_LOG(INFO, LIBARP, "populate_arp_entry: ND entry already"
+                               " exists(%d %d)\n", new_nd_data->mode, mode);
+               return;
+       }
 
        if (mode == DYNAMIC_ND) {
-               if (new_nd_data
-                               && is_same_ether_addr(&new_nd_data->eth_addr, hw_addr)) {
+               if (new_nd_data && is_same_ether_addr(&new_nd_data->eth_addr, hw_addr)) {
 
                        if (NDIPV6_DEBUG) {
                                RTE_LOG(INFO, LIBARP,
@@ -1355,61 +1516,48 @@ void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ipv6[],
                        }
 
                        lib_nd_duplicate_found++;
-                       RTE_LOG(INFO, LIBARP, "nd_entry exists\n");
-                       return;
-               }
-               uint32_t size =
-                               RTE_CACHE_LINE_ROUNDUP(sizeof(struct nd_entry_data));
-               new_nd_data = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
-
-               //new_nd_data = (struct nd_entry_data *)rte_malloc(NULL, sizeof(struct nd_entry_data *),RTE_CACHE_LINE_SIZE);
-               new_nd_data->eth_addr = *hw_addr;
-               new_nd_data->status = COMPLETE;
-               new_nd_data->port = portid;
-               new_nd_data->mode = mode;
-               if (rte_mempool_get
-                               (timer_mempool_arp, (void **)&(new_nd_data->timer)) < 0) {
-                       RTE_LOG(INFO, LIBARP,
-                               "TIMER - Error in getting timer alloc buffer\n");
+                       rte_rwlock_write_lock(&new_nd_data->queue_lock);
+                       if (new_nd_data->status == STALE) {
+                               new_nd_data->retry_count = 0;   // Reset
+                               new_nd_data->status = PROBE;
+                               request_nd(new_nd_data->ipv6,
+                                        ifm_get_port(new_nd_data->port));
+
+                               if (rte_timer_reset(new_nd_data->timer,
+                                               (arp_timeout * rte_get_tsc_hz()),
+                                               SINGLE, timer_lcore,
+                                               nd_timer_callback,
+                                               new_nd_data->timer_key) < 0) {
+                                       if (ARPICMP_DEBUG)
+                                               RTE_LOG(INFO, LIBARP,
+                                               "Err : Timer already running\n");
+                               }
+                       }
+                       rte_rwlock_write_unlock(&new_nd_data->queue_lock);
                        return;
-               }
-
-               if (NDIPV6_DEBUG)
-                       RTE_LOG(INFO, LIBARP, "populate_nd_entry ipv6=");
-
-               for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
-                       new_nd_data->ipv6[i] = ipv6[i];
-               }
-
-               if (NDIPV6_DEBUG) {
-                       for (i = 0; i < ND_IPV6_ADDR_SIZE; i += 2) {
-
-                               RTE_LOG(INFO, LIBARP, "%02X%02X ",
-                                       new_nd_data->ipv6[i],
-                                       new_nd_data->ipv6[i + 1]);
+               } else {
+                       rte_rwlock_write_lock(&new_nd_data->queue_lock);
+                       ether_addr_copy(hw_addr, &new_nd_data->eth_addr);
+                       if ((new_nd_data->status == INCOMPLETE) ||
+                               (new_nd_data->status == PROBE)) {
+                               new_nd_data->status = COMPLETE;
+                               new_nd_data->mode = mode;
+                               new_nd_data->n_confirmed = rte_rdtsc();
+                               new_nd_data->retry_count = 0;
+                               if (rte_timer_reset(new_nd_data->timer,
+                                       (arp_timeout * rte_get_tsc_hz()),
+                                       SINGLE, timer_lcore,
+                                       nd_timer_callback,
+                                       new_nd_data->timer_key) < 0) {
+                                       if (ARPICMP_DEBUG)
+                                               RTE_LOG(INFO, LIBARP,
+                                               "Err : Timer already running\n");
+                               }
                        }
-               }
-
-               /*Add a key-data pair at hash table for ND IPv6 static routing */
-               rte_hash_add_key_data(nd_hash_handle, &nd_key, new_nd_data);
-               /* need to check the return value of the hash add */
-
-               /* after the hash is created then time is started */
-               rte_timer_init(new_nd_data->timer);
-               struct nd_timer_key *callback_key =
-                               (struct nd_timer_key *)rte_malloc(NULL,
-                                                                       sizeof(struct nd_timer_key
-                                                                        *),
-                                                                       RTE_CACHE_LINE_SIZE);
-               callback_key->port_id = portid;
+                       rte_rwlock_write_unlock(&new_nd_data->queue_lock);
+                        return;
+                }
 
-               for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
-                       callback_key->ipv6[i] = ipv6[i];
-               }
-               if (rte_timer_reset
-                               (new_nd_data->timer, (arp_timeout * rte_get_tsc_hz()),
-                                SINGLE, timer_lcore, nd_timer_callback, callback_key) < 0)
-                       RTE_LOG(INFO, LIBARP, "Err : Timer already running\n");
        } else {
                if (new_nd_data
                                && is_same_ether_addr(&new_nd_data->eth_addr, hw_addr)) {
@@ -1433,7 +1581,6 @@ void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ipv6[],
                        new_nd_data =
                                        rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
 
-                       //new_nd_data = (struct nd_entry_data *)rte_malloc(NULL, sizeof(struct nd_entry_data *),RTE_CACHE_LINE_SIZE);
                        new_nd_data->eth_addr = *hw_addr;
                        new_nd_data->status = COMPLETE;
                        new_nd_data->port = portid;
@@ -1441,13 +1588,25 @@ void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ipv6[],
                        for (i = 0; i < ND_IPV6_ADDR_SIZE; i++) {
                                new_nd_data->ipv6[i] = ipv6[i];
                        }
+                       new_nd_data->mode = mode;
+                       new_nd_data->num_pkts = 0;
 
                        /*Add a key-data pair at hash table for ND IPv6 static routing */
-                       rte_hash_add_key_data(nd_hash_handle, &nd_key,
-                                                               new_nd_data);
+                       /* attempt to add arp_entry to hash */
+                       int ret;
+                       ret = add_nd_data(&nd_key, new_nd_data);
+                       if (ret) {
+                               rte_free(new_nd_data);
+                       }
+
                        /* need to check the return value of the hash add */
+                       #ifdef L3_STACK_SUPPORT
+                       // Call l3fwd module for resolving 2_adj structure.
+                       resolve_l2_adj(ipaddr, portid, hw_addr);
+                       #endif
                }
        }
+
        if (NDIPV6_DEBUG)
                printf
                                ("\n....Added a key-data pair at rte hash table for ND IPv6 static routing\n");
@@ -1743,7 +1902,6 @@ void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
                                        print_mbuf("TX", port->pmdid, pkt,
                                                         __LINE__);
                                printf("replying arp pkt done\n");
-                               //rte_pktmbuf_free(pkt);
                                return;
                        } else if (arp_h->arp_op ==
                                         rte_cpu_to_be_16(ARP_OP_REPLY)) {
@@ -1759,7 +1917,6 @@ void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
                                                                                 arp_data.arp_sip),
                                                         in_port_id, DYNAMIC_ARP);
 
-                               //rte_pktmbuf_free(pkt);
                                return;
                        } else {
                                if (ARPICMP_DEBUG)
@@ -1887,7 +2044,8 @@ void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
                                        arp_key.filler3 = 0;
 
                                        struct arp_entry_data *arp_entry =
-                                                       retrieve_arp_entry(arp_key, DYNAMIC_ARP);
+                                                       retrieve_arp_entry(arp_key,
+                                                                DYNAMIC_ARP);
                                        if (arp_entry == NULL) {
                                                if (ARPICMP_DEBUG)
                                                        RTE_LOG(INFO, LIBARP,
@@ -1903,7 +2061,6 @@ void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
 
                rte_pktmbuf_free(pkt);
        }
-       printf("reached end of process_arpicmp\n");
 }
 
 /* int
@@ -2095,7 +2252,6 @@ static int arp_parse_args(struct pipeline_params *params)
 {
        uint32_t arp_route_tbl_present = 0;
        uint32_t nd_route_tbl_present = 0;
-       uint32_t ports_mac_list_present = 0;
        uint32_t numArg;
        uint32_t n_vnf_threads_present = 0;
 
@@ -2110,7 +2266,6 @@ static int arp_parse_args(struct pipeline_params *params)
                pub_to_prv_map[i] = 0xff;
        }
 
-       RTE_SET_USED(ports_mac_list_present);
        RTE_SET_USED(nd_route_tbl_present);
        RTE_SET_USED(arp_route_tbl_present);
        for (numArg = 0; numArg < params->n_args; numArg++) {
@@ -2164,6 +2319,12 @@ static int arp_parse_args(struct pipeline_params *params)
 
                if (strcmp(arg_name, "arp_buf") == 0) {
                        arp_buffer = atoi(arg_value);
+                       continue;
+               }
+
+               if (strcmp(arg_name, "nd_buf") == 0) {
+                       nd_buffer = atoi(arg_value);
+                       continue;
                }
 
                /* prv_to_pub_map */
@@ -2247,50 +2408,6 @@ static int arp_parse_args(struct pipeline_params *params)
                        continue;
                }
 
-               /* ports_mac_list */
-               if (strcmp(arg_name, "ports_mac_list") == 0) {
-                       ports_mac_list_present = 1;
-
-                       uint32_t i = 0, j = 0, k = 0, MAC_NUM_BYTES = 6;
-
-                       char byteStr[MAC_NUM_BYTES][3];
-                       uint32_t byte[MAC_NUM_BYTES];
-
-                       char *token = strtok(arg_value, " ");
-                       while (token) {
-                               k = 0;
-                               for (i = 0; i < MAC_NUM_BYTES; i++) {
-                                       for (j = 0; j < 2; j++) {
-                                               byteStr[i][j] = token[k++];
-                                       }
-                                       byteStr[i][j] = '\0';
-                                       k++;
-                               }
-
-                               for (i = 0; i < MAC_NUM_BYTES; i++) {
-                                       byte[i] = strtoul(byteStr[i], NULL, 16);
-                               }
-
-                               if (ARPICMP_DEBUG) {
-                                       RTE_LOG(INFO, LIBARP, "token: %s",
-                                               token);
-                                       for (i = 0; i < MAC_NUM_BYTES; i++)
-                                               RTE_LOG(INFO, LIBARP,
-                                                       ", byte[%u] %u", i,
-                                                       byte[i]);
-                                       RTE_LOG(INFO, LIBARP, "\n");
-                               }
-                               //Populate the static arp_route_table
-                               for (i = 0; i < MAC_NUM_BYTES; i++)
-                                       p_arp_data->link_hw_addr[p_arp_data->link_hw_addr_array_idx].addr_bytes[i] = byte[i];
-
-                               p_arp_data->link_hw_addr_array_idx++;
-                               token = strtok(NULL, " ");
-                       }
-
-                       continue;
-               }
-
                /* arp_route_tbl */
                if (strcmp(arg_name, "arp_route_tbl") == 0) {
                        arp_route_tbl_present = 1;
@@ -2364,7 +2481,7 @@ static int arp_parse_args(struct pipeline_params *params)
                                //Populate the static arp_route_table
                                struct lib_arp_route_table_entry *lentry =
                                &p_arp_data->lib_arp_route_table
-                               [p_arp_data->lib_arp_route_ent_cnt];
+                               [p_arp_data->lib_arp_route_ent_cnt];
                                lentry->ip = dest_ip;
                                lentry->mask = mask;
                                lentry->port = tx_port;
@@ -2483,6 +2600,25 @@ static void local_arp_cache_init(void)
         }
 }
 
+struct ether_addr *get_nd_local_link_hw_addr(uint8_t out_port, uint8_t nhip[])
+{
+        int i, j, limit;
+        struct ether_addr *x = NULL;
+        limit = p_arp_data->nd_local_cache[out_port].num_nhip;
+
+        for (i=0; i < limit; i++) {
+               for (j=0;j<16;j++) {
+                       if (p_arp_data->nd_local_cache[out_port].nhip[i][j] != nhip[j])
+                               continue;
+               }
+
+                x = &p_arp_data->nd_local_cache[out_port].link_hw_laddr[i];
+               return x;
+        }
+
+       return x;
+}
+
 struct ether_addr *get_local_link_hw_addr(uint8_t out_port, uint32_t nhip)
 {
         int i, limit;
@@ -2492,7 +2628,7 @@ struct ether_addr *get_local_link_hw_addr(uint8_t out_port, uint32_t nhip)
         for (i=0; i < limit; i++) {
                 tmp = p_arp_data->arp_local_cache[out_port].nhip[i];
                 if (tmp == nhip) {
-                       x = &p_arp_data->arp_local_cache[out_port].link_hw_laddr[i];
+                       x = &p_arp_data->arp_local_cache[out_port].link_hw_laddr[i];
                         return x;
                }
         }
@@ -2513,13 +2649,27 @@ void lib_arp_init(struct pipeline_params *params,
         size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct arp_data));
         p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
         p_arp_data = (struct arp_data *)p;
-       
+
        /* Parse arguments */
        if (arp_parse_args(params)) {
                RTE_LOG(INFO, LIBARP, "arp_parse_args failed ...\n");
                return;
        }
 
+       /* acquire the mac addresses */
+       struct ether_addr hw_addr;
+       uint8_t nb_ports = rte_eth_dev_count();
+
+       for (i = 0; i < nb_ports; i++) {
+               rte_eth_macaddr_get(i, &hw_addr);
+               ether_addr_copy(&hw_addr, &p_arp_data->link_hw_addr[i]);
+               p_arp_data->link_hw_addr_array_idx++;
+       }
+
+       /* create a lock for arp/nd hash */
+       rte_rwlock_init(&arp_hash_handle_lock);
+       rte_rwlock_init(&nd_hash_handle_lock);
+
        /* create the arp_icmp mbuf rx pool */
        lib_arp_pktmbuf_tx_pool =
                        rte_pktmbuf_pool_create("lib_arp_mbuf_tx_pool", NB_ARPICMP_MBUF, 32,
@@ -2538,9 +2688,29 @@ void lib_arp_init(struct pipeline_params *params,
                        return;
                }
        }
+
+       /* create the nd icmp mbuf rx pool */
+       lib_nd_pktmbuf_tx_pool =
+                       rte_pktmbuf_pool_create("lib_nd_mbuf_tx_pool", NB_ARPICMP_MBUF, 32,
+                                               0, RTE_MBUF_DEFAULT_BUF_SIZE,
+                                               rte_socket_id());
+
+       if (lib_nd_pktmbuf_tx_pool == NULL) {
+               RTE_LOG(INFO, LIBARP, "ND mbuf pool create failed.\n");
+               return;
+       }
+
+       for (i=0; i<MAX_PORTS; i++) {
+               lib_nd_pkt[i] = rte_pktmbuf_alloc(lib_nd_pktmbuf_tx_pool);
+               if (lib_nd_pkt[i] == NULL) {
+                       RTE_LOG(INFO, LIBARP, "ND lib_nd_pkt alloc failed.\n");
+                       return;
+               }
+       }
+
        /* create the arp_icmp mbuf rx pool */
-       arp_icmp_pktmbuf_tx_pool = rte_pktmbuf_pool_create("arp_icmp_mbuf_tx_pool", 
-                                       NB_ARPICMP_MBUF, 32, 0,
+       arp_icmp_pktmbuf_tx_pool = rte_pktmbuf_pool_create("arp_icmp_mbuf_tx_pool",
+                                       NB_ARPICMP_MBUF, MAX_POOL, 0,
                                        RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
 
        if (arp_icmp_pktmbuf_tx_pool == NULL) {
@@ -2607,7 +2777,7 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
         arp_key.filler3 = 0;
 
        struct arp_entry_data *ret_arp_data = NULL;
-       time_t now;
+       uint64_t now;
        if (ARPICMP_DEBUG) {
                RTE_LOG(INFO, LIBARP, "arp_timer_callback ip %x, port %d\n",
                arp_key.ip, arp_key.port_id);
@@ -2615,7 +2785,7 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
 
        int ret = rte_hash_lookup_data(arp_hash_handle, &arp_key,
                                         (void **)&ret_arp_data);
-       now = time(NULL);
+       now = rte_rdtsc();
 
        if (ARPICMP_DEBUG)
                RTE_LOG(INFO, LIBARP, "ARP TIMER callback : expire :%d now:%ld\n",
@@ -2625,13 +2795,14 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
                return;
        } else {
                if (ret_arp_data->mode == DYNAMIC_ARP) {
-                       if (ret_arp_data->status == PROBE || 
+                       rte_rwlock_write_lock(&ret_arp_data->queue_lock);
+                       if (ret_arp_data->status == PROBE ||
                                ret_arp_data->status == INCOMPLETE) {
                                if (ret_arp_data->retry_count == 3) {
                                        remove_arp_entry(ret_arp_data, arg);
                                } else {
                                        ret_arp_data->retry_count++;
-                                       
+
                                        if (ARPICMP_DEBUG) {
                                                RTE_LOG(INFO, LIBARP,
                                                "RETRY ARP..retry count : %u\n",
@@ -2644,17 +2815,17 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
 
                                        if (ifm_chk_port_ipv4_enabled
                                                (ret_arp_data->port)) {
-                                               //printf("inside arp timer callback numpkts:%d\n", ret_arp_data->num_pkts);
                                                request_arp(ret_arp_data->port,
                                                                ret_arp_data->ip);
                                        } else {
                                                if (ARPICMP_DEBUG)
                                                        RTE_LOG(INFO, LIBARP,
-                                                       "%s: IP is not enabled on port %u, not sending GARP\n\r",
+                                                       "%s: IP is not enabled on port %u"
+                                                       ", not sending GARP\n\r",
                                                        __FUNCTION__,
                                                        ret_arp_data->port);
                                        }
-                                       
+
                                        if (rte_timer_reset(ret_arp_data->timer,
                                                                (PROBE_TIME *
                                                                 rte_get_tsc_hz()/ 1000),
@@ -2668,7 +2839,8 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
 
                                }
                        } else if (ret_arp_data->status == COMPLETE) {
-                               if (now <= (ret_arp_data->n_confirmed + arp_timeout)) { 
+                               if (now <= (ret_arp_data->n_confirmed +
+                                        (arp_timeout * rte_get_tsc_hz()))) {
                                        if (rte_timer_reset(ret_arp_data->timer,
                                                                (arp_timeout *
                                                                 rte_get_tsc_hz()), SINGLE,
@@ -2678,7 +2850,7 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
                                        if (ARPICMP_DEBUG)
                                                RTE_LOG(INFO, LIBARP,
                                                        "Err : Timer already running\n");
-                               } else if (now <= (ret_arp_data->n_last_update + USED_TIME)) {
+                               } else if (now <= (p_arp_data->update_tsc[ret_arp_data->port] + (USED_TIME * rte_get_tsc_hz()))) {
                                        if (rte_timer_reset(ret_arp_data->timer,
                                                                (arp_timeout *
                                                                 rte_get_tsc_hz()), SINGLE,
@@ -2693,6 +2865,7 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
                                        p_arp_data->arp_cache_hw_laddr_valid[ret_arp_data->port] = 0;
                                }
                        }
+                       rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
                } else {
                        rte_hash_del_key(arp_hash_handle, &arp_key);
                }
@@ -2702,11 +2875,104 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
 
 void nd_timer_callback(struct rte_timer *timer, void *arg)
 {
-       struct nd_timer_key *remove_key = (struct nd_timer_key *)arg;
+       struct nd_timer_key *timer_key = (struct nd_timer_key *)arg;
+        struct nd_key_ipv6 nd_key;
+       int j;
+       struct nd_entry_data *ret_nd_data = NULL;
+       uint64_t now;
+
+        nd_key.port_id = timer_key->port_id;
+        nd_key.filler1 = 0;
+        nd_key.filler2 = 0;
+        nd_key.filler3 = 0;
+
+       rte_mov16(&nd_key.ipv6[0], timer_key->ipv6);
+
+       if (ARPICMP_DEBUG) {
+               RTE_LOG(INFO, LIBARP, "nd_timer_callback port %d\n",
+               nd_key.port_id);
+       }
+
+       int ret = rte_hash_lookup_data(nd_hash_handle, &nd_key,
+                                        (void **)&ret_nd_data);
+       now = rte_rdtsc();
+
        if (ARPICMP_DEBUG)
-               RTE_LOG(INFO, LIBARP, "nd  time callback : expire :%d\n",
-                       (int)timer->expire);
-       remove_nd_entry_ipv6(remove_key->ipv6, remove_key->port_id);
+               RTE_LOG(INFO, LIBARP, "ND TIMER callback : expire :%d now:%ld\n",
+                       (int)timer->expire, now);
+       if (ret < 0) {
+               printf("Should not have come here \n");
+               for (j = 0; j < 16; j++)
+                       printf("*%d ", nd_key.ipv6[j]);
+               printf("*%d ", nd_key.port_id);
+               return;
+       } else {
+               if (ret_nd_data->mode == DYNAMIC_ARP) {
+                       rte_rwlock_write_lock(&ret_nd_data->queue_lock);
+                       if (ret_nd_data->status == PROBE ||
+                               ret_nd_data->status == INCOMPLETE) {
+                               if (ret_nd_data->retry_count == 3) {
+                                       remove_nd_entry_ipv6(ret_nd_data, arg);
+                               } else {
+                                       ret_nd_data->retry_count++;
+
+                                       if (ARPICMP_DEBUG) {
+                                               RTE_LOG(INFO, LIBARP,
+                                               "RETRY ND..retry count : %u\n",
+                                               ret_nd_data->retry_count);
+
+                                               RTE_LOG(INFO, LIBARP,
+                                               "TIMER STARTED FOR %u seconds\n",
+                                                       ARP_TIMER_EXPIRY);
+                                       }
+
+                                       request_nd(ret_nd_data->ipv6,
+                                                ifm_get_port(ret_nd_data->port));
+                                       if (rte_timer_reset(ret_nd_data->timer,
+                                                               (PROBE_TIME *
+                                                                rte_get_tsc_hz()/ 1000),
+                                                               SINGLE,
+                                                               timer_lcore,
+                                                               nd_timer_callback,
+                                                               arg) < 0)
+                                       if (ARPICMP_DEBUG)
+                                               RTE_LOG(INFO, LIBARP,
+                                                       "Err : Timer already running\n");
+
+                               }
+                       } else if (ret_nd_data->status == COMPLETE) {
+                               if (now <= (ret_nd_data->n_confirmed +
+                                (arp_timeout * rte_get_tsc_hz()))) {
+                                       if (rte_timer_reset(ret_nd_data->timer,
+                                                               (arp_timeout *
+                                                                rte_get_tsc_hz()), SINGLE,
+                                                               timer_lcore,
+                                                               nd_timer_callback,
+                                                               arg) < 0)
+                                       if (ARPICMP_DEBUG)
+                                               RTE_LOG(INFO, LIBARP,
+                                                       "Err : Timer already running\n");
+                               } else if (now <= (p_arp_data->update_tsc[ret_nd_data->port] + (USED_TIME * rte_get_tsc_hz()))) {
+                                       if (rte_timer_reset(ret_nd_data->timer,
+                                                               (arp_timeout *
+                                                                rte_get_tsc_hz()), SINGLE,
+                                                               timer_lcore,
+                                                               nd_timer_callback,
+                                                               arg) < 0)
+                                       if (ARPICMP_DEBUG)
+                                               RTE_LOG(INFO, LIBARP,
+                                                       "Err : Timer already running\n");
+                               } else {
+                                       printf("making it stale\n");
+                                       ret_nd_data->status = STALE;
+                                       p_arp_data->nd_cache_hw_laddr_valid[ret_nd_data->port] = 0;
+                               }
+                       }
+                       rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
+               } else {
+                       rte_hash_del_key(nd_hash_handle, &nd_key);
+               }
+       }
        return;
 }
 
index e7fcb42..9cb0205 100644 (file)
@@ -31,7 +31,7 @@
 #define MAX_ARP_RT_ENTRY 32
 #define NUM_DESC                (get_arp_buf())
 #define ARP_BUF_DEFAULT                30000
-#define PROBE_TIME             500
+#define PROBE_TIME             50
 #undef L3_STACK_SUPPORT
 
 /**
@@ -54,6 +54,12 @@ struct arp_cache {
         uint32_t num_nhip;
 };
 
+struct nd_cache {
+        uint8_t nhip[MAX_LOCAL_MAC_ADDRESS][16];
+        struct ether_addr link_hw_laddr[MAX_LOCAL_MAC_ADDRESS];
+        uint32_t num_nhip;
+};
+
 /**
 * A structure for Route table entires of IPv6
 *
@@ -65,28 +71,17 @@ struct lib_nd_route_table_entry {
        uint8_t nhipv6[16];     /**< next hop Ipv6 */
 };
 
-struct arp_data {
-       struct lib_arp_route_table_entry
-            lib_arp_route_table[MAX_ARP_RT_ENTRY];
-       uint8_t lib_arp_route_ent_cnt;
-       struct lib_nd_route_table_entry
-            lib_nd_route_table[MAX_ARP_RT_ENTRY];
-       uint8_t lib_nd_route_ent_cnt;
-       struct arp_cache arp_local_cache[MAX_PORTS];
-       struct ether_addr link_hw_addr[MAX_LOCAL_MAC_ADDRESS];
-       uint32_t link_hw_addr_array_idx;
-       uint8_t arp_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
-} __rte_cache_aligned;
-
 uint8_t arp_cache_dest_mac_present(uint32_t out_port);
-
+uint8_t nd_cache_dest_mac_present(uint32_t out_port);
 extern struct lib_nd_route_table_entry lib_nd_route_table[MAX_ND_RT_ENTRY];
 extern struct lib_arp_route_table_entry lib_arp_route_table[MAX_ARP_RT_ENTRY];
 extern struct ether_addr *get_local_link_hw_addr(uint8_t out_port, uint32_t nhip);
+extern struct ether_addr *get_nd_local_link_hw_addr(uint8_t out_port, uint8_t nhip[]);
 extern struct arp_cache arp_local_cache[MAX_PORTS];
 extern void prefetch(void);
-extern struct arp_entry_data *arp_data_ptr[16];
+extern void update_nhip_access(uint8_t);
 uint32_t get_arp_buf(void);
+uint32_t get_nd_buf(void);
 
 enum {
        ARP_FOUND,
@@ -156,8 +151,6 @@ enum {
        STALE
 };
 #define USED_TIME      5
-//#define COMPLETE   1 /**< ARP entry populated and echo reply recieved. */
-//#define INCOMPLETE 0 /**< ARP entry populated and either awaiting echo reply or stale entry. */
 
 extern uint32_t NDIPV6_DEBUG;  /**< ND IPv6 */
 
@@ -182,14 +175,10 @@ struct arp_entry_data {
        uint8_t retry_count;                    /**< retry count for ARP*/
        struct rte_timer *timer;    /**< Timer Associated with ARP*/
        struct arp_timer_key *timer_key;
-        struct rte_ring *queue;     /** pkts queued */
         rte_rwlock_t queue_lock;    /** queue lock */
        struct rte_mbuf **buf_pkts;
-       struct rte_mbuf *buffered_pkt_list_head;
-       struct rte_mbuf *buffered_pkt_list_tail;
        uint32_t num_pkts;
-       uint32_t n_confirmed;
-       uint32_t n_last_update;
+       uint64_t n_confirmed;
 } __attribute__ ((packed));
 
 /**
@@ -215,7 +204,13 @@ struct nd_entry_data {
        uint8_t status;                         /**< statusof the entry */
        uint8_t mode;                           /**< Mode */
        uint8_t ipv6[ND_IPV6_ADDR_SIZE];  /**< Ipv6 address */
+       uint8_t retry_count;                    /**< retry count for ARP*/
        struct rte_timer *timer;                /**< Timer */
+       struct nd_timer_key *timer_key;
+        rte_rwlock_t queue_lock;    /** queue lock */
+       struct rte_mbuf **buf_pkts;
+       uint32_t num_pkts;
+       uint64_t n_confirmed;
 } __attribute__ ((packed));
 
 /**
@@ -232,21 +227,22 @@ struct table_nd_entry_data {
        struct rte_timer *timer;         /**< Timer */
 } __attribute__ ((packed));
 
-/**
-* To get the destination MAC address andnext hop for the ip address  and outgoing port
-* @param1 ip addr
-* IP address for which MAC address is needed.
-* @param2 phy_port
-*  Physical Port
-* @param3 ether_addr
-* pointer to the ether_addr, This gets update with valid MAC addresss
-* @Param4 next nhip
-* Gets the next hop IP by Ip address and physical port
-* @return
-* 0 if failure, and 1 if success
-*/
+struct arp_data {
+       struct lib_arp_route_table_entry
+            lib_arp_route_table[MAX_ARP_RT_ENTRY];
+       uint8_t lib_arp_route_ent_cnt;
+       struct lib_nd_route_table_entry
+            lib_nd_route_table[MAX_ARP_RT_ENTRY];
+       uint8_t lib_nd_route_ent_cnt;
+       struct arp_cache arp_local_cache[MAX_PORTS];
+       struct nd_cache nd_local_cache[MAX_PORTS];
+       struct ether_addr link_hw_addr[MAX_LOCAL_MAC_ADDRESS];
+       uint32_t link_hw_addr_array_idx;
+       uint8_t arp_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
+       uint8_t nd_cache_hw_laddr_valid[MAX_LOCAL_MAC_ADDRESS];
+       uint64_t update_tsc[MAX_LOCAL_MAC_ADDRESS];
+} __rte_cache_aligned;
 
-struct arp_entry_data *get_dest_mac_address(const uint32_t ipaddr, uint32_t *phy_port, struct ether_addr *hw_addr, uint32_t *nhip);
 /**
 * To get the destination MAC address andnext hop for the ip address  and outgoing port
 * @param1 ip addr
@@ -264,35 +260,6 @@ struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
                                 uint32_t *phy_port, struct ether_addr *hw_addr);
 
 /**
-* To get the destination mac address for  IPv4  address
-* @param  Ipaddr
-* IP address which need the destination mac address
-* @param Phy_port
-* physical port
-* @param ether_addr
-* pointer to the ether_addr, This gets update with valid mac address
-* @return
-* 0 if failure, 1 if success
-*/
-int get_dest_mac_addr(const uint32_t ipaddr, uint32_t *phy_port,
-                                       struct ether_addr *hw_addr);
-
-/**
-* To get the destination mac address for IPV6 address
-* @param ipv6addr
-* IPv6 address which need the destination mac adress
-* @param Phy_Port
-* physical prt
-* @param ether_addr
-* pointer to the ether_address, This gets update with valid mac address
-* @param Nhipv6[]
-* Gets the next hop ipv6 address by ipv6 address and physical port
-* @return
-* 0 if failure, 1 ifsuccess
-*/
-int get_dest_mac_address_ipv6(uint8_t ipv6addr[], uint32_t *phy_port,
-                                               struct ether_addr *hw_addr, uint8_t nhipv6[]);
-/**
 * To get the destination mac address for IPV6 address
 * @param ipv6addr
 * IPv6 address which need the destination mac adress
@@ -306,13 +273,17 @@ int get_dest_mac_address_ipv6(uint8_t ipv6addr[], uint32_t *phy_port,
 * 0 if failure, 1 ifsuccess
 */
 
-int get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
+struct nd_entry_data *get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
                                         struct ether_addr *hw_addr,
                                         uint8_t nhipv6[]);
 int arp_queue_unresolved_packet(struct arp_entry_data * arp_data,
                         struct rte_mbuf * m);
 extern void arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,struct ether_addr *hw_addr, uint8_t port_id);
 
+int nd_queue_unresolved_packet(struct nd_entry_data *nd_data,
+                        struct rte_mbuf * m);
+extern void nd_send_buffered_pkts(struct nd_entry_data *ret_nd_data,struct ether_addr *hw_addr, uint8_t port_id);
+
 /**
 * To get hardware link address
 * @param out_port
@@ -352,7 +323,7 @@ void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg);
 * Port id
 */
 
-void remove_nd_entry_ipv6(uint8_t ipv6addr[], uint8_t portid);
+void remove_nd_entry_ipv6(struct nd_entry_data *ret_nd_data, void *arg);
 
 /**
 * Populate arp entry in arp Table
@@ -446,7 +417,7 @@ struct arp_entry_data *retrieve_arp_entry(const struct arp_key_ipv4 arp_key, uin
 * Nd key to validate Nd entry
 */
 
-struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key);
+struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key, uint8_t mode);
 
 /**
 * Setsup Arp Initilization
@@ -552,5 +523,5 @@ uint32_t get_nh(uint32_t, uint32_t *, struct ether_addr *addr);
 * @Param nhipv6
 * next hop ipv6
 */
-void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[]);
+void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[], struct ether_addr *hw_addr);
 #endif
index 44f30cb..eea67b0 100644 (file)
@@ -184,7 +184,7 @@ void process_icmpv6_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
                nd_key.filler3 = 0;
 
                /*Validate if key-value pair already exists in the hash table for ND IPv6 */
-               struct nd_entry_data *new_nd_data = retrieve_nd_entry(nd_key);
+               struct nd_entry_data *new_nd_data = retrieve_nd_entry(nd_key, DYNAMIC_ND);
                if (new_nd_data == NULL) {
                        printf
                                        ("Received unsolicited ICMPv6 echo reply on port %d\n",
@@ -209,6 +209,7 @@ void process_icmpv6_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
 
                for (i = 0; i < ND_IPV6_ADDR_SIZE; i++)
                        src_ipv6[i] = ipv6_h->src_addr[i];
+
                for (i = 0; i < ND_IPV6_ADDR_SIZE; i++)
                        dst_ipv6[i] = ipv6_h->dst_addr[i];
 
@@ -217,6 +218,7 @@ void process_icmpv6_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
                /*  Check for Multicast Address */
                if ((IPV6_MULTICAST & ((multi_addr << 8) | dst_ipv6[1]))
                                || !memcmp(&port->macaddr[0], &eth_h->d_addr, 6)) {
+
                        populate_nd_entry(src_hw_addr, src_ipv6, port->pmdid,
                                                DYNAMIC_ND);
 
@@ -346,6 +348,9 @@ struct rte_mbuf *request_icmpv6_echo(uint8_t ipv6[], l2_phy_interface_t *port)
                        sizeof(struct ether_hdr) + sizeof(struct ipv6_hdr) + 64;
        icmpv6_pkt->data_len = icmpv6_pkt->pkt_len;
 
+       if (port)
+               port->transmit_single_pkt(port, icmpv6_pkt);
+
        return icmpv6_pkt;
 }
 
@@ -357,13 +362,16 @@ struct rte_mbuf *request_nd(uint8_t ipv6[], l2_phy_interface_t *port)
        struct icmpv6_nd_hdr *icmpv6_nd_h;
        int i;
 
-       struct rte_mbuf *icmpv6_pkt = lib_icmpv6_pkt;
+       struct rte_mbuf *icmpv6_pkt = lib_nd_pkt[port->pmdid];
        if (icmpv6_pkt == NULL) {
                if (ARPICMP_DEBUG)
                        printf("Error allocating icmpv6_pkt rte_mbuf\n");
                return NULL;
        }
 
+       uint8_t dst_ip[] = {255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 16, 100, 20};
+       uint8_t dst_mac[] = {51,51,255, 16, 100, 20};
+
        eth_h = rte_pktmbuf_mtod(icmpv6_pkt, struct ether_hdr *);
 
        ipv6_h = (struct ipv6_hdr *)((char *)eth_h + sizeof(struct ether_hdr));
@@ -375,24 +383,37 @@ struct rte_mbuf *request_nd(uint8_t ipv6[], l2_phy_interface_t *port)
 
        ether_addr_copy((struct ether_addr *)&port->macaddr[0], &eth_h->s_addr);
        eth_h->ether_type = rte_bswap16(0x86dd);
+
        for (i = 0; i < 6; i++) {
-               eth_h->d_addr.addr_bytes[i] = 0;
+               if (i < 3)
+                       eth_h->d_addr.addr_bytes[i] = dst_mac[i];
+               else
+                       eth_h->d_addr.addr_bytes[i] = ipv6[i];
        }
 
-       ipv6_h->vtc_flow = 0x60000000;
+       for (i=13; i<16; i++)
+               dst_ip[i] = ipv6[i];
+
+       uint8_t *addr = ((ipv6list_t *) (port->ipv6_list))->ipaddr;
+
+       ipv6_h->vtc_flow = rte_bswap32(0x60000000);
        ipv6_h->payload_len = rte_bswap16(32);
        ipv6_h->proto = 58;
-       ipv6_h->hop_limits = 64;
+       ipv6_h->hop_limits = 255;
 
        for (i = 0; i < 16; i++) {
-               ipv6_h->src_addr[i] = 0x0;
-               ipv6_h->dst_addr[i] = ipv6[i];
+               ipv6_h->src_addr[i] = *(addr + i);
+               ipv6_h->dst_addr[i] = dst_ip[i];
        }
 
        icmpv6_h->icmpv6_type = ICMPV6_NEIGHBOR_SOLICITATION;
        icmpv6_h->icmpv6_code = 0;
 
        icmpv6_nd_h->icmpv6_reserved = 0x0;
+       icmpv6_nd_h->icmpv6_reserved |=
+                       rte_cpu_to_be_32
+                       (NEIGHBOR_ROUTER_OVERRIDE_SET);
+
        for (i = 0; i < ND_IPV6_ADDR_SIZE; i++)
                icmpv6_nd_h->target_ipv6[i] = ipv6[i];
        icmpv6_nd_h->type = e_Source_Link_Layer_Address;
@@ -401,10 +422,13 @@ struct rte_mbuf *request_nd(uint8_t ipv6[], l2_phy_interface_t *port)
 
        icmpv6_h->icmpv6_cksum = 0;
        icmpv6_h->icmpv6_cksum = ~icmpv6_ipv6_nd_checksum(icmpv6_pkt);
-
        icmpv6_pkt->pkt_len =
                        sizeof(struct ether_hdr) + sizeof(struct ipv6_hdr) + 32;
        icmpv6_pkt->data_len = icmpv6_pkt->pkt_len;
 
+       if (port) {
+               port->transmit_single_pkt(port, icmpv6_pkt);
+       }
+
        return icmpv6_pkt;
 }
index e9ccca1..b713d82 100644 (file)
@@ -111,3 +111,4 @@ struct rte_mbuf *lib_icmpv6_pkt;
  *  port - port structure
  */
 void process_icmpv6_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port);
+extern struct rte_mbuf *lib_nd_pkt[MAX_PORTS];
index 43e0be2..6b42ad7 100644 (file)
@@ -28,9 +28,7 @@
 
 #include "app.h"
 #include "vnf_common.h"
-#ifndef VNF_ACL
 #include "lib_arp.h"
-#endif
 
 #include <rte_ip.h>
 #include <rte_udp.h>
@@ -97,9 +95,7 @@ cmd_arp_add_parsed(void *parsed_result,
        } else {
                memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
                populate_nd_entry(&params->macaddr, ipv6, params->port_id
-                               #ifndef VNF_ACL
                                , STATIC_ND
-                               #endif
                                );
        }
 }
@@ -155,30 +151,25 @@ cmd_arp_del_parsed(void *parsed_result,
                         __rte_unused struct cmdline *cl, __rte_unused void *data)
 {
        struct cmd_arp_del_result *params = parsed_result;
-       uint8_t ipv6[16];
-
-       #if 0
-       struct pipeline_arp_icmp_arp_key key;
-       key.type = PIPELINE_ARP_ICMP_ARP_IPV4;
-       key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.port_id = params->port_id;
-       remove_arp_entry(rte_bswap32(req->key.key.ipv4.ip),
-               req->key.key.ipv4.port_id);
-       #endif
-       struct arp_key_ipv4 arp_key;
-        arp_key.port_id = params->port_id;
-        arp_key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
-        arp_key.filler1 = 0;
-        arp_key.filler2 = 0;
-        arp_key.filler3 = 0;
-
-        struct arp_entry_data *new_arp_data = retrieve_arp_entry(arp_key, STATIC_ARP);
 
        if (params->ip.family == AF_INET) {
+               struct arp_key_ipv4 arp_key;
+               arp_key.port_id = params->port_id;
+               arp_key.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
+               arp_key.filler1 = 0;
+               arp_key.filler2 = 0;
+               arp_key.filler3 = 0;
+               struct arp_entry_data *new_arp_data = retrieve_arp_entry(arp_key, STATIC_ARP);
                remove_arp_entry(new_arp_data, &arp_key);
        } else {
-               memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
-               remove_nd_entry_ipv6(ipv6, params->port_id);
+               struct nd_key_ipv6 nd_key;
+               nd_key.port_id = params->port_id;
+               memcpy(&nd_key.ipv6[0], params->ip.addr.ipv6.s6_addr, 16);
+               nd_key.filler1 = 0;
+               nd_key.filler2 = 0;
+               nd_key.filler3 = 0;
+               struct nd_entry_data *new_nd_data = retrieve_nd_entry(nd_key, STATIC_ND);
+               remove_nd_entry_ipv6(new_nd_data, &nd_key);
        }
 }
 
@@ -250,11 +241,7 @@ cmd_arp_req_parsed(void *parsed_result,
                printf("ARP - requesting arp for ip 0x%x, port %d\n",
                                         params->ip.addr.ipv4.s_addr, params->port_id);
 
-       #ifdef VNF_ACL
-       request_arp_wrap(params->port_id, params->ip.addr.ipv4.s_addr);
-       #else
        request_arp(params->port_id, params->ip.addr.ipv4.s_addr);
-       #endif
        /*give pipeline number too*/
 }
 
@@ -401,7 +388,6 @@ static cmdline_parse_inst_t cmd_show_ports_info = {
                         },
 };
 
-#ifndef VNF_ACL
 struct cmd_arp_dbg_result {
        cmdline_fixed_string_t arpdbg_str;
        uint32_t flag;
@@ -479,7 +465,6 @@ cmdline_parse_inst_t cmd_arp_timer = {
                NULL,
        },
 };
-#endif
 
 /*
  * Forwarding of packets in I/O mode.
@@ -2106,10 +2091,8 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
 /*      (cmdline_parse_inst_t *) & cmd_set_hash_input_set_5,*/
        (cmdline_parse_inst_t *) &cmd_set_hash_global_config,
        (cmdline_parse_inst_t *) &cmd_set_sym_hash_ena_per_port,
-       #ifndef VNF_ACL
        (cmdline_parse_inst_t *) &cmd_arp_dbg,
        (cmdline_parse_inst_t *) &cmd_arp_timer,
-       #endif
        NULL,
 };
 
index cfbbe61..a73dcb2 100644 (file)
@@ -44,157 +44,6 @@ f_ah(                                                                   \
 extern struct app_params *myApp;
 void print_pkt1(struct rte_mbuf *pkt);
 struct ether_addr *get_link_hw_addr(uint8_t out_port);
-#ifdef VNF_ACL
-
-#include <rte_pipeline.h>
-#include "rte_ether.h"
-#include "app.h"
-
-#if (RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN)
-// x86 == little endian
-// network  == big endian
-#define CHECK_ENDIAN_16(x) rte_be_to_cpu_16(x)
-#define CHECK_ENDIAN_32(x) rte_be_to_cpu_32(x)
-#else
-#define CHECK_ENDIAN_16(x) (x)
-#define CHECK_ENDIAN_32(x) (x)
-#endif
-
-
-#define MAX_ARP_RT_ENTRY 32
-#define MAX_ND_RT_ENTRY 32
-
-#define ND_IPV6_ADDR_SIZE 16   /* 16 Byte of IPv6 Address */
-
-enum {
-ARP_FOUND,
-ARP_NOT_FOUND,
-NH_NOT_FOUND,
-};
-
-enum arp_key_type {
-       ARP_IPV4,
-       /* ND IPv6 */
-       ND_IPV6,
-};
-
-struct arp_key_ipv4 {
-       uint32_t ip;
-       uint8_t port_id;
-       uint8_t filler1;
-       uint8_t filler2;
-       uint8_t filler3;
-};
-
-/* ND IPv6 */
-struct nd_key_ipv6 {
-       /*128 Bit of IPv6 Address */
-       /*<48bit Network> <16bit Subnet> <64bit Interface> */
-       uint8_t ipv6[ND_IPV6_ADDR_SIZE];
-       uint8_t port_id;
-       uint8_t filler1;
-       uint8_t filler2;
-       uint8_t filler3;
-};
-
-struct arp_key {
-       enum arp_key_type type;
-       union {
-               struct arp_key_ipv4 ipv4;
-       } key;
-};
-
-struct lib_arp_route_table_entry {
-       uint32_t ip;
-       uint32_t mask;
-       uint32_t port;
-       uint32_t nh;
-};
-
-struct lib_nd_route_table_entry {
-       uint8_t ipv6[16];
-       uint8_t depth;
-       uint32_t port;
-       uint8_t nhipv6[16];
-};
-extern struct lib_arp_route_table_entry lib_arp_route_table[MAX_ARP_RT_ENTRY];
-extern struct lib_nd_route_table_entry  lib_nd_route_table[MAX_ND_RT_ENTRY];
-
-extern uint8_t prv_in_port_a[PIPELINE_MAX_PORT_IN];
-extern void convert_prefixlen_to_netmask_ipv6(uint32_t depth,
-                                                               uint8_t netmask_ipv6[]);
-uint32_t get_nh(uint32_t, uint32_t*);
-void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[]);
-
-extern uint32_t ARPICMP_DEBUG;
-
-
-/* ARP entry populated and echo reply recieved */
-#define COMPLETE   1
-/* ARP entry populated and either awaiting echo reply or stale entry */
-#define INCOMPLETE 0
-
-/* ND IPv6 */
-extern uint32_t NDIPV6_DEBUG;
-
-/* ICMPv6 entry populated and echo reply recieved */
-#define ICMPv6_COMPLETE   1
-/* ICMPv6 entry populated and either awaiting echo reply or stale entry */
-#define ICMPv6_INCOMPLETE 0
-
-struct arp_entry_data {
-       struct ether_addr eth_addr;
-       uint8_t port;
-       uint8_t status;
-       uint32_t ip;
-} __attribute__ ((__packed__));
-
-/*ND IPv6*/
-struct nd_entry_data {
-       struct ether_addr eth_addr;
-       uint8_t port;
-       uint8_t status;
-       uint8_t ipv6[ND_IPV6_ADDR_SIZE];
-} __attribute__ ((__packed__));
-
-int get_dest_mac_address(const uint32_t ipaddr, const uint32_t phy_port,
-                        struct ether_addr *hw_addr, uint32_t *nhip);
-int get_dest_mac_addr(const uint32_t ipaddr, const uint32_t phy_port,
-                                       struct ether_addr *hw_addr);
-
-int get_dest_mac_address_ipv6(uint8_t ipv6addr[], uint32_t phy_port,
-                                               struct ether_addr *hw_addr, uint8_t nhipv6[]);
-
-void lib_arp_request_arp(
-       const uint32_t ipaddr,
-       const uint32_t phy_port,
-       struct rte_pipeline *rte_p);
-
-void print_arp_table(void);
-void print_nd_table(void);
-void remove_arp_entry(uint32_t ipaddr, uint8_t portid);
-void remove_nd_entry_ipv6(uint8_t ipv6addr[], uint8_t portid);
-void populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
-                       uint8_t portid);
-/*ND IPv6*/
-int populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ip[],
-                                       uint8_t portid);
-void request_arp(uint8_t port_id, uint32_t ip, struct rte_pipeline *rte_p);
-void request_arp_wrap(uint8_t port_id, uint32_t ip);
-void request_echo(unsigned int port_id, uint32_t ip);
-
-void process_arpicmp_pkt(struct rte_mbuf *pkt, uint32_t out_port,
-                        uint32_t pkt_num);
-
-struct arp_entry_data *retrieve_arp_entry(const struct arp_key_ipv4 arp_key);
-struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key);
-
-struct nd_entry_data *retrieve_nd_entry(struct nd_key_ipv6 nd_key);
-
-void lib_nd_init(/*struct pipeline_params *params, */ struct app_params *app);
-void print_pkt1(struct rte_mbuf *pkt);
-
-#endif
 
 uint8_t lb_outport_id[PIPELINE_MAX_PORT_IN];
 struct pipeline *loadb_pipeline[PIPELINE_MAX_PORT_IN];
@@ -203,14 +52,6 @@ uint8_t vnf_to_loadb_map[PIPELINE_MAX_PORT_IN];
 uint8_t port_to_loadb_map[PIPELINE_MAX_PORT_IN];
 uint8_t loadb_pipeline_nums[PIPELINE_MAX_PORT_IN];
 
-#if 0
-uint8_t lb_outport_id[PIPELINE_MAX_PORT_IN];
-struct pipeline *arp_pipeline[PIPELINE_MAX_PORT_IN];
-uint8_t vnf_to_arp_map[PIPELINE_MAX_PORT_IN];
-uint8_t port_to_arp_map[PIPELINE_MAX_PORT_IN];
-uint8_t arp_pipeline_nums[PIPELINE_MAX_PORT_IN];
-#endif
-
 void set_port_to_loadb_map(uint8_t pipeline_num);
 uint8_t get_port_to_loadb_map(uint8_t phy_port_id);
 /* acts on port_to_loadb_map */
@@ -270,74 +111,4 @@ struct pipeline_arpicmp_entry_dbg_msg_rsp {
        int status;
 };
 
-#ifdef VNF_ACL
-
- /* ICMPv6 Header */
-struct icmpv6_hdr {
-        uint8_t icmpv6_type;    /* ICMPV6 packet type. */
-        uint8_t icmpv6_code;    /* ICMPV6 packet code. */
-        uint16_t icmpv6_cksum;  /* ICMPV6 packet checksum. */
-} __attribute__ ((__packed__));
-
- /**
-  * ICMPV6 Info Header
-  */
-struct icmpv6_info_hdr {
-        uint16_t icmpv6_ident;  /* ICMPV6 packet identifier. */
-        uint16_t icmpv6_seq_nb; /* ICMPV6 packet sequence number. */
-} __attribute__ ((__packed__));
-
- /**
-  * ICMPV6 ND Header
-  */
-struct icmpv6_nd_hdr {
-        /*ND Advertisement flags */
-        uint32_t icmpv6_reserved;
-        /* bit31-Router, bit30-Solicited, bit29-Override, bit28-bit0 unused */
-
-        uint8_t target_ipv6[16];  /**< target IPv6 address */
- /*ICMPv6 Option*/
-        uint8_t type;
-        uint8_t length;
-        struct ether_addr link_layer_address;
-} __attribute__ ((__packed__));
-
- /* Icmpv6 types */
- #define ICMPV6_PROTOCOL_ID 58
- #define ICMPV6_ECHO_REQUEST 0x0080
- #define ICMPV6_ECHO_REPLY 0x0081
- #define ICMPV6_NEIGHBOR_SOLICITATION 0x0087
-  #define ICMPV6_NEIGHBOR_ADVERTISEMENT 0x0088
- #define IPV6_MULTICAST 0xFF02
-
- #define NEIGHBOR_SOLICITATION_SET 0x40000000
-enum icmpv6_link_layer_Address_type {
-        e_Source_Link_Layer_Address = 1,
-        e_Target_Link_Layer_Address,
-        e_Link_Layer_Address
-};
-
-uint8_t is_multicast_ipv6_addr(uint8_t ipv6[]);
-struct icmpv6_port_address {
-        uint32_t ipv6[16];
-        uint64_t mac_addr;
-};
-
-struct icmpv6_port_address icmpv6_port_addresses[RTE_MAX_ETHPORTS];
-
- #define MAX_NUM_ICMPv6_ENTRIES 64
- //struct rte_pipeline *myicmpP;
-struct rte_mbuf *lib_icmpv6_pkt;
-void request_icmpv6_echo(uint32_t port_id, uint8_t ipv6[]);
-void request_icmpv6_echo_message(uint16_t port_id, uint8_t ipv6[],
-                                        struct ether_addr *gw_addr);
-void
-process_icmpv6_pkt(struct rte_mbuf *pkt, uint32_t out_port, uint32_t pkt_num);
-
-int get_dest_mac_addr_port(const uint32_t ipaddr,
-       uint32_t *phy_port, struct ether_addr *hw_addr);
-
-int get_dest_mac_address_ipv6_port(uint8_t ipv6addr[], uint32_t *phy_port,
-       struct ether_addr *hw_addr, uint8_t nhipv6[]);
-#endif
 #endif
index 5df2977..d1fdb37 100644 (file)
@@ -31,9 +31,7 @@
 #include <cmdline.h>
 
 #include "pipeline_common_fe.h"
-#ifndef VNF_ACL
 #include "interface.h"
-#endif
 
 int
 app_pipeline_ping(struct app_params *app,
@@ -359,10 +357,8 @@ app_link_config(struct app_params *app,
        /* Save link parameters */
        p->ip = ip;
        p->depth = depth;
-        #ifndef VNF_ACL
         if (ifm_add_ipv4_port(link_id, rte_bswap32(ip), depth) == IFM_FAILURE)
             return -1;
-        #endif
 
        return 0;
 }
@@ -468,10 +464,8 @@ app_link_config_ipv6(struct app_params *app,
                ipv6[6], ipv6[7], ipv6[8], ipv6[9], ipv6[10], ipv6[11],
                ipv6[12], ipv6[13], ipv6[14], ipv6[15]);
 */
-        #ifndef VNF_ACL
        if (ifm_add_ipv6_port(link_id, ipv6, depth) == IFM_FAILURE)
                return -1;
-        #endif
        return 0;
 }
 
@@ -1276,9 +1270,7 @@ cmd_link_ls_parsed(
                 if (p)
                print_link_info(p);
        }
-       #ifndef VNF_ACL
         print_interface_details();
-       #endif
 }
 
 cmdline_parse_token_string_t cmd_link_ls_link_string =
index b47ee98..0f9ec3d 100644 (file)
@@ -30,9 +30,7 @@
 #include "pipeline_arpicmp_be.h"
 #include "vnf_common.h"
 #include "app.h"
-#ifndef VNF_ACL
 #include "lib_icmpv6.h"
-#endif
 
 uint8_t TXRX_DEBUG;
 int pkt_burst_cnt;
@@ -265,9 +263,8 @@ pkt_work_txrx(struct rte_mbuf *pkt, uint32_t pkt_num, void *arg)
                        || !memcmp(ipv6_h->dst_addr, solicited_node_multicast_addr, 13)) {
                                rte_pipeline_port_out_packet_insert(p_txrx->p.p,
                                        out_port, pkt);
-                               rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
+                               rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask);
                        } else {
-                               printf("Dropping the IPv6 pkt\n");
                                rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask);
                        }
                }
@@ -414,7 +411,7 @@ pkt4_work_txrx(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
                                || !memcmp(ipv6_h0->dst_addr, solicited_node_multicast_addr, 13)) {
                                rte_pipeline_port_out_packet_insert(p_txrx->p.p,
                                        out_port, pkt[0]);
-                               rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
+                               rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask0);
 
                        } else {
                                rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask0);
@@ -473,19 +470,14 @@ pkt4_work_txrx(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
        #ifdef IPV6
        case ETH_TYPE_IPV6:
                if (*protocol1 == ICMPV6_PROTOCOL_ID) {
-                       #ifndef VNF_ACL
                        if (!memcmp(ipv6_h1->dst_addr, link->ipv6, 16)
                                || !memcmp(ipv6_h1->dst_addr, solicited_node_multicast_addr, 13)) {
-                       #endif
                                rte_pipeline_port_out_packet_insert(p_txrx->p.p,
                                        out_port, pkt[1]);
-                               rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
-                       #ifndef VNF_ACL
+                               rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask1);
                        } else {
-                               printf("Dropping the IPv6 pkt\n");
                                rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask1);
                        }
-                       #endif
                }
        break;
        #endif
@@ -539,19 +531,14 @@ pkt4_work_txrx(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
        #ifdef IPV6
        case ETH_TYPE_IPV6:
                if (*protocol2 == ICMPV6_PROTOCOL_ID) {
-                       #ifndef VNF_ACL
                        if (!memcmp(ipv6_h2->dst_addr, link->ipv6, 16)
                                || !memcmp(ipv6_h2->dst_addr, solicited_node_multicast_addr, 13)) {
-                       #endif
                                rte_pipeline_port_out_packet_insert(p_txrx->p.p,
                                        out_port, pkt[2]);
-                               rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
-                       #ifndef VNF_ACL
+                               rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask2);
                        } else {
-                               printf("Dropping the IPv6 pkt\n");
                                rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask2);
                        }
-                       #endif
                }
        break;
        #endif
@@ -605,19 +592,14 @@ pkt4_work_txrx(struct rte_mbuf **pkt, uint32_t pkt_num, void *arg)
        #ifdef IPV6
        case ETH_TYPE_IPV6:
                if (*protocol3 == ICMPV6_PROTOCOL_ID) {
-                       #ifndef VNF_ACL
                        if (!memcmp(ipv6_h3->dst_addr, link->ipv6, 16)
                                || !memcmp(ipv6_h3->dst_addr, solicited_node_multicast_addr, 13)) {
-                       #endif
                                rte_pipeline_port_out_packet_insert(p_txrx->p.p,
                                        out_port, pkt[3]);
-                               rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
-                       #ifndef VNF_ACL
+                               rte_pipeline_ah_packet_hijack(p_txrx->p.p, pkt_mask3);
                        } else {
-                               printf("Dropping the IPv6 pkt\n");
                                rte_pipeline_ah_packet_drop(p_txrx->p.p, pkt_mask3);
                        }
-                       #endif
                }
        break;
        #endif
index b4b99d1..5f7ec8a 100644 (file)
@@ -92,13 +92,11 @@ static const struct app_link_params link_params_default = {
                        .mq_mode = ETH_MQ_TX_NONE,
                },
                .lpbk_mode = 0,
-               #ifndef VNF_ACL
                #ifdef LSC_GRARP
                 .intr_conf = {
                      .lsc = 1, /**< lsc interrupt feature enabled */
                 }
                #endif
-               #endif
        },
 
        .promisc = 1,
index a40d4d8..97f9021 100644 (file)
@@ -63,7 +63,7 @@ uint32_t get_prv_to_pub_port(uint32_t *ip_addr, uint8_t type)
        case 6:
        {
                uint8_t nhipv6[16];
-               get_nh_ipv6((uint8_t *)ip_addr, &dest_if, &nhipv6[0]);
+               get_nh_ipv6((uint8_t *)ip_addr, &dest_if, &nhipv6[0], &addr);
                if (dest_if != 0xff)
                        return dest_if;
                return 0xff;
@@ -92,7 +92,7 @@ uint32_t get_pub_to_prv_port(uint32_t *ip_addr, uint8_t type)
        case 6:
        {
                uint8_t nhipv6[16];
-               get_nh_ipv6((uint8_t *)ip_addr, &dest_if, &nhipv6[0]);
+               get_nh_ipv6((uint8_t *)ip_addr, &dest_if, &nhipv6[0], &addr);
                if (dest_if != 0xff)
                        return dest_if;
                return 0xff;