Merge "update userguide alignment"
authorDeepak S <deepak.s@linux.intel.com>
Mon, 2 Oct 2017 09:14:03 +0000 (09:14 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 2 Oct 2017 09:14:03 +0000 (09:14 +0000)
48 files changed:
VNFs/UDP_Replay/Makefile
VNFs/UDP_Replay/main.c
VNFs/vACL/Makefile
VNFs/vACL/config/IPv4_hwlb_acl.tc
VNFs/vACL/config/IPv4_swlb_acl.tc
VNFs/vACL/config/IPv6_hwlb_acl.tc
VNFs/vACL/config/IPv6_swlb_acl.tc
VNFs/vACL/main.c
VNFs/vACL/pipeline/pipeline_acl.c
VNFs/vACL/pipeline/pipeline_acl.h
VNFs/vACL/pipeline/pipeline_acl_be.c
VNFs/vACL/vnf_template.txt [new file with mode: 0644]
VNFs/vCGNAPT/Makefile
VNFs/vCGNAPT/config/sample_hwlb_2port_2WT.tc
VNFs/vCGNAPT/config/sample_swlb_2port_2WT.tc
VNFs/vCGNAPT/init.c
VNFs/vCGNAPT/main.c
VNFs/vCGNAPT/pipeline/pipeline_cgnapt.c
VNFs/vCGNAPT/pipeline/pipeline_cgnapt.h
VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.c
VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.h
VNFs/vCGNAPT/pipeline/pipeline_cgnapt_common.h
VNFs/vCGNAPT/vnf_template.txt [new file with mode: 0644]
VNFs/vFW/Makefile
VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc
VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc
VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc
VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc
VNFs/vFW/init.c
VNFs/vFW/main.c
VNFs/vFW/pipeline/pipeline_vfw.c
VNFs/vFW/pipeline/pipeline_vfw.h
VNFs/vFW/pipeline/pipeline_vfw_be.c
VNFs/vFW/vnf_template.txt [new file with mode: 0644]
common/VIL/gateway/gateway.c [new file with mode: 0644]
common/VIL/gateway/gateway.h [new file with mode: 0644]
common/VIL/l2l3_stack/lib_arp.c
common/VIL/l2l3_stack/lib_arp.h
common/VIL/l2l3_stack/tsx.h
common/VIL/pipeline_arpicmp/pipeline_arpicmp.c
common/VIL/pipeline_arpicmp/pipeline_arpicmp_be.c
common/VIL/pipeline_common/pipeline_common_fe.c
common/VIL/pipeline_master/pipeline_master_be.c
common/vnf_common/app.h
common/vnf_common/config_parse.c
common/vnf_common/rest_api.c [new file with mode: 0644]
common/vnf_common/vnf_common.c
tools/vnf_build.sh

index e237577..08fcbba 100644 (file)
@@ -35,6 +35,7 @@ VPATH += $(VNF_CORE)/common/VIL/pipeline_passthrough
 VPATH += $(SRCDIR)/pipeline
 VPATH += $(VNF_CORE)/common/VIL/pipeline_txrx
 VPATH += $(VNF_CORE)/common/VIL/l2l3_stack
+VPATH += $(VNF_CORE)/common/VIL/gateway
 
 INC += $(wildcard *.h)
 INC += $(wildcard pipeline/*.h)
@@ -47,6 +48,7 @@ INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_master/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_passthrough/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_txrx/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/l2l3_stack/*.h)
+INC += $(wildcard $(VNF_CORE)/common/VIL/gateway/*.h)
 
 CFLAGS += -I$(SRCDIR) -mrtm -mhle -I$(SRCDIR)/pipeline -I$(VNF_CORE)/common/vnf_common
 CFLAGS += -I$(VNF_CORE)/common/VIL/conntrack -I$(VNF_CORE)/common/VIL/l2l3_stack
@@ -54,6 +56,7 @@ CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_common -I$(VNF_CORE)/common/VIL/pipe
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_master -I$(VNF_CORE)/common/VIL/pipeline_passthrough
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_txrx
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_arpicmp
+CFLAGS += -I$(VNF_CORE)/common/VIL/gateway
 
 # all source are stored in SRCS-y
 SRCS-y := main.c
@@ -84,6 +87,7 @@ SRCS-y += pipeline_loadb.c
 SRCS-y += pipeline_loadb_be.c
 SRCS-y += vnf_common.c
 SRCS-y += pipeline_arpicmp_be.c
+SRCS-y += gateway.c
 
 CFLAGS += -O3 $(USER_FLAGS)
 CFLAGS += $(WERROR_FLAGS)
index 1b37c18..587057f 100644 (file)
@@ -94,6 +94,7 @@ performance of the solution should be sufficient for testing the UDP NAT perform
 #include "lib_icmpv6.h"
 #include "app.h"
 #include "vnf_common.h"
+#include "gateway.h"
 #define IN6ADDRSZ 16
 #define INADDRSZ 4
 #define APP_LOOKUP_EXACT_MATCH          0
@@ -200,6 +201,7 @@ cmdline_parse_ctx_t main_ctx[];
 uint32_t timer_lcore;
 uint32_t exit_loop = 1;
 port_config_t *port_config;
+
 #define MEMPOOL_SIZE   32 * 1024
 #define BUFFER_SIZE            2048
 #define CACHE_SIZE             256
@@ -436,160 +438,6 @@ app_link_down_internal(__rte_unused struct app_params *app, struct app_link_para
        cp->state = 0;
 }
 
-/* int
- * inet_pton_ipv4(src, dst)
- *      like inet_aton() but without all the hexadecimal and shorthand.
- * return:
- *      1 if `src' is a valid dotted quad, else 0.
- * notice:
- *      does not touch `dst' unless it's returning 1.
- * author:
- *      Paul Vixie, 1996.
- */
-static int inet_pton_ipv4(const char *src, unsigned char *dst)
-{
-       static const char digits[] = "0123456789";
-       int saw_digit, octets, ch;
-       unsigned char tmp[INADDRSZ], *tp;
-       saw_digit = 0;
-       octets = 0;
-       *(tp = tmp) = 0;
-       while ((ch = *src++) != '\0') {
-               const char *pch;
-               if ((pch = strchr(digits, ch)) != NULL) {
-                       unsigned int new = *tp * 10 + (pch - digits);
-                       if (new > 255)
-                               return 0;
-                       if (!saw_digit) {
-                               if (++octets > 4)
-                                       return 0;
-                               saw_digit = 1;
-                       }
-                       *tp = (unsigned char)new;
-               } else if (ch == '.' && saw_digit) {
-                       if (octets == 4)
-                               return 0;
-                       *++tp = 0;
-                       saw_digit = 0;
-               } else
-                       return 0;
-       }
-       if (octets < 4)
-               return 0;
-       memcpy(dst, tmp, INADDRSZ);
-       return 1;
-}
-
-/* int
- * inet_pton_ipv6(src, dst)
- *      convert presentation level address to network order binary form.
- * return:
- *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *      (1) does not touch `dst' unless it's returning 1.
- *      (2) :: in a full address is silently ignored.
- * credit:
- *      inspired by Mark Andrews.
- * author:
- *      Paul Vixie, 1996.
- */
-static int inet_pton_ipv6(const char *src, unsigned char *dst)
-{
-       static const char xdigits_l[] = "0123456789abcdef",
-           xdigits_u[] = "0123456789ABCDEF";
-       unsigned char tmp[IN6ADDRSZ], *tp = 0, *endp = 0, *colonp = 0;
-       const char *xdigits = 0, *curtok = 0;
-       int ch = 0, saw_xdigit = 0, count_xdigit = 0;
-       unsigned int val = 0;
-       unsigned dbloct_count = 0;
-       memset((tp = tmp), '\0', IN6ADDRSZ);
-       endp = tp + IN6ADDRSZ;
-       colonp = NULL;
-       if (*src == ':')
-               if (*++src != ':')
-                       return 0;
-       curtok = src;
-       saw_xdigit = count_xdigit = 0;
-       val = 0;
-       while ((ch = *src++) != '\0') {
-               const char *pch;
-               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-                       pch = strchr((xdigits = xdigits_u), ch);
-               if (pch != NULL) {
-                       if (count_xdigit >= 4)
-                               return 0;
-                       val <<= 4;
-                       val |= (pch - xdigits);
-                       if (val > 0xffff)
-                               return 0;
-                       saw_xdigit = 1;
-                       count_xdigit++;
-                       continue;
-               }
-               if (ch == ':') {
-                       curtok = src;
-                       if (!saw_xdigit) {
-                               if (colonp)
-                                       return 0;
-                               colonp = tp;
-                               continue;
-                       } else if (*src == '\0') {
-                               return 0;
-                       }
-                       if (tp + sizeof(int16_t) > endp)
-                               return 0;
-                       *tp++ = (unsigned char)((val >> 8) & 0xff);
-                       *tp++ = (unsigned char)(val & 0xff);
-                       saw_xdigit = 0;
-                       count_xdigit = 0;
-                       val = 0;
-                       dbloct_count++;
-                       continue;
-               }
-               if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
-                   inet_pton_ipv4(curtok, tp) > 0) {
-                       tp += INADDRSZ;
-                       saw_xdigit = 0;
-                       dbloct_count += 2;
-                       break;  /* '\0' was seen by inet_pton4(). */
-               }
-               return 0;
-       }
-       if (saw_xdigit) {
-               if (tp + sizeof(int16_t) > endp)
-                       return 0;
-               *tp++ = (unsigned char)((val >> 8) & 0xff);
-               *tp++ = (unsigned char)(val & 0xff);
-               dbloct_count++;
-       }
-       if (colonp != NULL) {
-               if (dbloct_count == 8)
-                       return 0;
-               const int n = tp - colonp;
-               int i;
-               for (i = 1; i <= n; i++) {
-                       endp[-i] = colonp[n - i];
-                       colonp[n - i] = 0;
-               }
-               tp = endp;
-       }
-       if (tp != endp)
-               return 0;
-       memcpy(dst, tmp, IN6ADDRSZ);
-       return 1;
-}
-static int my_inet_pton_ipv6(int af, const char *src, void *dst)
-{
-       switch (af) {
-       case AF_INET:
-               return inet_pton_ipv4(src, dst);
-       case AF_INET6:
-               return inet_pton_ipv6(src, dst);
-       default:
-               errno = EAFNOSUPPORT;
-               return -1;
-       }
-}
 void convert_ipstr_to_numeric(void)
 {
        uint32_t i;
@@ -2921,6 +2769,7 @@ main(int argc, char **argv)
        ifm_init();
        nb_ports = rte_eth_dev_count();
        num_ports = nb_ports;
+       gw_init(num_ports);
        if (nb_ports > RTE_MAX_ETHPORTS)
                nb_ports = RTE_MAX_ETHPORTS;
 
index febfc7b..0995f90 100644 (file)
@@ -30,7 +30,6 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # binary name
 APP = vACL
 
-
 VPATH += $(VNF_CORE)/common/vnf_common
 VPATH += $(VNF_CORE)/common/VIL/conntrack
 VPATH += $(VNF_CORE)/common/VIL/pipeline_common
@@ -41,6 +40,7 @@ VPATH += $(SRCDIR)/pipeline
 VPATH += $(VNF_CORE)/common/VIL/l2l3_stack
 VPATH += $(VNF_CORE)/common/VIL/pipeline_txrx
 VPATH += $(VNF_CORE)/common/VIL/pipeline_arpicmp
+VPATH += $(VNF_CORE)/common/VIL/gateway
 
 INC += $(wildcard *.h)
 INC += $(wildcard pipeline/*.h)
@@ -53,6 +53,7 @@ INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_master/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_passthrough/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_txrx/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/l2l3_stack/*.h)
+INC += $(wildcard $(VNF_CORE)/common/VIL/gateway/*.h)
 
 CFLAGS += -I$(SRCDIR) -mrtm -mhle -I$(SRCDIR)/pipeline -I$(VNF_CORE)/common/vnf_common
 CFLAGS += -I$(VNF_CORE)/common/VIL/l2l3_stack -I$(VNF_CORE)/common/VIL/conntrack
@@ -60,10 +61,18 @@ CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_common -I$(VNF_CORE)/common/VIL/pipe
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_master -I$(VNF_CORE)/common/VIL/pipeline_passthrough
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_txrx
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_arpicmp
+CFLAGS += -I$(VNF_CORE)/common/VIL/gateway
+
+TOP = $(RTE_SDK)/../civetweb
+CFLAGS += -I$(TOP)/include $(COPT) -DUSE_WEBSOCKET -DUSE_IPV6 -DUSE_SSL_DH=1
+CFLAGS += -DREST_API_SUPPORT
+LDFLAGS +=  -ljson -lcrypto -lssl
+LDFLAGS += -L$(RTE_SDK)/../civetweb/ -lcivetweb
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := main.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += rest_api.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse_tm.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_check.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += init.c
@@ -99,6 +108,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_txrx.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_txrx_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_arpicmp.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_arpicmp_be.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += gateway.c
+
 
 CFLAGS += -O3
 CFLAGS += -DIPV6
index 79b48ed..b8e2b15 100644 (file)
@@ -20,9 +20,9 @@ link 1 down
 link 1 config 172.16.40.10 8
 link 1 up
 
-; routeadd <port #> <ipv4 nhip address in decimal> <Mask>
-routeadd 0 202.16.100.20 0xff000000
-routeadd 1 172.16.40.20  0xff000000
+;routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+routeadd net 0 202.16.100.20 0xff000000
+routeadd net 1 172.16.40.20  0xff000000
 
 ; IPv4 static ARP
 ;p 1 arpadd 1 172.16.40.20 00:00:00:00:00:04
index 7274847..f736fc4 100644 (file)
@@ -20,9 +20,9 @@ link 1 down
 link 1 config 172.16.40.10 8
 link 1 up
 
-; routeadd <port #> <ipv4 nhip address in decimal> <Mask>
-routeadd 0 202.16.100.20 0xff000000
-routeadd 1 172.16.40.20  0xff000000
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+routeadd net 0 202.16.100.20 0xff000000
+routeadd net 1 172.16.40.20  0xff000000
 
 ; IPv4 static ARP
 ;p 1 arpadd 1 172.16.40.20 00:00:00:00:00:04
@@ -39,4 +39,4 @@ p action add 1 count
 ; IPv4 rules
 p acl add 1 202.16.100.20 8 172.16.40.20 8 0 65535 0 65535 0 0 1
 p acl add 1 172.16.40.20 8 202.16.100.20 8 0 65535 0 65535 0 0 0
-p acl applyruleset
\ No newline at end of file
+p acl applyruleset
index 4176110..da43b8d 100644 (file)
@@ -20,9 +20,9 @@ link 1 down
 link 1 config 2012:0000:0000:0000:6a05:caff:fe30:2071 64
 link 1 up
 
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-routeadd 0 fec0::6a05:caff:fe30:21b0  64
-routeadd 1 2012::6a05:caff:fe30:2081 64
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+routeadd net 0 fec0::6a05:caff:fe30:21b0 64
+routeadd net 1 2012::6a05:caff:fe30:2081 64
 
 ; IPv6 static ARP
 ;p 1 arpadd 0 fec0::6a05:caff:fe30:21b0 00:00:00:00:00:01
index c964609..8ffc3cc 100644 (file)
@@ -20,9 +20,9 @@ link 1 down
 link 1 config 2012:0000:0000:0000:6a05:caff:fe30:2071 64
 link 1 up
 
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-routeadd 0 fec0::6a05:caff:fe30:21b0  64
-routeadd 1 2012::6a05:caff:fe30:2081 64
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+routeadd net 0 fec0::6a05:caff:fe30:21b0 64
+routeadd net 1 2012::6a05:caff:fe30:2081 64
 
 ; IPv6 static ARP
 ;p 1 arpadd 0 fec0::6a05:caff:fe30:21b0 00:00:00:00:00:01
@@ -39,4 +39,4 @@ p action add 1 count
 ; IPv6 rules
 p acl add 1 fec0::6a05:caff:fe30:21b0 64 2012::6a05:caff:fe30:2081 64 0 65535 0 65535 0 0 1
 p acl add 1 2012::6a05:caff:fe30:2081 64 fec0::6a05:caff:fe30:21b0 64 0 65535 0 65535 0 0 0
-p acl applyruleset
\ No newline at end of file
+p acl applyruleset
index 9ebf6fc..a6ba00b 100644 (file)
 */
 
 #include "app.h"
+#include "pipeline_acl.h"
 
 static struct app_params app;
 
 int
 main(int argc, char **argv)
 {
+       struct mg_context *ctx = NULL;
        rte_openlog_stream(stderr);
 
        /* Config */
@@ -28,6 +30,12 @@ main(int argc, char **argv)
 
        app_config_args(&app, argc, argv);
 
+       if (is_rest_support()) {
+               /* initialize the rest api */
+               set_vnf_type("VACL");
+               ctx = rest_api_init(&app);
+       }
+
        app_config_preproc(&app);
 
        app_config_parse(&app, app.parser_file);
@@ -40,11 +48,21 @@ main(int argc, char **argv)
        /* Init */
        app_init(&app);
 
+       if (is_rest_support() && (ctx != NULL)) {
+               /* rest api's for cgnapt */
+               rest_api_acl_init(ctx, &app);
+       }
+
        /* Run-time */
        rte_eal_mp_remote_launch(
                app_thread,
                (void *) &app,
                CALL_MASTER);
 
+       if (is_rest_support() && (ctx != NULL)) {
+               mg_stop(ctx);
+               printf("Civet server stopped.\n");
+       }
+
        return 0;
 }
index 1a4ed4f..f193562 100644 (file)
 #include "pipeline_acl_be.h"
 #include "rte_cnxn_tracking.h"
 
+int acl_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int acl_clear_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int acl_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+uint32_t rules_loaded = 0;
+extern struct cmdline *pipe_cl;
+struct app_params *myapp;
+
 /**
  * A structure defining the ACL rule for the TAILQ Tables.
  */
@@ -4176,3 +4183,293 @@ struct pipeline_type pipeline_acl = {
        .be_ops = &pipeline_acl_be_ops,
        .fe_ops = &pipeline_acl_fe_ops,
 };
+
+void all_acl_stats(struct mg_connection *conn)
+{
+
+       struct app_params *app = myapp;
+       int i, j;
+       struct rte_ACL_counter_block acl_counter_sums;
+       struct rte_CT_counter_block ct_counter_sums;
+       struct rte_CT_counter_block *ct_counters;
+       struct action_counter_block action_counter_sum[action_array_max];
+
+       memset(&acl_counter_sums, 0, sizeof(acl_counter_sums));
+       memset(&ct_counter_sums, 0, sizeof(ct_counter_sums));
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+       mg_printf(conn, "ACL Stats\n");
+       for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
+               struct rte_ACL_counter_block *acl_ctrs =
+                   &rte_acl_counter_table[i];
+               ct_counters = rte_acl_counter_table[i].ct_counters;
+               mg_printf(conn, "acl entry[%i] tpkts_processed: %" PRIu64
+                      ", pkts_drop: %" PRIu64 ", pkts_received: %" PRIu64
+                      ", bytes_processed: %" PRIu64 "\n", i,
+                      acl_ctrs->tpkts_processed, acl_ctrs->pkts_drop,
+                      acl_ctrs->pkts_received, acl_ctrs->bytes_processed);
+
+               acl_counter_sums.tpkts_processed += acl_ctrs->tpkts_processed;
+               acl_counter_sums.bytes_processed += acl_ctrs->bytes_processed;
+               acl_counter_sums.pkts_drop += acl_ctrs->pkts_drop;
+               acl_counter_sums.pkts_received += acl_ctrs->pkts_received;
+               ct_counter_sums.pkts_forwarded += ct_counters->pkts_forwarded;
+               ct_counter_sums.pkts_drop += ct_counters->pkts_drop;
+       }
+
+       mg_printf(conn, "ACL TOTAL: tpkts_processed: %" PRIu64 ", pkts_drop: %" PRIu64
+              ", pkts_received: %" PRIu64 ", bytes_processed: %" PRIu64 "\n\n",
+              acl_counter_sums.tpkts_processed,
+              acl_counter_sums.pkts_drop,
+              acl_counter_sums.pkts_received,
+              acl_counter_sums.bytes_processed);
+
+       mg_printf(conn, "CT TOTAL: ct_packets_forwarded: %" PRIu64
+              ", ct_packets_dropped: %" PRIu64 "\n\n",
+              ct_counter_sums.pkts_forwarded, ct_counter_sums.pkts_drop);
+
+       for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
+               for (j = 0; j < action_array_max; j++) {
+                       if (action_array_active[j].action_bitmap &
+                           acl_action_count) {
+                               action_counter_sum[j].packetCount +=
+                                   action_counter_table[i][j].packetCount;
+                               action_counter_sum[j].byteCount +=
+                                   action_counter_table[i][j].byteCount;
+                       }
+               }
+       }
+
+       for (j = 0; j < action_array_max; j++) {
+               if (action_array_active[j].action_bitmap & acl_action_count)
+                       mg_printf(conn, "Action ID: %02u, packetCount: %" PRIu64
+                              ", byteCount: %" PRIu64 "\n", j,
+                              action_counter_sum[j].packetCount,
+                              action_counter_sum[j].byteCount);
+       }
+        mg_printf(conn, "<p>Command Passed</p>");
+        mg_printf(conn, "</body></html>\n");
+}
+
+int acl_stats_handler(struct mg_connection *conn, void *cbdata)
+{
+        uint32_t num_links = 0, len = 0;
+        char buf[1024];
+        const struct mg_request_info *ri = mg_get_request_info(conn);
+        struct app_params *app = myapp;
+        int i;
+
+        if (!strcmp(ri->request_method, "GET")) {
+                all_acl_stats(conn);
+                mg_printf(conn, "%s\n", &buf[0]);
+                return 1;
+        }
+
+        if (strcmp(ri->request_method, "POST")) {
+                mg_printf(conn,
+                    "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the GET handler\n",
+                          ri->request_method);
+        }
+
+        for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
+                rte_acl_counter_table[i].tpkts_processed = 0;
+                rte_acl_counter_table[i].bytes_processed = 0;
+                rte_acl_counter_table[i].pkts_drop = 0;
+                rte_acl_counter_table[i].pkts_received = 0;
+                rte_acl_counter_table[i].pkts_drop_ttl = 0;
+                rte_acl_counter_table[i].pkts_drop_bad_size = 0;
+                rte_acl_counter_table[i].pkts_drop_fragmented = 0;
+                rte_acl_counter_table[i].pkts_drop_without_arp_entry = 0;
+                rte_acl_counter_table[i].ct_counters->pkts_forwarded = 0;
+                rte_acl_counter_table[i].ct_counters->pkts_drop = 0;
+        }
+
+        memset(&action_counter_table, 0, sizeof(action_counter_table));
+
+        mg_printf(conn, "%s\n", &buf[0]);
+        return 1;
+
+}
+
+int acl_version_handler(struct mg_connection *conn, void *cbdata)
+{
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        mg_printf(conn, "<p>Command Passed</p>");
+        mg_printf(conn, "</body></html>\n");
+
+        return 1;
+}
+
+int acl_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+
+       const struct mg_request_info *req_info = mg_get_request_info(conn);
+       if (strcmp(req_info->request_method, "GET")) {
+                       mg_printf(conn, "Only GET method allowed");
+                       return 1;
+       }
+
+       mg_printf(conn,
+                "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                "close\r\n\r\n");
+       mg_printf(conn, "<html><body>");
+       mg_printf(conn, "<h2> These are the methods that are supported </h2>");
+       mg_printf(conn, "<h3>     /load  </h3>");
+       mg_printf(conn, "<h3>     /clear </h3>");
+       mg_printf(conn, "<html><body>");
+
+       mg_printf(conn, "</body></html>\n");
+
+       return 1;
+}
+
+static int acl_field_found(const char *key,
+                       const char *filename,
+                       char *path,
+                       size_t pathlen,
+                       void *user_data)
+{
+       struct mg_connection *conn = (struct mg_connection *)user_data;
+
+       mg_printf(conn, "\r\n\r\n%s:\r\n", key);
+       mg_printf(conn, "Inside vfw_field_found %s \n", filename);
+
+       if (filename && *filename) {
+               snprintf(path, pathlen, "/tmp/%s", filename);
+               struct app_params *app = myapp;
+               int status;
+               int fd;
+
+               mg_printf(conn, "path: %s\n", path);
+
+               /* Make sure the file exists before clearing rules and actions */
+               fd = open(path, O_RDONLY);
+               if (fd < 0) {
+                       mg_printf(conn, "Cannot open file \"%s\"\n", filename);
+                       return FORM_FIELD_STORAGE_GET;
+               }
+               close(fd);
+
+               return FORM_FIELD_STORAGE_STORE;
+       }
+
+       return FORM_FIELD_STORAGE_GET;
+}
+
+static int acl_field_get(const char *key, const char *value, size_t valuelen,
+                void *user_data)
+{
+       struct mg_connection *conn = (struct mg_connection *)user_data;
+
+       if (key[0]) {
+               mg_printf(conn, "%s = ", key);
+       }
+       mg_write(conn, value, valuelen);
+
+       return 0;
+}
+
+static int acl_field_stored(const char *path, long long file_size,
+                void *user_data)
+{
+       struct mg_connection *conn = (struct mg_connection *)user_data;
+       int status;
+
+       mg_printf(conn,
+                 "stored as %s (%lu bytes)\r\n\r\n",
+                 path,
+                 (unsigned long)file_size);
+
+       /* Clear all rules and actions */
+       status = app_pipeline_acl_clearrules(myapp);
+
+       if (status != 0) {
+               mg_printf(conn, "Command failed\n");
+               return 1;
+       }
+
+       /* Process commands in script file */
+       app_loadrules_file(pipe_cl->ctx, path);
+       rules_loaded = 1;
+
+       return 0;
+}
+
+int acl_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+               /* Handler may access the request info using mg_get_request_info */
+               int ret;
+               const struct mg_request_info *req_info = mg_get_request_info(conn);
+               struct mg_form_data_handler fdh = {acl_field_found, acl_field_get,
+                                                                                                acl_field_stored, 0};
+
+               /* It would be possible to check the request info here before calling
+                * mg_handle_form_request. */
+               (void)req_info;
+
+               mg_printf(conn,
+                                 "HTTP/1.1 200 OK\r\nContent-Type: "
+                                 "text/plain\r\nConnection: close\r\n\r\n");
+
+               if (!strcmp(req_info->request_method, "GET")) {
+                               mg_printf(conn, "Rule file is %s\n", rules_loaded? "LOADED":"NOT LOADED");
+               }
+
+               if (strcmp(req_info->request_method, "PUT")) {
+                               mg_printf(conn, "Only PUT method allowed");
+                               return 1;
+               }
+
+               fdh.user_data = (void *)conn;
+
+               /* Call the form handler */
+               mg_printf(conn, "Form data:");
+               ret = mg_handle_form_request(conn, &fdh);
+               mg_printf(conn, "\r\n%i fields found", ret);
+
+               return 1;
+}
+
+int acl_clear_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+       struct app_params *app = myapp;
+       int status;
+       mg_printf(conn,
+               "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+               "close\r\n\r\n");
+       mg_printf(conn, "<html><body>");
+       status = app_pipeline_acl_clearrules(app);
+
+       if (status != 0) {
+               mg_printf(conn, "Command failed\n");
+               return 1;
+       }
+
+       mg_printf(conn, "Command Success\n");
+       mg_printf(conn, "</body></html>\n");
+       return 1;
+}
+
+void rest_api_acl_init(struct mg_context *ctx, struct app_params *app)
+{
+        myapp = app;
+
+        /* vCGNAPT commands */
+        mg_set_request_handler(ctx, "/vnf/config/rules", acl_rules_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/config/rules/load", acl_load_rules_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/config/rules/clear", acl_clear_rules_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/status", acl_version_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/stats", acl_stats_handler, 0);
+
+}
index 80a85ca..93b92c4 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "pipeline.h"
 #include "pipeline_acl_be.h"
+#include <civetweb.h>
+#include <json/json.h>
 
 /* ACL IPV4 and IPV6 enable flags for debugging (Default both on) */
 extern int acl_ipv4_enabled;
@@ -47,6 +49,8 @@ extern void *acl_rule_table_ipv6_standby;
 #define acl_delete_command     1
 #define IPV6_32BIT_LENGTH      4
 
+void rest_api_acl_init(struct mg_context *ctx, struct app_params *app);
+
 /**
  * Add ACL rule to the ACL rule table.
  * Rules are added standby table.
index b6e6076..d3fa051 100644 (file)
@@ -47,6 +47,8 @@
 #include "pipeline_actions_common.h"
 #include "lib_arp.h"
 #include "lib_icmpv6.h"
+#include "gateway.h"
+
 static uint8_t acl_prv_que_port_index[PIPELINE_MAX_PORT_IN];
 extern void convert_prefixlen_to_netmask_ipv6(uint32_t depth,
                                               uint8_t netmask_ipv6[]);
@@ -83,14 +85,6 @@ struct pipeline_acl {
        struct acl_table_entry *acl_entries_ipv4[RTE_PORT_IN_BURST_SIZE_MAX];
        struct acl_table_entry *acl_entries_ipv6[RTE_PORT_IN_BURST_SIZE_MAX];
 
-       /* Local ARP & ND Tables */
-       struct lib_arp_route_table_entry
-        local_lib_arp_route_table[MAX_ARP_RT_ENTRY];
-       uint8_t local_lib_arp_route_ent_cnt;
-       struct lib_nd_route_table_entry
-        local_lib_nd_route_table[MAX_ND_RT_ENTRY];
-       uint8_t local_lib_nd_route_ent_cnt;
-
 } __rte_cache_aligned;
 
 /**
@@ -147,74 +141,6 @@ static pipeline_msg_req_handler custom_handlers[] = {
 uint64_t arp_pkts_mask;
 
 uint8_t ACL_DEBUG;
-uint32_t local_get_nh_ipv4(uint32_t ip,
-                          uint32_t *port,
-                          uint32_t *nhip, struct pipeline_acl *p_acl)
-{
-       int i;
-
-       for (i = 0; i < p_acl->local_lib_arp_route_ent_cnt; i++) {
-               if (((p_acl->local_lib_arp_route_table[i].ip &
-                       p_acl->local_lib_arp_route_table[i].mask) ==
-                       (ip & p_acl->local_lib_arp_route_table[i].mask))) {
-                       *port = p_acl->local_lib_arp_route_table[i].port;
-
-                       *nhip = p_acl->local_lib_arp_route_table[i].nh;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static uint32_t local_get_nh_ipv6(uint8_t *ip,
-                                 uint32_t *port,
-                                 uint8_t nhip[], struct pipeline_acl *p_acl)
-{
-       int i = 0;
-        uint8_t netmask_ipv6[16],netip_nd[16],netip_in[16];
-        uint8_t 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 < p_acl->local_lib_nd_route_ent_cnt; i++) {
-
-                convert_prefixlen_to_netmask_ipv6
-                    (p_acl->local_lib_nd_route_table[i].depth, netmask_ipv6);
-
-                for (k = 0; k < 16; k++)
-                        if (p_acl->local_lib_nd_route_table[i].ipv6[k] &
-                            netmask_ipv6[k]) {
-                                depthflags++;
-                                netip_nd[k] = p_acl->
-                                local_lib_nd_route_table[i].ipv6[k];
-                        }
-
-
-                for (l = 0; l < 16; l++)
-                        if (ip[l] & netmask_ipv6[l]) {
-                                depthflags1++;
-                                netip_in[l] = ip[l];
-                        }
-
-                int j = 0;
-
-                if ((depthflags == depthflags1) && (memcmp(netip_nd, netip_in,
-                                                        sizeof(netip_nd)) == 0)){
-                        *port = p_acl->local_lib_nd_route_table[i].port;
-
-                        for (j = 0; j < 16; j++)
-                                nhip[j] =
-                                    p_acl->local_lib_nd_route_table[i].
-                                    nhipv6[j];
-                        return 1;
-                }
-
-                depthflags = 0;
-                depthflags1 = 0;
-        }
-        return 0;
-}
 
 static uint8_t check_arp_icmp(struct rte_mbuf *pkt,
                              uint64_t pkt_mask, struct pipeline_acl *p_acl)
@@ -396,675 +322,689 @@ void print_pkt_acl(struct rte_mbuf *pkt)
  */
 static int
 pkt_work_acl_key(struct rte_pipeline *p,
-                struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
+        struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
 {
 
-       struct pipeline_acl *p_acl = arg;
-
-       p_acl->counters->pkts_received =
-           p_acl->counters->pkts_received + n_pkts;
-       if (ACL_DEBUG)
-               printf("pkt_work_acl_key pkts_received: %" PRIu64
-                      " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
-
-       uint64_t lookup_hit_mask = 0;
-       uint64_t lookup_hit_mask_ipv4 = 0;
-       uint64_t lookup_hit_mask_ipv6 = 0;
-       uint64_t lookup_miss_mask = 0;
-       uint64_t conntrack_mask = 0;
-       uint64_t connexist_mask = 0;
-       uint32_t dest_address = 0;
-       arp_pkts_mask = 0;
-       int dest_if = 0;
-       int status;
-       uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
-       uint64_t keep_mask = pkts_mask;
-       uint16_t port;
-       uint32_t ret;
-
-       p_acl->in_port_time_stamp = rte_get_tsc_cycles();
-
-       if (acl_ipv4_enabled) {
-               if (ACL_DEBUG)
-                       printf("ACL IPV4 Lookup Mask Before = %p\n",
-                              (void *)pkts_mask);
-               status =
-                   rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
-                                              pkts_mask, &lookup_hit_mask_ipv4,
-                                              (void **)
-                                              p_acl->acl_entries_ipv4);
-               if (ACL_DEBUG)
-                       printf("ACL IPV4 Lookup Mask After = %p\n",
-                              (void *)lookup_hit_mask_ipv4);
-       }
-
-       if (acl_ipv6_enabled) {
-               if (ACL_DEBUG)
-                       printf("ACL IPV6 Lookup Mask Before = %p\n",
-                              (void *)pkts_mask);
-               status =
-                   rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
-                                              pkts_mask, &lookup_hit_mask_ipv6,
-                                              (void **)
-                                              p_acl->acl_entries_ipv6);
-               if (ACL_DEBUG)
-                       printf("ACL IPV6 Lookup Mask After = %p\n",
-                              (void *)lookup_hit_mask_ipv6);
-       }
-
-       /* Merge lookup results since we process both IPv4 and IPv6 below */
-       lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
-       if (ACL_DEBUG)
-               printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
-
-       lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
-       pkts_mask = lookup_hit_mask;
-       p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
-       if (ACL_DEBUG)
-               printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
-                      p_acl->counters->pkts_drop,
-                      __builtin_popcountll(lookup_miss_mask));
-
-       uint64_t pkts_to_process = lookup_hit_mask;
-               /* bitmap of packets left to process for ARP */
-
-       for (; pkts_to_process;) {
-               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
-               uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-               pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-               struct rte_mbuf *pkt = pkts[pos];
-
-               if (enable_hwlb)
-                       if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
-                               pkts_mask &= ~(1LLU << pos);
-                               continue;
-                       }
-
-               uint8_t hdr_chk =
-                   RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
-               hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-
-               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 action_id = entry->action_id;
-
-                       if (ACL_DEBUG)
-                               printf("action_id = %u\n", action_id);
-
-                       uint32_t dscp_offset =
-                           MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_count) {
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].packetCount++;
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].byteCount +=
-                                   rte_pktmbuf_pkt_len(pkt);
-                               if (ACL_DEBUG)
-                                       printf("Action Count   Packet Count: %"
-                                              PRIu64 "  Byte Count: %" PRIu64
-                                              "\n",
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].packetCount,
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].byteCount);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_drop) {
-
-                               /* 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 (action_array_active[action_id].action_bitmap &
-                           acl_action_fwd) {
-                               phy_port =
-                                   action_array_active[action_id].fwd_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action FWD  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_nat) {
-                               phy_port =
-                                   action_array_active[action_id].nat_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action NAT  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_dscp) {
-
-                               /* Set DSCP priority */
-                               uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
-                                                           dscp_offset);
-                               *dscp =
-                                   action_array_active[action_id].dscp_priority
-                                   << 2;
-                               if (ACL_DEBUG)
-                                       printf
-                                           ("Action DSCP  DSCP Priority: %u\n",
-                                            *dscp);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_accept) {
-                               if (ACL_DEBUG)
-                                       printf("Action Accept\n");
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_conntrack) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack enabled: "
-                                                       "%p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)pkt_mask);
-                               }
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_connexist) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-
-               /* Set connexist bit for this pkt for public -> private */
-               /* Private -> public packet will open the connection */
-                                       if (action_array_active
-                                           [action_id].private_public ==
-                                           acl_public_private)
-                                               connexist_mask |= pkt_mask;
-
-                                       if (ACL_DEBUG)
-                                               printf("ACL Connexist enabled  "
-                               "conntrack: %p  connexist: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)connexist_mask,
-                                                    (void *)pkt_mask);
-                               }
-                       }
-               }
-
-               if (hdr_chk == IPv6_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv6[pos];
-                       uint16_t phy_port = entry->head.port_id;
-                       uint32_t action_id = entry->action_id;
-
-                       if (ACL_DEBUG)
-                               printf("action_id = %u\n", action_id);
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_count) {
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].packetCount++;
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].byteCount +=
-                                   rte_pktmbuf_pkt_len(pkt);
-                               if (ACL_DEBUG)
-                                       printf("Action Count   Packet Count: %"
-                                              PRIu64 "  Byte Count: %" PRIu64
-                                              "\n",
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].packetCount,
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].byteCount);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_drop) {
-                               /* 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 (action_array_active[action_id].action_bitmap &
-                           acl_action_fwd) {
-                               phy_port =
-                                   action_array_active[action_id].fwd_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action FWD  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_nat) {
-                               phy_port =
-                                   action_array_active[action_id].nat_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action NAT  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_dscp) {
-
-                               /* Set DSCP priority */
-                               uint32_t dscp_offset =
-                                   MBUF_HDR_ROOM + ETH_HDR_SIZE +
-                                   IP_HDR_DSCP_OFST_IPV6;
-                               uint16_t *dscp =
-                                   RTE_MBUF_METADATA_UINT16_PTR(pkt,
-                                                                dscp_offset);
-                               uint16_t dscp_value =
-                                   (rte_bswap16
-                                    (RTE_MBUF_METADATA_UINT16
-                                     (pkt, dscp_offset)) & 0XF00F);
-                               uint8_t dscp_store =
-                                   action_array_active[action_id].dscp_priority
-                                   << 2;
-                               uint16_t dscp_temp = dscp_store;
-
-                               dscp_temp = dscp_temp << 4;
-                               *dscp = rte_bswap16(dscp_temp | dscp_value);
-                               if (ACL_DEBUG)
-                                       printf
-                                           ("Action DSCP  DSCP Priority: %u\n",
-                                            *dscp);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_accept) {
-                               if (ACL_DEBUG)
-                                       printf("Action Accept\n");
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_conntrack) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack enabled: "
-                                                       " %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)pkt_mask);
-                               }
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_connexist) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-
-               /* Set connexist bit for this pkt for public -> private */
-               /* Private -> public packet will open the connection */
-                                       if (action_array_active
-                                           [action_id].private_public ==
-                                           acl_public_private)
-                                               connexist_mask |= pkt_mask;
-
-                                       if (ACL_DEBUG)
-                                               printf("ACL Connexist enabled  "
-                               "conntrack: %p  connexist: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)connexist_mask,
-                                                    (void *)pkt_mask);
-                               }
-                       }
-               }
-       }
-
-       /* Only call connection tracker if required */
-       if (conntrack_mask > 0) {
-               if (ACL_DEBUG)
-                       printf
-                           ("ACL Call Conntrack Before = %p  Connexist = %p\n",
-                            (void *)conntrack_mask, (void *)connexist_mask);
-               conntrack_mask =
-                   rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
-                   (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
-               if (ACL_DEBUG)
-                       printf("ACL Call Conntrack After = %p\n",
-                              (void *)conntrack_mask);
-
-               /* Only change pkt mask for pkts that have conntrack enabled */
-               /* Need to loop through packets to check if conntrack enabled */
-               pkts_to_process = pkts_mask;
-               for (; pkts_to_process;) {
-                       uint32_t action_id = 0;
-                       uint8_t pos =
-                           (uint8_t) __builtin_ctzll(pkts_to_process);
-                       uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-                       pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-                       struct rte_mbuf *pkt = pkts[pos];
-
-                       uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
-                                                                 MBUF_HDR_ROOM
-                                                                 +
-                                                                 ETH_HDR_SIZE);
-
-                       hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-                       if (hdr_chk == IPv4_HDR_VERSION) {
-                               struct acl_table_entry *entry =
-                                   (struct acl_table_entry *)
-                                   p_acl->acl_entries_ipv4[pos];
-                               action_id = entry->action_id;
-                       } else {
-                               struct acl_table_entry *entry =
-                                   (struct acl_table_entry *)
-                                   p_acl->acl_entries_ipv6[pos];
-                               action_id = entry->action_id;
-                       }
-
-                       if ((action_array_active[action_id].action_bitmap &
-                            acl_action_conntrack)
-                           || (action_array_active[action_id].action_bitmap &
-                               acl_action_connexist)) {
-
-                               if (conntrack_mask & pkt_mask) {
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack Accept  "
-                                                               "packet = %p\n",
-                                                    (void *)pkt_mask);
-                               } else {
-                                       /* Drop packet by changing the mask */
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack Drop  "
-                                                               "packet = %p\n",
-                                                    (void *)pkt_mask);
-                                       pkts_mask &= ~pkt_mask;
-                                       p_acl->counters->pkts_drop++;
-                               }
-                       }
-               }
-       }
-
-       pkts_to_process = pkts_mask;
-               /* bitmap of packets left to process for ARP */
-
-       for (; pkts_to_process;) {
-               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
-               uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-               pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-               struct rte_mbuf *pkt = pkts[pos];
-
-               uint8_t hdr_chk =
-                   RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
-               hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-
-               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 = pkt->port;
-                       uint32_t *port_out_id =
-                           RTE_MBUF_METADATA_UINT32_PTR(pkt,
-                                                        META_DATA_OFFSET +
-                                                        offsetof(struct
-                                                         mbuf_acl_meta_data,
-                                                                 output_port));
-                       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;
-                       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);
-                               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,
-                                       (struct ether_addr *)eth_dest, *port_out_id);
-
-                               }
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
-                       } else {
-                               if (unlikely(ret_arp_data == NULL)) {
-                                       if (ACL_DEBUG)
-                                       printf("%s: NHIP Not Found, "
-                                       "outport_id: %d\n", __func__,
-                                       *port_out_id);
-
-                                       /* Drop the pkt */
-                                       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;
-                               }
+    struct pipeline_acl *p_acl = arg;
+
+    p_acl->counters->pkts_received =
+        p_acl->counters->pkts_received + n_pkts;
+    if (ACL_DEBUG)
+        printf("pkt_work_acl_key pkts_received: %" PRIu64
+                " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
+
+    uint64_t lookup_hit_mask = 0;
+    uint64_t lookup_hit_mask_ipv4 = 0;
+    uint64_t lookup_hit_mask_ipv6 = 0;
+    uint64_t lookup_miss_mask = 0;
+    uint64_t conntrack_mask = 0;
+    uint64_t connexist_mask = 0;
+    uint32_t dest_address = 0;
+    arp_pkts_mask = 0;
+    int status;
+    uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
+    uint64_t keep_mask = pkts_mask;
+    uint16_t port;
+    uint32_t ret;
+
+    p_acl->in_port_time_stamp = rte_get_tsc_cycles();
+
+    if (acl_ipv4_enabled) {
+        if (ACL_DEBUG)
+            printf("ACL IPV4 Lookup Mask Before = %p\n",
+                    (void *)pkts_mask);
+        status =
+            rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
+                    pkts_mask, &lookup_hit_mask_ipv4,
+                    (void **)
+                    p_acl->acl_entries_ipv4);
+        if (ACL_DEBUG)
+            printf("ACL IPV4 Lookup Mask After = %p\n",
+                    (void *)lookup_hit_mask_ipv4);
+    }
+
+    if (acl_ipv6_enabled) {
+        if (ACL_DEBUG)
+            printf("ACL IPV6 Lookup Mask Before = %p\n",
+                    (void *)pkts_mask);
+        status =
+            rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
+                    pkts_mask, &lookup_hit_mask_ipv6,
+                    (void **)
+                    p_acl->acl_entries_ipv6);
+        if (ACL_DEBUG)
+            printf("ACL IPV6 Lookup Mask After = %p\n",
+                    (void *)lookup_hit_mask_ipv6);
+    }
+
+    /* Merge lookup results since we process both IPv4 and IPv6 below */
+    lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
+    if (ACL_DEBUG)
+        printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
+
+    lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
+    pkts_mask = lookup_hit_mask;
+    p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
+    if (ACL_DEBUG)
+        printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
+                p_acl->counters->pkts_drop,
+                __builtin_popcountll(lookup_miss_mask));
+
+    uint64_t pkts_to_process = lookup_hit_mask;
+    /* bitmap of packets left to process for ARP */
+
+    for (; pkts_to_process;) {
+        uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
+        uint64_t pkt_mask = 1LLU << pos;
+        /* bitmask representing only this packet */
+
+        pkts_to_process &= ~pkt_mask;
+        /* remove this packet from remaining list */
+        struct rte_mbuf *pkt = pkts[pos];
+
+        if (enable_hwlb)
+            if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
+                pkts_mask &= ~(1LLU << pos);
+                continue;
+            }
+
+        uint8_t hdr_chk =
+            RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
+        hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+
+        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 action_id = entry->action_id;
+
+            if (ACL_DEBUG)
+                printf("action_id = %u\n", action_id);
+
+            uint32_t dscp_offset =
+                MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_count) {
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].packetCount++;
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].byteCount +=
+                        rte_pktmbuf_pkt_len(pkt);
+                if (ACL_DEBUG)
+                    printf("Action Count   Packet Count: %"
+                            PRIu64 "  Byte Count: %" PRIu64
+                            "\n",
+                            action_counter_table
+                            [p_acl->action_counter_index]
+                            [action_id].packetCount,
+                            action_counter_table
+                            [p_acl->action_counter_index]
+                            [action_id].byteCount);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_packet_drop) {
+
+                /* 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 (action_array_active[action_id].action_bitmap &
+                    acl_action_fwd) {
+                phy_port =
+                    action_array_active[action_id].fwd_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action FWD  Port ID: %u\n",
+                            phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_nat) {
+                phy_port =
+                    action_array_active[action_id].nat_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action NAT  Port ID: %u\n",
+                            phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_dscp) {
+
+                /* Set DSCP priority */
+                uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
+                        dscp_offset);
+                *dscp =
+                    action_array_active[action_id].dscp_priority
+                    << 2;
+                if (ACL_DEBUG)
+                    printf
+                        ("Action DSCP  DSCP Priority: %u\n",
+                         *dscp);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_packet_accept) {
+                if (ACL_DEBUG)
+                    printf("Action Accept\n");
+
+                if (action_array_active[action_id].action_bitmap
+                        & acl_action_conntrack) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack enabled: "
+                                "%p  pkt_mask: %p\n",
+                                (void *)conntrack_mask,
+                                (void *)pkt_mask);
+                }
 
-                               if (ret_arp_data->status == INCOMPLETE ||
-                                       ret_arp_data->status == PROBE) {
-                                       if (ret_arp_data->num_pkts >= NUM_DESC) {
-                                               /* Drop the pkt */
-                                               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;
-                                               arp_queue_unresolved_packet(ret_arp_data,
-                                                                        pkt);
-                                               continue;
-                                       }
-                               }
-                       }
+                if (action_array_active[action_id].action_bitmap
+                        & acl_action_connexist) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+
+                    /* Set connexist bit for this pkt for public -> private */
+                    /* Private -> public packet will open the connection */
+                    if (action_array_active
+                            [action_id].private_public ==
+                            acl_public_private)
+                        connexist_mask |= pkt_mask;
+
+                    if (ACL_DEBUG)
+                        printf("ACL Connexist enabled  "
+                                "conntrack: %p  connexist: %p  pkt_mask: %p\n",
+                                (void *)conntrack_mask,
+                                (void *)connexist_mask,
+                                (void *)pkt_mask);
+                }
+            }
+        }
 
-               } /* end of if (hdr_chk == IPv4_HDR_VERSION) */
-
-               if (hdr_chk == IPv6_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv6[pos];
-                       //uint16_t phy_port = entry->head.port_id;
-                       uint16_t phy_port = pkt->port;
-                       uint32_t *port_out_id =
-                           RTE_MBUF_METADATA_UINT32_PTR(pkt,
-                                                        META_DATA_OFFSET +
-                                                        offsetof(struct
-                                                         mbuf_acl_meta_data,
-                                                                 output_port));
-                       /*if (is_phy_port_privte(phy_port))
-                               *port_out_id = ACL_PUB_PORT_ID;
-                       else
-                               *port_out_id = ACL_PRV_PORT_ID;*/
-
-                       /*      *port_out_id = p_acl->links_map[phy_port]; */
-                       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_IPV6;
-                       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;
-                       uint8_t dest_address[16];
-                       uint8_t nhip[16];
-
-                       nhip[0] =
-                       RTE_MBUF_METADATA_UINT8(pkt,
-                                                   META_DATA_OFFSET +
-                                                   offsetof(struct
-                                                            mbuf_acl_meta_data,
-                                                            nhip));
-                       uint8_t *dst_addr[16];
-                       uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
-                       int i = 0;
-
-                       for (i = 0; i < 16; i++) {
-                               dst_addr[i] =
-                                   RTE_MBUF_METADATA_UINT8_PTR(pkt,
-                                                               dst_addr_offset
-                                                               + i);
-                       }
-                       memcpy(dest_address, *dst_addr, sizeof(dest_address));
-                       memset(nhip, 0, sizeof(nhip));
-
-                       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);
-                               }
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
-                       } else {
-                               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;
-                               }
+        if (hdr_chk == IPv6_HDR_VERSION) {
+
+            struct acl_table_entry *entry =
+                (struct acl_table_entry *)
+                p_acl->acl_entries_ipv6[pos];
+            uint16_t phy_port = entry->head.port_id;
+            uint32_t action_id = entry->action_id;
+
+            if (ACL_DEBUG)
+                printf("action_id = %u\n", action_id);
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_count) {
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].packetCount++;
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].byteCount +=
+                        rte_pktmbuf_pkt_len(pkt);
+                if (ACL_DEBUG)
+                    printf("Action Count   Packet Count: %"
+                            PRIu64 "  Byte Count: %" PRIu64
+                            "\n",
+                            action_counter_table
+                            [p_acl->action_counter_index]
+                            [action_id].packetCount,
+                            action_counter_table
+                            [p_acl->action_counter_index]
+                            [action_id].byteCount);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_packet_drop) {
+                /* 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 (action_array_active[action_id].action_bitmap &
+                    acl_action_fwd) {
+                phy_port =
+                    action_array_active[action_id].fwd_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action FWD  Port ID: %u\n",
+                            phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_nat) {
+                phy_port =
+                    action_array_active[action_id].nat_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action NAT  Port ID: %u\n",
+                            phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_dscp) {
+
+                /* Set DSCP priority */
+                uint32_t dscp_offset =
+                    MBUF_HDR_ROOM + ETH_HDR_SIZE +
+                    IP_HDR_DSCP_OFST_IPV6;
+                uint16_t *dscp =
+                    RTE_MBUF_METADATA_UINT16_PTR(pkt,
+                            dscp_offset);
+                uint16_t dscp_value =
+                    (rte_bswap16
+                     (RTE_MBUF_METADATA_UINT16
+                      (pkt, dscp_offset)) & 0XF00F);
+                uint8_t dscp_store =
+                    action_array_active[action_id].dscp_priority
+                    << 2;
+                uint16_t dscp_temp = dscp_store;
+
+                dscp_temp = dscp_temp << 4;
+                *dscp = rte_bswap16(dscp_temp | dscp_value);
+                if (ACL_DEBUG)
+                    printf
+                        ("Action DSCP  DSCP Priority: %u\n",
+                         *dscp);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                    acl_action_packet_accept) {
+                if (ACL_DEBUG)
+                    printf("Action Accept\n");
+
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_conntrack) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack enabled: "
+                                " %p  pkt_mask: %p\n",
+                                (void *)conntrack_mask,
+                                (void *)pkt_mask);
+                }
 
-                               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 (action_array_active[action_id].action_bitmap
+                        & acl_action_connexist) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+
+                    /* Set connexist bit for this pkt for public -> private */
+                    /* Private -> public packet will open the connection */
+                    if (action_array_active
+                            [action_id].private_public ==
+                            acl_public_private)
+                        connexist_mask |= pkt_mask;
+
+                    if (ACL_DEBUG)
+                        printf("ACL Connexist enabled  "
+                                "conntrack: %p  connexist: %p  pkt_mask: %p\n",
+                                (void *)conntrack_mask,
+                                (void *)connexist_mask,
+                                (void *)pkt_mask);
+                }
+            }
+        }
+    }
+
+    /* Only call connection tracker if required */
+    if (conntrack_mask > 0) {
+        if (ACL_DEBUG)
+            printf
+                ("ACL Call Conntrack Before = %p  Connexist = %p\n",
+                 (void *)conntrack_mask, (void *)connexist_mask);
+        conntrack_mask =
+            rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
+            (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
+        if (ACL_DEBUG)
+            printf("ACL Call Conntrack After = %p\n",
+                    (void *)conntrack_mask);
+
+        /* Only change pkt mask for pkts that have conntrack enabled */
+        /* Need to loop through packets to check if conntrack enabled */
+        pkts_to_process = pkts_mask;
+        for (; pkts_to_process;) {
+            uint32_t action_id = 0;
+            uint8_t pos =
+                (uint8_t) __builtin_ctzll(pkts_to_process);
+            uint64_t pkt_mask = 1LLU << pos;
+            /* bitmask representing only this packet */
+
+            pkts_to_process &= ~pkt_mask;
+            /* remove this packet from remaining list */
+            struct rte_mbuf *pkt = pkts[pos];
+
+            uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
+                    MBUF_HDR_ROOM
+                    +
+                    ETH_HDR_SIZE);
+
+            hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+            if (hdr_chk == IPv4_HDR_VERSION) {
+                struct acl_table_entry *entry =
+                    (struct acl_table_entry *)
+                    p_acl->acl_entries_ipv4[pos];
+                action_id = entry->action_id;
+            } else {
+                struct acl_table_entry *entry =
+                    (struct acl_table_entry *)
+                    p_acl->acl_entries_ipv6[pos];
+                action_id = entry->action_id;
+            }
+
+            if ((action_array_active[action_id].action_bitmap &
+                        acl_action_conntrack)
+                || (action_array_active[action_id].action_bitmap &
+                acl_action_connexist)) {
+
+                if (conntrack_mask & pkt_mask) {
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack Accept  "
+                                "packet = %p\n",
+                             (void *)pkt_mask);
+                } else {
+                    /* Drop packet by changing the mask */
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack Drop  "
+                                "packet = %p\n",
+                             (void *)pkt_mask);
+                    pkts_mask &= ~pkt_mask;
+                    p_acl->counters->pkts_drop++;
+                }
+            }
+        }
+    }
+
+    pkts_to_process = pkts_mask;
+    /* bitmap of packets left to process for ARP */
+
+    for (; pkts_to_process;) {
+        uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
+        uint64_t pkt_mask = 1LLU << pos;
+        /* bitmask representing only this packet */
+
+        pkts_to_process &= ~pkt_mask;
+        /* remove this packet from remaining list */
+        struct rte_mbuf *pkt = pkts[pos];
+
+        uint8_t hdr_chk =
+            RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
+        hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+
+        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 = pkt->port;
+            uint32_t *port_out_id =
+                RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                             META_DATA_OFFSET +
+                             offsetof(struct
+                              mbuf_acl_meta_data,
+                                  output_port));
+            if (ACL_DEBUG)
+                printf
+                   ("phy_port = %i, links_map[phy_port] = %i\n",
+                     phy_port, p_acl->links_map[phy_port]);
+            uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
+
+            uint32_t dest_if = INVALID_DESTIF;
+            uint32_t src_phy_port = pkt->port;
+
+            if(is_gateway()){
+
+                /* Gateway Proc Starts */
+                struct ether_hdr *ehdr = (struct ether_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                            META_DATA_OFFSET + MBUF_HDR_ROOM);
+
+                struct ipv4_hdr *ipv4hdr = (struct ipv4_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
+
+                struct arp_entry_data *ret_arp_data = NULL;
+                struct ether_addr dst_mac;
+                uint32_t nhip = 0;
+                uint32_t dst_ip_addr = rte_bswap32(ipv4hdr->dst_addr);
+
+                gw_get_nh_port_ipv4(dst_ip_addr, &dest_if, &nhip);
+
+                ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if, &dst_mac);
+
+                /* Gateway Proc Ends */
+                if (arp_cache_dest_mac_present(dest_if)) {
+
+                    ether_addr_copy(&dst_mac, &ehdr->d_addr);
+                    ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+
+                    *port_out_id = p_acl->port_out_id[dest_if];
+
+                    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,
+                                p_acl->port_out_id[dest_if]);
+
+                    }
+                    p_acl->counters->tpkts_processed++;
+                    p_acl->counters->bytes_processed +=
+                        packet_length;
+                } else {
+                    if (unlikely(ret_arp_data == NULL)) {
+                        if (ACL_DEBUG)
+                            printf("%s: NHIP Not Found, "
+                                    "outport_id: %d\n", __func__,
+                                    p_acl->port_out_id[dest_if]);
+
+                        /* Drop the pkt */
+                        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;
+                    }
+
+                    if (ret_arp_data->status == INCOMPLETE ||
+                            ret_arp_data->status == PROBE) {
+                        if (ret_arp_data->num_pkts >= NUM_DESC) {
+                            /* Drop the pkt */
+                            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;
+                            arp_queue_unresolved_packet(ret_arp_data,
+                                    pkt);
+                            continue;
+                        }
+                    }
+                 }
+
+              } else {
+                    /* IP Pkt forwarding based on pub/prv mapping */
+                    if(is_phy_port_privte(src_phy_port))
+                        dest_if = prv_to_pub_map[src_phy_port];
+                    else
+                        dest_if = pub_to_prv_map[src_phy_port];
+
+                    *port_out_id = p_acl->port_out_id[dest_if];
+             }
+
+        } /* end of if (hdr_chk == IPv4_HDR_VERSION) */
+
+        if (hdr_chk == IPv6_HDR_VERSION) {
+
+            struct acl_table_entry *entry =
+                (struct acl_table_entry *)
+                p_acl->acl_entries_ipv6[pos];
+            //uint16_t phy_port = entry->head.port_id;
+            uint16_t phy_port = pkt->port;
+            uint32_t *port_out_id =
+                RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                        META_DATA_OFFSET +
+                        offsetof(struct
+                            mbuf_acl_meta_data,
+                            output_port));
+            if (ACL_DEBUG)
+                printf("phy_port = %i,  "
+                        "links_map[phy_port] = %i\n",
+                        phy_port, p_acl->links_map[phy_port]);
+
+            uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
+
+            uint32_t dest_if = INVALID_DESTIF;
+            uint32_t src_phy_port = pkt->port;
+
+            if(is_gateway()){
+
+                /* Gateway Proc Starts */
+                struct ipv6_hdr *ipv6hdr = (struct ipv6_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
+
+                struct ether_hdr *ehdr = (struct ether_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                            META_DATA_OFFSET + MBUF_HDR_ROOM);
+
+                struct ether_addr dst_mac;
+                uint8_t nhipv6[IPV6_ADD_SIZE];
+                uint8_t dest_ipv6_address[IPV6_ADD_SIZE];
+                struct nd_entry_data *ret_nd_data = NULL;
+
+                memset(nhipv6, 0, IPV6_ADD_SIZE);
+                rte_mov16(dest_ipv6_address,  (uint8_t *)ipv6hdr->dst_addr);
+
+                gw_get_nh_port_ipv6(dest_ipv6_address,
+                        &dest_if, nhipv6);
+
+                ret_nd_data = get_dest_mac_addr_ipv6(nhipv6, dest_if, &dst_mac);
+
+                /* Gateway Proc Ends */
+
+                if (nd_cache_dest_mac_present(dest_if)) {
+
+                    ether_addr_copy(&dst_mac, &ehdr->d_addr);
+                    ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+
+                    *port_out_id = p_acl->port_out_id[dest_if];
+
+                    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, &ehdr->d_addr,
+                                p_acl->port_out_id[dest_if]);
+                    }
+                    p_acl->counters->tpkts_processed++;
+                    p_acl->counters->bytes_processed +=
+                        packet_length;
+                } else {
+                    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;
+                    }
+
+                    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;
+                        }
+                    }
+                }
 
-                       }
+            } else {
+                /* IP Pkt forwarding based on  pub/prv mapping */
+                if(is_phy_port_privte(src_phy_port))
+                    dest_if = prv_to_pub_map[src_phy_port];
+                else
+                    dest_if = pub_to_prv_map[src_phy_port];
 
-               } /* if (hdr_chk == IPv6_HDR_VERSION) */
+                *port_out_id = p_acl->port_out_id[dest_if];
+            }
+        }
 
-       }
+    } /* if (hdr_chk == IPv6_HDR_VERSION) */
 
-       pkts_drop_mask = keep_mask & ~pkts_mask;
-       rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-       keep_mask = pkts_mask;
+    pkts_drop_mask = keep_mask & ~pkts_mask;
+    rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
+    keep_mask = pkts_mask;
 
-       if (arp_pkts_mask) {
-               keep_mask &= ~(arp_pkts_mask);
-               rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
-       }
+    if (arp_pkts_mask) {
+        keep_mask &= ~(arp_pkts_mask);
+        rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
+    }
 
-       /* don't bother measuring if traffic very low, might skew stats */
-       uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
+    /* don't bother measuring if traffic very low, might skew stats */
+    uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
 
-       if (packets_this_iteration > 1) {
-               uint64_t latency_this_iteration =
-                   rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
+    if (packets_this_iteration > 1) {
+        uint64_t latency_this_iteration =
+            rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
 
-               p_acl->counters->sum_latencies += latency_this_iteration;
-               p_acl->counters->count_latencies++;
-       }
+        p_acl->counters->sum_latencies += latency_this_iteration;
+        p_acl->counters->count_latencies++;
+    }
 
-       if (ACL_DEBUG)
-               printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
-                      (void *)pkts_mask);
+    if (ACL_DEBUG)
+        printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
+               (void *)pkts_mask);
 
-       return 0;
+    return 0;
 }
 
 /**
@@ -1093,674 +1033,559 @@ pkt_work_acl_key(struct rte_pipeline *p,
  */
 static int
 pkt_work_acl_ipv4_key(struct rte_pipeline *p,
-                     struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
+              struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
 {
 
-       struct pipeline_acl *p_acl = arg;
-
-       p_acl->counters->pkts_received =
-           p_acl->counters->pkts_received + n_pkts;
-       if (ACL_DEBUG)
-               printf("pkt_work_acl_key pkts_received: %" PRIu64
-                      " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
-
-       uint64_t lookup_hit_mask = 0;
-       uint64_t lookup_hit_mask_ipv4 = 0;
-       uint64_t lookup_hit_mask_ipv6 = 0;
-       uint64_t lookup_miss_mask = 0;
-       uint64_t conntrack_mask = 0;
-       uint64_t connexist_mask = 0;
-       uint32_t dest_address = 0;
-       arp_pkts_mask = 0;
-       int dest_if = 0;
-       int status;
-       uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
-       uint64_t keep_mask = pkts_mask;
-       uint16_t port;
-       uint32_t ret;
-
-       p_acl->in_port_time_stamp = rte_get_tsc_cycles();
-
-       if (acl_ipv4_enabled) {
-               if (ACL_DEBUG)
-                       printf("ACL IPV4 Lookup Mask Before = %p\n",
-                              (void *)pkts_mask);
-               status =
-                   rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
-                                              pkts_mask, &lookup_hit_mask_ipv4,
-                                              (void **)
-                                              p_acl->acl_entries_ipv4);
-               if (ACL_DEBUG)
-                       printf("ACL IPV4 Lookup Mask After = %p\n",
-                              (void *)lookup_hit_mask_ipv4);
-       }
-
-       /* Merge lookup results since we process both IPv4 and IPv6 below */
-       lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
-       if (ACL_DEBUG)
-               printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
-
-       lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
-       pkts_mask = lookup_hit_mask;
-       p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
-       if (ACL_DEBUG)
-               printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
-                      p_acl->counters->pkts_drop,
-                      __builtin_popcountll(lookup_miss_mask));
-
-       uint64_t pkts_to_process = lookup_hit_mask;
-               /* bitmap of packets left to process for ARP */
-
-       for (; pkts_to_process;) {
-               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
-               uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-               pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-               struct rte_mbuf *pkt = pkts[pos];
-
-               if (enable_hwlb)
-                       if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
-                               pkts_mask &= ~(1LLU << pos);
-                               continue;
-                       }
-
-               uint8_t hdr_chk =
-                   RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
-               hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-
-               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 action_id = entry->action_id;
-
-                       if (ACL_DEBUG)
-                               printf("action_id = %u\n", action_id);
-
-                       uint32_t dscp_offset =
-                           MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_count) {
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].packetCount++;
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].byteCount +=
-                                   rte_pktmbuf_pkt_len(pkt);
-                               if (ACL_DEBUG)
-                                       printf("Action Count   Packet Count: %"
-                                              PRIu64 "  Byte Count: %" PRIu64
-                                              "\n",
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].packetCount,
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].byteCount);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_drop) {
-
-                               /* 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 (action_array_active[action_id].action_bitmap &
-                           acl_action_fwd) {
-                               phy_port =
-                                   action_array_active[action_id].fwd_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action FWD  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_nat) {
-                               phy_port =
-                                   action_array_active[action_id].nat_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action NAT  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_dscp) {
-
-                               /* Set DSCP priority */
-                               uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
-                                                           dscp_offset);
-                               *dscp =
-                                   action_array_active[action_id].dscp_priority
-                                   << 2;
-                               if (ACL_DEBUG)
-                                       printf
-                                           ("Action DSCP  DSCP Priority: %u\n",
-                                            *dscp);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_accept) {
-                               if (ACL_DEBUG)
-                                       printf("Action Accept\n");
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_conntrack) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack  "
-                                               "enabled: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)pkt_mask);
-                               }
+    struct pipeline_acl *p_acl = arg;
+
+    p_acl->counters->pkts_received =
+        p_acl->counters->pkts_received + n_pkts;
+    if (ACL_DEBUG)
+        printf("pkt_work_acl_key pkts_received: %" PRIu64
+               " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
+
+    uint64_t lookup_hit_mask = 0;
+    uint64_t lookup_hit_mask_ipv4 = 0;
+    uint64_t lookup_hit_mask_ipv6 = 0;
+    uint64_t lookup_miss_mask = 0;
+    uint64_t conntrack_mask = 0;
+    uint64_t connexist_mask = 0;
+    uint32_t dest_address = 0;
+    arp_pkts_mask = 0;
+    int status;
+    uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
+    uint64_t keep_mask = pkts_mask;
+    uint16_t port;
+    uint32_t ret;
+
+    p_acl->in_port_time_stamp = rte_get_tsc_cycles();
+
+    if (acl_ipv4_enabled) {
+        if (ACL_DEBUG)
+            printf("ACL IPV4 Lookup Mask Before = %p\n",
+                   (void *)pkts_mask);
+        status =
+            rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
+                           pkts_mask, &lookup_hit_mask_ipv4,
+                           (void **)
+                           p_acl->acl_entries_ipv4);
+        if (ACL_DEBUG)
+            printf("ACL IPV4 Lookup Mask After = %p\n",
+                   (void *)lookup_hit_mask_ipv4);
+    }
+
+    /* Merge lookup results since we process both IPv4 and IPv6 below */
+    lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
+    if (ACL_DEBUG)
+        printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
+
+    lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
+    pkts_mask = lookup_hit_mask;
+    p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
+    if (ACL_DEBUG)
+        printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
+               p_acl->counters->pkts_drop,
+               __builtin_popcountll(lookup_miss_mask));
+
+    uint64_t pkts_to_process = lookup_hit_mask;
+        /* bitmap of packets left to process for ARP */
+
+    for (; pkts_to_process;) {
+        uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
+        uint64_t pkt_mask = 1LLU << pos;
+        /* bitmask representing only this packet */
+
+        pkts_to_process &= ~pkt_mask;
+        /* remove this packet from remaining list */
+        struct rte_mbuf *pkt = pkts[pos];
+
+        if (enable_hwlb)
+            if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
+                pkts_mask &= ~(1LLU << pos);
+                continue;
+            }
+
+        uint8_t hdr_chk =
+            RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
+        hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+
+        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 action_id = entry->action_id;
+
+            if (ACL_DEBUG)
+                printf("action_id = %u\n", action_id);
+
+            uint32_t dscp_offset =
+                MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_count) {
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].packetCount++;
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].byteCount +=
+                    rte_pktmbuf_pkt_len(pkt);
+                if (ACL_DEBUG)
+                    printf("Action Count   Packet Count: %"
+                           PRIu64 "  Byte Count: %" PRIu64
+                           "\n",
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].packetCount,
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].byteCount);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_drop) {
+
+                /* 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 (action_array_active[action_id].action_bitmap &
+                acl_action_fwd) {
+                phy_port =
+                    action_array_active[action_id].fwd_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action FWD  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_nat) {
+                phy_port =
+                    action_array_active[action_id].nat_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action NAT  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_dscp) {
+
+                /* Set DSCP priority */
+                uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
+                                dscp_offset);
+                *dscp =
+                    action_array_active[action_id].dscp_priority
+                    << 2;
+                if (ACL_DEBUG)
+                    printf
+                        ("Action DSCP  DSCP Priority: %u\n",
+                         *dscp);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_accept) {
+                if (ACL_DEBUG)
+                    printf("Action Accept\n");
+
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_conntrack) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack  "
+                        "enabled: %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)pkt_mask);
+                }
 
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_connexist) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-
-               /* Set connexist bit for this pkt for public -> private */
-               /* Private -> public packet will open the connection */
-                                       if (action_array_active
-                                           [action_id].private_public ==
-                                           acl_public_private)
-                                               connexist_mask |= pkt_mask;
-
-                                       if (ACL_DEBUG)
-                                               printf("ACL Connexist  "
-                       "enabled conntrack: %p  connexist: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)connexist_mask,
-                                                    (void *)pkt_mask);
-                               }
-                       }
-               }
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_connexist) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+
+        /* Set connexist bit for this pkt for public -> private */
+        /* Private -> public packet will open the connection */
+                    if (action_array_active
+                        [action_id].private_public ==
+                        acl_public_private)
+                        connexist_mask |= pkt_mask;
+
+                    if (ACL_DEBUG)
+                        printf("ACL Connexist  "
+            "enabled conntrack: %p  connexist: %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)connexist_mask,
+                             (void *)pkt_mask);
+                }
+            }
+        }
 #if 0
-               if (hdr_chk == IPv6_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv6[pos];
-                       uint16_t phy_port = entry->head.port_id;
-                       uint32_t action_id = entry->action_id;
-
-                       if (ACL_DEBUG)
-                               printf("action_id = %u\n", action_id);
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_count) {
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].packetCount++;
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].byteCount +=
-                                   rte_pktmbuf_pkt_len(pkt);
-                               if (ACL_DEBUG)
-                                       printf("Action Count   Packet Count: %"
-                                              PRIu64 "  Byte Count: %" PRIu64
-                                              "\n",
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].packetCount,
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].byteCount);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_drop) {
-                               /* 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 (action_array_active[action_id].action_bitmap &
-                           acl_action_fwd) {
-                               phy_port =
-                                   action_array_active[action_id].fwd_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action FWD  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_nat) {
-                               phy_port =
-                                   action_array_active[action_id].nat_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action NAT  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_dscp) {
-
-                               /* Set DSCP priority */
-                               uint32_t dscp_offset =
-                                   MBUF_HDR_ROOM + ETH_HDR_SIZE +
-                                   IP_HDR_DSCP_OFST_IPV6;
-                               uint16_t *dscp =
-                                   RTE_MBUF_METADATA_UINT16_PTR(pkt,
-                                                                dscp_offset);
-                               uint16_t dscp_value =
-                                   (rte_bswap16
-                                    (RTE_MBUF_METADATA_UINT16
-                                     (pkt, dscp_offset)) & 0XF00F);
-                               uint8_t dscp_store =
-                                   action_array_active[action_id].dscp_priority
-                                   << 2;
-                               uint16_t dscp_temp = dscp_store;
-
-                               dscp_temp = dscp_temp << 4;
-                               *dscp = rte_bswap16(dscp_temp | dscp_value);
-                               if (ACL_DEBUG)
-                                       printf
-                                   ("Action DSCP   DSCP Priority: %u\n",
-                                            *dscp);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_accept) {
-                               if (ACL_DEBUG)
-                                       printf("Action Accept\n");
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_conntrack) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack  "
-                                               "enabled: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)pkt_mask);
-                               }
+        if (hdr_chk == IPv6_HDR_VERSION) {
+
+            struct acl_table_entry *entry =
+                (struct acl_table_entry *)
+                p_acl->acl_entries_ipv6[pos];
+            uint16_t phy_port = entry->head.port_id;
+            uint32_t action_id = entry->action_id;
+
+            if (ACL_DEBUG)
+                printf("action_id = %u\n", action_id);
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_count) {
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].packetCount++;
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].byteCount +=
+                    rte_pktmbuf_pkt_len(pkt);
+                if (ACL_DEBUG)
+                    printf("Action Count   Packet Count: %"
+                           PRIu64 "  Byte Count: %" PRIu64
+                           "\n",
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].packetCount,
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].byteCount);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_drop) {
+                /* 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 (action_array_active[action_id].action_bitmap &
+                acl_action_fwd) {
+                phy_port =
+                    action_array_active[action_id].fwd_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action FWD  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_nat) {
+                phy_port =
+                    action_array_active[action_id].nat_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action NAT  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_dscp) {
+
+                /* Set DSCP priority */
+                uint32_t dscp_offset =
+                    MBUF_HDR_ROOM + ETH_HDR_SIZE +
+                    IP_HDR_DSCP_OFST_IPV6;
+                uint16_t *dscp =
+                    RTE_MBUF_METADATA_UINT16_PTR(pkt,
+                                 dscp_offset);
+                uint16_t dscp_value =
+                    (rte_bswap16
+                     (RTE_MBUF_METADATA_UINT16
+                      (pkt, dscp_offset)) & 0XF00F);
+                uint8_t dscp_store =
+                    action_array_active[action_id].dscp_priority
+                    << 2;
+                uint16_t dscp_temp = dscp_store;
+
+                dscp_temp = dscp_temp << 4;
+                *dscp = rte_bswap16(dscp_temp | dscp_value);
+                if (ACL_DEBUG)
+                    printf
+                    ("Action DSCP   DSCP Priority: %u\n",
+                         *dscp);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_accept) {
+                if (ACL_DEBUG)
+                    printf("Action Accept\n");
+
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_conntrack) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack  "
+                        "enabled: %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)pkt_mask);
+                }
 
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_connexist) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-
-               /* Set connexist bit for this pkt for public -> private */
-               /* Private -> public packet will open the connection */
-                                       if (action_array_active
-                                           [action_id].private_public ==
-                                           acl_public_private)
-                                               connexist_mask |= pkt_mask;
-
-                                       if (ACL_DEBUG)
-                                               printf("ACL Connexist enabled  "
-                               "conntrack: %p  connexist: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)connexist_mask,
-                                                    (void *)pkt_mask);
-                               }
-                       }
-               }
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_connexist) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+
+        /* Set connexist bit for this pkt for public -> private */
+        /* Private -> public packet will open the connection */
+                    if (action_array_active
+                        [action_id].private_public ==
+                        acl_public_private)
+                        connexist_mask |= pkt_mask;
+
+                    if (ACL_DEBUG)
+                        printf("ACL Connexist enabled  "
+                "conntrack: %p  connexist: %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)connexist_mask,
+                             (void *)pkt_mask);
+                }
+            }
+        }
 #endif
-       }
-       /* Only call connection tracker if required */
-       if (conntrack_mask > 0) {
-               if (ACL_DEBUG)
-                       printf
-                           ("ACL Call Conntrack Before = %p  Connexist = %p\n",
-                            (void *)conntrack_mask, (void *)connexist_mask);
-               conntrack_mask =
-                   rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
-                   (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
-               if (ACL_DEBUG)
-                       printf("ACL Call Conntrack After = %p\n",
-                              (void *)conntrack_mask);
-
-               /* Only change pkt mask for pkts that have conntrack enabled */
-               /* Need to loop through packets to check if conntrack enabled */
-               pkts_to_process = pkts_mask;
-               for (; pkts_to_process;) {
-                       uint32_t action_id = 0;
-                       uint8_t pos =
-                           (uint8_t) __builtin_ctzll(pkts_to_process);
-                       uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-                       pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-                       struct rte_mbuf *pkt = pkts[pos];
-
-                       uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
-                                                                 MBUF_HDR_ROOM
-                                                                 +
-                                                                 ETH_HDR_SIZE);
-                       hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-                       if (hdr_chk == IPv4_HDR_VERSION) {
-                               struct acl_table_entry *entry =
-                                   (struct acl_table_entry *)
-                                   p_acl->acl_entries_ipv4[pos];
-                               action_id = entry->action_id;
-                       } else {
-                               struct acl_table_entry *entry =
-                                   (struct acl_table_entry *)
-                                   p_acl->acl_entries_ipv6[pos];
-                               action_id = entry->action_id;
-                       }
-
-                       if ((action_array_active[action_id].action_bitmap &
-                            acl_action_conntrack)
-                           || (action_array_active[action_id].action_bitmap &
-                               acl_action_connexist)) {
-
-                               if (conntrack_mask & pkt_mask) {
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack Accept  "
-                                                               "packet = %p\n",
-                                                    (void *)pkt_mask);
-                               } else {
+    }
+    /* Only call connection tracker if required */
+    if (conntrack_mask > 0) {
+        if (ACL_DEBUG)
+            printf
+                ("ACL Call Conntrack Before = %p  Connexist = %p\n",
+                 (void *)conntrack_mask, (void *)connexist_mask);
+        conntrack_mask =
+            rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
+            (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
+        if (ACL_DEBUG)
+            printf("ACL Call Conntrack After = %p\n",
+                   (void *)conntrack_mask);
+
+        /* Only change pkt mask for pkts that have conntrack enabled */
+        /* Need to loop through packets to check if conntrack enabled */
+        pkts_to_process = pkts_mask;
+        for (; pkts_to_process;) {
+            uint32_t action_id = 0;
+            uint8_t pos =
+                (uint8_t) __builtin_ctzll(pkts_to_process);
+            uint64_t pkt_mask = 1LLU << pos;
+        /* bitmask representing only this packet */
+
+            pkts_to_process &= ~pkt_mask;
+        /* remove this packet from remaining list */
+            struct rte_mbuf *pkt = pkts[pos];
+
+            uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
+                                  MBUF_HDR_ROOM
+                                  +
+                                  ETH_HDR_SIZE);
+            hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+            if (hdr_chk == IPv4_HDR_VERSION) {
+                struct acl_table_entry *entry =
+                    (struct acl_table_entry *)
+                    p_acl->acl_entries_ipv4[pos];
+                action_id = entry->action_id;
+            } else {
+                struct acl_table_entry *entry =
+                    (struct acl_table_entry *)
+                    p_acl->acl_entries_ipv6[pos];
+                action_id = entry->action_id;
+            }
+
+            if ((action_array_active[action_id].action_bitmap &
+                 acl_action_conntrack)
+                || (action_array_active[action_id].action_bitmap &
+                acl_action_connexist)) {
+
+                if (conntrack_mask & pkt_mask) {
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack Accept  "
+                                "packet = %p\n",
+                             (void *)pkt_mask);
+                } else {
 /* Drop packet by changing the mask */
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack Drop  "
-                                                               "packet = %p\n",
-                                                    (void *)pkt_mask);
-                                       pkts_mask &= ~pkt_mask;
-                                       p_acl->counters->pkts_drop++;
-                               }
-                       }
-               }
-       }
-
-       pkts_to_process = pkts_mask;
-       /* bitmap of packets left to process for ARP */
-
-       for (; pkts_to_process;) {
-               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
-               uint64_t pkt_mask = 1LLU << pos;
-       /* bitmask representing only this packet */
-
-               pkts_to_process &= ~pkt_mask;
-       /* remove this packet from remaining list */
-               struct rte_mbuf *pkt = pkts[pos];
-
-               uint8_t hdr_chk =
-                   RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
-               hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-
-               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;
-                       uint16_t phy_port = pkt->port;
-                       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;
-                       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);
-                               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,
-                                       (struct ether_addr *)eth_dest, *port_out_id);
-
-                               }
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
-                       } else {
-                               if (unlikely(ret_arp_data == NULL)) {
-
-                                       if (ACL_DEBUG)
-                                       printf("%s: NHIP Not Found, "
-                                       "outport_id: %d\n", __func__,
-                                       *port_out_id);
-
-                                       /* Drop the pkt */
-                                       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;
-                               }
-
-                               if (ret_arp_data->status == INCOMPLETE ||
-                               ret_arp_data->status == PROBE) {
-                                       if (ret_arp_data->num_pkts >= NUM_DESC) {
-                                               /* Drop the pkt */
-                                               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;
-                                       arp_queue_unresolved_packet(ret_arp_data, pkt);
-                                       continue;
-                                       }
-                               }
-                       }
-               }
-#if 0
-               if (hdr_chk == IPv6_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv6[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));
-                       if (is_phy_port_privte(phy_port))
-                               *port_out_id = ACL_PUB_PORT_ID;
-                       else
-                               *port_out_id = ACL_PRV_PORT_ID;
-
-                       /*  *port_out_id = p_acl->links_map[phy_port]; */
-                       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_IPV6;
-                       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;
-                       uint8_t dest_address[16];
-                       uint8_t nhip[16];
-
-                       nhip[0] =
-                           RTE_MBUF_METADATA_UINT8(pkt,
-                                                   META_DATA_OFFSET +
-                                                   offsetof(struct
-                                                            mbuf_acl_meta_data,
-                                                            nhip));
-                       uint8_t *dst_addr[16];
-                       uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
-                       int i = 0;
-
-                       for (i = 0; i < 16; i++) {
-                               dst_addr[i] =
-                                   RTE_MBUF_METADATA_UINT8_PTR(pkt,
-                                                               dst_addr_offset
-                                                               + i);
-                       }
-                       memcpy(dest_address, *dst_addr, sizeof(dest_address));
-                       memset(nhip, 0, sizeof(nhip));
-                       if (is_phy_port_privte(phy_port))
-                               port = ACL_PUB_PORT_ID;
-                       else
-                               port = ACL_PRV_PORT_ID;
-
-                       if (get_dest_mac_address_ipv6_port
-                           (dest_address, port, &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 (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 {
-
-                               /* 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 (ACL_DEBUG)
+                        printf("ACL Conntrack Drop  "
+                                "packet = %p\n",
+                             (void *)pkt_mask);
+                    pkts_mask &= ~pkt_mask;
+                    p_acl->counters->pkts_drop++;
+                }
+            }
+        }
+    }
+
+    pkts_to_process = pkts_mask;
+    /* bitmap of packets left to process for ARP */
+
+    for (; pkts_to_process;) {
+        uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
+        uint64_t pkt_mask = 1LLU << pos;
+    /* bitmask representing only this packet */
+
+        pkts_to_process &= ~pkt_mask;
+    /* remove this packet from remaining list */
+        struct rte_mbuf *pkt = pkts[pos];
+
+        uint8_t hdr_chk =
+            RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
+        hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+
+        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;
+            uint16_t phy_port = pkt->port;
+            uint32_t *port_out_id =
+                RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                             META_DATA_OFFSET +
+                             offsetof(struct
+                              mbuf_acl_meta_data,
+                                  output_port));
+            if (ACL_DEBUG)
+                printf
+                   ("phy_port = %i, links_map[phy_port] = %i\n",
+                     phy_port, p_acl->links_map[phy_port]);
+
+            uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
+
+            uint32_t dest_if = INVALID_DESTIF;
+            uint32_t src_phy_port = pkt->port;
+
+            if(is_gateway()){
+
+                /* Gateway Proc Starts */
+                struct ether_hdr *ehdr = (struct ether_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                            META_DATA_OFFSET + MBUF_HDR_ROOM);
+
+                struct ipv4_hdr *ipv4hdr = (struct ipv4_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
+
+                struct arp_entry_data *ret_arp_data = NULL;
+                struct ether_addr dst_mac;
+                uint32_t dest_if = INVALID_DESTIF;
+                uint32_t nhip = 0;
+                uint32_t src_phy_port = pkt->port;
+                uint32_t dst_ip_addr = rte_bswap32(ipv4hdr->dst_addr);
+
+                gw_get_nh_port_ipv4(dst_ip_addr, &dest_if, &nhip);
+
+                ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if, &dst_mac);
+
+                /* Gateway Proc Ends */
+                if (arp_cache_dest_mac_present(dest_if)) {
+
+                    ether_addr_copy(&dst_mac, &ehdr->d_addr);
+                    ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+
+                    *port_out_id = p_acl->port_out_id[dest_if];
+
+                    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,
+                                p_acl->port_out_id[dest_if]);
+                    }
+                    p_acl->counters->tpkts_processed++;
+                    p_acl->counters->bytes_processed += packet_length;
+                } else {
+                    if (unlikely(ret_arp_data == NULL)) {
+
+                        if (ACL_DEBUG)
+                            printf("%s: NHIP Not Found, "
+                                    "outport_id: %d\n", __func__,
+                                    p_acl->port_out_id[dest_if]);
+
+                        /* Drop the pkt */
+                        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;
+                    }
+
+                    if (ret_arp_data->status == INCOMPLETE ||
+                            ret_arp_data->status == PROBE) {
+                        if (ret_arp_data->num_pkts >= NUM_DESC) {
+                            /* Drop the pkt */
+                            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;
+                            arp_queue_unresolved_packet(ret_arp_data, pkt);
+                            continue;
+                        }
+                    }
+                }
 
-       pkts_drop_mask = keep_mask & ~pkts_mask;
-       rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-       keep_mask = pkts_mask;
+            } else {
+                /* IP Pkt forwarding based on  pub/prv mapping */
+                if(is_phy_port_privte(src_phy_port))
+                    dest_if = prv_to_pub_map[src_phy_port];
+                else
+                    dest_if = pub_to_prv_map[src_phy_port];
 
-       if (arp_pkts_mask) {
-               keep_mask &= ~(arp_pkts_mask);
-               rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
-       }
+                *port_out_id = p_acl->port_out_id[dest_if];
+            }
 
-       /* don't bother measuring if traffic very low, might skew stats */
-       uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
-
-       if (packets_this_iteration > 1) {
-               uint64_t latency_this_iteration =
-                   rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
-               p_acl->counters->sum_latencies += latency_this_iteration;
-               p_acl->counters->count_latencies++;
-       }
-       if (ACL_DEBUG)
-               printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
-                       (void *)pkts_mask);
+        }
 
-       return 0;
+    }
+    pkts_drop_mask = keep_mask & ~pkts_mask;
+    rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
+    keep_mask = pkts_mask;
+
+    if (arp_pkts_mask) {
+        keep_mask &= ~(arp_pkts_mask);
+        rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
+    }
+
+    /* don't bother measuring if traffic very low, might skew stats */
+    uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
+
+    if (packets_this_iteration > 1) {
+        uint64_t latency_this_iteration =
+            rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
+        p_acl->counters->sum_latencies += latency_this_iteration;
+        p_acl->counters->count_latencies++;
+    }
+    if (ACL_DEBUG)
+        printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
+            (void *)pkts_mask);
+
+    return 0;
 }
 
 /**
@@ -1789,563 +1614,567 @@ pkt_work_acl_ipv4_key(struct rte_pipeline *p,
  */
 static int
 pkt_work_acl_ipv6_key(struct rte_pipeline *p,
-                     struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
+              struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
 {
 
-       struct pipeline_acl *p_acl = arg;
-
-       p_acl->counters->pkts_received =
-           p_acl->counters->pkts_received + n_pkts;
-       if (ACL_DEBUG)
-               printf("pkt_work_acl_key pkts_received: %" PRIu64
-                      " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
-
-       uint64_t lookup_hit_mask = 0;
-       uint64_t lookup_hit_mask_ipv4 = 0;
-       uint64_t lookup_hit_mask_ipv6 = 0;
-       uint64_t lookup_miss_mask = 0;
-       uint64_t conntrack_mask = 0;
-       uint64_t connexist_mask = 0;
-       uint32_t dest_address = 0;
-       arp_pkts_mask = 0;
-       int dest_if = 0;
-       int status;
-       uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
-       uint64_t keep_mask = pkts_mask;
-       uint16_t port;
-       uint32_t ret;
-
-       p_acl->in_port_time_stamp = rte_get_tsc_cycles();
-
-       if (acl_ipv6_enabled) {
-               if (ACL_DEBUG)
-                       printf("ACL IPV6 Lookup Mask Before = %p\n",
-                              (void *)pkts_mask);
-               status =
-                   rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
-                                              pkts_mask, &lookup_hit_mask_ipv6,
-                                              (void **)
-                                              p_acl->acl_entries_ipv6);
-               if (ACL_DEBUG)
-                       printf("ACL IPV6 Lookup Mask After = %p\n",
-                              (void *)lookup_hit_mask_ipv6);
-       }
-
-       /* Merge lookup results since we process both IPv4 and IPv6 below */
-       lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
-       if (ACL_DEBUG)
-               printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
-
-       lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
-       pkts_mask = lookup_hit_mask;
-       p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
-       if (ACL_DEBUG)
-               printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
-                      p_acl->counters->pkts_drop,
-                      __builtin_popcountll(lookup_miss_mask));
-
-       uint64_t pkts_to_process = lookup_hit_mask;
-               /* bitmap of packets left to process for ARP */
-
-       for (; pkts_to_process;) {
-               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
-               uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-               pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-               struct rte_mbuf *pkt = pkts[pos];
-
-               if (enable_hwlb)
-                       if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
-                               pkts_mask &= ~(1LLU << pos);
-                               continue;
-                       }
-               uint8_t hdr_chk =
-                   RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
-               hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+    struct pipeline_acl *p_acl = arg;
+
+    p_acl->counters->pkts_received =
+        p_acl->counters->pkts_received + n_pkts;
+    if (ACL_DEBUG)
+        printf("pkt_work_acl_key pkts_received: %" PRIu64
+               " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
+
+    uint64_t lookup_hit_mask = 0;
+    uint64_t lookup_hit_mask_ipv4 = 0;
+    uint64_t lookup_hit_mask_ipv6 = 0;
+    uint64_t lookup_miss_mask = 0;
+    uint64_t conntrack_mask = 0;
+    uint64_t connexist_mask = 0;
+    uint32_t dest_address = 0;
+    arp_pkts_mask = 0;
+    int status;
+    uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
+    uint64_t keep_mask = pkts_mask;
+    uint16_t port;
+    uint32_t ret;
+
+    p_acl->in_port_time_stamp = rte_get_tsc_cycles();
+
+    if (acl_ipv6_enabled) {
+        if (ACL_DEBUG)
+            printf("ACL IPV6 Lookup Mask Before = %p\n",
+                   (void *)pkts_mask);
+        status =
+            rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
+                           pkts_mask, &lookup_hit_mask_ipv6,
+                           (void **)
+                           p_acl->acl_entries_ipv6);
+        if (ACL_DEBUG)
+            printf("ACL IPV6 Lookup Mask After = %p\n",
+                   (void *)lookup_hit_mask_ipv6);
+    }
+
+    /* Merge lookup results since we process both IPv4 and IPv6 below */
+    lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
+    if (ACL_DEBUG)
+        printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
+
+    lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
+    pkts_mask = lookup_hit_mask;
+    p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
+    if (ACL_DEBUG)
+        printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
+               p_acl->counters->pkts_drop,
+               __builtin_popcountll(lookup_miss_mask));
+
+    uint64_t pkts_to_process = lookup_hit_mask;
+        /* bitmap of packets left to process for ARP */
+
+    for (; pkts_to_process;) {
+        uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
+        uint64_t pkt_mask = 1LLU << pos;
+        /* bitmask representing only this packet */
+
+        pkts_to_process &= ~pkt_mask;
+        /* remove this packet from remaining list */
+        struct rte_mbuf *pkt = pkts[pos];
+
+        if (enable_hwlb)
+            if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
+                pkts_mask &= ~(1LLU << pos);
+                continue;
+            }
+        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 action_id = entry->action_id;
-
-                       if (ACL_DEBUG)
-                               printf("action_id = %u\n", action_id);
-
-                       uint32_t dscp_offset =
-                           MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_count) {
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].packetCount++;
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].byteCount +=
-                                   rte_pktmbuf_pkt_len(pkt);
-                               if (ACL_DEBUG)
-                                       printf("Action Count   Packet Count: %"
-                                              PRIu64 "  Byte Count: %" PRIu64
-                                              "\n",
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].packetCount,
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].byteCount);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_drop) {
-
-                               /* 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 (action_array_active[action_id].action_bitmap &
-                           acl_action_fwd) {
-                               phy_port =
-                                   action_array_active[action_id].fwd_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action FWD  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_nat) {
-                               phy_port =
-                                   action_array_active[action_id].nat_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action NAT  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_dscp) {
-
-                               /* Set DSCP priority */
-                               uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
-                                                           dscp_offset);
-                               *dscp =
-                                   action_array_active[action_id].dscp_priority
-                                   << 2;
-                               if (ACL_DEBUG)
-                                       printf
-                                           ("Action DSCP  DSCP Priority: %u\n",
-                                            *dscp);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_accept) {
-                               if (ACL_DEBUG)
-                                       printf("Action Accept\n");
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_conntrack) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack enabled: "
-                                                       " %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)pkt_mask);
-                               }
+        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 action_id = entry->action_id;
+
+            if (ACL_DEBUG)
+                printf("action_id = %u\n", action_id);
+
+            uint32_t dscp_offset =
+                MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_count) {
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].packetCount++;
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].byteCount +=
+                    rte_pktmbuf_pkt_len(pkt);
+                if (ACL_DEBUG)
+                    printf("Action Count   Packet Count: %"
+                           PRIu64 "  Byte Count: %" PRIu64
+                           "\n",
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].packetCount,
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].byteCount);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_drop) {
+
+                /* 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 (action_array_active[action_id].action_bitmap &
+                acl_action_fwd) {
+                phy_port =
+                    action_array_active[action_id].fwd_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action FWD  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_nat) {
+                phy_port =
+                    action_array_active[action_id].nat_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action NAT  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_dscp) {
+
+                /* Set DSCP priority */
+                uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
+                                dscp_offset);
+                *dscp =
+                    action_array_active[action_id].dscp_priority
+                    << 2;
+                if (ACL_DEBUG)
+                    printf
+                        ("Action DSCP  DSCP Priority: %u\n",
+                         *dscp);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_accept) {
+                if (ACL_DEBUG)
+                    printf("Action Accept\n");
+
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_conntrack) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack enabled: "
+                            " %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)pkt_mask);
+                }
 
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_connexist) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-
-               /* Set connexist bit for this pkt for public -> private */
-                       /* Private -> public packet will open the connection */
-                                       if (action_array_active
-                                           [action_id].private_public ==
-                                           acl_public_private)
-                                               connexist_mask |= pkt_mask;
-
-                                       if (ACL_DEBUG)
-                                               printf("ACL Connexist enabled  "
-                               "conntrack: %p  connexist: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)connexist_mask,
-                                                    (void *)pkt_mask);
-                               }
-                       }
-               }
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_connexist) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+
+        /* Set connexist bit for this pkt for public -> private */
+            /* Private -> public packet will open the connection */
+                    if (action_array_active
+                        [action_id].private_public ==
+                        acl_public_private)
+                        connexist_mask |= pkt_mask;
+
+                    if (ACL_DEBUG)
+                        printf("ACL Connexist enabled  "
+                "conntrack: %p  connexist: %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)connexist_mask,
+                             (void *)pkt_mask);
+                }
+            }
+        }
 #endif
 
-               if (hdr_chk == IPv6_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv6[pos];
-                       uint16_t phy_port = entry->head.port_id;
-                       uint32_t action_id = entry->action_id;
-
-                       if (ACL_DEBUG)
-                               printf("action_id = %u\n", action_id);
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_count) {
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].packetCount++;
-                               action_counter_table
-                                   [p_acl->action_counter_index]
-                                   [action_id].byteCount +=
-                                   rte_pktmbuf_pkt_len(pkt);
-                               if (ACL_DEBUG)
-                                       printf("Action Count   Packet Count: %"
-                                              PRIu64 "  Byte Count: %" PRIu64
-                                              "\n",
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].packetCount,
-                                              action_counter_table
-                                              [p_acl->action_counter_index]
-                                              [action_id].byteCount);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_drop) {
-                               /* 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 (action_array_active[action_id].action_bitmap &
-                           acl_action_fwd) {
-                               phy_port =
-                                   action_array_active[action_id].fwd_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action FWD  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_nat) {
-                               phy_port =
-                                   action_array_active[action_id].nat_port;
-                               entry->head.port_id = phy_port;
-                               if (ACL_DEBUG)
-                                       printf("Action NAT  Port ID: %u\n",
-                                              phy_port);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_dscp) {
-
-                               /* Set DSCP priority */
-                               uint32_t dscp_offset =
-                                   MBUF_HDR_ROOM + ETH_HDR_SIZE +
-                                   IP_HDR_DSCP_OFST_IPV6;
-                               uint16_t *dscp =
-                                   RTE_MBUF_METADATA_UINT16_PTR(pkt,
-                                                                dscp_offset);
-                               uint16_t dscp_value =
-                                   (rte_bswap16
-                                    (RTE_MBUF_METADATA_UINT16
-                                     (pkt, dscp_offset)) & 0XF00F);
-                               uint8_t dscp_store =
-                                   action_array_active[action_id].dscp_priority
-                                   << 2;
-                               uint16_t dscp_temp = dscp_store;
-
-                               dscp_temp = dscp_temp << 4;
-                               *dscp = rte_bswap16(dscp_temp | dscp_value);
-                               if (ACL_DEBUG)
-                                       printf
-                                           ("Action DSCP  DSCP Priority: %u\n",
-                                            *dscp);
-                       }
-
-                       if (action_array_active[action_id].action_bitmap &
-                           acl_action_packet_accept) {
-                               if (ACL_DEBUG)
-                                       printf("Action Accept\n");
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_conntrack) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack enabled: "
-                                                       " %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)pkt_mask);
-                               }
-
-                               if (action_array_active[action_id].action_bitmap
-                                   & acl_action_connexist) {
-
-                                       /* Set conntrack bit for this pkt */
-                                       conntrack_mask |= pkt_mask;
-
-               /* Set connexist bit for this pkt for public -> private */
-                       /* Private -> public packet will open the connection */
-                                       if (action_array_active
-                                           [action_id].private_public ==
-                                           acl_public_private)
-                                               connexist_mask |= pkt_mask;
-
-                                       if (ACL_DEBUG)
-                                               printf("ACL Connexist enabled "
-                               "conntrack: %p  connexist: %p  pkt_mask: %p\n",
-                                                    (void *)conntrack_mask,
-                                                    (void *)connexist_mask,
-                                                    (void *)pkt_mask);
-                               }
-                       }
-               }
-       }
-       /* Only call connection tracker if required */
-       if (conntrack_mask > 0) {
-               if (ACL_DEBUG)
-                       printf
-                           ("ACL Call Conntrack Before = %p  Connexist = %p\n",
-                            (void *)conntrack_mask, (void *)connexist_mask);
-               conntrack_mask =
-                   rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
-                   (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
-               if (ACL_DEBUG)
-                       printf("ACL Call Conntrack After = %p\n",
-                              (void *)conntrack_mask);
-
-               /* Only change pkt mask for pkts that have conntrack enabled */
-               /* Need to loop through packets to check if conntrack enabled */
-               pkts_to_process = pkts_mask;
-               for (; pkts_to_process;) {
-                       uint32_t action_id = 0;
-                       uint8_t pos =
-                           (uint8_t) __builtin_ctzll(pkts_to_process);
-                       uint64_t pkt_mask = 1LLU << pos;
-               /* bitmask representing only this packet */
-
-                       pkts_to_process &= ~pkt_mask;
-               /* remove this packet from remaining list */
-                       struct rte_mbuf *pkt = pkts[pos];
-
-                       uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
-                                                                 MBUF_HDR_ROOM
-                                                                 +
-                                                                 ETH_HDR_SIZE);
-                       hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-                       if (hdr_chk == IPv4_HDR_VERSION) {
-                               struct acl_table_entry *entry =
-                                   (struct acl_table_entry *)
-                                   p_acl->acl_entries_ipv4[pos];
-                               action_id = entry->action_id;
-                       } else {
-                               struct acl_table_entry *entry =
-                                   (struct acl_table_entry *)
-                                   p_acl->acl_entries_ipv6[pos];
-                               action_id = entry->action_id;
-                       }
+        if (hdr_chk == IPv6_HDR_VERSION) {
+
+            struct acl_table_entry *entry =
+                (struct acl_table_entry *)
+                p_acl->acl_entries_ipv6[pos];
+            uint16_t phy_port = entry->head.port_id;
+            uint32_t action_id = entry->action_id;
+
+            if (ACL_DEBUG)
+                printf("action_id = %u\n", action_id);
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_count) {
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].packetCount++;
+                action_counter_table
+                    [p_acl->action_counter_index]
+                    [action_id].byteCount +=
+                    rte_pktmbuf_pkt_len(pkt);
+                if (ACL_DEBUG)
+                    printf("Action Count   Packet Count: %"
+                           PRIu64 "  Byte Count: %" PRIu64
+                           "\n",
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].packetCount,
+                           action_counter_table
+                           [p_acl->action_counter_index]
+                           [action_id].byteCount);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_drop) {
+                /* 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 (action_array_active[action_id].action_bitmap &
+                acl_action_fwd) {
+                phy_port =
+                    action_array_active[action_id].fwd_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action FWD  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_nat) {
+                phy_port =
+                    action_array_active[action_id].nat_port;
+                entry->head.port_id = phy_port;
+                if (ACL_DEBUG)
+                    printf("Action NAT  Port ID: %u\n",
+                           phy_port);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_dscp) {
+
+                /* Set DSCP priority */
+                uint32_t dscp_offset =
+                    MBUF_HDR_ROOM + ETH_HDR_SIZE +
+                    IP_HDR_DSCP_OFST_IPV6;
+                uint16_t *dscp =
+                    RTE_MBUF_METADATA_UINT16_PTR(pkt,
+                                 dscp_offset);
+                uint16_t dscp_value =
+                    (rte_bswap16
+                     (RTE_MBUF_METADATA_UINT16
+                      (pkt, dscp_offset)) & 0XF00F);
+                uint8_t dscp_store =
+                    action_array_active[action_id].dscp_priority
+                    << 2;
+                uint16_t dscp_temp = dscp_store;
+
+                dscp_temp = dscp_temp << 4;
+                *dscp = rte_bswap16(dscp_temp | dscp_value);
+                if (ACL_DEBUG)
+                    printf
+                        ("Action DSCP  DSCP Priority: %u\n",
+                         *dscp);
+            }
+
+            if (action_array_active[action_id].action_bitmap &
+                acl_action_packet_accept) {
+                if (ACL_DEBUG)
+                    printf("Action Accept\n");
+
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_conntrack) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack enabled: "
+                            " %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)pkt_mask);
+                }
 
-                       if ((action_array_active[action_id].action_bitmap &
-                            acl_action_conntrack)
-                           || (action_array_active[action_id].action_bitmap &
-                               acl_action_connexist)) {
-
-                               if (conntrack_mask & pkt_mask) {
-                                       if (ACL_DEBUG)
-                                               printf("ACL Conntrack Accept  "
-                                                       "packet = %p\n",
-                                                    (void *)pkt_mask);
-                               } else {
+                if (action_array_active[action_id].action_bitmap
+                    & acl_action_connexist) {
+
+                    /* Set conntrack bit for this pkt */
+                    conntrack_mask |= pkt_mask;
+
+        /* Set connexist bit for this pkt for public -> private */
+            /* Private -> public packet will open the connection */
+                    if (action_array_active
+                        [action_id].private_public ==
+                        acl_public_private)
+                        connexist_mask |= pkt_mask;
+
+                    if (ACL_DEBUG)
+                        printf("ACL Connexist enabled "
+                "conntrack: %p  connexist: %p  pkt_mask: %p\n",
+                             (void *)conntrack_mask,
+                             (void *)connexist_mask,
+                             (void *)pkt_mask);
+                }
+            }
+        }
+    }
+    /* Only call connection tracker if required */
+    if (conntrack_mask > 0) {
+        if (ACL_DEBUG)
+            printf
+                ("ACL Call Conntrack Before = %p  Connexist = %p\n",
+                 (void *)conntrack_mask, (void *)connexist_mask);
+        conntrack_mask =
+            rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
+            (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
+        if (ACL_DEBUG)
+            printf("ACL Call Conntrack After = %p\n",
+                   (void *)conntrack_mask);
+
+        /* Only change pkt mask for pkts that have conntrack enabled */
+        /* Need to loop through packets to check if conntrack enabled */
+        pkts_to_process = pkts_mask;
+        for (; pkts_to_process;) {
+            uint32_t action_id = 0;
+            uint8_t pos =
+                (uint8_t) __builtin_ctzll(pkts_to_process);
+            uint64_t pkt_mask = 1LLU << pos;
+        /* bitmask representing only this packet */
+
+            pkts_to_process &= ~pkt_mask;
+        /* remove this packet from remaining list */
+            struct rte_mbuf *pkt = pkts[pos];
+
+            uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
+                                  MBUF_HDR_ROOM
+                                  +
+                                  ETH_HDR_SIZE);
+            hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+            if (hdr_chk == IPv4_HDR_VERSION) {
+                struct acl_table_entry *entry =
+                    (struct acl_table_entry *)
+                    p_acl->acl_entries_ipv4[pos];
+                action_id = entry->action_id;
+            } else {
+                struct acl_table_entry *entry =
+                    (struct acl_table_entry *)
+                    p_acl->acl_entries_ipv6[pos];
+                action_id = entry->action_id;
+            }
+
+            if ((action_array_active[action_id].action_bitmap &
+                 acl_action_conntrack)
+                || (action_array_active[action_id].action_bitmap &
+                acl_action_connexist)) {
+
+                if (conntrack_mask & pkt_mask) {
+                    if (ACL_DEBUG)
+                        printf("ACL Conntrack Accept  "
+                            "packet = %p\n",
+                             (void *)pkt_mask);
+                } else {
 /* Drop packet by changing the mask */
-                                       if (ACL_DEBUG)
-                                               printf
-                                           ("ACL Conntrack Drop packet = %p\n",
-                                                    (void *)pkt_mask);
-                                       pkts_mask &= ~pkt_mask;
-                                       p_acl->counters->pkts_drop++;
-                               }
-                       }
-               }
-       }
-
-       pkts_to_process = pkts_mask;
-       /* bitmap of packets left to process for ARP */
-
-       for (; pkts_to_process;) {
-               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
-               uint64_t pkt_mask = 1LLU << pos;
-       /* bitmask representing only this packet */
-
-               pkts_to_process &= ~pkt_mask;
-       /* remove this packet from remaining list */
-               struct rte_mbuf *pkt = pkts[pos];
-
-               uint8_t hdr_chk =
-                   RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
-               hdr_chk = hdr_chk >> IP_VERSION_CHECK;
-
-               if (hdr_chk == IPv6_HDR_VERSION) {
-
-                       struct acl_table_entry *entry =
-                           (struct acl_table_entry *)
-                           p_acl->acl_entries_ipv6[pos];
-                       //uint16_t phy_port = entry->head.port_id;
-                       uint16_t phy_port = pkt->port;
-                       uint32_t *port_out_id =
-                           RTE_MBUF_METADATA_UINT32_PTR(pkt,
-                                                        META_DATA_OFFSET +
-                                                        offsetof(struct
-                                                         mbuf_acl_meta_data,
-                                                                 output_port));
-               /*      if (is_phy_port_privte(phy_port))
-                               *port_out_id = ACL_PUB_PORT_ID;
-                       else
-                               *port_out_id = ACL_PRV_PORT_ID;*/
-
-                       /*  *port_out_id = p_acl->links_map[phy_port]; */
-                       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_IPV6;
-                       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;
-                       uint8_t dest_address[16];
-                       uint8_t nhip[16];
-
-                       nhip[0] =
-                           RTE_MBUF_METADATA_UINT8(pkt,
-                                                   META_DATA_OFFSET +
-                                                   offsetof(struct
-                                                            mbuf_acl_meta_data,
-                                                            nhip));
-                       uint8_t *dst_addr[16];
-                       uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
-                       int i = 0;
-
-                       for (i = 0; i < 16; i++) {
-                               dst_addr[i] =
-                                   RTE_MBUF_METADATA_UINT8_PTR(pkt,
-                                                               dst_addr_offset
-                                                               + i);
-                       }
-                       memcpy(dest_address, *dst_addr, sizeof(dest_address));
-                       memset(nhip, 0, sizeof(nhip));
-                       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);
-                               }
-                               p_acl->counters->tpkts_processed++;
-                               p_acl->counters->bytes_processed +=
-                                   packet_length;
-                       } else {
-                               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;
-                               }
+                    if (ACL_DEBUG)
+                        printf
+                        ("ACL Conntrack Drop packet = %p\n",
+                             (void *)pkt_mask);
+                    pkts_mask &= ~pkt_mask;
+                    p_acl->counters->pkts_drop++;
+                }
+            }
+        }
+    }
+
+    pkts_to_process = pkts_mask;
+    /* bitmap of packets left to process for ARP */
+
+    for (; pkts_to_process;) {
+        uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
+        uint64_t pkt_mask = 1LLU << pos;
+    /* bitmask representing only this packet */
+
+        pkts_to_process &= ~pkt_mask;
+    /* remove this packet from remaining list */
+        struct rte_mbuf *pkt = pkts[pos];
+
+        uint8_t hdr_chk =
+            RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
+        hdr_chk = hdr_chk >> IP_VERSION_CHECK;
+
+        if (hdr_chk == IPv6_HDR_VERSION) {
+
+            struct acl_table_entry *entry =
+                (struct acl_table_entry *)
+                p_acl->acl_entries_ipv6[pos];
+            //uint16_t phy_port = entry->head.port_id;
+            uint16_t phy_port = pkt->port;
+            uint32_t *port_out_id =
+                RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                             META_DATA_OFFSET +
+                             offsetof(struct
+                              mbuf_acl_meta_data,
+                                  output_port));
+
+            if (ACL_DEBUG)
+                printf
+                    ("phy_port = %i,links_map[phy_port] = %i\n",
+                     phy_port, p_acl->links_map[phy_port]);
+
+            uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
+
+            uint32_t dest_if = INVALID_DESTIF;
+            uint32_t src_phy_port = pkt->port;
+
+            if(is_gateway()){
+
+                /* Gateway Proc Starts */
+                struct ipv6_hdr *ipv6hdr = (struct ipv6_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
+
+                struct ether_hdr *ehdr = (struct ether_hdr *)
+                    RTE_MBUF_METADATA_UINT32_PTR(pkt,
+                            META_DATA_OFFSET + MBUF_HDR_ROOM);
+
+                struct ether_addr dst_mac;
+                uint32_t dest_if = INVALID_DESTIF;
+                uint8_t nhipv6[IPV6_ADD_SIZE];
+                uint8_t dest_ipv6_address[IPV6_ADD_SIZE];
+                uint32_t src_phy_port;
+                struct nd_entry_data *ret_nd_data = NULL;
+
+                memset(nhipv6, 0, IPV6_ADD_SIZE);
+                src_phy_port = pkt->port;
+                rte_mov16(dest_ipv6_address,  (uint8_t *)ipv6hdr->dst_addr);
+
+                gw_get_nh_port_ipv6(dest_ipv6_address,
+                        &dest_if, nhipv6);
+
+                ret_nd_data = get_dest_mac_addr_ipv6(nhipv6, dest_if, &dst_mac);
+
+                /* Gateway Proc Ends */
+
+                if (nd_cache_dest_mac_present(dest_if)) {
+
+                    ether_addr_copy(&dst_mac, &ehdr->d_addr);
+                    ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
+
+                    *port_out_id = p_acl->port_out_id[dest_if];
+
+                    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, &ehdr->d_addr,
+                                p_acl->port_out_id[dest_if]);
+                    }
+                    p_acl->counters->tpkts_processed++;
+                    p_acl->counters->bytes_processed += packet_length;
+                } else {
+                    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;
+                    }
+
+                    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 (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;
-                                       }
-                               }
+            } else {
+                /* IP Pkt forwarding based on  pub/prv mapping */
+                if(is_phy_port_privte(src_phy_port))
+                    dest_if = prv_to_pub_map[src_phy_port];
+                else
+                    dest_if = pub_to_prv_map[src_phy_port];
 
-                       }
+                *port_out_id = p_acl->port_out_id[dest_if];
 
-               }
+            }
+        }
 
-       } /* end of for loop */
+    } /* end of for loop */
 
-       pkts_drop_mask = keep_mask & ~pkts_mask;
-       rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-       keep_mask = pkts_mask;
+    pkts_drop_mask = keep_mask & ~pkts_mask;
+    rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
+    keep_mask = pkts_mask;
 
-       if (arp_pkts_mask) {
-               keep_mask &= ~(arp_pkts_mask);
-               rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
-       }
+    if (arp_pkts_mask) {
+        keep_mask &= ~(arp_pkts_mask);
+        rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
+    }
 
-       /* don't bother measuring if traffic very low, might skew stats */
-       uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
+    /* don't bother measuring if traffic very low, might skew stats */
+    uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
 
-       if (packets_this_iteration > 1) {
-               uint64_t latency_this_iteration =
-                   rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
-               p_acl->counters->sum_latencies += latency_this_iteration;
-               p_acl->counters->count_latencies++;
-       }
-       if (ACL_DEBUG)
-               printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
-                      (void *)pkts_mask);
+    if (packets_this_iteration > 1) {
+        uint64_t latency_this_iteration =
+            rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
+        p_acl->counters->sum_latencies += latency_this_iteration;
+        p_acl->counters->count_latencies++;
+    }
+    if (ACL_DEBUG)
+        printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
+               (void *)pkts_mask);
 
-       return 0;
+    return 0;
 }
 
 static struct rte_acl_field_def field_format_ipv4[] = {
diff --git a/VNFs/vACL/vnf_template.txt b/VNFs/vACL/vnf_template.txt
new file mode 100644 (file)
index 0000000..ed8253b
--- /dev/null
@@ -0,0 +1,82 @@
+[MASTER]
+type = MASTER
+core = 0
+
+[ARPICMP]
+type = ARPICMP
+core = 1
+pktq_in  = SWQ0
+pktq_out = TXQ0.0 TXQ1.0
+pktq_in_prv =  RXQ0.0
+prv_to_pub_map = (0,1)
+prv_que_handler = (0)
+
+[TIMER]
+type = TIMER
+core = 2
+n_flows = 1048576
+
+[TXRX-BEGIN]
+type = TXRX
+core = 2
+pktq_in  = RXQ0.0 RXQ1.0
+pktq_out = SWQ0 SWQ1 SWQ2
+pipeline_txrx_type = RXRX
+dest_if_offset=176
+
+[TXRX-END]
+type = TXRX
+core = 5
+pktq_in  = SWQ5 SWQ6
+pktq_out = TXQ0.1 TXQ1.1
+pipeline_txrx_type = TXTX
+
+[LOADB]
+type = LOADB
+core = 3
+pktq_in  = SWQ0 SWQ1
+pktq_out = SWQ3 SWQ4
+outport_offset = 136
+phyport_offset = 204
+n_vnf_threads = 1
+prv_que_handler = (0)
+
+[VACL]
+type = ACL
+core = 4
+pktq_in  = SWQ3 SWQ4
+pktq_out = SWQ5 SWQ6
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+
+[VCGNAPT]
+type = CGNAPT
+core = 3
+pktq_in = RXQ0.0 RXQ1.0
+pktq_out = TXQ0.1 TXQ1.1 SWQ0
+phyport_offset = 204
+n_flows = 1048576
+key_offset = 192;64
+key_size = 8
+hash_offset = 200;72
+timer_period = 100
+max_clients_per_ip = 65535
+max_port_per_client = 10
+public_ip_port_range = 98103214:(1, 65535)
+vnf_set = (3,4,5)
+pkt_type = ipv4
+cgnapt_meta_offset = 128
+prv_que_handler = (0,)
+
+[VFW]
+type = VFW
+core = s0c4
+pktq_in  = SWQ3 SWQ4
+pktq_out = SWQ7 SWQ8;TXQ0.0 TXQ1.0
+n_rules = 10000
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+tcp_time_wait = 10
+
index e349f62..41cacfb 100644 (file)
@@ -41,6 +41,7 @@ VPATH += $(SRCDIR)/pipeline
 VPATH += $(VNF_CORE)/common/VIL/pipeline_txrx
 VPATH += $(VNF_CORE)/common/VIL/alg
 VPATH += $(VNF_CORE)/common/VIL/l2l3_stack
+VPATH += $(VNF_CORE)/common/VIL/gateway
 
 INC += $(wildcard *.h)
 INC += $(wildcard pipeline/*.h)
@@ -54,6 +55,7 @@ INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_passthrough/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_txrx/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/conntrack/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/alg/*.h)
+INC += $(wildcard $(VNF_CORE)/common/VIL/gateway/*.h)
 
 CFLAGS += -I$(SRCDIR) -mrtm -mhle -I$(SRCDIR)/pipeline -I$(VNF_CORE)/common/vnf_common
 CFLAGS += -I$(VNF_CORE)/common/VIL/l2l3_stack -I$(VNF_CORE)/common/VIL/conntrack
@@ -61,10 +63,18 @@ CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_common -I$(VNF_CORE)/common/VIL/pipe
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_master -I$(VNF_CORE)/common/VIL/pipeline_passthrough
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_txrx -I$(VNF_CORE)/common/VIL/alg
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_arpicmp
+CFLAGS += -I$(VNF_CORE)/common/VIL/gateway
+
+TOP = $(RTE_SDK)/../civetweb
+CFLAGS += -I$(TOP)/include $(COPT) -DUSE_WEBSOCKET -DUSE_IPV6 -DUSE_SSL_DH=1
+CFLAGS += -DREST_API_SUPPORT
+LDFLAGS +=  -ljson -lcrypto -lssl
+LDFLAGS += -L$(RTE_SDK)/../civetweb/ -lcivetweb
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := main.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += rest_api.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse_tm.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_check.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += init.c
@@ -106,6 +116,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += cgnapt_pcp_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += cgnapt_pcp_fe.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib_sip_alg.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib_ftp_alg.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += gateway.c
 
 CFLAGS += -O3
 CFLAGS += -DIPV6
index 47ee063..3cb90c9 100644 (file)
@@ -19,12 +19,13 @@ link 1 up
 ;p 1 arpadd 0 0064:ff9b:0:0:0:0:ca10:6414 00:00:00:00:00:01
 ;p 1 arpadd 1 0064:ff9b:0:0:0:0:ac10:2814 00:00:00:00:00:02
 
-routeadd 0 202.16.100.20 0xff000000
-routeadd 2 172.16.40.20  0xff000000
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+routeadd net 0 202.16.100.20 0xff000000
+routeadd net 1 172.16.40.20  0xff000000
 
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-;routeadd 0 0064:ff9b:0:0:0:0:ca10:6414 64
-;routeadd 1 0064:ff9b:0:0:0:0:ac10:6414 64
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+;routeadd net 0 0064:ff9b:0:0:0:0:ca10:6414 64
+;routeadd net 1 0064:ff9b:0:0:0:0:ac10:6414 64
 
 
 set fwd rxonly
index 05ed058..d746569 100644 (file)
@@ -20,8 +20,8 @@ link 1 up
 ;p 1 arpadd 1 0064:ff9b:0:0:0:0:ac10:2814 00:00:00:00:00:02
 
 routeadd 0 202.16.100.20 0xff000000
-routeadd 2 172.16.40.20  0xff000000
+routeadd 1 172.16.40.20  0xff000000
 
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-;routeadd 0 0064:ff9b:0:0:0:0:ca10:6414 64
-;routeadd 1 0064:ff9b:0:0:0:0:ac10:6414 64
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+;routeadd net 0 0064:ff9b:0:0:0:0:ca10:6414 64
+;routeadd net 1 0064:ff9b:0:0:0:0:ac10:6414 64
index 76621d5..d61e419 100644 (file)
@@ -75,6 +75,7 @@ app_init_core_mask(struct app_params *app)
                        p->socket_id,
                        p->core_id,
                        p->hyper_th_id);
+               printf("lcore_id:%d\n", lcore_id);
 
                if (lcore_id < 0)
                        rte_panic("Cannot create CPU core mask\n");
index 9ebf6fc..83fc37f 100644 (file)
 */
 
 #include "app.h"
+#include "pipeline_cgnapt.h"
 
 static struct app_params app;
 
 int
 main(int argc, char **argv)
 {
+       struct mg_context *ctx = NULL;
        rte_openlog_stream(stderr);
 
        /* Config */
@@ -28,6 +30,12 @@ main(int argc, char **argv)
 
        app_config_args(&app, argc, argv);
 
+       /* initialize the rest api */
+       if (is_rest_support()) {
+               set_vnf_type("VCGNAPT");
+               ctx = rest_api_init(&app);
+       }
+
        app_config_preproc(&app);
 
        app_config_parse(&app, app.parser_file);
@@ -40,11 +48,21 @@ main(int argc, char **argv)
        /* Init */
        app_init(&app);
 
+       if (is_rest_support() && (ctx != NULL)) {
+               /* rest api's for cgnapt */
+               rest_api_cgnapt_init(ctx, &app);
+       }
+
        /* Run-time */
        rte_eal_mp_remote_launch(
                app_thread,
                (void *) &app,
                CALL_MASTER);
 
+       if (is_rest_support() && (ctx != NULL)) {
+               mg_stop(ctx);
+               printf("Civet server stopped.\n");
+       }
+
        return 0;
 }
index fb0b95d..0c6bf48 100644 (file)
 #include <cmdline_parse_string.h>
 #include <cmdline_parse_ipaddr.h>
 #include <cmdline_parse_etheraddr.h>
+#include <cmdline_rdline.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "app.h"
 #include "pipeline_common_fe.h"
@@ -40,6 +46,8 @@
 #include "cgnapt_pcp_fe.h"
 #endif
 
+#define MAX_BUF_SIZE   2048
+
 /**
  * A structure defining the CG-NAPT entry that is stored on
  * front end.
@@ -66,6 +74,12 @@ struct pipeline_cgnapt_t {
 
 };
 
+int nat_load_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int nat_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+uint32_t rules_loaded = 0;
+extern struct cmdline *pipe_cl;
+struct app_params *myapp;
+
 /**
  * Init function for CG-NAPT FE.
  *
@@ -1405,7 +1419,8 @@ cmd_cgnapt_stats_parsed(
        __rte_unused struct cmdline *cl,
        __rte_unused void *data)
 {
-       all_cgnapt_stats();
+       char buf[2048];
+       all_cgnapt_stats(&buf[0]);
 }
 
 static cmdline_parse_token_string_t cmd_cgnapt_stats_p_string =
@@ -1457,7 +1472,8 @@ cmd_cgnapt_clear_stats_parsed(
        __rte_unused struct cmdline *cl,
        __rte_unused void *data)
 {
-       all_cgnapt_clear_stats();
+       char buf[2048];
+       all_cgnapt_clear_stats(&buf[0]);
 }
 
 static cmdline_parse_token_string_t cmd_cgnapt_clear_stats_p_string =
@@ -1475,6 +1491,212 @@ static cmdline_parse_token_string_t cmd_cgnapt_clear_stats_stats_string =
 TOKEN_STRING_INITIALIZER(struct cmd_cgnapt_clear_stats_result, stats_string,
                                "stats");
 
+int cgnapt_stats_handler(struct mg_connection *conn, void *cbdata)
+{
+       uint32_t num_links = 0, len = 0;
+       char buf[1024];
+        const struct mg_request_info *ri = mg_get_request_info(conn);
+        struct app_params *app = myapp;
+       int i;
+
+       if (!strcmp(ri->request_method, "GET")) {
+               all_cgnapt_stats(&buf[0]);
+               mg_printf(conn, "%s\n", &buf[0]);
+                return 1; 
+        }
+
+       if (strcmp(ri->request_method, "POST")) {
+                mg_printf(conn,
+                    "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the GET handler\n",
+                          ri->request_method);
+       }
+
+       all_cgnapt_clear_stats(&buf[0]);
+       mg_printf(conn, "%s\n", &buf[0]);
+       return 1;
+
+}
+
+int cgnapt_cmd_ver_handler(struct mg_connection *conn, void *cbdata)
+{
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        mg_printf(conn, "<p>Command Passed</p>");
+        mg_printf(conn, "</body></html>\n");
+
+       return 1;
+}
+
+/*
+ * loadrules
+ */
+
+/**
+ * Open file and process all commands in the file.
+ *
+ * @param ctx
+ *  A pointer to the CLI context
+ * @param file_name
+ *  A pointer to the file to process.
+ *
+ */
+static void cgnapt_loadrules_file(cmdline_parse_ctx_t *ctx, const char *file_name)
+{
+       struct cmdline *file_cl;
+       int fd;
+
+       fd = open(file_name, O_RDONLY);
+       if (fd < 0) {
+              printf("Cannot open file \"%s\"\n", file_name);
+              return;
+       }
+
+       file_cl = cmdline_new(ctx, "", fd, 1);
+       cmdline_interact(file_cl);
+       close(fd);
+}
+
+
+int nat_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+
+       const struct mg_request_info *req_info = mg_get_request_info(conn);
+       if (strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn, "Only GET method allowed");
+               return 1;
+       }
+
+       mg_printf(conn,
+                "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                "close\r\n\r\n");
+       mg_printf(conn, "<html><body>");
+       mg_printf(conn, "<h2> These are the methods that are supported </h2>");
+       mg_printf(conn, "<h3>     /load  </h3>");
+       mg_printf(conn, "<html><body>");
+
+       mg_printf(conn, "</body></html>\n");
+
+       return 1;
+}
+
+static int nat_field_found(const char *key,
+       const char *filename,
+       char *path,
+       size_t pathlen,
+       void *user_data)
+{
+       struct mg_connection *conn = (struct mg_connection *)user_data;
+
+       mg_printf(conn, "\r\n\r\n%s:\r\n", key);
+       mg_printf(conn, "Inside vfw_field_found %s \n", filename);
+
+       if (filename && *filename) {
+               snprintf(path, pathlen, "/tmp/%s", filename);
+               struct app_params *app = myapp;
+               int status;
+               int fd;
+
+               mg_printf(conn, "path: %s\n", path);
+
+               /* Make sure the file exists before clearing rules and actions */
+               fd = open(path, O_RDONLY);
+               if (fd < 0) {
+                       mg_printf(conn, "Cannot open file \"%s\"\n", filename);
+                       return FORM_FIELD_STORAGE_GET;
+               }
+
+               close(fd);
+               return FORM_FIELD_STORAGE_STORE;
+       }
+
+       return FORM_FIELD_STORAGE_GET;
+}
+
+static int nat_field_get(const char *key, const char *value, size_t valuelen,
+       void *user_data)
+{
+       struct mg_connection *conn = (struct mg_connection *)user_data;
+
+       if (key[0]) {
+               mg_printf(conn, "%s = ", key);
+       }
+       mg_write(conn, value, valuelen);
+
+       return 0;
+}
+
+static int nat_field_stored(const char *path, long long file_size,
+       void *user_data)
+{
+       struct mg_connection *conn = (struct mg_connection *)user_data;
+       int status;
+
+       mg_printf(conn,
+                 "stored as %s (%lu bytes)\r\n\r\n",
+                 path,
+                 (unsigned long)file_size);
+
+       /* Process commands in script file */
+       cgnapt_loadrules_file(pipe_cl->ctx, path);
+       rules_loaded = 1;
+
+       return 0;
+}
+
+int nat_load_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+       /* Handler may access the request info using mg_get_request_info */
+       int ret;
+       const struct mg_request_info *req_info = mg_get_request_info(conn);
+       struct mg_form_data_handler fdh = {nat_field_found, nat_field_get,
+                                nat_field_stored, 0};
+
+       /* It would be possible to check the request info here before calling
+        * mg_handle_form_request. */
+       (void)req_info;
+
+       mg_printf(conn,
+                 "HTTP/1.1 200 OK\r\nContent-Type: "
+                 "text/plain\r\nConnection: close\r\n\r\n");
+
+       if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn, "Rule file is %s\n", rules_loaded? "LOADED":"NOT LOADED");
+       }
+
+       if (strcmp(req_info->request_method, "PUT")) {
+               mg_printf(conn, "Only PUT method allowed");
+               return 1;
+       }
+
+       fdh.user_data = (void *)conn;
+
+       /* Call the form handler */
+       mg_printf(conn, "Form data:");
+       ret = mg_handle_form_request(conn, &fdh);
+       mg_printf(conn, "\r\n%i fields found", ret);
+
+       return 1;
+}
+
+void rest_api_cgnapt_init(struct mg_context *ctx, struct app_params *app)
+{
+       myapp = app;
+
+        /* vCGNAPT commands */
+        mg_set_request_handler(ctx, "/vnf/config/nat", nat_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/config/nat/load", nat_load_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/status", cgnapt_cmd_ver_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/stats", cgnapt_stats_handler, 0);
+
+}
+
 static cmdline_parse_inst_t cmd_clear_stats = {
         .f = cmd_cgnapt_clear_stats_parsed,
         .data = NULL,
index 5491648..6497de2 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "pipeline.h"
 #include "pipeline_cgnapt_common.h"
+#include <civetweb.h>
+#include <json/json.h>
 
 /**
  * Add NAPT rule to the NAPT rule table.
@@ -129,6 +131,12 @@ int
 app_pipeline_cgnapt_nsp_del_entry(struct app_params *app,
                                        uint32_t pipeline_id,
                                        struct pipeline_cgnapt_nsp_t *nsp);
+#ifdef REST_API_SUPPORT
+/* REST api's are defined here */
+int cgnapt_cmd_ver_handler(struct mg_connection *conn, void *cbdata);
+int cgnapt_stats_handler(struct mg_connection *conn, void *cbdata);
+void rest_api_cgnapt_init(struct mg_context *ctx, struct app_params *app);
+#endif
 
 /*
  * Pipeline type
index eb0aca9..7758c5b 100644 (file)
@@ -64,6 +64,7 @@
 #include "vnf_common.h"
 #include "lib_sip_alg.h"
 #include "lib_icmpv6.h"
+#include "gateway.h"
 
 #include "pipeline_common_fe.h"
 #ifdef CT_CGNAT
@@ -177,21 +178,6 @@ uint8_t well_known_prefix[16] = {
        0x00, 0x00, 0x00, 0x00
 };
 
-static uint32_t local_get_nh_ipv4(
-       uint32_t ip,
-       uint32_t *port,
-       uint32_t *nhip,
-       struct pipeline_cgnapt *p_nat);
-static void do_local_nh_ipv4_cache(
-       uint32_t dest_if,
-       struct pipeline_cgnapt *p_nat);
-
-static uint32_t local_get_nh_ipv6(
-       uint8_t *ip,
-       uint32_t *port,
-       uint8_t nhip[],
-       struct pipeline_cgnapt *p_nat);
-
 static uint8_t check_arp_icmp(
        struct rte_mbuf *pkt,
        uint64_t pkt_mask,
@@ -219,123 +205,6 @@ uint64_t nextPowerOf2(uint64_t n)
        return n;
 }
 
-void remove_local_cache(uint8_t port)
-{
-       link_hw_laddr_valid[port] = 0;
-}
-
-/**
- * Function to get IPv4-IP NH from thread local array
- *
- * @params ip
- *  IPv4 - IP
- * @params port
- *  NH port number
- * @params nhip
- *  NHIP of IPv4 type
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- * @return
- *  1 on success, 0 for failure
- */
-
-static uint32_t local_get_nh_ipv4(
-       uint32_t ip,
-       uint32_t *port,
-       uint32_t *nhip,
-       struct pipeline_cgnapt *p_nat)
-{
-       int i;
-       for (i = 0; i < p_nat->local_lib_arp_route_ent_cnt; i++) {
-               if (((p_nat->local_lib_arp_route_table[i].ip &
-                       p_nat->local_lib_arp_route_table[i].mask) ==
-                       (ip & p_nat->local_lib_arp_route_table[i].mask))) {
-                       *port = p_nat->local_lib_arp_route_table[i].port;
-
-                       *nhip = p_nat->local_lib_arp_route_table[i].nh;
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/**
- * Function to make local copy for NH of type IPv4
- *
- * @params dest_if
- *  Physical port number
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- */
-
-static void do_local_nh_ipv4_cache(
-       uint32_t dest_if,
-       struct pipeline_cgnapt *p_nat)
-{
-       return;
-}
-
-
-/**
- * Function to get IPv6-IP NH from thread local array
- *
- * @params ip
- *  Pointer to starting addr of IPv6
- * @params port
- *  NH port number
- * @params nhip
- *  NHIP of IPv6 type
- * @params p_nat
- *  CGNAPT pipeline ptr
- *
- * @return
- *  1 on success, 0 for failure
- */
-
-static uint32_t local_get_nh_ipv6(
-       uint8_t *ip,
-       uint32_t *port,
-       uint8_t nhip[],
-       struct pipeline_cgnapt *p_nat)
-{
-       int i = 0;
-       uint8_t netmask_ipv6[16];
-       uint8_t k = 0, l = 0, depthflags = 0, depthflags1 = 0;
-
-       for (i = 0; i < p_nat->local_lib_nd_route_ent_cnt; i++) {
-
-               convert_prefixlen_to_netmask_ipv6(
-                       p_nat->local_lib_nd_route_table[i].depth,
-                       netmask_ipv6);
-
-               for (k = 0; k < 16; k++)
-                       if (p_nat->local_lib_nd_route_table[i].ipv6[k] &
-                                       netmask_ipv6[k])
-                               depthflags++;
-
-               for (l = 0; l < 16; l++)
-                       if (ip[l] & netmask_ipv6[l])
-                               depthflags1++;
-
-               int j = 0;
-               if (depthflags == depthflags1) {
-                       *port = p_nat->local_lib_nd_route_table[i].port;
-
-                       for (j = 0; j < 16; j++)
-                               nhip[j] = p_nat->local_lib_nd_route_table[i].
-                                               nhipv6[j];
-                       return 1;
-               }
-
-               depthflags = 0;
-               depthflags1 = 0;
-                       }
-                       return 0;
-}
-
-
 #ifdef SIP_ALG
 /* Commented code may be required for future usage, Please keep it*/
 #if 0
@@ -2078,7 +1947,7 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                uint8_t nh_ipv6[16];
                uint32_t nhip = 0;
 
-               uint32_t dest_if = 0xff;
+               uint32_t dest_if = INVALID_DESTIF;
                uint32_t ret;
 
                uint16_t *outport_id =
@@ -2091,52 +1960,54 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        && rte_be_to_cpu_16(*dst_port) == 53) {
                        p_nat->invalid_packets |= 1LLU << pkt_index;
                        p_nat->naptDroppedPktCount++;
-                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                        p_nat->naptDroppedPktCount6++;
-                       #endif
+#endif
                        continue;
                        }
 
                        dest_address = rte_bswap32(*dst_addr);
-                       ret = local_get_nh_ipv4(dest_address, &dest_if,
-                                       &nhip, p_nat);
-                       if (!ret) {
-                               dest_if = get_prv_to_pub_port(&dest_address,
-                                               IP_VERSION_4);
-                               if (dest_if == INVALID_DESTIF) {
-                                       p_nat->invalid_packets |=
-                                               1LLU << pkt_index;
-                                       p_nat->naptDroppedPktCount++;
-                                       #ifdef CGNAPT_DEBUGGING
-                                       p_nat->naptDroppedPktCount6++;
-                                       #endif
-                                       continue;
-                               }
-                               do_local_nh_ipv4_cache(dest_if, p_nat);
-                       }
+                       /* Gateway Proc Starts */
 
-                       *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 *)eth_dest);
+                       struct arp_entry_data *ret_arp_data = NULL;
+                       uint32_t src_phy_port = *src_port;
 
-                       if (unlikely(ret_arp_data == NULL)) {
+                       gw_get_nh_port_ipv4(dest_address,
+                                       &dest_if, &nhip);
 
-                               #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;
+                       if (dest_if == INVALID_DESTIF) {
+                               p_nat->invalid_packets |=
+                                       1LLU << pkt_index;
                                p_nat->naptDroppedPktCount++;
-
-                               #ifdef CGNAPT_DEBUGGING
-                               p_nat->naptDroppedPktCount4++;
-                               #endif
+#ifdef CGNAPT_DEBUGGING
+                               p_nat->naptDroppedPktCount6++;
+#endif
                                continue;
                        }
 
+               *outport_id = p_nat->outport_id[dest_if];
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if, &hw_addr);
+
+               if (unlikely(ret_arp_data == NULL)) {
+
+                       #ifdef CGNAPT_DEBUGGING
+                       printf("%s: NHIP Not Found, nhip: %x, "
+                       "outport_id: %d\n", __func__, nhip,
+                       *outport_id);
+                       #endif
+                       /* Drop the pkt */
+                       p_nat->invalid_packets |= pkt_mask;
+                       p_nat->naptDroppedPktCount++;
+
+                       #ifdef CGNAPT_DEBUGGING
+                       p_nat->naptDroppedPktCount4++;
+                       #endif
+                       continue;
+               }
+
+               /* Gateway Proc Ends */
+
                        if (ret_arp_data->status == COMPLETE) {
 
                                if (ret_arp_data->num_pkts) {
@@ -2267,21 +2138,28 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                                         &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]);
+
+                       dest_if = INVALID_DESTIF;
+
+                       uint32_t src_phy_port = pkts[pkt_index]->port;
+
+                       gw_get_nh_port_ipv6((uint8_t *) &dst_addr[0],
+                                       &dest_if, &nh_ipv6[0]);
+
+                       ret_nd_data = get_dest_mac_addr_ipv6(&nh_ipv6[0],
+                                       dest_if, &hw_addr);
                        *outport_id = p_nat->outport_id[dest_if];
 
                        if (nd_cache_dest_mac_present(dest_if)) {
                                ether_addr_copy(get_link_hw_addr(dest_if),
-                                       (struct ether_addr *)eth_src);
+                                               (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);
+                                                       (struct ether_addr *)eth_dest,
+                                                       *outport_id);
                                }
                        } else {
                                if (unlikely(ret_nd_data == NULL)) {
@@ -2335,46 +2213,49 @@ static int cgnapt_in_port_ah_mix(struct rte_pipeline *rte_p,
                        } else {
                                *dst_addr = rte_bswap32(entry->data.u.prv_ip);
                                dest_address = entry->data.u.prv_ip;
-                               ret = local_get_nh_ipv4(dest_address, &dest_if,
-                                       &nhip, p_nat);
-                               if (!ret) {
-                                       dest_if = get_pub_to_prv_port(
-                                               &dest_address, IP_VERSION_4);
+                               /* Gateway Proc Starts */
+
+                               struct arp_entry_data *ret_arp_data = NULL;
+                               dest_if = INVALID_DESTIF;
+                               uint32_t src_phy_port = *src_port;
+
+                               gw_get_nh_port_ipv4(dest_address,
+                                               &dest_if, &nhip);
+
                                if (dest_if == INVALID_DESTIF) {
                                        p_nat->invalid_packets |=
                                                1LLU << pkt_index;
                                        p_nat->naptDroppedPktCount++;
-                                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                                        p_nat->naptDroppedPktCount6++;
-                                       #endif
+#endif
                                        continue;
                                }
-                                       do_local_nh_ipv4_cache(dest_if, p_nat);
-                               };
 
                                *outport_id = p_nat->outport_id[dest_if];
-                               struct arp_entry_data *ret_arp_data;
-                               ret_arp_data = get_dest_mac_addr_port(dest_address,
-                                       &dest_if, (struct ether_addr *)eth_dest);
+
+                               ret_arp_data = get_dest_mac_addr_ipv4(nhip,
+                                               dest_if, (struct ether_addr *)eth_dest);
 
                                if (unlikely(ret_arp_data == NULL)) {
 
-                                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                                        printf("%s: NHIP Not Found, nhip: %x, "
-                                       "outport_id: %d\n", __func__, nhip,
-                                       *outport_id);
-                                       #endif
-
+                                                       "outport_id: %d\n", __func__, nhip,
+                                                       *outport_id);
+#endif
                                        /* Drop the pkt */
                                        p_nat->invalid_packets |= pkt_mask;
                                        p_nat->naptDroppedPktCount++;
 
-                                       #ifdef CGNAPT_DEBUGGING
+#ifdef CGNAPT_DEBUGGING
                                        p_nat->naptDroppedPktCount4++;
-                                       #endif
+#endif
                                        continue;
                                }
 
+                               /* Gateway Proc Ends */
+
                                if (ret_arp_data->status == COMPLETE) {
 
                                        if (ret_arp_data->num_pkts) {
@@ -3713,7 +3594,7 @@ pkt_work_cgnapt_ipv4_prv(
 
        uint8_t protocol = RTE_MBUF_METADATA_UINT8(pkt, PROT_OFST_IP4);
 
-       uint32_t dest_if = 0xff;        /* Added for Multiport */
+       uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
        uint16_t *outport_id =
                RTE_MBUF_METADATA_UINT16_PTR(pkt, cgnapt_meta_offset);
 
@@ -3822,7 +3703,6 @@ pkt_work_cgnapt_ipv4_prv(
        if (entry->data.ttl == NAPT_ENTRY_STALE)
                entry->data.ttl = NAPT_ENTRY_VALID;
 
-       struct ether_addr hw_addr;
        uint32_t dest_address = 0;
 
        /* Egress */
@@ -3840,8 +3720,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);
+
+       uint32_t src_phy_port = *src_port;
+
+       gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                       (struct ether_addr *)eth_dest);
+
        *outport_id = p_nat->outport_id[dest_if];
 
        if (arp_cache_dest_mac_present(dest_if)) {
@@ -3850,7 +3736,7 @@ pkt_work_cgnapt_ipv4_prv(
                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);
+                                       (struct ether_addr *)eth_dest, *outport_id);
 
                }
        } else {
@@ -4083,7 +3969,7 @@ pkt_work_cgnapt_ipv4_pub(
 
        uint8_t protocol = RTE_MBUF_METADATA_UINT8(pkt, PROT_OFST_IP4);
 
-       uint32_t dest_if = 0xff;        /* Added for Multiport */
+       uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
        uint16_t *outport_id =
                RTE_MBUF_METADATA_UINT16_PTR(pkt, cgnapt_meta_offset);
 
@@ -4166,7 +4052,6 @@ pkt_work_cgnapt_ipv4_pub(
        if (entry->data.ttl == NAPT_ENTRY_STALE)
                entry->data.ttl = NAPT_ENTRY_VALID;
 
-       struct ether_addr hw_addr;
        uint32_t dest_address = 0;
 
        /* Multiport Changes */
@@ -4188,8 +4073,13 @@ pkt_work_cgnapt_ipv4_pub(
 
        dest_address = entry->data.u.prv_ip;
        struct arp_entry_data *ret_arp_data = NULL;
-       ret_arp_data = get_dest_mac_addr_port(dest_address,
-                &dest_if, (struct ether_addr *)eth_dest);
+
+       uint32_t src_phy_port = *src_port;
+
+       gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                       (struct ether_addr *)eth_dest);
        *outport_id = p_nat->outport_id[dest_if];
 
        if (arp_cache_dest_mac_present(dest_if)) {
@@ -4441,7 +4331,7 @@ pkt4_work_cgnapt_ipv4_prv(
        __rte_unused void *arg,
        struct pipeline_cgnapt *p_nat)
 {
-       uint32_t dest_if = 0xff;        /* Added for Multiport */
+       uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
        struct rte_mbuf *pkt;
        uint8_t i;
        uint8_t pkt_num;
@@ -4602,7 +4492,6 @@ pkt4_work_cgnapt_ipv4_prv(
                if (entry->data.ttl == NAPT_ENTRY_STALE)
                        entry->data.ttl = NAPT_ENTRY_VALID;
 
-               struct ether_addr hw_addr;
                uint32_t dest_address = 0;
                /*Multiport Changes */
                uint32_t nhip = 0;
@@ -4626,9 +4515,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);
+               uint32_t src_phy_port = *src_port;
+
+               gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                               (struct ether_addr *)eth_dest);
+
                *outport_id = p_nat->outport_id[dest_if];
+
                if (arp_cache_dest_mac_present(dest_if)) {
                        ether_addr_copy(get_link_hw_addr(dest_if),
                                 (struct ether_addr *)eth_src);
@@ -4882,7 +4777,7 @@ pkt4_work_cgnapt_ipv4_pub(
 
                uint8_t protocol = RTE_MBUF_METADATA_UINT8(pkt, PROT_OFST_IP4);
 
-               uint32_t dest_if = 0xff;        /* Added for Multiport */
+               uint32_t dest_if = INVALID_DESTIF;      /* Added for Multiport */
                uint16_t *outport_id =
                        RTE_MBUF_METADATA_UINT16_PTR(pkt, cgnapt_meta_offset);
 
@@ -4971,7 +4866,6 @@ pkt4_work_cgnapt_ipv4_pub(
                if (entry->data.ttl == NAPT_ENTRY_STALE)
                        entry->data.ttl = NAPT_ENTRY_VALID;
 
-               struct ether_addr hw_addr;
                uint32_t dest_address = 0;
                /* Multiport Changes */
                uint32_t nhip = 0;
@@ -4991,23 +4885,29 @@ pkt4_work_cgnapt_ipv4_pub(
                }
                dest_address = entry->data.u.prv_ip;
                struct arp_entry_data *ret_arp_data = NULL;
-               ret_arp_data = get_dest_mac_addr_port(dest_address,
-                        &dest_if, (struct ether_addr *)eth_dest);
+               uint32_t src_phy_port = *src_port;
+
+               gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                               (struct ether_addr *)eth_dest);
+
                *outport_id = p_nat->outport_id[dest_if];
 
-       if (arp_cache_dest_mac_present(dest_if)) {
-               ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src);
-               update_nhip_access(dest_if);
+               if (arp_cache_dest_mac_present(dest_if)) {
+                       ether_addr_copy(get_link_hw_addr(dest_if),
+                                       (struct ether_addr *)eth_src);
+                       update_nhip_access(dest_if);
 
-               if (ret_arp_data && ret_arp_data->num_pkts) {
-                       p_nat->naptedPktCount += ret_arp_data->num_pkts;
-                       arp_send_buffered_pkts(ret_arp_data,
-                                (struct ether_addr *)eth_dest, *outport_id);
-               }
+                       if (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 {
+               } else {
 
-               if (unlikely(ret_arp_data == NULL)) {
+                       if (unlikely(ret_arp_data == NULL)) {
 
                        #ifdef CGNAPT_DEBUGGING
                        printf("%s: NHIP Not Found, nhip: %x, "
@@ -6058,7 +5958,6 @@ pkt_work_cgnapt_ipv6_prv(
 
        struct ipv6_hdr ipv6_hdr;
 
-       struct ether_addr hw_addr;
        uint32_t dest_address = 0;
        uint32_t nhip = 0;
        /* Egress */
@@ -6164,9 +6063,16 @@ pkt_work_cgnapt_ipv6_prv(
        #endif
 
        struct arp_entry_data *ret_arp_data;
-       ret_arp_data = get_dest_mac_addr_port(dest_address,
-                &dest_if, (struct ether_addr *)eth_dest);
+
+       uint32_t src_phy_port = *src_port;
+
+       gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                       (struct ether_addr *)eth_dest);
+
        *outport_id = p_nat->outport_id[dest_if];
+
        if (arp_cache_dest_mac_present(dest_if)) {
                ether_addr_copy(get_link_hw_addr(dest_if),
                        (struct ether_addr *)eth_src);
@@ -6342,11 +6248,16 @@ pkt_work_cgnapt_ipv6_pub(
 
        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]);
+
+       dest_if = INVALID_DESTIF;
+
+       uint32_t src_phy_port = pkt->port;
+
+       gw_get_nh_port_ipv6((uint8_t *) &dest_addr_ipv6[0],
+                       &dest_if, &nh_ipv6[0]);
+
+       ret_nd_data = get_dest_mac_addr_ipv6(&nh_ipv6[0],
+                       dest_if, (struct ether_addr *)eth_dest);
 
        *outport_id = p_nat->outport_id[dest_if];
 
@@ -6536,7 +6447,6 @@ pkt4_work_cgnapt_ipv6_prv(
                p_nat->entries[pkt_num] = &(entry->head);
 
                struct ipv6_hdr ipv6_hdr;
-               struct ether_addr hw_addr;
                uint32_t dest_address = 0;
                uint8_t nh_ipv6[16];
                uint32_t nhip = 0;
@@ -6645,15 +6555,18 @@ 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 *)eth_dest);
+               uint32_t src_phy_port = *src_port;
+
+               gw_get_nh_port_ipv4(dest_address, &dest_if, &nhip);
+
+               ret_arp_data = get_dest_mac_addr_ipv4(nhip, dest_if,
+                               (struct ether_addr *)eth_dest);
                *outport_id = p_nat->outport_id[dest_if];
 
                if (arp_cache_dest_mac_present(dest_if)) {
                        ether_addr_copy(get_link_hw_addr(dest_if),
                                (struct ether_addr *)eth_src);
                        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,
@@ -6846,10 +6759,15 @@ pkt4_work_cgnapt_ipv6_pub(
 
                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]);
+               dest_if = INVALID_DESTIF;
+
+               uint32_t src_phy_port = pkt->port;
 
+               gw_get_nh_port_ipv6((uint8_t *) &dest_addr_ipv6[0],
+                               &dest_if, &nh_ipv6[0]);
+
+               ret_nd_data = get_dest_mac_addr_ipv6(&nh_ipv6[0],
+                               dest_if, (struct ether_addr *)eth_dest);
                *outport_id = p_nat->outport_id[dest_if];
 
                if (nd_cache_dest_mac_present(dest_if)) {
@@ -10551,9 +10469,9 @@ void *pipeline_cgnapt_msg_req_ver_handler(__rte_unused struct pipeline *p,
  * Function to show CGNAPT stats
  *
  */
-void all_cgnapt_stats(void)
+void all_cgnapt_stats(char *buf)
 {
-       int i;
+       int i, len = 0;
        struct pipeline_cgnapt *p_nat;
        uint64_t receivedPktCount = 0;
        uint64_t missedPktCount = 0;
@@ -10563,7 +10481,7 @@ void all_cgnapt_stats(void)
        uint64_t enaptedPktCount = 0;
        uint64_t arpicmpPktCount = 0;
 
-       printf("\nCG-NAPT Packet Stats:\n");
+       len += sprintf(buf + len, "\nCG-NAPT Packet Stats:\n");
        for (i = 0; i < n_cgnapt_pipeline; i++) {
                p_nat = all_pipeline_cgnapt[i];
 
@@ -10575,6 +10493,16 @@ void all_cgnapt_stats(void)
                enaptedPktCount         += p_nat->enaptedPktCount;
                arpicmpPktCount         += p_nat->arpicmpPktCount;
 
+               len += sprintf(buf + len, "pipeline %d stats:\n", p_nat->pipeline_num);
+               len += sprintf(buf + len, "Received %" PRIu64 ",", p_nat->receivedPktCount);
+               len += sprintf(buf + len, "Missed %" PRIu64 ",", p_nat->missedPktCount);
+               len += sprintf(buf + len, "Dropped %" PRIu64 ",",  p_nat->naptDroppedPktCount);
+               len += sprintf(buf + len, "Translated %" PRIu64 ",", p_nat->naptedPktCount);
+               len += sprintf(buf + len, "ingress %" PRIu64 ",",  p_nat->inaptedPktCount);
+               len += sprintf(buf + len, "egress %" PRIu64 "\n", p_nat->enaptedPktCount);
+               len += sprintf(buf + len, "arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
+
+       printf("\nCG-NAPT Packet Stats:\n");
                printf("pipeline %d stats:\n", p_nat->pipeline_num);
                printf("Received %" PRIu64 ",", p_nat->receivedPktCount);
                printf("Missed %" PRIu64 ",", p_nat->missedPktCount);
@@ -10585,33 +10513,34 @@ void all_cgnapt_stats(void)
                printf("arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
 
 
+
                #ifdef CGNAPT_DEBUGGING
-               printf("\n Drop detail 1:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 1:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount1);
-               printf("\n Drop detail 2:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 2:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount2);
-               printf("\n Drop detail 3:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 3:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount3);
-               printf("\n Drop detail 4:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 4:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount4);
-               printf("\n Drop detail 5:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 5:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount5);
-               printf("\n Drop detail 6:%" PRIu64 "",
+               len += sprintf(buf + len, "\n Drop detail 6:%" PRIu64 "",
                                p_nat->naptDroppedPktCount6);
 
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount1,
                                p_nat->missedpktcount2);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount3,
                                p_nat->missedpktcount4);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount5,
                                p_nat->missedpktcount6);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount7,
                                p_nat->missedpktcount8);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount9,
                                p_nat->missedpktcount10);
 
@@ -10619,7 +10548,16 @@ void all_cgnapt_stats(void)
 
        }
 
-       printf("\nTotal pipeline stats:\n");
+       len += sprintf(buf + len, "\nTotal pipeline stats:\n");
+       len += sprintf(buf + len, "Received %" PRIu64 ",", receivedPktCount);
+       len += sprintf(buf + len, "Missed %" PRIu64 ",", missedPktCount);
+       len += sprintf(buf + len, "Dropped %" PRIu64 ",",  naptDroppedPktCount);
+       len += sprintf(buf + len, "Translated %" PRIu64 ",", naptedPktCount);
+       len += sprintf(buf + len, "ingress %" PRIu64 ",",  inaptedPktCount);
+       len += sprintf(buf + len, "egress %" PRIu64 "\n", enaptedPktCount);
+       len += sprintf(buf + len, "arpicmp pkts %" PRIu64 "\n", arpicmpPktCount);
+
+ printf("\nTotal pipeline stats:\n");
        printf("Received %" PRIu64 ",", receivedPktCount);
        printf("Missed %" PRIu64 ",", missedPktCount);
        printf("Dropped %" PRIu64 ",",  naptDroppedPktCount);
@@ -10627,24 +10565,27 @@ void all_cgnapt_stats(void)
        printf("ingress %" PRIu64 ",",  inaptedPktCount);
        printf("egress %" PRIu64 "\n", enaptedPktCount);
        printf("arpicmp pkts %" PRIu64 "\n", arpicmpPktCount);
+
+       if (!rest_api_supported())
+               printf("%s\n", buf);
 }
 
-void all_cgnapt_clear_stats(void)
+void all_cgnapt_clear_stats(char *buf)
 {
-       int i;
+       int i, len = 0;
        struct pipeline_cgnapt *p_nat;
-               printf("\nCG-NAPT Packet Stats:\n");
+               len += sprintf(buf + len, "\nCG-NAPT Packet Stats:\n");
        for (i = 0; i < n_cgnapt_pipeline; i++) {
                p_nat = all_pipeline_cgnapt[i];
 
-               printf("pipeline %d stats:\n", p_nat->pipeline_num);
-               printf("Received %" PRIu64 ",", p_nat->receivedPktCount);
-               printf("Missed %" PRIu64 ",", p_nat->missedPktCount);
-               printf("Dropped %" PRIu64 ",",  p_nat->naptDroppedPktCount);
-               printf("Translated %" PRIu64 ",", p_nat->naptedPktCount);
-               printf("ingress %" PRIu64 ",",  p_nat->inaptedPktCount);
-               printf("egress %" PRIu64 "\n", p_nat->enaptedPktCount);
-               printf("arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
+               len += sprintf(buf + len, "pipeline %d stats:\n", p_nat->pipeline_num);
+               len += sprintf(buf + len, "Received %" PRIu64 ",", p_nat->receivedPktCount);
+               len += sprintf(buf + len, "Missed %" PRIu64 ",", p_nat->missedPktCount);
+               len += sprintf(buf + len, "Dropped %" PRIu64 ",",  p_nat->naptDroppedPktCount);
+               len += sprintf(buf + len, "Translated %" PRIu64 ",", p_nat->naptedPktCount);
+               len += sprintf(buf + len, "ingress %" PRIu64 ",",  p_nat->inaptedPktCount);
+               len += sprintf(buf + len, "egress %" PRIu64 "\n", p_nat->enaptedPktCount);
+               len += sprintf(buf + len, "arpicmp pkts %" PRIu64 "\n", p_nat->arpicmpPktCount);
 
                p_nat->receivedPktCount = 0;
                p_nat->missedPktCount = 0;
@@ -10655,38 +10596,41 @@ void all_cgnapt_clear_stats(void)
                p_nat->arpicmpPktCount = 0;
 
                #ifdef CGNAPT_DEBUGGING
-               printf("\n Drop detail 1:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 1:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount1);
-               printf("\n Drop detail 2:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 2:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount2);
-               printf("\n Drop detail 3:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 3:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount3);
-               printf("\n Drop detail 4:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 4:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount4);
-               printf("\n Drop detail 5:%" PRIu64 ",",
+               len += sprintf(buf + len, "\n Drop detail 5:%" PRIu64 ",",
                                p_nat->naptDroppedPktCount5);
-               printf("\n Drop detail 6:%" PRIu64 "",
+               len += sprintf(buf + len, "\n Drop detail 6:%" PRIu64 "",
                                p_nat->naptDroppedPktCount6);
 
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount1,
                                p_nat->missedpktcount2);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount3,
                                p_nat->missedpktcount4);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount5,
                                p_nat->missedpktcount6);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount7,
                                p_nat->missedpktcount8);
-               printf("\nPkt_miss: %" PRIu64 " %" PRIu64 "",
+               len += sprintf(buf + len, "\nPkt_miss: %" PRIu64 " %" PRIu64 "",
                                p_nat->missedpktcount9,
                                p_nat->missedpktcount10);
 
                #endif
 
        }
+
+       if (!rest_api_supported())
+               printf("%s\n", buf);
 }
 
 /**
index 943d0fc..7fde0c5 100644 (file)
@@ -418,14 +418,6 @@ struct pipeline_cgnapt {
 
        uint8_t vnf_set;        /* to identify as separate LB-CGNAPT set */
 
-       /* Local ARP & ND Tables */
-       struct lib_arp_route_table_entry
-               local_lib_arp_route_table[MAX_ARP_RT_ENTRY];
-       uint8_t local_lib_arp_route_ent_cnt;
-       struct lib_nd_route_table_entry
-               local_lib_nd_route_table[MAX_ND_RT_ENTRY];
-       uint8_t local_lib_nd_route_ent_cnt;
-
        /* For internal debugging purpose */
 #ifdef CGNAPT_TIMING_INST
        uint64_t in_port_exit_timestamp;
index 4f4253c..a7cd88a 100644 (file)
@@ -265,7 +265,7 @@ struct pipeline_cgnapt_entry_dbg_msg_req {
 
 extern struct pipeline_be_ops pipeline_cgnapt_be_ops;
 void print_num_ip_clients(void);
-void all_cgnapt_stats(void);
-void all_cgnapt_clear_stats(void);
+void all_cgnapt_stats(char *);
+void all_cgnapt_clear_stats(char *);
 void print_static_cgnapt_entries(void);
 #endif
diff --git a/VNFs/vCGNAPT/vnf_template.txt b/VNFs/vCGNAPT/vnf_template.txt
new file mode 100644 (file)
index 0000000..385c531
--- /dev/null
@@ -0,0 +1,80 @@
+[MASTER]
+type = MASTER
+core = 0
+
+[ARPICMP]
+type = ARPICMP
+core = 1
+pktq_in  = SWQ0
+pktq_out = TXQ0.0 TXQ1.0
+pktq_in_prv =  RXQ0.0
+prv_to_pub_map = (0,1)
+prv_que_handler = (0)
+
+[TIMER]
+type = TIMER
+core = 2
+n_flows = 1048576
+
+[TXRX-BEGIN]
+type = TXRX
+core = 2
+pktq_in  = RXQ0.0 RXQ1.0
+pktq_out = SWQ0 SWQ1 SWQ2
+pipeline_txrx_type = RXRX
+dest_if_offset=176
+
+[TXRX-END]
+type = TXRX
+core = 5
+pktq_in  = SWQ5 SWQ6
+pktq_out = TXQ0.1 TXQ1.1
+pipeline_txrx_type = TXTX
+
+[LOADB]
+type = LOADB
+core = 3
+pktq_in  = SWQ0 SWQ1
+pktq_out = SWQ3 SWQ4
+outport_offset = 136
+phyport_offset = 204
+n_vnf_threads = 1
+prv_que_handler = (0)
+
+[VACL]
+type = ACL
+core = 4
+pktq_in  = SWQ3 SWQ4
+pktq_out = SWQ5 SWQ6
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+
+[VCGNAPT]
+type = CGNAPT
+core = 3
+pktq_in = RXQ0.0 RXQ1.0
+pktq_out = TXQ0.1 TXQ1.1 SWQ0
+phyport_offset = 204
+n_flows = 1048576
+key_offset = 192;64
+key_size = 8
+hash_offset = 200;72
+timer_period = 100
+max_clients_per_ip = 65535
+max_port_per_client = 10
+pkt_type = ipv4
+cgnapt_meta_offset = 128
+prv_que_handler = (0,)
+
+[VFW]
+type = VFW
+core = s0c4
+pktq_in  = SWQ3 SWQ4
+pktq_out = SWQ7 SWQ8;TXQ0.0 TXQ1.0
+n_rules = 10000
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+tcp_time_wait = 10
+
index c96246b..b011eca 100644 (file)
@@ -41,6 +41,7 @@ VPATH += $(SRCDIR)/pipeline
 VPATH += $(VNF_CORE)/common/VIL/pipeline_txrx
 VPATH += $(VNF_CORE)/common/VIL/acl
 VPATH += $(VNF_CORE)/common/VIL/l2l3_stack
+VPATH += $(VNF_CORE)/common/VIL/gateway
 
 INC += $(wildcard *.h)
 INC += $(wildcard pipeline/*.h)
@@ -54,6 +55,7 @@ INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_master/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_passthrough/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_txrx/*.h)
 INC += $(wildcard $(VNF_CORE)/common/VIL/acl/*.h)
+INC += $(wildcard $(VNF_CORE)/common/VIL/gateway/*.h)
 
 CFLAGS += -I$(SRCDIR) -mrtm -mhle -I$(SRCDIR)/pipeline -I$(VNF_CORE)/common/vnf_common
 CFLAGS += -I$(VNF_CORE)/common/VIL/conntrack -I$(VNF_CORE)/common/VIL/l2l3_stack
@@ -62,10 +64,17 @@ CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_master -I$(VNF_CORE)/common/VIL/pipe
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_txrx
 CFLAGS += -I$(VNF_CORE)/common/VIL/acl
 CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_arpicmp
+CFLAGS += -I$(VNF_CORE)/common/VIL/gateway
+
+TOP = $(RTE_SDK)/../civetweb
+CFLAGS += -I$(TOP)/include $(COPT) -DUSE_WEBSOCKET -DUSE_IPV6 -DUSE_SSL_DH=1 -DREST_API_SUPPORT=1
+LDFLAGS +=  -ljson -lcrypto -lssl
+LDFLAGS += -L$(RTE_SDK)/../civetweb/ -lcivetweb
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := main.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += rest_api.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse_tm.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_check.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += init.c
@@ -104,6 +113,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_arpicmp_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_txrx.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_txrx_be.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib_acl.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += gateway.c
 
 
 CFLAGS += -O3
index 46355be..b27c66f 100644 (file)
@@ -32,18 +32,17 @@ link 3 config 172.16.40.10 8
 ;link 3 config 2016:0000:0000:0000:6a05:caff:fe30:2071 64
 link 3 up
 
-; routeadd <port #> <ipv4 nhip address in decimal> <Mask>
-routeadd 0 203.16.100.20 0xff000000
-routeadd 1 202.16.100.20 0xff000000
-routeadd 2 173.16.40.20  0xff000000
-routeadd 3 172.16.40.20  0xff000000
-
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-;routeadd 0 fec0:0000:0000:0000:6a05:caff:fe30:21a0 64
-;routeadd 1 fec1:0000:0000:0000:6a05:caff:fe30:21a0 64
-;routeadd 2 2012:0000:0000:0000:6a05:caff:fe30:2071 64
-;routeadd 3 2016:0000:0000:0000:6a05:caff:fe30:2071 64
-
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+routeadd net 0 203.16.100.20 0xff000000
+routeadd net 1 202.16.100.20 0xff000000
+routeadd net 2 173.16.40.20  0xff000000
+routeadd net 3 172.16.40.20  0xff000000
+
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+;routeadd net 0 fec0:0000:0000:0000:6a05:caff:fe30:21a0 64
+;routeadd net 1 fec1:0000:0000:0000:6a05:caff:fe30:21a0 64
+;routeadd net 2 2012:0000:0000:0000:6a05:caff:fe30:2071 64
+;routeadd net 3 2016:0000:0000:0000:6a05:caff:fe30:2071 64
 
 ; IPv4 Static ARP
 ;p 1 arpadd 0 203.16.100.20 00:00:00:00:00:01
index f20796a..35bb519 100644 (file)
@@ -22,13 +22,13 @@ link 1 config 172.16.40.10 8
 ;link 1 config 2012:0000:0000:0000:6a05:caff:fe30:2071 64
 link 1 up
 
-; routeadd <port #> <ipv4 nhip address in decimal> <Mask>
-routeadd 0 202.16.100.20 0xff000000
-routeadd 1 172.16.40.20  0xff000000
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+routeadd net 0 202.16.100.20 0xff000000
+routeadd net 1 172.16.40.20  0xff000000
 
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-;routeadd 0 fec0::6a05:caff:fe30:21b0  64
-;routeadd 1 2012::6a05:caff:fe30:2081 64
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+;routeadd net 0 fec0::6a05:caff:fe30:21b0 64
+;routeadd net 1 2012::6a05:caff:fe30:2081 64
 
 ; IPv4 static ARP
 ;p 1 arpadd 1 172.16.40.20 00:00:00:00:00:04
index 392320e..ff502e5 100644 (file)
@@ -32,17 +32,17 @@ link 3 config 172.16.40.10 8
 ;link 3 config 2016:0000:0000:0000:6a05:caff:fe30:2071 64
 link 3 up
 
-; routeadd <port #> <ipv4 nhip address in decimal> <Mask>
-routeadd 0 203.16.100.20 0xff000000
-routeadd 1 202.16.100.20 0xff000000
-routeadd 2 173.16.40.20  0xff000000
-routeadd 3 172.16.40.20  0xff000000
-
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-;routeadd 0 fec0:0000:0000:0000:6a05:caff:fe30:21a0 64
-;routeadd 1 fec1:0000:0000:0000:6a05:caff:fe30:21a0 64
-;routeadd 2 2012:0000:0000:0000:6a05:caff:fe30:2071 64
-;routeadd 3 2016:0000:0000:0000:6a05:caff:fe30:2071 64
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+routeadd net 0 203.16.100.20 0xff000000
+routeadd net 1 202.16.100.20 0xff000000
+routeadd net 2 173.16.40.20  0xff000000
+routeadd net 3 172.16.40.20  0xff000000
+
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+;routeadd net 0 fec0:0000:0000:0000:6a05:caff:fe30:21a0 64
+;routeadd net 1 fec1:0000:0000:0000:6a05:caff:fe30:21a0 64
+;routeadd net 2 2012:0000:0000:0000:6a05:caff:fe30:2071 64
+;routeadd net 3 2016:0000:0000:0000:6a05:caff:fe30:2071 64
 
 ; IPv4 Static ARP
 ;p 1 arpadd 0 203.16.100.20 00:00:00:00:00:01
index d85e17b..b9dd226 100644 (file)
@@ -22,17 +22,21 @@ link 1 config 172.16.40.10 8
 ;link 1 config 2012:0000:0000:0000:6a05:caff:fe30:2071 64
 link 1 up
 
-; routeadd <port #> <ipv4 nhip address in decimal> <Mask>
-routeadd 0 202.16.100.20 0xff000000
-routeadd 1 172.16.40.20 0xff000000
+; routeadd <net/host> <port #> <ipv4 nhip address in decimal> <Mask/NotApplicable>
+;routeadd host 0 202.16.100.20
+;routeadd host 1 172.16.40.20
+routeadd net 0 202.16.100.20 0xff000000
+routeadd net 1 172.16.40.20 0xff000000
 
-;routeadd <port #> <ipv6 nhip address in hex> <Depth>
-;routeadd 0 fec0::6a05:caff:fe30:21b0 64
-;routeadd 1 2012::6a05:caff:fe30:2081 64
+;routeadd <net/host> <port #> <ipv6 nhip address in hex> <Depth/NotApplicable>
+;routeadd host 0 fec0::6a05:caff:fe30:21b0
+;routeadd host 1 2012::6a05:caff:fe30:2081
+routeadd net 0 fec0::6a05:caff:fe30:21b0 64
+routeadd net 1 2012::6a05:caff:fe30:2081 64
 
 ; IPv4 static ARP
-;p 1 arpadd 1 172.16.40.20 00:00:00:00:00:04
-;p 1 arpadd 0 202.16.100.20 00:00:00:00:00:01
+p 1 arpadd 1 172.16.40.20 00:00:00:00:00:02
+p 1 arpadd 0 202.16.100.20 00:00:00:00:00:01
 
 ; IPv6 static ARP
 ;p 1 arpadd 0 fec0::6a05:caff:fe30:21b0 00:00:00:00:00:01
index 4e98b33..0edc5e3 100644 (file)
@@ -705,7 +705,7 @@ app_init_link(struct app_params *app)
        port_config = rte_zmalloc(NULL, (app->n_links * size),
                        RTE_CACHE_LINE_SIZE);
        if (port_config == NULL)
-               rte_panic("port_config is NULL: Memory Allocation failure\n");
+               rte_panic("port_config is NULL: Memory Allocation failure num_links %d %d\n", app->n_links, app->n_links * size);
 
        for (i = 0; i < app->n_links; i++) {
                struct app_link_params *p_link = &app->link_params[i];
index 9ebf6fc..aec04ac 100644 (file)
 */
 
 #include "app.h"
+#include <civetweb.h>
 
 static struct app_params app;
+extern void rest_api_vfw_init(struct mg_context *ctx, struct app_params *app);
 
 int
 main(int argc, char **argv)
 {
+       struct mg_context *ctx = NULL;
        rte_openlog_stream(stderr);
 
        /* Config */
@@ -28,6 +31,12 @@ main(int argc, char **argv)
 
        app_config_args(&app, argc, argv);
 
+       if (is_rest_support()) {
+               /* initialize the rest api */
+               set_vnf_type("VFW");
+               ctx = rest_api_init(&app);
+       }
+
        app_config_preproc(&app);
 
        app_config_parse(&app, app.parser_file);
@@ -40,11 +49,21 @@ main(int argc, char **argv)
        /* Init */
        app_init(&app);
 
+       if (is_rest_support() && (ctx != NULL)) {
+               /* rest api's for cgnapt */
+               rest_api_vfw_init(ctx, &app);
+       }
+
        /* Run-time */
        rte_eal_mp_remote_launch(
                app_thread,
                (void *) &app,
                CALL_MASTER);
 
+       if (is_rest_support() && (ctx != NULL)) {
+               mg_stop(ctx);
+               printf("Civet server stopped.\n");
+       }
+
        return 0;
 }
index f235bc5..df94b5f 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <sys/queue.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <rte_common.h>
 #include <rte_hexdump.h>
 
 #include "app.h"
 #include "pipeline_common_fe.h"
+#include "pipeline_master.h"
 #include "pipeline_vfw.h"
 #include "pipeline_vfw_be.h"
 #include "rte_cnxn_tracking.h"
 
+struct app_params *myapp;
+#define MAX_BUF_SIZE    2048
+extern struct cmdline *pipe_cl;
+extern int my_inet_pton_ipv6(int af, const char *src, void *dst);
+
 /**
  * A structure defining the VFW rule for the TAILQ Tables.
  */
@@ -4619,6 +4626,477 @@ cmdline_parse_token_num_t cmd_vfw_synproxy_flag =
 TOKEN_NUM_INITIALIZER(struct cmd_vfw_synproxy_flag_result, synproxy_flag,
               UINT8);
 
+static uint32_t rules_loaded;
+static int vfw_field_found(const char *key,
+            const char *filename,
+            char *path,
+            size_t pathlen,
+            void *user_data);
+
+static int vfw_field_get(const char *key, const char *value, size_t valuelen,
+ void *user_data);
+static int vfw_field_stored(const char *path, long long file_size, void *user_data);
+
+int vfw_clearrules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+       struct app_params *app = myapp;
+       int status;
+       mg_printf(conn,
+                 "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                 "close\r\n\r\n");
+       mg_printf(conn, "<html><body>");
+       mg_printf(conn, "</body></html>\n");
+
+       status = app_pipeline_vfw_clearrules(app);
+
+       if (status != 0) {
+              mg_printf(conn, "Command failed\n");
+              return 1;
+       }
+
+       mg_printf(conn, "Command Success\n");
+       return 1;
+}
+
+int vfw_clearstats_handler(__rte_unused struct mg_connection *conn,
+                __rte_unused void *cbdata)
+{
+       int i;
+       struct rte_CT_counter_block *ct_counters;
+
+       for (i = 0; i <= rte_VFW_hi_counter_block_in_use; i++) {
+              ct_counters = rte_vfw_counter_table[i].ct_counters;
+              rte_vfw_counter_table[i].bytes_processed = 0;
+              rte_vfw_counter_table[i].pkts_drop_without_rule = 0;
+              rte_vfw_counter_table[i].pkts_received = 0;
+              rte_vfw_counter_table[i].pkts_drop_ttl = 0;
+              rte_vfw_counter_table[i].pkts_drop_bad_size = 0;
+              rte_vfw_counter_table[i].pkts_drop_fragmented = 0;
+              rte_vfw_counter_table[i].pkts_drop_unsupported_type = 0;
+              rte_vfw_counter_table[i].pkts_drop_without_arp_entry = 0;
+              rte_vfw_counter_table[i].internal_time_sum = 0;
+              rte_vfw_counter_table[i].external_time_sum = 0;
+              rte_vfw_counter_table[i].time_measurements = 0;
+              rte_vfw_counter_table[i].ct_counters->pkts_forwarded = 0;
+              rte_vfw_counter_table[i].ct_counters->pkts_drop = 0;
+              rte_vfw_counter_table[i].pkts_fw_forwarded = 0;
+              rte_vfw_counter_table[i].pkts_acl_forwarded = 0;
+              ct_counters->current_active_sessions = 0;
+              ct_counters->sessions_activated = 0;
+              ct_counters->sessions_reactivated = 0;
+              ct_counters->sessions_established = 0;
+              ct_counters->sessions_closed = 0;
+              ct_counters->sessions_timedout = 0;
+              ct_counters->pkts_drop_invalid_conn = 0;
+              ct_counters->pkts_drop_invalid_state = 0;
+              ct_counters->pkts_drop_invalid_rst = 0;
+              ct_counters->pkts_drop_outof_window = 0;
+       }
+
+       memset(&action_counter_table, 0, sizeof(action_counter_table));
+       rte_vfw_reset_running_averages();
+       return 1;
+}
+
+int vfw_stats_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+       const struct mg_request_info *ri = mg_get_request_info(conn);
+       int i, j;
+       struct rte_VFW_counter_block vfw_counter_sums;
+       struct rte_CT_counter_block ct_counter_sums;
+       struct rte_CT_counter_block *ct_counters;
+       struct action_counter_block action_counter_sum[action_array_max];
+       uint64_t sum_pkts_drop_fw = 0;
+       
+       if (!strcmp(ri->request_method, "POST")) {
+               mg_printf(conn,
+                       "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                       "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "Command Passed \n");
+               vfw_clearstats_handler(conn, cbdata);
+               mg_printf(conn, "</body></html>\n");
+               return 1;
+       }
+
+       if (strcmp(ri->request_method, "GET")) {
+               mg_printf(conn,
+                         "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+               mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+               mg_printf(conn,
+                         "%s method not allowed in the GET handler\n",
+                         ri->request_method);
+               return 1;
+       }
+
+       memset(&vfw_counter_sums, 0, sizeof(vfw_counter_sums));
+       memset(&ct_counter_sums, 0, sizeof(ct_counter_sums));
+
+       mg_printf(conn,
+                "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                "close\r\n\r\n");
+       mg_printf(conn, "<html><body>");
+       mg_printf(conn, "VFW Stats\n");
+       for (i = 0; i <= rte_VFW_hi_counter_block_in_use; i++) {
+              struct rte_VFW_counter_block *vfw_ctrs =
+                  &rte_vfw_counter_table[i];
+              ct_counters = rte_vfw_counter_table[i].ct_counters;
+
+              uint64_t average_internal_time =
+                  vfw_ctrs->time_measurements ==
+                  0 ? 0 : vfw_ctrs->internal_time_sum /
+                  vfw_ctrs->time_measurements;
+              uint64_t average_external_time =
+                  vfw_ctrs->time_measurements ==
+                  0 ? 0 : vfw_ctrs->external_time_sum /
+                  vfw_ctrs->time_measurements;
+              uint64_t average_pkts_in_batch =
+                  vfw_ctrs->num_pkts_measurements ==
+                  0 ? 0 : vfw_ctrs->num_batch_pkts_sum /
+                  vfw_ctrs->num_pkts_measurements;
+              uint64_t pkts_drop_fw = vfw_ctrs->pkts_drop_ttl +
+                                   vfw_ctrs->pkts_drop_bad_size +
+                                   vfw_ctrs->pkts_drop_fragmented +
+                                   vfw_ctrs->pkts_drop_unsupported_type;
+
+              mg_printf(conn, "{\"VFW_counters\" : {\"id\" : \"%s\", \" pkts_received\": %"
+                     PRIu64 ", \" pkts_fw_forwarded\": %"
+                     PRIu64 ", \" pkts_drop_fw\": %"
+                     PRIu64 ", \" pkts_acl_forwarded\": %"
+                     PRIu64 ", \"pkts_drop_without_rule\" : %"
+                     PRIu64 ", \"average_pkts_in_batch\" : %"
+                     PRIu64 ", \"average_internal_time_in_clocks\" : %"
+                     PRIu64 ", \"average_external_time_in_clocks\" : %"
+                     PRIu64 ", \"total_time_measures\" : %"
+                     PRIu32 ", \"ct_packets_forwarded\" : %"
+                     PRIu64 ", \"ct_packets_dropped\" : %"
+                     PRIu64 ", \"bytes_processed \": %"
+                     PRIu64 ", \"ct_sessions\" : {"
+                     "\"active\" : %" PRIu64 ", \"open_attempt\" : %"
+                     PRIu64 ", \"re-open_attempt\" : %"
+                     PRIu64 ", \"established\" : %"
+                     PRIu64 ", \"closed\" : %"
+                     PRIu64 ", \"timeout\" : %"
+                     PRIu64 "}, \"ct_drops\" : {"
+                     "\"out_of_window\" : %" PRIu64 ", \"invalid_conn\" : %"
+                     PRIu64 ", \"invalid_state_transition\" : %"
+                     PRIu64 " \"RST\" : %"
+                     PRIu64 "}}\n",
+                     vfw_ctrs->name,
+                     vfw_ctrs->pkts_received,
+                     vfw_ctrs->pkts_fw_forwarded,
+                     pkts_drop_fw,
+                     vfw_ctrs->pkts_acl_forwarded,
+                     vfw_ctrs->pkts_drop_without_rule,
+                     average_pkts_in_batch,
+                     average_internal_time,
+                     average_external_time,
+                     vfw_ctrs->time_measurements,
+                     ct_counters->pkts_forwarded,
+                     ct_counters->pkts_drop,
+                     vfw_ctrs->bytes_processed,
+                     ct_counters->current_active_sessions,
+                     ct_counters->sessions_activated,
+                     ct_counters->sessions_reactivated,
+                     ct_counters->sessions_established,
+                     ct_counters->sessions_closed,
+                     ct_counters->sessions_timedout,
+                     ct_counters->pkts_drop_outof_window,
+                     ct_counters->pkts_drop_invalid_conn,
+                     ct_counters->pkts_drop_invalid_state,
+                     ct_counters->pkts_drop_invalid_rst);
+
+              vfw_counter_sums.bytes_processed +=
+                  vfw_ctrs->bytes_processed;
+
+              vfw_counter_sums.internal_time_sum +=
+                  vfw_ctrs->internal_time_sum;
+              vfw_counter_sums.external_time_sum +=
+                  vfw_ctrs->external_time_sum;
+              vfw_counter_sums.time_measurements +=
+                  vfw_ctrs->time_measurements;
+
+              vfw_counter_sums.pkts_drop_ttl += vfw_ctrs->pkts_drop_ttl;
+              vfw_counter_sums.pkts_drop_bad_size +=
+                  vfw_ctrs->pkts_drop_bad_size;
+              vfw_counter_sums.pkts_drop_fragmented +=
+                  vfw_ctrs->pkts_drop_fragmented;
+              vfw_counter_sums.pkts_drop_unsupported_type +=
+                  vfw_ctrs->pkts_drop_unsupported_type;
+              vfw_counter_sums.pkts_drop_without_arp_entry +=
+                  vfw_ctrs->pkts_drop_without_arp_entry;
+
+              vfw_counter_sums.pkts_drop_without_rule +=
+                  vfw_ctrs->pkts_drop_without_rule;
+              vfw_counter_sums.pkts_received += vfw_ctrs->pkts_received;
+              vfw_counter_sums.pkts_fw_forwarded +=
+                     vfw_ctrs->pkts_fw_forwarded;
+              vfw_counter_sums.pkts_acl_forwarded +=
+                     vfw_ctrs->pkts_acl_forwarded;
+              sum_pkts_drop_fw += pkts_drop_fw;
+              ct_counter_sums.pkts_forwarded += ct_counters->pkts_forwarded;
+              ct_counter_sums.pkts_drop += ct_counters->pkts_drop;
+              ct_counter_sums.current_active_sessions +=
+                  ct_counters->current_active_sessions;
+              ct_counter_sums.sessions_activated +=
+                  ct_counters->sessions_activated;
+              ct_counter_sums.sessions_reactivated +=
+                  ct_counters->sessions_reactivated;
+              ct_counter_sums.sessions_established +=
+                  ct_counters->sessions_established;
+              ct_counter_sums.sessions_closed += ct_counters->sessions_closed;
+              ct_counter_sums.sessions_timedout +=
+                  ct_counters->sessions_timedout;
+              ct_counter_sums.pkts_drop_invalid_conn +=
+                  ct_counters->pkts_drop_invalid_conn;
+              ct_counter_sums.pkts_drop_invalid_state +=
+                  ct_counters->pkts_drop_invalid_state;
+              ct_counter_sums.pkts_drop_invalid_rst +=
+                  ct_counters->pkts_drop_invalid_rst;
+              ct_counter_sums.pkts_drop_outof_window +=
+                  ct_counters->pkts_drop_outof_window;
+
+       }
+
+       mg_printf(conn, "VFW TOTAL: pkts_received: %"
+                     PRIu64 ", \"pkts_fw_forwarded\": %"
+                     PRIu64 ", \"pkts_drop_fw\": %"
+                     PRIu64 ", \"fw_drops\" : {"
+                     "\"TTL_zero\" : %" PRIu64 ", \"bad_size\" : %"
+                     PRIu64 ", \"fragmented_packet\" : %"
+                     PRIu64 ", \"unsupported_packet_types\" : %"
+                     PRIu64 ", \"no_arp_entry\" : %"
+                     PRIu64 "}, \"pkts_acl_forwarded\": %"
+                     PRIu64 ", \"pkts_drop_without_rule\": %"
+                     PRIu64 ", \"packets_last_sec\" : %"
+                     PRIu32 ", \"average_packets_per_sec\" : %"
+                     PRIu32 ", \"bytes_last_sec\" : %"
+                     PRIu32 ", \"average_bytes_per_sec\" : %"
+                     PRIu32 ", \"bytes_processed \": %"
+                     PRIu64 "\n",
+                     vfw_counter_sums.pkts_received,
+                     vfw_counter_sums.pkts_fw_forwarded,
+                     sum_pkts_drop_fw,
+                     vfw_counter_sums.pkts_drop_ttl,
+                     vfw_counter_sums.pkts_drop_bad_size,
+                     vfw_counter_sums.pkts_drop_fragmented,
+                     vfw_counter_sums.pkts_drop_unsupported_type,
+                     vfw_counter_sums.pkts_drop_without_arp_entry,
+                     vfw_counter_sums.pkts_acl_forwarded,
+                     vfw_counter_sums.pkts_drop_without_rule,
+                     rte_vfw_performance_measures.pkts_last_second,
+                     rte_vfw_performance_measures.ave_pkts_per_second,
+                     rte_vfw_performance_measures.bytes_last_second,
+                     rte_vfw_performance_measures.ave_bytes_per_second,
+                     vfw_counter_sums.bytes_processed);
+
+       mg_printf(conn, "\"CT TOTAL: ct_packets_forwarded\" : %"
+                     PRIu64 ", \" ct_packets_dropped\" : %"
+                     PRIu64 ", \"ct_sessions\" : {"
+                     "\"active\" : %" PRIu64 ", \"open_attempt\" : %"
+                     PRIu64 ", \"re-open_attempt\" : %"
+                     PRIu64 ", \"established\" : %"
+                     PRIu64 ", \"closed\" : %"
+                     PRIu64 ", \"timeout\" : %"
+                     PRIu64 "}, \"ct_drops\" : {"
+                     "\"out_of_window\" : %" PRIu64 ", \"invalid_conn\" : %"
+                     PRIu64 ", \"invalid_state_transition\" : %"
+                     PRIu64 " \"RST\" : %"
+                     PRIu64 "}\n",
+                     ct_counter_sums.pkts_forwarded,
+                     ct_counter_sums.pkts_drop,
+                     ct_counter_sums.current_active_sessions,
+                     ct_counter_sums.sessions_activated,
+                     ct_counter_sums.sessions_reactivated,
+                     ct_counter_sums.sessions_established,
+                     ct_counter_sums.sessions_closed,
+                     ct_counter_sums.sessions_timedout,
+                     ct_counter_sums.pkts_drop_outof_window,
+                     ct_counter_sums.pkts_drop_invalid_conn,
+                     ct_counter_sums.pkts_drop_invalid_state,
+                     ct_counter_sums.pkts_drop_invalid_rst);
+
+       for (i = 0; i <= rte_VFW_hi_counter_block_in_use; i++) {
+              for (j = 0; j < action_array_max; j++) {
+                     if (action_array_active[j].
+                         action_bitmap & lib_acl_action_count) {
+                            action_counter_sum[j].packetCount +=
+                                action_counter_table[i][j].packetCount;
+                            action_counter_sum[j].byteCount +=
+                                action_counter_table[i][j].byteCount;
+                     }
+              }
+       }
+
+       for (j = 0; j < action_array_max; j++) {
+              if (action_array_active[j].action_bitmap & lib_acl_action_count)
+                     mg_printf(conn, "Action ID: %02u, packetCount: %" PRIu64
+                            ", byteCount: %" PRIu64 "\n", j,
+                            action_counter_sum[j].packetCount,
+                            action_counter_sum[j].byteCount);
+       }
+       mg_printf(conn, "</body></html>");
+
+       return 1;
+
+}
+
+int vfw_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+       if (strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn, "Only GET method allowed");
+               return 1;
+       }
+
+        mg_printf(conn,
+                 "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                 "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        mg_printf(conn, "<h2> These are the methods that are supported </h2>");
+        mg_printf(conn, "<h3>     /load  </h3>");
+        mg_printf(conn, "<h3>     /clear </h3>");
+        mg_printf(conn, "<html><body>");
+       
+        mg_printf(conn, "</body></html>\n");
+
+       return 1;
+}
+
+static int vfw_field_found(const char *key,
+            const char *filename,
+            char *path,
+            size_t pathlen,
+            void *user_data)
+{
+        struct mg_connection *conn = (struct mg_connection *)user_data;
+
+        mg_printf(conn, "\r\n\r\n%s:\r\n", key);
+       mg_printf(conn, "Inside vfw_field_found %s \n", filename);
+
+        if (filename && *filename) {
+               snprintf(path, pathlen, "/tmp/%s", filename);
+               int fd;
+
+               mg_printf(conn, "path: %s\n", path);
+
+               /* Make sure the file exists before clearing rules and actions */
+               fd = open(path, O_RDONLY);
+               if (fd < 0) {
+                       mg_printf(conn, "Cannot open file \"%s\"\n", filename);
+                       return FORM_FIELD_STORAGE_GET;
+               }
+               close(fd);
+
+               return FORM_FIELD_STORAGE_STORE;
+       }
+        
+       return FORM_FIELD_STORAGE_GET;
+}
+
+static int vfw_field_get(const char *key, const char *value, size_t valuelen,
+        void *user_data)
+{
+        struct mg_connection *conn = (struct mg_connection *)user_data;
+
+        if (key[0]) {
+                mg_printf(conn, "%s = ", key);
+        }
+        mg_write(conn, value, valuelen);
+
+        return 0;
+}
+
+static int vfw_field_stored(const char *path, long long file_size,
+        void *user_data)
+{
+        struct mg_connection *conn = (struct mg_connection *)user_data;
+       int status;
+
+        mg_printf(conn,
+                  "stored as %s (%lu bytes)\r\n\r\n",
+                  path,
+                  (unsigned long)file_size);
+
+       /* Clear all rules and actions */
+       status = app_pipeline_vfw_clearrules(myapp);
+       if (status != 0) {
+               mg_printf(conn, "Command clearrules failed\n");
+               return 1;
+       }
+
+       /* Process commands in script file */
+       app_loadrules_file(pipe_cl->ctx, path);
+       rules_loaded = 1;
+
+        return 0;
+}
+
+int vfw_cmd_ver_handler(__rte_unused struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: "
+                  "text/plain\r\nConnection: close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+       mg_printf(conn, "<p>Command Passed</p>");
+        mg_printf(conn, "</body></html>\n");
+
+       return 1;
+}
+
+int vfw_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+       int ret;
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+        struct mg_form_data_handler fdh = {vfw_field_found, vfw_field_get,
+                                                vfw_field_stored, 0};
+
+        /* It would be possible to check the request info here before calling
+         * mg_handle_form_request. */
+        (void)req_info;
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: "
+                  "text/plain\r\nConnection: close\r\n\r\n");
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn, "Rule file is %s\n", rules_loaded? "LOADED":"NOT LOADED");
+       }
+
+        if (strcmp(req_info->request_method, "PUT")) {
+               mg_printf(conn, "Only PUT method allowed");
+               return 1;
+       }
+
+        fdh.user_data = (void *)conn;
+
+        /* Call the form handler */
+        mg_printf(conn, "Form data:");
+        ret = mg_handle_form_request(conn, &fdh);
+        mg_printf(conn, "\r\n%i fields found", ret);
+
+        //mg_handle_form_request(conn, &fdh);
+        //mg_printf(conn, "\r\n script file handled");
+       //rules_loaded = 1;
+
+        return 1;
+}
+
+void rest_api_vfw_init(struct mg_context *ctx, struct app_params *app)
+{
+       myapp = app;
+
+       /* vFW commands */
+       mg_set_request_handler(ctx, "/vnf/config/rules", vfw_rules_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/config/rules/load", vfw_load_rules_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/config/rules/clear", vfw_clearrules_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/stats", vfw_stats_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/status", vfw_cmd_ver_handler, 0);
+
+}
+
 cmdline_parse_inst_t cmd_vfw_synproxy = {
        .f = cmd_vfw_synproxy_flag_parsed,
        .data = NULL,
index 3b1b25f..96e7ad3 100644 (file)
@@ -30,6 +30,9 @@
 #include "app.h"
 #include "pipeline_vfw_be.h"
 
+#include <civetweb.h>
+#include <json/json.h>
+
 /* VFW IPV4 and IPV6 enable flags for debugging (Default both on) */
 extern int vfw_ipv4_enabled;
 extern int vfw_ipv6_enabled;
@@ -142,4 +145,16 @@ app_pipeline_action_delete(struct app_params *app,
 
 extern struct pipeline_type pipeline_vfw;
 
+#ifdef REST_API_SUPPORT
+/* REST Api's defined here */
+int vfw_rules_handler(struct mg_connection *conn, void *cbdata);
+int vfw_load_rules_handler(struct mg_connection *conn, void *cbdata);
+int vfw_clearrules_handler(struct mg_connection *conn, void *cbdata);
+int vfw_stats_handler(struct mg_connection *conn, void *cbdata);
+int vfw_clearstats_handler(__rte_unused struct mg_connection *conn,
+        __rte_unused void *cbdata);
+int vfw_cmd_ver_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+void rest_api_vfw_init(struct mg_context *ctx, struct app_params *app);
+#endif
+
 #endif
index fed424e..f0eab34 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #define EN_SWP_ACL 1
-#define EN_SWP_ARP 1
+//#define EN_SWP_ARP 1
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -64,6 +64,7 @@
 #include "lib_arp.h"
 #include "lib_icmpv6.h"
 #include "pipeline_common_fe.h"
+#include "gateway.h"
 
 uint32_t timer_lcore;
 
@@ -94,13 +95,6 @@ struct pipeline_vfw {
        uint8_t traffic_type;
        uint8_t links_map[PIPELINE_MAX_PORT_IN];
        uint8_t outport_id[PIPELINE_MAX_PORT_IN];
-       /* Local ARP & ND Tables */
-       struct lib_arp_route_table_entry
-              local_lib_arp_route_table[MAX_ARP_RT_ENTRY];
-       uint8_t local_lib_arp_route_ent_cnt;
-       struct lib_nd_route_table_entry
-              local_lib_nd_route_table[MAX_ND_RT_ENTRY];
-       uint8_t local_lib_nd_route_ent_cnt;
 
 } __rte_cache_aligned;
 /**
@@ -799,10 +793,12 @@ pkt4_work_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
                                 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++;
+                                       vfw_pipe->counters->
+                                               pkts_drop_without_arp_entry++;
                                         continue;
                                 } else {
-                                        arp_pkts_mask |= pkt_mask;
+                                        //arp_pkts_mask |= pkt_mask;
+                                       *arp_hijack_mask |= pkt_mask;
                                         arp_queue_unresolved_packet(ret_arp_data, pkt);
                                         continue;
                      }
@@ -895,7 +891,8 @@ pkt_work_vfw_arp_ipv4_packets(struct rte_mbuf *pkts,
                                 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++;
+                                       vfw_pipe->counters->
+                                               pkts_drop_without_arp_entry++;
                                         return;
                                 } else {
                                         arp_pkts_mask |= pkt_mask;
@@ -999,7 +996,8 @@ pkt4_work_vfw_arp_ipv6_packets(struct rte_mbuf **pkts,
                          if (ret_nd_data->num_pkts >= NUM_DESC) {
                                 /* Drop the pkt */
                                 *pkts_mask &= ~pkt_mask;
-                               vfw_pipe->counters->pkts_drop_without_arp_entry++;
+                                vfw_pipe->counters->
+                                       pkts_drop_without_arp_entry++;
                                continue;
                           } else {
                                 arp_pkts_mask |= pkt_mask;
@@ -1099,7 +1097,8 @@ pkt_work_vfw_arp_ipv6_packets(struct rte_mbuf *pkts,
                           if (ret_nd_data->num_pkts >= NUM_DESC) {
                                 /* Drop the pkt */
                                 *pkts_mask &= ~pkt_mask;
-                               vfw_pipe->counters->pkts_drop_without_arp_entry++;
+                                vfw_pipe->counters->
+                                    pkts_drop_without_arp_entry++;
                                 return;
                           } else {
                                 arp_pkts_mask |= pkt_mask;
@@ -1116,211 +1115,257 @@ pkt_work_vfw_arp_ipv6_packets(struct rte_mbuf *pkts,
 #else
 
 /**
- * walk every valid mbuf (denoted by pkts_mask) and apply arp to the packet.
+ * walk every valid mbuf (denoted by pkts_mask) and forward the packet.
  * To support synproxy, some (altered) packets may need to be sent back where
  * they came from. The ip header has already been adjusted, but the ethernet
  * header has not, so this must be performed here.
- * Return an updated pkts_mask, since arp may drop some packets
+ * Return an updated pkts_mask and arp_hijack_mask since arp may drop some packets
  *
  * @param pkts
- *  A pointer to the packet.
+ *  A pointer to the packet array.
  * @param pkts_mask
- *  Packet mask
- * @param synproxy_reply_mask
- *  Reply Packet mask for Synproxy
+ *  Packets mask to be processed
+ * @param arp_hijack_mask
+ *  Packets to be hijacked for arp buffering
  * @param vfw_pipe
  *  A pointer to VFW pipeline.
  */
-static uint64_t
-rte_vfw_arp_ipv4_packets(struct rte_mbuf **pkts,
-              uint64_t pkts_mask,
-              uint64_t synproxy_reply_mask,
-              struct pipeline_vfw *vfw_pipe)
+static void vfw_fwd_pkts_ipv4(struct rte_mbuf **pkts, uint64_t *pkts_mask,
+               uint64_t *arp_hijack_mask, struct pipeline_vfw *vfw_pipe)
 {
-       uint64_t pkts_to_arp = pkts_mask;
+       uint64_t pkts_to_arp = *pkts_mask;
 
-       uint32_t ret;
-       uint32_t dest_if = INVALID_DESTIF;
-       for (; pkts_to_arp;) {
-              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 pos = (uint8_t) __builtin_ctzll(pkts_to_arp);
-              /* bitmask representing only this packet */
-              uint64_t pkt_mask = 1LLU << pos;
-              /* remove this packet from remaining list */
-              pkts_to_arp &= ~pkt_mask;
-              pkt = pkts[pos];
-              int must_reverse = ((synproxy_reply_mask & pkt_mask) != 0);
+       for (; pkts_to_arp;) {
 
-              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);
+               struct mbuf_tcp_meta_data *meta_data_addr;
+               struct ether_hdr *ehdr;
+               struct rte_mbuf *pkt;
+               uint32_t src_phy_port;
 
+               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_arp);
+               /* bitmask representing only this packet */
+               uint64_t pkt_mask = 1LLU << pos;
+               /* remove this packet from remaining list */
+               pkts_to_arp &= ~pkt_mask;
+               pkt = pkts[pos];
 
-              struct ipv4_hdr *ihdr = (struct ipv4_hdr *)
-                     RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
-              uint32_t nhip = 0;
+               if(VFW_DEBUG) {
+                       printf("----------------\n");
+                       print_pkt(pkt);
+               }
 
-              uint32_t dest_address = rte_bswap32(ihdr->dst_addr);
-              if (must_reverse)
-                     rte_sp_exchange_mac_addresses(ehdr);
-               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)) {
+               meta_data_addr = (struct mbuf_tcp_meta_data *)
+                       RTE_MBUF_METADATA_UINT32_PTR(pkt, META_DATA_OFFSET);
 
-                ether_addr_copy(get_link_hw_addr(dest_if), &ehdr->s_addr);
-               update_nhip_access(dest_if);
-                if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+               ehdr = (struct ether_hdr *)
+                       RTE_MBUF_METADATA_UINT32_PTR(pkt, ETHERNET_START);
 
-                        arp_send_buffered_pkts(ret_arp_data,
-                                 &ehdr->d_addr, vfw_pipe->outport_id[dest_if]);
+               src_phy_port = pkt->port;
+               uint32_t dst_phy_port = INVALID_DESTIF;
 
-                            }
+               if(is_gateway()){
+                       struct ipv4_hdr *ipv4hdr = (struct ipv4_hdr *)
+                               RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
 
-                     } else {
-                if (unlikely(ret_arp_data == NULL)) {
+                       /* Gateway Proc Starts */
 
-                       if (VFW_DEBUG)
-                        printf("%s: NHIP Not Found, nhip:%x , "
-                        "outport_id: %d\n", __func__, nhip,
-                        vfw_pipe->outport_id[dest_if]);
+                       struct arp_entry_data *ret_arp_data = NULL;
+                       struct ether_addr dst_mac;
+                       uint32_t nhip = 0;
+                       uint32_t dst_ip_addr = rte_bswap32(ipv4hdr->dst_addr);
 
-                        /* Drop the pkt */
-                                   vfw_pipe->counters->
-                                          pkts_drop_without_arp_entry++;
-                        continue;
-                     }
-               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++;
-                                        continue;
-                                } else {
-                                        arp_pkts_mask |= pkt_mask;
-                                        arp_queue_unresolved_packet(ret_arp_data, pkt);
-                                        continue;
-              }
-}
-       }
+                       gw_get_nh_port_ipv4(dst_ip_addr, &dst_phy_port, &nhip);
 
-       }
+                       ret_arp_data = get_dest_mac_addr_ipv4(nhip, dst_phy_port, &dst_mac);
+
+                       /* Gateway Proc Ends */
+
+                       if (arp_cache_dest_mac_present(dst_phy_port)) {
+
+                               ether_addr_copy(&dst_mac, &ehdr->d_addr);
+                               ether_addr_copy(get_link_hw_addr(dst_phy_port), &ehdr->s_addr);
+
+                               meta_data_addr->output_port = vfw_pipe->outport_id[dst_phy_port];
+
+                               update_nhip_access(dst_phy_port);
+
+                               if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
+
+                                       arp_send_buffered_pkts(ret_arp_data, &ehdr->d_addr,
+                                                       vfw_pipe->outport_id[dst_phy_port]);
+                               }
+
+                       } else {
+                               if (unlikely(ret_arp_data == NULL)) {
+
+                                       printf("NHIP Not Found\n");
+
+                                       /* Drop the pkt */
+                                       vfw_pipe->counters->
+                                               pkts_drop_without_arp_entry++;
+                                       continue;
+                               }
+                               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++;
+                                               continue;
+                                       } else {
+                                               *arp_hijack_mask |= pkt_mask;
+                                               arp_queue_unresolved_packet(ret_arp_data, pkt);
+                                               continue;
+                                       }
+                               }
+                       }
+               } else {
+                       /* IP Pkt forwarding based on  pub/prv mapping */
+                       if(is_phy_port_privte(src_phy_port))
+                               dst_phy_port = prv_to_pub_map[src_phy_port];
+                       else
+                               dst_phy_port = pub_to_prv_map[src_phy_port];
+
+                       meta_data_addr->output_port = vfw_pipe->outport_id[dst_phy_port];
+
+                       if(VFW_DEBUG) {
+                               printf("IP_PKT_FWD: src_phy_port=%d, dst_phy_port=%d\n",
+                                               src_phy_port, dst_phy_port);
+                       }
+               }
+
+               if(VFW_DEBUG)
+                       print_pkt(pkt);
+       }
 
-       return pkts_mask;
 }
+
 /**
- * walk every valid mbuf (denoted by pkts_mask) and apply arp to the packet.
+ * walk every valid mbuf (denoted by pkts_mask) and forward the packet.
  * To support synproxy, some (altered) packets may need to be sent back where
  * they came from. The ip header has already been adjusted, but the ethernet
  * header has not, so this must be performed here.
- * Return an updated pkts_mask, since arp may drop some packets
+ * Return an updated pkts_mask and arp_hijack_mask since arp may drop some packets
  *
  * @param pkts
- *  A pointer to the packet.
+ *  A pointer to the packet array.
  * @param pkts_mask
- *  Packet mask
- * @param synproxy_reply_mask
- *  Reply Packet mask for Synproxy
+ *  Packets mask to be processed
+ * @param arp_hijack_mask
+ *  Packets to be hijacked for arp buffering
  * @param vfw_pipe
  *  A pointer to VFW pipeline.
  */
-
-       static uint64_t
-rte_vfw_arp_ipv6_packets(struct rte_mbuf **pkts,
-              uint64_t pkts_mask,
-              uint64_t synproxy_reply_mask,
-              struct pipeline_vfw *vfw_pipe)
+static void vfw_fwd_pkts_ipv6(struct rte_mbuf **pkts, uint64_t *pkts_mask,
+                       uint64_t *arp_hijack_mask, struct pipeline_vfw *vfw_pipe)
 {
-       uint64_t pkts_to_arp = pkts_mask;
-       uint8_t nh_ipv6[IPV6_ADD_SIZE];
-       uint32_t ret;
-       uint32_t dest_if = INVALID_DESTIF;
+       uint64_t pkts_to_arp = *pkts_mask;
 
-       for (; pkts_to_arp;) {
-              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;
+       for (; pkts_to_arp;) {
 
-              uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_arp);
-              /* bitmask representing only this packet */
-              uint64_t pkt_mask = 1LLU << pos;
-              /* remove this packet from remaining list */
-              pkts_to_arp &= ~pkt_mask;
-              pkt = pkts[pos];
-              int must_reverse = ((synproxy_reply_mask & pkt_mask) != 0);
+               struct mbuf_tcp_meta_data *meta_data_addr;
+               struct ether_hdr *ehdr;
+               struct rte_mbuf *pkt;
+               uint32_t src_phy_port;
 
-              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);
+               struct nd_entry_data *ret_nd_data = NULL;
 
-              struct ipv6_hdr *ihdr = (struct ipv6_hdr *)
-                     RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
+               uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_arp);
+               /* bitmask representing only this packet */
+               uint64_t pkt_mask = 1LLU << pos;
+               /* remove this packet from remaining list */
+               pkts_to_arp &= ~pkt_mask;
+               pkt = pkts[pos];
 
-              uint8_t nhip[IPV6_ADD_SIZE];
-              uint8_t dest_address[IPV6_ADD_SIZE];
+               if(VFW_DEBUG) {
+                       printf("----------------\n");
+                       print_pkt(pkt);
+               }
 
-              memset(nhip, 0, IPV6_ADD_SIZE);
-              if (must_reverse)
-                     rte_sp_exchange_mac_addresses(ehdr);
+               meta_data_addr = (struct mbuf_tcp_meta_data *)
+                       RTE_MBUF_METADATA_UINT32_PTR(pkt, META_DATA_OFFSET);
 
-              rte_mov16(dest_address, ihdr->dst_addr);
-              memset(nh_ipv6, 0, IPV6_ADD_SIZE);
-              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]);
+               ehdr = (struct ether_hdr *)
+                       RTE_MBUF_METADATA_UINT32_PTR(pkt, ETHERNET_START);
 
-             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);
+               src_phy_port = pkt->port;
+               uint32_t dst_phy_port = INVALID_DESTIF;
 
-                    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);
-                     }
+               if(is_gateway()){
+                       struct ipv6_hdr *ipv6hdr = (struct ipv6_hdr *)
+                               RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
 
-              } else {
-                    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;
-                          }
-                    }
-             }
+                       /* Gateway Proc Starts */
 
-       }
+                       struct ether_addr dst_mac;
+                       uint32_t dst_phy_port = INVALID_DESTIF;
+                       uint8_t nhipv6[IPV6_ADD_SIZE];
+                       uint8_t dest_ipv6_address[IPV6_ADD_SIZE];
+                       memset(nhipv6, 0, IPV6_ADD_SIZE);
+                       src_phy_port = pkt->port;
+                       rte_mov16(dest_ipv6_address, (uint8_t *)ipv6hdr->dst_addr);
+
+                       gw_get_nh_port_ipv6(dest_ipv6_address, &dst_phy_port, nhipv6);
+
+                       ret_nd_data = get_dest_mac_addr_ipv6(nhipv6, dst_phy_port, &dst_mac);
+
+                       /* Gateway Proc Ends */
+
+                       if (nd_cache_dest_mac_present(dst_phy_port)) {
+
+                               ether_addr_copy(&dst_mac, &ehdr->d_addr);
+                               ether_addr_copy(get_link_hw_addr(dst_phy_port), &ehdr->s_addr);
+
+                               meta_data_addr->output_port = vfw_pipe->outport_id[dst_phy_port];
 
-       return pkts_mask;
+                               update_nhip_access(dst_phy_port);
+
+                               if (unlikely(ret_nd_data && ret_nd_data->num_pkts)) {
+                                       nd_send_buffered_pkts(ret_nd_data, &ehdr->d_addr,
+                                                       vfw_pipe->outport_id[dst_phy_port]);
+                               }
+
+                       } else {
+                               if (unlikely(ret_nd_data == NULL)) {
+
+                                       printf("NHIP Not Found\n");
+
+                                       /* Drop the pkt */
+                                       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) {
+                                               /* ICMP req sent, drop packet by
+                                                * changing the mask */
+                                               vfw_pipe->counters->pkts_drop_without_arp_entry++;
+                                               continue;
+                                       } else {
+                                               *arp_hijack_mask |= pkt_mask;
+                                               nd_queue_unresolved_packet(ret_nd_data, pkt);
+                                               continue;
+                                       }
+                               }
+                       }
+
+               } else {
+                       /* IP Pkt forwarding based on  pub/prv mapping */
+                       if(is_phy_port_privte(src_phy_port))
+                               dst_phy_port = prv_to_pub_map[src_phy_port];
+                       else
+                               dst_phy_port = pub_to_prv_map[src_phy_port];
+
+                       meta_data_addr->output_port = vfw_pipe->outport_id[dst_phy_port];
+
+                       if(VFW_DEBUG) {
+                               printf("IP_PKT_FWD: src_phy_port=%d, dst_phy_port=%d\n",
+                                               src_phy_port, dst_phy_port);
+                       }
+               }
+               if(VFW_DEBUG)
+                       print_pkt(pkt);
+       }
 }
 
 #endif
@@ -1516,9 +1561,9 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
 
        uint64_t packet_mask_in = RTE_LEN2MASK(n_pkts, uint64_t);
        uint64_t pkts_drop_mask;
-       uint64_t hijack_mask = 0;
-       arp_pkts_mask = 0;
-       uint64_t synproxy_reply_mask = 0;       /* for synproxy */
+       uint64_t synp_hijack_mask = 0;
+       uint64_t arp_hijack_mask = 0;
+//       uint64_t synproxy_reply_mask;       /* for synproxy */
        uint64_t keep_mask = packet_mask_in;
 
        uint64_t conntrack_mask = 0, connexist_mask = 0;
@@ -1598,8 +1643,8 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
        if (likely(cnxn_tracking_is_active)) {
               rte_ct_cnxn_tracker_batch_lookup_type(ct, pkts,
                             &keep_mask, &ct_helper, IPv4_HEADER_SIZE);
-              synproxy_reply_mask = ct_helper.reply_pkt_mask;
-              hijack_mask = ct_helper.hijack_mask;
+//              synproxy_reply_mask = ct_helper.reply_pkt_mask;
+              synp_hijack_mask = ct_helper.hijack_mask;
 
        }
 
@@ -1637,9 +1682,9 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
 #else
        rte_prefetch0((void*)in_port_dir_a);
        rte_prefetch0((void*)prv_to_pub_map);
-       rte_prefetch0((void*) & vfw_pipe->local_lib_arp_route_table);
-       keep_mask = rte_vfw_arp_ipv4_packets(pkts, keep_mask,
-                     synproxy_reply_mask, vfw_pipe);
+
+       vfw_fwd_pkts_ipv4(pkts, &keep_mask, &arp_hijack_mask, vfw_pipe);
+
 #endif
 
        if (vfw_debug > 1) {
@@ -1651,9 +1696,14 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
                                    (void *)keep_mask);
        }
 
-       /* Update mask before returning, so that bad packets are dropped */
-        if (arp_pkts_mask) {
-                rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
+          /* Hijack the Synproxy and ARP buffered packets */
+
+       if (unlikely(arp_hijack_mask || synp_hijack_mask)) {
+
+//                printf("Pkts hijacked arp = %lX, synp = %lX\n",
+//                                   arp_hijack_mask, synp_hijack_mask);
+
+                rte_pipeline_ah_packet_hijack(p,(arp_hijack_mask | synp_hijack_mask));
         }
 
        pkts_drop_mask = packet_mask_in & ~keep_mask;
@@ -1663,9 +1713,6 @@ vfw_port_in_action_ipv4(struct rte_pipeline *p,
               rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
        }
 
-       if (unlikely(hijack_mask != 0))
-              rte_pipeline_ah_packet_hijack(p, hijack_mask);
-
        vfw_pipe->counters->num_batch_pkts_sum += n_pkts;
        vfw_pipe->counters->num_pkts_measurements++;
 
@@ -1705,8 +1752,10 @@ vfw_port_in_action_ipv6(struct rte_pipeline *p,
 
        uint64_t packet_mask_in = RTE_LEN2MASK(n_pkts, uint64_t);
        uint64_t pkts_drop_mask;
-       uint64_t hijack_mask = 0;
-       uint64_t synproxy_reply_mask = 0;       /* for synproxy */
+       uint64_t synp_hijack_mask = 0;
+       uint64_t arp_hijack_mask = 0;
+//       uint64_t hijack_mask = 0;
+//       uint64_t synproxy_reply_mask = 0;       /* for synproxy */
        uint64_t keep_mask = packet_mask_in;
 
        uint64_t conntrack_mask = 0, connexist_mask = 0;
@@ -1782,8 +1831,8 @@ vfw_port_in_action_ipv6(struct rte_pipeline *p,
        if (likely(cnxn_tracking_is_active)) {
               rte_ct_cnxn_tracker_batch_lookup_type(ct, pkts,
                             &keep_mask, &ct_helper, IPv6_HEADER_SIZE);
-              synproxy_reply_mask = ct_helper.reply_pkt_mask;
-              hijack_mask = ct_helper.hijack_mask;
+//              synproxy_reply_mask = ct_helper.reply_pkt_mask;
+              synp_hijack_mask = ct_helper.hijack_mask;
 
        }
 
@@ -1795,7 +1844,7 @@ vfw_port_in_action_ipv6(struct rte_pipeline *p,
                                    ETHERNET_START));
        }
        rte_prefetch0((void*)in_port_dir_a);
-       rte_prefetch0(vfw_pipe->local_lib_nd_route_table);
//      rte_prefetch0(vfw_pipe->local_lib_nd_route_table);
        uint32_t i;
 
        for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {
@@ -1820,9 +1869,9 @@ vfw_port_in_action_ipv6(struct rte_pipeline *p,
        }
 #else
        rte_prefetch0((void*)in_port_dir_a);
-       rte_prefetch0((void*) & vfw_pipe->local_lib_arp_route_table);
-       keep_mask = rte_vfw_arp_ipv6_packets(pkts, keep_mask,
-                     synproxy_reply_mask, vfw_pipe);
+
+       vfw_fwd_pkts_ipv6(pkts, &keep_mask, &arp_hijack_mask, vfw_pipe);
+
 #endif
 
        if (vfw_debug > 1) {
@@ -1834,6 +1883,16 @@ vfw_port_in_action_ipv6(struct rte_pipeline *p,
                                    (void *)keep_mask);
        }
 
+       /* Hijack the Synproxy and ARP buffered packets */
+
+        if (unlikely(arp_hijack_mask || synp_hijack_mask)) {
+
+//                printf("Pkts hijacked arp = %lX, synp = %lX\n",
+//                                   arp_hijack_mask, synp_hijack_mask);
+
+                rte_pipeline_ah_packet_hijack(p,(arp_hijack_mask | synp_hijack_mask));
+        }
+
        /* Update mask before returning, so that bad packets are dropped */
 
        pkts_drop_mask = packet_mask_in & ~keep_mask;
@@ -1843,9 +1902,6 @@ vfw_port_in_action_ipv6(struct rte_pipeline *p,
               rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
        }
 
-       if (unlikely(hijack_mask != 0))
-              rte_pipeline_ah_packet_hijack(p, hijack_mask);
-
        vfw_pipe->counters->num_batch_pkts_sum += n_pkts;
        vfw_pipe->counters->num_pkts_measurements++;
 
diff --git a/VNFs/vFW/vnf_template.txt b/VNFs/vFW/vnf_template.txt
new file mode 100644 (file)
index 0000000..ed8253b
--- /dev/null
@@ -0,0 +1,82 @@
+[MASTER]
+type = MASTER
+core = 0
+
+[ARPICMP]
+type = ARPICMP
+core = 1
+pktq_in  = SWQ0
+pktq_out = TXQ0.0 TXQ1.0
+pktq_in_prv =  RXQ0.0
+prv_to_pub_map = (0,1)
+prv_que_handler = (0)
+
+[TIMER]
+type = TIMER
+core = 2
+n_flows = 1048576
+
+[TXRX-BEGIN]
+type = TXRX
+core = 2
+pktq_in  = RXQ0.0 RXQ1.0
+pktq_out = SWQ0 SWQ1 SWQ2
+pipeline_txrx_type = RXRX
+dest_if_offset=176
+
+[TXRX-END]
+type = TXRX
+core = 5
+pktq_in  = SWQ5 SWQ6
+pktq_out = TXQ0.1 TXQ1.1
+pipeline_txrx_type = TXTX
+
+[LOADB]
+type = LOADB
+core = 3
+pktq_in  = SWQ0 SWQ1
+pktq_out = SWQ3 SWQ4
+outport_offset = 136
+phyport_offset = 204
+n_vnf_threads = 1
+prv_que_handler = (0)
+
+[VACL]
+type = ACL
+core = 4
+pktq_in  = SWQ3 SWQ4
+pktq_out = SWQ5 SWQ6
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+
+[VCGNAPT]
+type = CGNAPT
+core = 3
+pktq_in = RXQ0.0 RXQ1.0
+pktq_out = TXQ0.1 TXQ1.1 SWQ0
+phyport_offset = 204
+n_flows = 1048576
+key_offset = 192;64
+key_size = 8
+hash_offset = 200;72
+timer_period = 100
+max_clients_per_ip = 65535
+max_port_per_client = 10
+public_ip_port_range = 98103214:(1, 65535)
+vnf_set = (3,4,5)
+pkt_type = ipv4
+cgnapt_meta_offset = 128
+prv_que_handler = (0,)
+
+[VFW]
+type = VFW
+core = s0c4
+pktq_in  = SWQ3 SWQ4
+pktq_out = SWQ7 SWQ8;TXQ0.0 TXQ1.0
+n_rules = 10000
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+tcp_time_wait = 10
+
diff --git a/common/VIL/gateway/gateway.c b/common/VIL/gateway/gateway.c
new file mode 100644 (file)
index 0000000..baf22cf
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+/**
+ * @file
+ * Gateway packet forwarding Implementation.
+ *
+ * Implementation of gateway packet forwarding, next hop IP and
+ * associated processing.
+ *
+ */
+
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_ethdev.h>
+#include <rte_memcpy.h>
+
+#include "gateway.h"
+#include "pipeline_common_fe.h"
+
+#define IP_VERSION_4 4
+#define IP_VERSION_6 6
+#define MAX_PORTS 32
+
+/* Global stats counters used in ARP */
+extern uint32_t lib_nd_nh_found;
+extern uint32_t lib_arp_nh_found;
+
+struct route_data *p_route_data[MAX_PORTS];
+struct nd_route_data *p_nd_route_data[MAX_PORTS];
+
+/**
+* VNF is configured with routing info or not
+* vnf_gateway = 0: No Routes Added , 1: Routes defined
+* Flag is part of the ARPICMP config parameter
+*/
+
+/* Initialized for IP Pkt forwarding */
+uint32_t vnf_gateway = 0;
+
+/* Initialized number of out ports to route */
+uint32_t num_out_ports = 0;
+
+/**
+ * Initialize the gateway for routing tables
+ *
+ * @param void
+ *  None
+ * @return uint32_t
+ * 1 to MAX_PORTS
+ */
+
+void gw_init(uint32_t num_ports)
+{
+     void *p;
+     uint32_t size;
+     uint32_t i;
+
+     num_out_ports = num_ports;
+
+     for(i = 0; i < num_ports; i++) {
+            /* IPv4 route table */
+            size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct route_data));
+            p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
+            p_route_data[i] = (struct route_data *)p;
+
+            /* IPv6 route touble */
+            size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct nd_route_data));
+            p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
+            p_nd_route_data[i] = (struct nd_route_data *)p;
+   }
+}
+/*
+ * Get the the number of ports to route
+ * @param void
+ *  None
+ * @return uint32_t
+ *  Number of ports enabled in the VNF
+*/
+
+uint32_t gw_get_num_ports(void)
+{
+       return num_out_ports;
+}
+
+
+/**
+ * Check if the gateway is enabled
+ *
+ * @param void
+ *  None
+ * @return uint32_t
+ *  0: No routes, 1: Route entries available
+ */
+uint32_t is_gateway(void)
+{
+       return vnf_gateway;
+}
+
+
+/**
+ * Get the next hop ip address and port number for IPv4
+ * @param dst_ip_addr
+ *  Destination IPv4 address
+ * @param dst_port
+ *  A pointer to destination port
+ * @param nhip
+ *  A pointer to next hop ip address
+ */
+
+void gw_get_nh_port_ipv4(uint32_t dst_ip_addr,
+                               uint32_t *dst_port, uint32_t *nhip)
+{
+       int i;
+       uint32_t j;
+
+       *nhip = 0;
+       *dst_port = 0xff;
+
+       for(j = 0; j < gw_get_num_ports(); j++){
+
+               for (i = 0; i < p_route_data[j]->route_ent_cnt; i++) {
+
+                       if ((p_route_data[j]->route_table[i].nh_mask) ==
+                                       (dst_ip_addr &
+                                        p_route_data[j]->route_table[i].mask)) {
+
+                               *dst_port = p_route_data[j]->route_table[i].port;
+                               *nhip =  p_route_data[j]->route_table[i].nh;
+
+                               lib_arp_nh_found++;
+                               return;
+                       }
+               }
+       }
+}
+
+/**
+ * Get the next hop ip address and port number for IPv6
+ * @param dst_ipv6_addr
+ *  Destination IPv6 address
+ * @param dst_port
+ *  A pointer to destination port
+ * @param nhipv6
+ *  A pointer to next hop ip address
+ */
+
+void gw_get_nh_port_ipv6(uint8_t *dst_ipv6_addr,
+                                       uint32_t *dst_port, uint8_t *nhipv6)
+{
+    if (!dst_ipv6_addr)
+           return;
+    uint32_t j;
+    for(j = 0; j < gw_get_num_ports(); j++){
+
+           if(p_nd_route_data[j]->nd_route_ent_cnt){
+
+                   memset(nhipv6, 0, IPV6_ADD_SIZE);
+
+                   int i=0;
+                   uint8_t netmask_ipv6[IPV6_ADD_SIZE], netip_nd[IPV6_ADD_SIZE];
+                   uint8_t netip_in[IPV6_ADD_SIZE];
+                   uint8_t k = 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 < p_nd_route_data[j]->nd_route_ent_cnt; i++) {
+
+                            convert_prefixlen_to_netmask_ipv6(
+                                            p_nd_route_data[j]->nd_route_table[i].depth, netmask_ipv6);
+
+                            for (k = 0; k < IPV6_ADD_SIZE; k++) {
+                                    if (p_nd_route_data[j]->nd_route_table[i].nhipv6[k] &
+                                                    netmask_ipv6[k]) {
+
+                                            depthflags++;
+                                            netip_nd[k] = p_nd_route_data[j]->nd_route_table[i].nhipv6[k];
+                                    }
+
+                                    if (dst_ipv6_addr[k] & netmask_ipv6[k]) {
+                                            depthflags1++;
+                                            netip_in[k] = dst_ipv6_addr[k];
+                                    }
+                            }
+
+                            if ((depthflags == depthflags1) &&
+                                            (memcmp(netip_nd, netip_in, sizeof(netip_nd)) == 0)) {
+
+                                    *dst_port = p_nd_route_data[j]->nd_route_table[i].port;
+
+                                    lib_nd_nh_found++;
+
+                                    rte_mov16(nhipv6, (uint8_t *)
+                                                    &(p_nd_route_data[j]->nd_route_table[i].nhipv6[0]));
+
+                                    return;
+                            }
+
+                    }
+
+           }
+    }
+}
+
diff --git a/common/VIL/gateway/gateway.h b/common/VIL/gateway/gateway.h
new file mode 100644 (file)
index 0000000..47a3b8a
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#ifndef __INCLUDE_GATEWAY_H__
+#define __INCLUDE_GATEWAY_H__
+
+/**
+ * @file
+ * gateway.h
+ *
+ * Provide APIs for Packet fowarding in gateway configuration.
+ *
+ */
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_udp.h>
+#include <rte_mbuf.h>
+#include <rte_byteorder.h>
+
+#include "pipeline.h"
+#include "app.h"
+#include "vnf_common.h"
+#include "vnf_define.h"
+
+/**
+* A structure for Route table entries of IPv4
+*/
+#define MAX_ROUTE_ENTRY_SIZE   32
+#define MAX_ND_ROUTE_ENTRY_SIZE 32
+
+extern struct route_data *p_route_data[];
+extern struct nd_route_data *p_nd_route_data[];
+
+extern uint32_t vnf_gateway;
+
+/**
+ * A structure for Route table entires of IPv4
+ *
+ */
+struct route_table_entry {
+       uint32_t nh;    /**< next hop */
+       uint32_t mask;  /**< mask */
+       uint32_t port;  /**< Physical port */
+       uint32_t nh_mask;
+} __rte_cache_aligned;
+
+/**
+ * Routing table for IPv4
+ *
+ */
+struct route_data {
+       struct route_table_entry route_table[MAX_ROUTE_ENTRY_SIZE];
+       uint8_t route_ent_cnt;
+};
+
+/**
+ * A structure for Route table entires of IPv6
+ *
+ */
+struct nd_route_table_entry {
+       uint8_t nhipv6[16];     /**< next hop Ipv6 */
+       uint8_t depth;          /**< Depth */
+       uint32_t port;          /**< Port */
+};
+
+/**
+ * Routing table for IPv6
+ *
+ */
+struct nd_route_data {
+       struct nd_route_table_entry nd_route_table[MAX_ND_ROUTE_ENTRY_SIZE];
+       uint8_t nd_route_ent_cnt;
+};
+
+extern void gw_init(uint32_t num_ports);
+
+extern uint32_t gw_get_num_ports(void);
+
+extern uint32_t is_gateway(void);
+
+extern void gw_get_nh_port_ipv4(uint32_t dst_ip_addr,
+                                       uint32_t *dst_port, uint32_t *nhip);
+
+extern void gw_get_nh_port_ipv6(uint8_t *dst_ipv6_addr,
+                                       uint32_t *dst_port, uint8_t *nhipv6);
+
+#endif
index c37e486..b8976d3 100644 (file)
@@ -40,6 +40,7 @@
 #include "lib_arp.h"
 #include "l3fwd_lpm4.h"
 #include "vnf_common.h"
+#include "gateway.h"
 
 #if (RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN)
 #define CHECK_ENDIAN_16(x) rte_be_to_cpu_16(x)
@@ -70,7 +71,7 @@ uint32_t nd_buffer = ARP_BUF_DEFAULT;
 #define IN6ADDRSZ 16
 #define MAX_PORTS      32
 
-static int my_inet_pton_ipv6(int af, const char *src, void *dst);
+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);
@@ -140,15 +141,6 @@ void update_nhip_access(uint8_t dest_if)
        p_arp_data->update_tsc[dest_if] = rte_rdtsc();
 }
 
-/**
- * A structure defining the mbuf meta data for VFW.
- */
-struct mbuf_arp_meta_data {
-/* output port stored for RTE_PIPELINE_ACTION_PORT_META */
-       uint32_t output_port;
-       struct rte_mbuf *next;       /* next pointer for chained buffers */
-} __rte_cache_aligned;
-
 static struct arp_entry_data arp_entry_data_default = {
        .status = COMPLETE,
        .num_pkts = 0,
@@ -224,11 +216,6 @@ int timer_objs_mempool_count = 70000;
 
 #define MAX_NUM_ARP_ENTRIES 64
 #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[],
-        struct ether_addr *hw_addr);
-
 #define MAX_ARP_DATA_ENTRY_TABLE 7
 
 struct table_arp_entry_data arp_entry_data_table[MAX_ARP_DATA_ENTRY_TABLE] = {
@@ -260,73 +247,6 @@ struct table_nd_entry_data nd_entry_data_table[MAX_ND_DATA_ENTRY_TABLE] = {
         {7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1}, 0},
 };
 
-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}, 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, 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, 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, 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, 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} },
-       {{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, 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)
@@ -368,132 +288,48 @@ void print_trace(void)
        free(strings);
 }
 
-uint32_t get_nh(uint32_t ip, uint32_t *port, struct ether_addr *addr)
-{
-       int i = 0;
-       for (i = 0; i < p_arp_data->lib_arp_route_ent_cnt; i++) {
-               if ((p_arp_data->lib_arp_route_table[i].nh_mask) ==
-                                (ip & p_arp_data->lib_arp_route_table[i].mask)) {
-
-                       *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);
-                       return p_arp_data->lib_arp_route_table[i].nh;
-               }
-       }
-       lib_arp_no_nh_found++;
-       return 0;
-}
-
-/*ND IPv6 */
-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];
-       uint8_t 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));
-       if (!ipv6)
-               return;
-       for (i = 0; i < MAX_ARP_RT_ENTRY; i++) {
-
-               convert_prefixlen_to_netmask_ipv6(lib_nd_route_table[i].depth,
-                                                       netmask_ipv6);
-
-               for (k = 0; k < 16; k++) {
-                       if (lib_nd_route_table[i].ipv6[k] & netmask_ipv6[k]) {
-                               depthflags++;
-                               netip_nd[k] = lib_nd_route_table[i].ipv6[k];
-                       }
-               }
-
-               for (l = 0; l < 16; l++) {
-                       if (ipv6[l] & netmask_ipv6[l]) {
-                               depthflags1++;
-                               netip_in[l] = ipv6[l];
-                       }
-               }
-               int j = 0;
-               if ((depthflags == depthflags1)
-                               && (memcmp(netip_nd, netip_in, sizeof(netip_nd)) == 0)) {
-                       //&& (lib_nd_route_table[i].port == port))
-                       *port = lib_nd_route_table[i].port;
-                       lib_nd_nh_found++;
-
-                       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;
-               }
-
-               if (NDIPV6_DEBUG)
-                       printf("No nh match\n");
-               depthflags = 0;
-               depthflags1 = 0;
-       }
-       if (NDIPV6_DEBUG)
-               printf("No NH - ip 0x%x, \n", ipv6[0]);
-       lib_nd_no_nh_found++;
-}
 
 /* Added for Multiport changes*/
-struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
-                                uint32_t *phy_port, struct ether_addr *hw_addr)
+struct arp_entry_data *get_dest_mac_addr_ipv4(const uint32_t nhip,
+                                uint32_t phy_port, struct ether_addr *hw_addr)
 {
        struct arp_entry_data *ret_arp_data = NULL;
-       uint32_t nhip = 0;
        uint8_t index;
 
-       nhip = get_nh(ipaddr, phy_port, hw_addr);
-       if (unlikely(nhip == 0)) {
-               if (ARPICMP_DEBUG)
-                       printf("ARPICMP no nh found for ip %x, port %d\n",
-                                                ipaddr, *phy_port);
-               return ret_arp_data;
-       }
-
        /* as part of optimization we store mac address in cache
         * & thus can be sent without having to retrieve
         */
-       if (arp_cache_dest_mac_present(*phy_port)) {
+       if (arp_cache_dest_mac_present(phy_port)) {
+               ether_addr_copy(get_local_cache_hw_addr(phy_port, nhip), hw_addr);
                return &arp_entry_data_default;
        }
 
        struct arp_key_ipv4 tmp_arp_key;
-       tmp_arp_key.port_id = *phy_port;        /* Changed for Multi Port */
+       tmp_arp_key.port_id = phy_port; /* Changed for Multi Port */
        tmp_arp_key.ip = nhip;
 
        if (ARPICMP_DEBUG)
                printf("%s: nhip: %x, phyport: %d\n", __FUNCTION__, nhip,
-                                        *phy_port);
+                                        phy_port);
 
        ret_arp_data = retrieve_arp_entry(tmp_arp_key, DYNAMIC_ARP);
        if (ret_arp_data == NULL) {
-               if (ARPICMP_DEBUG && ipaddr)
+               if (ARPICMP_DEBUG && nhip)
                 {
                        RTE_LOG(INFO, LIBARP,"ARPICMP no arp entry found for ip %x,"
-                       " port %u\n", ipaddr, *phy_port);
+                                      " port %u\n", nhip, 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);
-               p_arp_data->arp_cache_hw_laddr_valid[*phy_port] = 1;
-               index = p_arp_data->arp_local_cache[*phy_port].num_nhip;
-               p_arp_data->arp_local_cache[*phy_port].nhip[index] = nhip;
+               p_arp_data->arp_cache_hw_laddr_valid[phy_port] = 1;
+               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]);
-               p_arp_data->arp_local_cache[*phy_port].num_nhip++;
+                     &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)
@@ -501,43 +337,26 @@ struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
         }
 
        if (ret_arp_data)
-               p_arp_data->update_tsc[*phy_port] = rte_rdtsc();
+               p_arp_data->update_tsc[phy_port] = rte_rdtsc();
 
         return ret_arp_data;
 }
 
-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[])
+
+struct nd_entry_data *get_dest_mac_addr_ipv6(uint8_t nhipv6[],
+                        uint32_t phy_port, struct ether_addr *hw_addr)
 {
-       int i = 0, j = 0, flag = 0;
+       int i = 0;
        uint8_t index;
        lib_nd_get_mac_req++;
 
-       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 "
-                                                "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
-                                                "%02x%02x%02x%02x%02x%02x, port %d\n",
-                                                ipv6addr[0], ipv6addr[1], ipv6addr[2],
-                                                ipv6addr[3], ipv6addr[4], ipv6addr[5],
-                                                ipv6addr[6], ipv6addr[7], ipv6addr[8],
-                                                ipv6addr[9], ipv6addr[10], ipv6addr[11],
-                                                ipv6addr[12], ipv6addr[13], ipv6addr[14],
-                                                ipv6addr[15], *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;
+       tmp_nd_key.port_id = phy_port;
 
-       if (nd_cache_dest_mac_present(*phy_port)) {
+       if (nd_cache_dest_mac_present(phy_port)) {
+               ether_addr_copy(get_nd_local_link_hw_addr(
+                                       (uint8_t)phy_port, nhipv6), hw_addr);
                return &nd_entry_data_default;
        }
 
@@ -548,28 +367,29 @@ struct nd_entry_data *get_dest_mac_address_ipv6_port(uint8_t ipv6addr[],
        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);
+                       printf("NDIPV6 no entry found for ip %x, port %d\n",
+                                                nhipv6[0], phy_port);
                }
                lib_nd_no_arp_entry_found++;
                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]);
+               p_arp_data->nd_cache_hw_laddr_valid[phy_port] = 1;
+               index = p_arp_data->nd_local_cache[phy_port].num_nhip;
+               for (i=0; i<16; i++) {
+                       p_arp_data->nd_local_cache[phy_port].nhip[index][i] = nhipv6[i];
+               }
                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++;
+                       &p_arp_data->nd_local_cache[phy_port].link_hw_laddr[index]);
+               p_arp_data->nd_local_cache[phy_port].num_nhip++;
 
                lib_nd_nd_entry_found++;
                rte_rwlock_write_unlock(&ret_nd_data->queue_lock);
        }
 
        if (ret_nd_data)
-               p_arp_data->update_tsc[*phy_port] = rte_rdtsc();
+               p_arp_data->update_tsc[phy_port] = rte_rdtsc();
 
        return ret_nd_data;
 }
@@ -822,8 +642,7 @@ 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),
@@ -1045,10 +864,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) {
@@ -1057,9 +876,9 @@ 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",
-                                tmp_arp_data->port, tmp_arp_data->eth_addr.addr_bytes[0],
+               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],
                                 tmp_arp_data->eth_addr.addr_bytes[3],
@@ -1073,22 +892,24 @@ void print_arp_table(void)
        }
 
        uint32_t i = 0;
-       printf("\nARP routing table has %d entries\n", p_arp_data->lib_arp_route_ent_cnt);
-       printf("\nIP_Address    Mask          Port    NH_IP_Address\n");
-       for (i = 0; i < p_arp_data->lib_arp_route_ent_cnt; i++) {
-               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);
+       uint32_t j = 0;
+
+       printf("\nARP routing table...\n");
+       printf("\nIP_Address \t Mask \t\t Port\n");
+       for (j = 0; j < gw_get_num_ports(); j++) {
+               for (i = 0; i < p_route_data[j]->route_ent_cnt; i++) {
+                       printf("0x%08x \t 0x%08x \t %d\n",
+                                       p_route_data[j]->route_table[i].nh,
+                                       p_route_data[j]->route_table[i].mask,
+                                       p_route_data[j]->route_table[i].port);
+               }
        }
-
-       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,
-                        lib_arp_duplicate_found);
+       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,
+                lib_arp_duplicate_found);
 
        printf("ARP table key len is %lu\n", sizeof(struct arp_key_ipv4));
 }
@@ -1099,11 +920,13 @@ void print_nd_table(void)
        const void *next_key;
        void *next_data;
        uint32_t iter = 0;
-       uint8_t ii = 0, j = 0, k = 0;
-       printf("-----------------------------------------------------------------------\n");
+       uint8_t ii = 0, k = 0;
+       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) {
 
@@ -1111,7 +934,7 @@ void print_nd_table(void)
                                (struct nd_entry_data *)next_data;
                struct nd_key_ipv6 tmp_nd_key;
                memcpy(&tmp_nd_key, next_key, sizeof(struct nd_key_ipv6));
-               printf("\t%4d  %02X:%02X:%02X:%02X:%02X:%02X  %10s\n",
+               printf("\t%4d  %02X:%02X:%02X:%02X:%02X:%02X  %10s",
                                         tmp_nd_data->port,
                                         tmp_nd_data->eth_addr.addr_bytes[0],
                                         tmp_nd_data->eth_addr.addr_bytes[1],
@@ -1120,7 +943,7 @@ void print_nd_table(void)
                                         tmp_nd_data->eth_addr.addr_bytes[4],
                                         tmp_nd_data->eth_addr.addr_bytes[5],
                                         arp_status[tmp_nd_data->status]);
-               printf("\t\t\t\t\t\t");
+               printf("\t");
                for (ii = 0; ii < ND_IPV6_ADDR_SIZE; ii += 2) {
                        printf("%02X%02X ", tmp_nd_data->ipv6[ii],
                                                 tmp_nd_data->ipv6[ii + 1]);
@@ -1129,30 +952,24 @@ 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");
-       printf("          Port                          NH_IP_Address\n");
-       for (i = 0; i < nd_route_tbl_index; i++) {
-               printf("\n");
-
-               for (j = 0; j < ND_IPV6_ADDR_SIZE; j += 2) {
-                       RTE_LOG(INFO, LIBARP, "%02X%02X ",
-                               lib_nd_route_table[i].ipv6[j],
-                               lib_nd_route_table[i].ipv6[j + 1]);
-               }
+       printf("\n\nND IPV6 routing table ...\n");
+       printf ("\nNH_IP_Address                                        Depth          Port \n");
+       for(uint32_t p = 0; p < gw_get_num_ports(); p++ ) {
+               for (i = 0; i < p_nd_route_data[p]->nd_route_ent_cnt; i++) {
+                       //              printf("\n");
+
+                       for (k = 0; k < ND_IPV6_ADDR_SIZE; k += 2) {
+                               printf("%02X%02X ", p_nd_route_data[p]->nd_route_table[i].nhipv6[k],
+                                               p_nd_route_data[p]->nd_route_table[i].nhipv6[k + 1]);
+                       }
 
-               printf
-                               ("\n\t\t\t                      %d                                       %d                                     \n",
-                                lib_nd_route_table[i].depth, lib_nd_route_table[i].port);
-               printf("\t\t\t\t\t\t\t\t\t");
-               for (k = 0; k < ND_IPV6_ADDR_SIZE; k += 2) {
-                       printf("%02X%02X ", lib_nd_route_table[i].nhipv6[k],
-                                                lib_nd_route_table[i].ipv6[k + 1]);
+                       printf("\t%d            %d                                      \n",
+                                       p_nd_route_data[p]->nd_route_table[i].depth,
+                                       p_nd_route_data[p]->nd_route_table[i].port);
                }
        }
-       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,
@@ -1166,10 +983,13 @@ void remove_arp_entry(struct arp_entry_data *ret_arp_data, void *arg)
        struct arp_timer_key *arp_key = (struct arp_timer_key *)arg;
        lib_arp_delete_called++;
 
-       rte_timer_stop(ret_arp_data->timer);
-       rte_free(ret_arp_data->timer_key);
-       rte_free(ret_arp_data->buf_pkts);
-        ret_arp_data->buf_pkts = NULL;
+       if (ret_arp_data->timer) {
+               rte_timer_stop(ret_arp_data->timer);
+               rte_free(ret_arp_data->timer_key);
+               rte_free(ret_arp_data->buf_pkts);
+               ret_arp_data->buf_pkts = NULL;
+       }
+
        if (ARPICMP_DEBUG) {
                RTE_LOG(INFO, LIBARP,
                        "ARP Entry Deleted for IP :%d.%d.%d.%d , port %d\n",
@@ -1249,6 +1069,7 @@ arp_send_buffered_pkts(struct arp_entry_data *ret_arp_data,
                tmp = pkt;
                rte_pktmbuf_free(tmp);
        }
+       printf("arp send buffered pkts = %d\n",ret_arp_data->num_pkts);
        ret_arp_data->num_pkts = 0;
        rte_rwlock_write_unlock(&ret_arp_data->queue_lock);
 }
@@ -1346,7 +1167,7 @@ populate_arp_entry(const struct ether_addr *hw_addr, uint32_t ipaddr,
                        if (new_arp_data->status == STALE) {
                                new_arp_data->status = PROBE;
                                if (ifm_chk_port_ipv4_enabled
-                                       (new_arp_data->port)) {
+                                       (new_arp_data->port) != IFM_FAILURE) {
                                        request_arp(new_arp_data->port,
                                                        new_arp_data->ip);
                                } else {
@@ -1501,7 +1322,8 @@ void populate_nd_entry(const struct ether_addr *hw_addr, uint8_t ipv6[],
        }
 
        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,
@@ -2075,7 +1897,7 @@ void process_arpicmp_pkt(struct rte_mbuf *pkt, l2_phy_interface_t *port)
  * author:
  *      Paul Vixie, 1996.
  */
-static int my_inet_pton_ipv6(int af, const char *src, void *dst)
+int my_inet_pton_ipv6(int af, const char *src, void *dst)
 {
        switch (af) {
        case AF_INET:
@@ -2412,9 +2234,8 @@ static int arp_parse_args(struct pipeline_params *params)
                /* arp_route_tbl */
                if (strcmp(arg_name, "arp_route_tbl") == 0) {
                        arp_route_tbl_present = 1;
-
-                       uint32_t dest_ip = 0, mask = 0, tx_port = 0, nh_ip =
-                                       0, i = 0, j = 0, k = 0, l = 0;
+                       uint32_t dest_ip = 0, mask = 0, tx_port = 0, nh_ip = 0,
+                                i = 0, j = 0, k = 0;
                        uint32_t arp_route_tbl_str_max_len = 10;
                        char dest_ip_str[arp_route_tbl_str_max_len];
                        char mask_str[arp_route_tbl_str_max_len];
@@ -2425,11 +2246,11 @@ static int arp_parse_args(struct pipeline_params *params)
                                i = 0;
                                while ((i < (arp_route_tbl_str_max_len - 1))
                                                         && (token[i] != ',')) {
-                                       dest_ip_str[i] = token[i];
+                                       nh_ip_str[i] = token[i];
                                        i++;
                                }
-                               dest_ip_str[i] = '\0';
-                               dest_ip = strtoul(dest_ip_str, NULL, 16);
+                               nh_ip_str[i] = '\0';
+                               nh_ip = strtoul(nh_ip_str, NULL, 16);
 
                                i++;
                                j = 0;
@@ -2452,19 +2273,11 @@ static int arp_parse_args(struct pipeline_params *params)
                                tx_port = strtoul(tx_port_str, NULL, 16);       //atoi(tx_port_str);
 
                                k++;
-                               l = 0;
-                               while ((l < (arp_route_tbl_str_max_len - 1))
-                                                        && (token[i + j + k + l] != ')')) {
-                                       nh_ip_str[l] = token[i + j + k + l];
-                                       l++;
-                               }
-                               nh_ip_str[l] = '\0';
-                               nh_ip = strtoul(nh_ip_str, NULL, 16);   //atoi(nh_ip_str);
 
                                if (1) {
                                        RTE_LOG(INFO, LIBARP, "token: %s, "
                                                "dest_ip_str: %s, dest_ip %u, "
-                                               "mask_str: %s, mask %u, "
+                                               "mask_str: %s, mask %x, "
                                                "tx_port_str: %s, tx_port %u, "
                                                "nh_ip_str: %s, nh_ip %u\n",
                                                token, dest_ip_str, dest_ip,
@@ -2480,15 +2293,15 @@ 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];
-                               lentry->ip = dest_ip;
+
+                               struct route_table_entry *lentry =
+                               &p_route_data[tx_port]->route_table
+                               [p_route_data[tx_port]->route_ent_cnt];
                                lentry->mask = mask;
                                lentry->port = tx_port;
                                lentry->nh = nh_ip;
                                lentry->nh_mask = nh_ip & mask;
-                               p_arp_data->lib_arp_route_ent_cnt++;
+                               p_route_data[tx_port]->route_ent_cnt++;
                                token = strtok(NULL, "(");
                        }
 
@@ -2499,10 +2312,10 @@ static int arp_parse_args(struct pipeline_params *params)
                if (strcmp(arg_name, "nd_route_tbl") == 0) {
                        nd_route_tbl_present = 1;
 
-                       uint8_t dest_ipv6[16], depth = 0, tx_port =
-                                       0, nh_ipv6[16], i = 0, j = 0, k = 0, l = 0;
+                       uint8_t depth = 0, tx_port = 0, nh_ipv6[16];
+                       uint8_t i = 0, j = 0, k = 0;
                        uint8_t nd_route_tbl_str_max_len = 128; //64;
-                       char dest_ipv6_str[nd_route_tbl_str_max_len];
+//                     char dest_ipv6_str[nd_route_tbl_str_max_len];
                        char depth_str[nd_route_tbl_str_max_len];
                        char tx_port_str[nd_route_tbl_str_max_len];
                        char nh_ipv6_str[nd_route_tbl_str_max_len];
@@ -2511,13 +2324,12 @@ static int arp_parse_args(struct pipeline_params *params)
                                i = 0;
                                while ((i < (nd_route_tbl_str_max_len - 1))
                                                         && (token[i] != ',')) {
-                                       dest_ipv6_str[i] = token[i];
+                                       nh_ipv6_str[i] = token[i];
                                        i++;
                                }
-                               dest_ipv6_str[i] = '\0';
-                               my_inet_pton_ipv6(AF_INET6, dest_ipv6_str,
-                                                       &dest_ipv6);
-
+                               nh_ipv6_str[i] = '\0';
+                               my_inet_pton_ipv6(AF_INET6, nh_ipv6_str,
+                                                       &nh_ipv6);
                                i++;
                                j = 0;
                                while ((j < (nd_route_tbl_str_max_len - 1))
@@ -2542,31 +2354,19 @@ static int arp_parse_args(struct pipeline_params *params)
                                tx_port = strtoul(tx_port_str, NULL, 16);       //atoi(tx_port_str);
 
                                k++;
-                               l = 0;
-                               while ((l < (nd_route_tbl_str_max_len - 1))
-                                                        && (token[i + j + k + l] != ')')) {
-                                       nh_ipv6_str[l] = token[i + j + k + l];
-                                       l++;
-                               }
-                               nh_ipv6_str[l] = '\0';
-                               my_inet_pton_ipv6(AF_INET6, nh_ipv6_str,
-                                                       &nh_ipv6);
+                               struct nd_route_table_entry *lentry =
+                                       &p_nd_route_data[tx_port]->nd_route_table
+                               [p_nd_route_data[tx_port]->nd_route_ent_cnt];
 
                                //Populate the static arp_route_table
-                               for (i = 0; i < 16; i++) {
-                                       lib_nd_route_table
-                                                       [nd_route_tbl_index].ipv6[i] =
-                                                       dest_ipv6[i];
-                                       lib_nd_route_table
-                                                       [nd_route_tbl_index].nhipv6[i] =
-                                                       nh_ipv6[i];
-                               }
-                               lib_nd_route_table[nd_route_tbl_index].depth =
-                                               depth;
-                               lib_nd_route_table[nd_route_tbl_index].port =
-                                               tx_port;
+                               for (i = 0; i < 16; i++)
+                                       lentry->nhipv6[i] = nh_ipv6[i];
+
+                               lentry->depth = depth;
+                               lentry->port = tx_port;
+
+                               p_nd_route_data[tx_port]->nd_route_ent_cnt++;
 
-                               nd_route_tbl_index++;
                                token = strtok(NULL, "(");
                        }
 
@@ -2614,13 +2414,19 @@ struct ether_addr *get_nd_local_link_hw_addr(uint8_t out_port, uint8_t nhip[])
                }
 
                 x = &p_arp_data->nd_local_cache[out_port].link_hw_laddr[i];
+
+               if(ARPICMP_DEBUG) {
+                       for (j = 0; j < 6; j++)
+                           printf("%d  %d", x->addr_bytes[j],
+                               p_arp_data->nd_local_cache[out_port].link_hw_laddr[i].addr_bytes[j]);
+               }
                return x;
         }
 
        return x;
 }
 
-struct ether_addr *get_local_link_hw_addr(uint8_t out_port, uint32_t nhip)
+struct ether_addr *get_local_cache_hw_addr(uint8_t out_port, uint32_t nhip)
 {
         int i, limit;
        uint32_t tmp;
@@ -2642,7 +2448,7 @@ void lib_arp_init(struct pipeline_params *params,
 
        int i;
        uint32_t size;
-       struct pipeline_cgnapt *p;
+       struct arp_data *p;
 
        RTE_LOG(INFO, LIBARP, "ARP initialization ...\n");
 
@@ -2799,7 +2605,7 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
                        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) {
+                               if (ret_arp_data->retry_count == ARP_RETRY_COUNT) {
                                        remove_arp_entry(ret_arp_data, arg);
                                } else {
                                        ret_arp_data->retry_count++;
@@ -2815,7 +2621,7 @@ void arp_timer_callback(struct rte_timer *timer, void *arg)
                                        }
 
                                        if (ifm_chk_port_ipv4_enabled
-                                               (ret_arp_data->port)) {
+                                               (ret_arp_data->port) != IFM_FAILURE) {
                                                request_arp(ret_arp_data->port,
                                                                ret_arp_data->ip);
                                        } else {
@@ -2912,7 +2718,7 @@ void nd_timer_callback(struct rte_timer *timer, void *arg)
                        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) {
+                               if (ret_nd_data->retry_count == ARP_RETRY_COUNT) {
                                        remove_nd_entry_ipv6(ret_nd_data, arg);
                                } else {
                                        ret_nd_data->retry_count++;
index 9cb0205..c635c94 100644 (file)
 #define NUM_DESC                (get_arp_buf())
 #define ARP_BUF_DEFAULT                30000
 #define PROBE_TIME             50
+#define ARP_RETRY_COUNT 100
 #undef L3_STACK_SUPPORT
 
-/**
-* A structure for Route table entries of IPv4
-*/
-
-struct lib_arp_route_table_entry {
-       uint32_t ip;    /**< Ipv4 address*/
-       uint32_t mask;  /**< mask */
-       uint32_t port;  /**< Physical port */
-       uint32_t nh;    /**< next hop */
-       uint32_t nh_mask;
-};
-
 #define MAX_LOCAL_MAC_ADDRESS         32
 #define MAX_PORTS                      32
 struct arp_cache {
@@ -60,28 +49,35 @@ struct nd_cache {
         uint32_t num_nhip;
 };
 
-/**
-* A structure for Route table entires of IPv6
-*
-*/
-struct lib_nd_route_table_entry {
-       uint8_t ipv6[16];       /**< Ipv6 address */
-       uint8_t depth;          /**< Depth */
-       uint32_t port;          /**< Port */
-       uint8_t nhipv6[16];     /**< next hop Ipv6 */
-};
-
 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_local_cache_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 void update_nhip_access(uint8_t);
 uint32_t get_arp_buf(void);
 uint32_t get_nd_buf(void);
+extern int my_inet_pton_ipv6(int af, const char *src, void *dst);
+extern struct rte_hash *arp_hash_handle;
+extern struct rte_hash *nd_hash_handle;
+extern uint32_t lib_arp_get_mac_req;
+extern uint32_t lib_arp_nh_found;
+extern uint32_t lib_arp_no_nh_found;
+extern uint32_t lib_arp_arp_entry_found;
+extern uint32_t lib_arp_no_arp_entry_found;
+extern uint32_t lib_arp_populate_called;
+extern uint32_t lib_arp_delete_called;
+extern uint32_t lib_arp_duplicate_found;
+extern uint32_t arp_route_tbl_index;
+extern uint32_t lib_nd_get_mac_req;
+extern uint32_t lib_nd_nh_found;
+extern uint32_t lib_nd_no_nh_found;
+extern uint32_t lib_nd_nd_entry_found;
+extern uint32_t lib_nd_no_arp_entry_found;
+extern uint32_t lib_nd_populate_called;
+extern uint32_t lib_nd_delete_called;
+extern uint32_t lib_nd_duplicate_found;
 
 enum {
        ARP_FOUND,
@@ -228,12 +224,6 @@ struct table_nd_entry_data {
 } __attribute__ ((packed));
 
 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];
@@ -257,7 +247,7 @@ struct arp_data {
 * 0 if failure, and 1 if success
 */
 struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
-                                uint32_t *phy_port, struct ether_addr *hw_addr);
+                                uint32_t phy_port, struct ether_addr *hw_addr);
 
 /**
 * To get the destination mac address for IPV6 address
@@ -272,10 +262,6 @@ struct arp_entry_data *get_dest_mac_addr_port(const uint32_t ipaddr,
 * @return
 * 0 if failure, 1 ifsuccess
 */
-
-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);
@@ -524,4 +510,10 @@ uint32_t get_nh(uint32_t, uint32_t *, struct ether_addr *addr);
 * next hop ipv6
 */
 void get_nh_ipv6(uint8_t ipv6[], uint32_t *port, uint8_t nhipv6[], struct ether_addr *hw_addr);
+
+struct arp_entry_data *get_dest_mac_addr_ipv4(const uint32_t nhip,
+                   uint32_t phy_port, struct ether_addr *hw_addr);
+struct nd_entry_data *get_dest_mac_addr_ipv6(uint8_t nhipv6[],
+                   uint32_t phy_port, struct ether_addr *hw_addr);
+
 #endif
index 8b74816..01bde70 100644 (file)
 #ifndef _TSX_H_
 #define _RSX_H_
 #include <rte_atomic.h>
+
+#ifndef TRUE
 #define TRUE 1
+#endif
+
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 volatile int mutex_val;
 
index 6b42ad7..607d13d 100644 (file)
@@ -70,6 +70,14 @@ struct cmd_arp_add_result {
 
 };
 
+uint16_t str2flowtype(char *string);
+int parse_flexbytes(const char *q_arg, uint8_t *flexbytes,
+        uint16_t max_num);
+enum rte_eth_input_set_field str2inset(char *string);
+int app_pipeline_arpicmp_entry_dbg(struct app_params *app,
+                       uint32_t pipeline_id, uint8_t *msg);
+
+
 static void
 cmd_arp_add_parsed(void *parsed_result,
                         __rte_unused struct cmdline *cl, __rte_unused void *data)
@@ -952,8 +960,7 @@ cmdline_parse_inst_t cmd_set_fwd_mode = {
 
 #if 1
 
-static uint16_t
-str2flowtype(char *string)
+uint16_t str2flowtype(char *string)
 {
        uint8_t i = 0;
        static const struct {
@@ -983,7 +990,7 @@ str2flowtype(char *string)
        return RTE_ETH_FLOW_UNKNOWN;
 }
 
-static inline int
+int
 parse_flexbytes(const char *q_arg, uint8_t *flexbytes, uint16_t max_num)
 {
        char s[256];
@@ -1442,7 +1449,7 @@ struct cmd_set_hash_input_set_result {
        cmdline_fixed_string_t select;
 };
 
-static enum rte_eth_input_set_field
+enum rte_eth_input_set_field
 str2inset(char *string)
 {
        uint16_t i;
@@ -1966,7 +1973,7 @@ cmdline_parse_inst_t cmd_set_sym_hash_ena_per_port = {
 };
 #endif
 
-static int
+int
 app_pipeline_arpicmp_entry_dbg(struct app_params *app,
                                        uint32_t pipeline_id, uint8_t *msg)
 {
index 1dbf34a..481f852 100644 (file)
@@ -50,6 +50,7 @@
 #include "lib_arp.h"
 #include "lib_icmpv6.h"
 #include "interface.h"
+#include "gateway.h"
 
 /* Shared among all VNFs including LB */
 struct app_params *myApp;
@@ -811,7 +812,7 @@ static void *pipeline_arpicmp_init(struct pipeline_params *params,
 
        p_arp->receivedPktCount = 0;
        p_arp->droppedPktCount = 0;
-
+       gw_init(rte_eth_dev_count());
        lib_arp_init(params, app);
 
        /* Pipeline */
index 5d6976b..6fc6109 100644 (file)
@@ -33,6 +33,9 @@
 #include "pipeline_common_fe.h"
 #include "interface.h"
 #include "lib_arp.h"
+#include "gateway.h"
+
+void app_run_file(cmdline_parse_ctx_t *ctx, const char *file_name);
 
 int
 app_pipeline_ping(struct app_params *app,
@@ -541,12 +544,12 @@ app_link_down(struct app_params *app,
  */
 struct cmd_routeadd_config_result {
         cmdline_fixed_string_t routeadd_string;
+        cmdline_fixed_string_t type_string;
         uint32_t port_id;
         cmdline_ipaddr_t ip;
         cmdline_fixed_string_t depth;
 };
 
-extern struct lib_nd_route_table_entry lib_nd_route_table[MAX_ND_RT_ENTRY];
 extern struct arp_data *p_arp_data;
 extern uint32_t nd_route_tbl_index;
 
@@ -556,25 +559,48 @@ extern uint32_t nd_route_tbl_index;
 int app_routeadd_config_ipv4(__attribute__((unused)) struct app_params *app,
        uint32_t port_id, uint32_t ip, uint32_t mask)
 {
-       if (port_id > MAX_PORTS) {
-               printf("Max ports allowed is %d\n", MAX_PORTS);
+       uint32_t i = 0;
+       if (port_id >= gw_get_num_ports()) {
+               printf("Max ports allowed is %d\n", gw_get_num_ports());
                return 1;
        }
 
-       printf("port id:%d ip: %x mask:%x", port_id, ip, mask);
+       printf("port id:%d ip: %x mask:%x\n", port_id, ip, mask);
+
+       struct route_table_entry *lentry = NULL;
+
+       /* Check for matching entry */
+       for(i = 0 ; i< p_route_data[port_id]->route_ent_cnt; i++) {
+
+               lentry = &p_route_data[port_id]->route_table[i];
+
+               /* Entry already exists? */
+               if(mask == 0) {
+                       if(lentry->nh == ip)
+                               return 1;
+               } else {
+                       if( lentry->nh_mask == (ip & mask))
+                               return 1;
+               }
+       }
+       if(i < MAX_ROUTE_ENTRY_SIZE) {
+
+               lentry = &p_route_data[port_id]->route_table[i];
 
-       struct lib_arp_route_table_entry *lentry =
-               &p_arp_data->lib_arp_route_table
-               [port_id];
-               if (!lentry->ip)
-                       p_arp_data->lib_arp_route_ent_cnt++;
-               lentry->ip = ip;
+               p_route_data[port_id]->route_ent_cnt++;
                lentry->mask = mask;
                lentry->port = port_id;
                lentry->nh = ip;
-               lentry->nh_mask = ip & mask;
+               lentry->nh_mask = (ip & mask);
+               /* Set the VNF Gateway flag */
+               vnf_gateway = 1;
+               return 0;
+       } else {
+
+               printf("Error: Number of entries more than supported\n");
+               return 1;
+       }
 
-       return 0;
 }
 
 /*
@@ -585,8 +611,8 @@ int app_routeadd_config_ipv6(__attribute__((unused)) struct app_params *app,
 {
        int i;
 
-       if (port_id > MAX_ND_RT_ENTRY) {
-               printf("Max ports allowed is %d\n", MAX_ND_RT_ENTRY);
+       if (port_id >= gw_get_num_ports()) {
+               printf("Max ports allowed is %d\n", gw_get_num_ports());
                return 1;
        }
 
@@ -594,25 +620,72 @@ int app_routeadd_config_ipv6(__attribute__((unused)) struct app_params *app,
                nd_route_tbl_index++;
 
        printf("port id:%d depth:%d\n", port_id, depth);
-       printf("ipv6 address ");
-       for (i = 0; i < 16; i++) {
-               lib_nd_route_table[port_id].ipv6[i] = ipv6[i];
-               lib_nd_route_table[port_id].nhipv6[i] = ipv6[i];
-               printf("%x ", ipv6[i]);
-       }
+       printf("ipv6 address: ");
+       for(i = 0; i < IPV6_ADD_SIZE; i++)
+               printf("%02x ", ipv6[i]);
        printf("\n");
 
+       struct nd_route_table_entry *lentry = NULL;
+       int k;
+       uint8_t netmask_ipv6[16], netip_nd[16], netip_in[16];
+       uint8_t depthflags = 0, depthflags1 = 0;
 
-       lib_nd_route_table[port_id].depth = depth;
-       lib_nd_route_table[port_id].port = port_id;
+       i = 0;
 
-       printf("num ports :%d\n", nd_route_tbl_index);
+       /* Check for matching entry */
+       for(i = 0 ; i< p_nd_route_data[port_id]->nd_route_ent_cnt; i++) {
 
-       return 0;
+               lentry = &p_nd_route_data[port_id]->nd_route_table[i];
+
+               memset(netmask_ipv6, 0, sizeof(netmask_ipv6));
+               memset(netip_nd, 0, sizeof(netip_nd));
+               memset(netip_in, 0, sizeof(netip_in));
+
+               /* Create netmask from depth */
+               convert_prefixlen_to_netmask_ipv6(lentry->depth, netmask_ipv6);
+
+               for (k = 0; k < 16; k++) {
+                       if (lentry->nhipv6[k] & netmask_ipv6[k]) {
+                               depthflags++;
+                               netip_nd[k] = lentry->nhipv6[k];
+                       }
+
+                       if (ipv6[k] & netmask_ipv6[k]) {
+                               depthflags1++;
+                               netip_in[k] = ipv6[k];
+                       }
+               }
+
+               if ((depthflags == depthflags1)
+                               && (memcmp(netip_nd, netip_in, sizeof(netip_nd)) == 0)) {
+                               /* Route already exists */
+                       printf("Route already exists \n");
+                               return 1;
+               }
+       }
+
+       if(i < MAX_ND_ROUTE_ENTRY_SIZE) {
+
+               lentry = &p_nd_route_data[port_id]->nd_route_table[i];
+
+               rte_mov16(lentry->nhipv6, ipv6);
+
+               lentry->depth = depth;
+               lentry->port = port_id;
+               p_nd_route_data[port_id]->nd_route_ent_cnt++;
+               /* Set the VNF Gateway flag */
+               vnf_gateway = 1;
+
+               return 0;
+       } else {
+
+               printf("Error: Number of entries more than supported\n");
+               return 1;
+       }
 }
 
 /*
- * cmd handler for handling route add entry at runtime.
+ * cmd handler for handling route abj entry at runtime.
  * the same handle takes care of both ipv4 & ipv6
  */
 static void
@@ -629,15 +702,30 @@ cmd_routeadd_parsed(
        uint32_t i, ip = 0, depth = 0, mask = 0;
         uint8_t ipv6[16];
 
+       printf("Adding route for %s \n", params->type_string);
+
         if (params->ip.family == AF_INET) {
                 ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-                               mask = strtoul(params->depth, NULL, 16);
-               printf("ip:%x mask:%x port_id:%d\n", ip, mask, port_id);
+
+               if(strcmp(params->type_string, "net") == 0)
+               {
+                       mask = strtoul(params->depth, NULL, 16);
+               } else {
+                       mask = 0xffffffff;
+               }
+
+               printf("nhip:0x%08x mask:%x port_id:%d\n", ip, mask, port_id);
        } else {
                 memcpy(ipv6, params->ip.addr.ipv6.s6_addr, 16);
-                               depth = atoi(params->depth);
-               for (i=0;i<16;i++)
-                       printf("%d ", ipv6[i]);
+               if(strcmp(params->type_string, "net") == 0)
+               {
+                       depth = atoi(params->depth);
+               } else {
+                       depth = 64;
+               }
+
+               for (i=0; i < 16; i++)
+                       printf("%02x ", ipv6[i]);
                printf("\n port_id:%d depth:%d \n", port_id, depth);
        }
 
@@ -657,6 +745,14 @@ cmdline_parse_token_string_t cmd_routeadd_config_string =
         TOKEN_STRING_INITIALIZER(struct cmd_routeadd_config_result, routeadd_string,
                 "routeadd");
 
+cmdline_parse_token_string_t cmd_routeadd_net_string =
+        TOKEN_STRING_INITIALIZER(struct cmd_routeadd_config_result, type_string,
+                "net");
+
+cmdline_parse_token_string_t cmd_routeadd_host_string =
+        TOKEN_STRING_INITIALIZER(struct cmd_routeadd_config_result, type_string,
+                "host");
+
 cmdline_parse_token_num_t cmd_routeadd_config_port_id =
         TOKEN_NUM_INITIALIZER(struct cmd_routeadd_config_result, port_id, UINT32);
 
@@ -666,15 +762,29 @@ cmdline_parse_token_ipaddr_t cmd_routeadd_config_ip =
 cmdline_parse_token_string_t cmd_routeadd_config_depth_string =
         TOKEN_STRING_INITIALIZER(struct cmd_routeadd_config_result, depth, NULL);
 
-cmdline_parse_inst_t cmd_routeadd = {
+cmdline_parse_inst_t cmd_routeadd_net = {
         .f = cmd_routeadd_parsed,
         .data = NULL,
-        .help_str = "Add Route entry",
+        .help_str = "Add Route entry for gateway",
         .tokens = {
                 (void *) &cmd_routeadd_config_string,
+                (void *) &cmd_routeadd_net_string,
                 (void *) &cmd_routeadd_config_port_id,
-                               (void *) &cmd_routeadd_config_ip,
-                               (void *) &cmd_routeadd_config_depth_string,
+               (void *) &cmd_routeadd_config_ip,
+               (void *) &cmd_routeadd_config_depth_string,
+                NULL,
+        },
+};
+
+cmdline_parse_inst_t cmd_routeadd_host = {
+        .f = cmd_routeadd_parsed,
+        .data = NULL,
+        .help_str = "Add Route entry for host",
+        .tokens = {
+                (void *) &cmd_routeadd_config_string,
+                (void *) &cmd_routeadd_host_string,
+                (void *) &cmd_routeadd_config_port_id,
+               (void *) &cmd_routeadd_config_ip,
                 NULL,
         },
 };
@@ -1469,7 +1579,7 @@ static cmdline_parse_inst_t cmd_quit = {
  * run
  */
 
-static void
+void
 app_run_file(
        cmdline_parse_ctx_t *ctx,
        const char *file_name)
@@ -1525,7 +1635,8 @@ cmdline_parse_inst_t cmd_run = {
 static cmdline_parse_ctx_t pipeline_common_cmds[] = {
        (cmdline_parse_inst_t *) &cmd_quit,
        (cmdline_parse_inst_t *) &cmd_run,
-       (cmdline_parse_inst_t *) &cmd_routeadd,
+       (cmdline_parse_inst_t *) &cmd_routeadd_net,
+       (cmdline_parse_inst_t *) &cmd_routeadd_host,
 
        (cmdline_parse_inst_t *) &cmd_link_config,
        (cmdline_parse_inst_t *) &cmd_link_up,
index 425e233..cc50497 100644 (file)
@@ -28,6 +28,8 @@
 #include "app.h"
 #include "pipeline_master_be.h"
 
+struct cmdline *pipe_cl;
+
 struct pipeline_master {
        struct app_params *app;
        struct cmdline *cl;
@@ -59,6 +61,7 @@ pipeline_init(__rte_unused struct pipeline_params *params, void *arg)
                rte_free(p);
                return NULL;
        }
+       pipe_cl = p->cl;
 
        p->script_file_done = 0;
        if (app->script_file == NULL)
@@ -85,6 +88,7 @@ static int
 pipeline_run(void *pipeline)
 {
        struct pipeline_master *p = (struct pipeline_master *) pipeline;
+
        int status;
 
        if (p->script_file_done == 0) {
index 51c40c9..752780d 100644 (file)
@@ -566,6 +566,17 @@ do {                                                                       \
                fprintf(stdout, "[APP] " fmt "\n", ## __VA_ARGS__);     \
 } while (0)
 
+#ifdef REST_API_SUPPORT
+static inline int rest_api_supported(void)
+{
+       return 1;
+}
+#else
+static inline int rest_api_supported(void)
+{
+       return 0;
+}
+#endif
 static inline uint32_t
 app_link_get_n_rxq(struct app_params *app, struct app_link_params *link)
 {
@@ -955,6 +966,11 @@ int app_config_check(struct app_params *app);
 
 int app_init(struct app_params *app);
 
+struct mg_context *rest_api_init(struct app_params *app);
+void set_vnf_type(const char *type);
+uint32_t is_rest_support(void);
+extern uint32_t rest_support;
+
 int app_thread(void *arg);
 
 int app_pipeline_type_register(struct app_params *app,
index 5f7ec8a..eeb547e 100644 (file)
@@ -35,6 +35,7 @@
 /**
  * Default config values
  **/
+uint32_t rest_support = 1;
 
 static struct app_params app_params_default = {
        .config_file = "./config/ip_pipeline.cfg",
@@ -239,6 +240,11 @@ do {                                                                       \
                "Parse error in section \"%s\"", section_name);         \
 } while (0)
 
+uint32_t is_rest_support(void)
+{
+       return rest_support;
+}
+
 int
 parser_read_arg_bool(const char *p)
 {
@@ -3264,6 +3270,9 @@ app_config_args(struct app_params *app, int argc, char **argv)
                                        "more than once\n");
                        f_present = 1;
 
+                       /* REST API not needed as user has supplied the config file */
+                       rest_support = 0;
+
                        if (!strlen(optarg))
                                rte_panic("Error: Config file name is null\n");
 
@@ -3271,6 +3280,7 @@ app_config_args(struct app_params *app, int argc, char **argv)
                        if (app->config_file == NULL)
                                rte_panic("Error: Memory allocation failure\n");
 
+
                        break;
 
                case 's':
diff --git a/common/vnf_common/rest_api.c b/common/vnf_common/rest_api.c
new file mode 100644 (file)
index 0000000..62e9646
--- /dev/null
@@ -0,0 +1,2448 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_hash.h>
+#include <rte_ethdev.h>
+#include <rte_cycles.h>
+#include <rte_timer.h>
+#include <rte_debug.h>
+#include <rte_cfgfile.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cmdline_rdline.h>
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline_parse_ipaddr.h>
+#include <cmdline_parse_etheraddr.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+
+#include "pipeline_common_fe.h"
+#include "pipeline_arpicmp.h"
+
+#include <civetweb.h>
+#include <json/json.h>
+#include "app.h"
+#include "lib_arp.h"
+#include "interface.h"
+#include "tsx.h"
+#include "gateway.h"
+
+#define MAX_PIPELINES          30
+#define MAX_VNFS               3
+#define CFG_NAME_LEN           64
+#define MAX_CORES              64
+#define MAX_SOCKET             2
+#define MAX_BUF_SIZE           2048
+#define MAX_SIZE               24
+#define MAX_LINKS              64
+#define MAX_LB                 20
+#define        msleep(x)               rte_delay_us(x * 1000)
+
+const char *pipelines[9] = {"MASTER", "ARPICMP", "TIMER", "TXRX-BEGIN",
+                        "TXRX-END", "LOADB", "VACL", "VCGNAPT", "VFW"};
+const char *VNFS[] = {"VACL", "VCGNAPT", "VFW"};
+struct mg_context *ctx;
+struct pub_ip_range {
+       char value[MAX_BUF_SIZE];
+};
+
+struct stat_cfg {
+       uint8_t num_workers;
+       uint8_t num_lb;
+       uint8_t num_ports;
+       uint8_t hyper_thread;
+       uint8_t sock_in;
+       uint8_t sw_lb;
+       char vnf_type[MAX_SIZE];
+       char pkt_type[MAX_SIZE];
+       char pci_white_list[MAX_BUF_SIZE];
+       struct pub_ip_range ip_range[MAX_LB];
+};
+
+struct arp_params {
+       uint8_t family;
+       uint8_t action;
+       union {
+               uint32_t ip;
+               uint8_t ipv6[16];
+       };
+       uint32_t portid;
+       struct ether_addr mac_addr;
+};
+
+struct link_params {
+       uint32_t id;
+       uint32_t state;
+       union {
+               uint32_t ip;
+               uint8_t ipv6[16];
+       };
+       uint32_t depth;
+       uint32_t family;
+};
+
+struct route_params {
+       uint32_t enable;
+       union {
+               uint32_t ip;
+               uint8_t ipv6[16];
+       };
+       uint32_t depth;
+       uint32_t family;
+       char type[255];
+};
+
+struct dbg_mode {
+       uint32_t  cmd;
+       uint32_t  d1;
+       uint32_t  pipe_num;
+};
+
+struct dbg_mode        current_dbg;
+struct link_params     current_link_parms[MAX_LINKS];
+struct stat_cfg                current_cfg;
+struct arp_params      current_arp_parms;
+struct route_params    current_route_parms[MAX_LINKS];
+
+static int static_cfg_set = 0;
+uint8_t pipe_arr[MAX_PIPELINES];
+uint8_t num_pipelines;
+uint8_t num_workers, pub_ip = 0, ip_range = 0, num_lb = 1, num_ports;
+uint8_t num_entries, start_lb, end_lb, start_lbout;
+uint8_t swq_index = 0, workers = 0;
+uint8_t txq_index = 0, sw_lb = 1;
+uint8_t rxq_index = 0;
+uint8_t arp_index = 0, tx_start_port = 0, rx_start_port = 0;
+uint8_t pipenum = 0, hyper_thread = 0;
+char traffic_type[4] = "4";
+struct rte_cfgfile_entry entries[30];
+int n_entries1 = 0;
+char loadb_in[256];
+char vnf_type[256];
+uint8_t sock_cpus[MAX_SOCKET][MAX_CORES];
+uint8_t sock_in = 0, sock0 = 0, sock1 = 0, sock_index = 0;
+int hyper = 0;
+uint32_t flow_dir_cfg = 0;
+struct app_params *rapp;
+
+extern uint32_t nd_route_tbl_index;
+extern struct arp_data *p_arp_data;
+extern int USE_RTM_LOCKS;
+extern rte_rwlock_t rwlock;
+extern interface_main_t ifm;
+extern struct cmdline *pipe_cl;
+extern uint16_t str2flowtype(char *string);
+extern void app_run_file(cmdline_parse_ctx_t *ctx, const char *file_name);
+extern int parse_flexbytes(const char *q_arg, uint8_t *flexbytes,
+                        uint16_t max_num);
+extern int app_pipeline_arpicmp_entry_dbg(struct app_params *app,
+                                    uint32_t pipeline_id, uint8_t *msg);
+extern unsigned eal_cpu_socket_id(unsigned cpu_id);
+extern int app_routeadd_config_ipv4(__attribute__((unused))
+                                        struct app_params *app,
+                                       uint32_t port_id, uint32_t ip,
+                                        uint32_t mask);
+extern int app_routeadd_config_ipv6(__attribute__((unused))
+                                        struct app_params *app,
+                                       uint32_t port_id, uint8_t ipv6[],
+                                        uint32_t depth);
+
+enum rte_eth_input_set_field str2inset(char *string);
+
+enum {
+       MASTER = 0,
+       ARPICMP,
+       TIMER,
+       TXRX_BEGIN,
+       TXRX_END,
+       LOADB,
+       VNF_VACL,
+       VNF_VCGNAPT,
+       VNF_VFW,
+       PIPE_MAX
+};
+
+struct json_data {
+       char key[256];
+       char value[256];
+};
+
+struct json_data static_cfg[40];
+uint32_t post_not_received = 1;
+
+int flow_director_handler(struct mg_connection *conn,
+        __rte_unused void *cbdata);
+int vnf_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+void init_stat_cfg(void);
+void bind_the_ports(struct mg_connection *conn, char *pci_white_list);
+int route_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int dbg_pipelines_handler(struct mg_connection *conn,
+        __rte_unused void *cbdata);
+int dbg_pipelines_id_handler(struct mg_connection *conn,
+        __rte_unused void *cbdata);
+int get_pipelines_tokens(char *buf);
+void get_swq_offset(uint8_t start, uint8_t num, char *buf);
+void get_swq(uint8_t num, char *buf);
+void get_txq(uint8_t start_q, uint8_t queue_num, uint8_t ports, char *buf);
+void get_rxq(uint8_t start_q, uint8_t queue_num, uint8_t ports, char *buf);
+void fix_pipelines_data_types(FILE *f, const char *sect_name,
+                        struct rte_cfgfile *tcfg);
+void print_to_file(FILE *f, struct rte_cfgfile *tcfg);
+int get_vnf_index(void);
+void build_pipeline(void);
+void get_pktq_in_prv(char *buf);
+void get_prv_to_pub_map(char *buf);
+void get_prv_que_handler(char *buf);
+int static_cfg_handler(struct mg_connection *conn, void *cbdata);
+int link_handler(struct mg_connection *conn, void *cbdata);
+int linkid_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int arp_handler(struct mg_connection *conn, void *cbdata);
+int arpls_handler(struct mg_connection *conn, void *cbdata);
+int nd_handler(struct mg_connection *conn, void *cbdata);
+int linkls_handler(struct mg_connection *conn, void *cbdata);
+int set_hash_input_set_2(struct mg_connection *conn, uint32_t port_id,
+        const char *flow_type, const char *inset_field0,
+        const char *inset_field1, const char *select);
+int set_hash_input_set_4(struct mg_connection *conn, uint32_t port_id,
+       char *flow_type, char *inset_field0, char *inset_field1,
+       char *inset_field2, char *inset_field3, const char *select);
+int set_hash_global_config(struct mg_connection *conn, uint32_t port_id,
+       char *flow_type, const char *hash_func, const char *enable);
+int set_sym_hash_per_port(struct mg_connection *conn, uint32_t port_id);
+int cmd_quit_handler(struct mg_connection *conn, void *cbdata);
+int dbg_run_handler(struct mg_connection *conn, void *cbdata);
+int dbg_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int dbg_cmd_handler(struct mg_connection *conn, void *cbdata);
+int run_field_found(const char *key, const char *filename, char *path,
+            size_t pathlen, void *user_data);
+int run_field_get(const char *key, const char *value, size_t valuelen,
+        void *user_data);
+int run_field_stored(const char *path, long long file_size, void *user_data);
+void print_interface_details_rest(struct mg_connection *conn, uint32_t link);
+void print_link_info(struct app_link_params *p, struct mg_connection *conn);
+int get_link_tokens(char *buf);
+void get_mac(struct ether_addr *mac_addr, char *buf);
+
+int run_field_found(const char *key, const char *filename, char *path,
+       size_t pathlen, void *user_data)
+{
+        struct mg_connection *conn = (struct mg_connection *)user_data;
+
+        mg_printf(conn, "\r\n\r\n%s:\r\n", key);
+
+        if (filename && *filename) {
+               snprintf(path, pathlen, "%s", filename);
+               int fd;
+
+               /* Make sure file exists before clearing rules and actions */
+               fd = open(filename, O_RDONLY);
+               if (fd < 0) {
+                       mg_printf(conn, "Cannot open file \"%s\"\n", filename);
+                       return FORM_FIELD_STORAGE_GET;
+               }
+
+               close(fd);
+               mg_printf(conn, "file to be loaded is %s\n", filename);
+               app_run_file(pipe_cl->ctx, filename);
+
+               return FORM_FIELD_STORAGE_STORE;
+       }
+        
+       return FORM_FIELD_STORAGE_GET;
+}
+
+int run_field_get(const char *key, const char *value, size_t valuelen,
+        void *user_data)
+{
+        struct mg_connection *conn = (struct mg_connection *)user_data;
+
+        if (key[0]) {
+                mg_printf(conn, "%s = ", key);
+        }
+        mg_write(conn, value, valuelen);
+
+        return 0;
+}
+
+int run_field_stored(const char *path, long long file_size, void *user_data)
+{
+        struct mg_connection *conn = (struct mg_connection *)user_data;
+
+        mg_printf(conn,
+                  "stored as %s (%lu bytes)\r\n\r\n",
+                  path,
+                  (unsigned long)file_size);
+
+        return 0;
+}
+
+int dbg_run_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+        struct mg_form_data_handler fdh = {run_field_found, run_field_get,
+                                        run_field_stored, NULL};
+
+        if (strcmp(req_info->request_method, "POST")) {
+
+                mg_printf(conn,
+                          "HTTP/1.1 405 Method Not Allowed\r\nConnection:");
+               mg_printf(conn," close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+
+        /* It would be possible to check the request info here before calling
+         * mg_handle_form_request. */
+        (void)req_info;
+
+        mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: ");
+        mg_printf(conn, "text/plain\r\nConnection: close\r\n\r\n");
+        if (strcmp(req_info->request_method, "PUT")) {
+               mg_printf(conn, "Only PUT method allowed");
+               return 1;
+       }
+
+        fdh.user_data = (void *)conn;
+
+        /* Call the form handler */
+        mg_handle_form_request(conn, &fdh);
+        mg_printf(conn, "\r\n script file handled");
+
+        return 1;
+}
+
+int cmd_quit_handler(__rte_unused struct mg_connection *conn,
+                __rte_unused void *cbdata)
+{
+       cmdline_quit(pipe_cl);
+       return 0;
+}
+
+int dbg_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+
+        const struct mg_request_info *ri = mg_get_request_info(conn);
+
+        if (!strcmp(ri->request_method, "GET")) {
+               mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n");
+               mg_printf(conn, "Connection: close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "<h2> These are the methods supported</h2>");
+               mg_printf(conn, "<h3>     /pipelines\n</h3>");
+               mg_printf(conn, "<h3>     /cmd \n</h3>");
+               mg_printf(conn, "<h3>     /run\n</h3>");
+               mg_printf(conn, "</body></html>");
+       }
+
+       return 1;
+
+}
+
+int get_pipelines_tokens(char *buf)
+{
+        char *token;
+        uint32_t id;
+
+        token = strtok(buf, "/ ");
+        if (strcmp(token, "pipelines")) {
+                return -1;
+        }
+
+        token = strtok(NULL, "/ ");
+        id = atoi(token);
+        if (id > rapp->n_pipelines) {
+                return -1;
+        }
+
+        return id;
+}
+
+
+int dbg_pipelines_id_handler(struct mg_connection *conn,
+                        __rte_unused void *cbdata)
+{
+       struct app_eal_params *p = &rapp->eal_params;
+        const struct mg_request_info *ri = mg_get_request_info(conn);
+        //uint32_t id = (uint32_t *)cbdata;
+
+       mg_printf(conn, "Inside dbg_pipelines_id_handler\n");
+
+        if (!strcmp(ri->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               if (p->log_level_present) {
+                      mg_printf(conn, "<h2> The pipeline log level is %d</h2>",
+                               p->log_level);
+               } else {
+                      mg_printf(conn, "<h2> No log level found in the\
+                               pipeline</h2>");
+               }
+               mg_printf(conn, "</body></html>");
+       }
+
+       return 1;
+
+}
+
+
+int dbg_pipelines_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+
+       uint32_t i;
+        const struct mg_request_info *ri = mg_get_request_info(conn);
+
+        if (!strcmp(ri->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "<h2> These are pipelines available</h2>");
+               for (i = 0; i < rapp->n_pipelines; i++) {
+                       mg_printf(conn, "<h3> pipeline %d:      %s\n</h3>",i,
+                               rapp->pipeline_params[i].type);
+               }
+               mg_printf(conn, "</body></html>");
+       }
+
+       return 1;
+
+}
+
+int dbg_cmd_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        struct app_params *app = rapp;
+        uint8_t msg[2];
+        int status;
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+       char buf[MAX_BUF_SIZE];
+        
+       if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "<h2> The last command executed </h2>");
+               mg_printf(conn, "<h3>     cmd: %d\n </h3>", current_dbg.cmd);
+               mg_printf(conn, "<h3>     d1 : %d\n </h3>", current_dbg.d1);
+               mg_printf(conn, "<h3>     pipeline : %d\n </h3>",
+                                current_dbg.pipe_num);
+               mg_printf(conn, "</body></html>\n");
+
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                       "HTTP/1.1 405 Method Not Allowed\r\nConnection:");
+               mg_printf(conn, " close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn, "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        mg_printf(conn, "</body></html>\n");
+        
+       mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       json_object_object_foreach(jobj, key, val) {
+               if (!strcmp(key, "cmd")) {
+                       current_dbg.cmd = atoi(json_object_get_string(val));
+               } else if (!strcmp(key, "d1")) {
+                       current_dbg.d1 = atoi(json_object_get_string(val));
+               } else if (!strcmp(key, "pipeline")) {
+                       current_dbg.pipe_num = atoi(json_object_get_string(val));
+               }
+       }
+
+
+        msg[0] = current_dbg.cmd;
+        msg[1] = current_dbg.d1;
+        status = app_pipeline_arpicmp_entry_dbg(app, current_dbg.pipe_num, msg);
+
+        if (status != 0) {
+                mg_printf(conn, "Dbg Command failed\n");
+                return 1;
+        }
+
+       return 1;
+}
+
+int set_sym_hash_per_port(struct mg_connection *conn, uint32_t port_id)
+{
+        int ret;
+        struct rte_eth_hash_filter_info info;
+
+        if (rte_eth_dev_filter_supported(port_id,
+                 RTE_ETH_FILTER_HASH) < 0) {
+                mg_printf(conn, "RTE_ETH_FILTER_HASH not supported on port: %d\n",
+                        port_id);
+                return 1;
+        }
+
+        memset(&info, 0, sizeof(info));
+        info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
+
+        ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_HASH,
+                                 RTE_ETH_FILTER_SET, &info);
+        if (ret < 0) {
+                mg_printf(conn, "Cannot set symmetric hash enable per port on "
+                        "port %u\n", port_id);
+                return 1;
+        }
+
+       return 1;
+}
+
+int set_hash_input_set_4(struct mg_connection *conn, uint32_t port_id,
+       char *flow_type, char *inset_field0, char *inset_field1,
+       char *inset_field2, char *inset_field3, const char *select)
+{
+        struct rte_eth_hash_filter_info info;
+
+        if (enable_flow_dir) {
+                mg_printf(conn, "FDIR Filter is Defined!\n");
+                mg_printf(conn, "Please undefine FDIR_FILTER flag and define "
+                        "HWLD flag\n");
+                return 1;
+        }
+
+        memset(&info, 0, sizeof(info));
+        info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+        info.info.input_set_conf.flow_type = str2flowtype(flow_type);
+
+        info.info.input_set_conf.field[0] = str2inset(inset_field0);
+        info.info.input_set_conf.field[1] = str2inset(inset_field1);
+        info.info.input_set_conf.field[2] = str2inset(inset_field2);
+        info.info.input_set_conf.field[3] = str2inset(inset_field3);
+
+        info.info.input_set_conf.inset_size = 4;
+        if (!strcmp(select, "select"))
+                info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+        else if (!strcmp(select, "add"))
+                info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+
+        rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_HASH,
+                RTE_ETH_FILTER_SET, &info);
+
+        mg_printf(conn, "Command Passed!\n");
+       return 1;
+}
+
+int set_hash_input_set_2(struct mg_connection *conn, uint32_t port_id,
+        const char *flow_type, const char *inset_field0,
+        const char *inset_field1, const char *select)
+{
+        struct rte_eth_hash_filter_info info;
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                    "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        mg_printf(conn, "</body></html>\n");
+
+        if (enable_flow_dir) {
+                mg_printf(conn, "FDIR Filter is Defined!\n");
+                mg_printf(conn, "Please undefine FDIR_FILTER flag and define "
+                        "HWLD flag\n");
+                return 1;
+        }
+
+        if (enable_flow_dir) {
+                mg_printf(conn, "FDIR Filter is Defined!\n");
+                mg_printf(conn, "Please undefine FDIR_FILTER flag and define "
+                        "HWLD flag\n");
+                return 1;
+        }
+
+        memset(&info, 0, sizeof(info));
+        info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+        info.info.input_set_conf.flow_type = str2flowtype(strdup(flow_type));
+
+        info.info.input_set_conf.field[0] = str2inset(strdup(inset_field0));
+        info.info.input_set_conf.field[1] = str2inset(strdup(inset_field1));
+
+        info.info.input_set_conf.inset_size = 2;
+
+        if (!strcmp(select, "select"))
+                info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+        else if (!strcmp(select, "add"))
+                info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+
+        rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_HASH,
+                RTE_ETH_FILTER_SET, &info);
+
+        mg_printf(conn, "Command Passed!\n");
+       return 1;
+}
+
+void print_interface_details_rest(struct mg_connection *conn, uint32_t link)
+{
+       l2_phy_interface_t *port;
+       int i = 0;
+       struct sockaddr_in ip;
+       mg_printf(conn, "\n\r");
+
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+
+       i = link;
+       port = ifm.port_list[i];
+       mg_printf(conn, "%u", port->pmdid);
+       if (port->ifname && strlen(port->ifname)) {
+               mg_printf(conn, " (%s)\t", port->ifname);
+       } else
+               mg_printf(conn, "\t\t");
+       mg_printf(conn, "MAC:%02x:%02x:%02x:%02x:%02x:%02x Adminstate:%s"
+                                " Operstate:%s \n\r<br/>",
+                                port->macaddr[0], port->macaddr[1],
+                                port->macaddr[2], port->macaddr[3],
+                                port->macaddr[4], port->macaddr[5],
+                                port->admin_status ? "UP" : "DOWN",
+                                port->link_status ? "UP" : "DOWN");
+       mg_printf(conn, "\t\t");
+       mg_printf(conn, "Speed: %u, %s-duplex\n\r<br/>", port->link_speed,
+                                port->link_duplex ? "full" : "half");
+       mg_printf(conn, "\t\t");
+
+       if (port->ipv4_list != NULL) {
+               ip.sin_addr.s_addr =
+                               (unsigned long)((ipv4list_t *) (port->ipv4_list))->
+                               ipaddr;
+               mg_printf(conn, "IP: %s/%d", inet_ntoa(ip.sin_addr),
+                                        ((ipv4list_t *) (port->ipv4_list))->addrlen);
+       } else {
+               mg_printf(conn, "IP: NA");
+       }
+
+       mg_printf(conn, "\r\n<br/>");
+       mg_printf(conn, "\t\t");
+       if (port->ipv6_list != NULL) {
+               uint8_t *addr =
+                               ((ipv6list_t *) (port->ipv6_list))->ipaddr;
+               mg_printf(conn, "IPv6: %02x%02x:%02x%02x:%02x%02x:"
+                               "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+                                addr[0], addr[1], addr[2], addr[3], addr[4],
+                                addr[5], addr[6], addr[7], addr[8], addr[9],
+                                addr[10], addr[11], addr[12], addr[13], addr[14],
+                                addr[15]);
+       } else {
+               mg_printf(conn, "IPv6: NA");
+       }
+
+       if (port->flags & IFM_SLAVE) {
+               mg_printf(conn, "  IFM_SLAVE ");
+               mg_printf(conn, " MasterPort: %u",
+                                        port->bond_config->bond_portid);
+       }
+       if (port->flags & IFM_MASTER) {
+               mg_printf(conn, "  IFM_MASTER ");
+               mg_printf(conn, "  Mode: %u", port->bond_config->mode);
+               mg_printf(conn, "  PrimaryPort: %u",
+                                port->bond_config->primary);
+               mg_printf(conn, "\n\r<br/>");
+               mg_printf(conn, "\t\tSlavePortCount: %u",
+                                        port->bond_config->slave_count);
+               mg_printf(conn, " SlavePorts:");
+               int i;
+               for (i = 0; i < port->bond_config->slave_count; i++) {
+                       mg_printf(conn, " %u ",
+                                port->bond_config->slaves[i]);
+               }
+               mg_printf(conn, " ActivePortCount: %u",
+                                        port->bond_config->active_slave_count);
+               mg_printf(conn, " ActivePorts:");
+               for (i = 0; i < port->bond_config->active_slave_count;
+                                i++) {
+                       mg_printf(conn, " %u ",
+                                        port->bond_config->active_slaves[i]);
+               }
+               mg_printf(conn, "\n\r<br/>");
+               mg_printf(conn, "\t\t");
+               mg_printf(conn, "Link_monitor_freq: %u ms ",
+                                        port->bond_config->internal_ms);
+               mg_printf(conn, " Link_up_prop_delay: %u ms ",
+                                        port->bond_config->link_up_delay_ms);
+               mg_printf(conn, " Link_down_prop_delay: %u ms ",
+                                        port->bond_config->link_down_delay_ms);
+               mg_printf(conn, "\n\r<br/>");
+               mg_printf(conn, "\t\t");
+               mg_printf(conn, "Xmit_policy: %u",
+                                        port->bond_config->xmit_policy);
+       }
+       mg_printf(conn, "\n\r<br/>");
+       mg_printf(conn, "\t\t");
+       mg_printf(conn, "n_rxpkts: %" PRIu64 " ,n_txpkts: %" PRIu64 " ,",
+                                port->n_rxpkts, port->n_txpkts);
+       struct rte_eth_stats eth_stats;
+       rte_eth_stats_get(port->pmdid, &eth_stats);
+       mg_printf(conn, "pkts_in: %" PRIu64 " ,", eth_stats.ipackets);
+       mg_printf(conn, "pkts_out: %" PRIu64 " ", eth_stats.opackets);
+       mg_printf(conn, "\n\r<br/>");
+       mg_printf(conn, "\t\t");
+       mg_printf(conn, "in_errs: %" PRIu64 " ,", eth_stats.ierrors);
+       mg_printf(conn, "in_missed: %" PRIu64 " ,", eth_stats.imissed);
+       mg_printf(conn, "out_errs: %" PRIu64 " ,", eth_stats.oerrors);
+       mg_printf(conn, "mbuf_errs: %" PRIu64 " ", eth_stats.rx_nombuf);
+       mg_printf(conn, "\n\r<br/>");
+       mg_printf(conn, "\n\r");
+
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_read_unlock(&rwlock);
+}
+
+void print_link_info(struct app_link_params *p, struct mg_connection *conn)
+{
+        struct rte_eth_stats stats;
+        struct ether_addr *mac_addr;
+        uint32_t netmask = (~0U) << (32 - p->depth);
+        uint32_t host = p->ip & netmask;
+        uint32_t bcast = host | (~netmask);
+
+        memset(&stats, 0, sizeof(stats));
+        rte_eth_stats_get(p->pmd_id, &stats);
+
+        mac_addr = (struct ether_addr *) &p->mac_addr;
+
+        if (strlen(p->pci_bdf))
+                mg_printf(conn, "%s(%s): flags=%s\r\n<br/>",
+                        p->name,
+                        p->pci_bdf,
+                        (p->state) ? "UP" : "DOWN");
+        else
+                mg_printf(conn, "%s: flags=%s\r\n<br/>",
+                        p->name,
+                        (p->state) ? "UP" : "DOWN");
+        if (p->ip)
+                mg_printf(conn, "\tinet %" PRIu32 ".%" PRIu32
+                        ".%" PRIu32 ".%" PRIu32
+                        " netmask %" PRIu32 ".%" PRIu32
+                        ".%" PRIu32 ".%" PRIu32 " "
+                        "broadcast %" PRIu32 ".%" PRIu32
+                        ".%" PRIu32 ".%" PRIu32 "\r\n<br/>",
+                        (p->ip >> 24) & 0xFF,
+                        (p->ip >> 16) & 0xFF,
+                        (p->ip >> 8) & 0xFF,
+                        p->ip & 0xFF,
+                        (netmask >> 24) & 0xFF,
+                        (netmask >> 16) & 0xFF,
+                        (netmask >> 8) & 0xFF,
+                        netmask & 0xFF,
+                        (bcast >> 24) & 0xFF,
+                        (bcast >> 16) & 0xFF,
+                        (bcast >> 8) & 0xFF,
+                        bcast & 0xFF);
+        mg_printf(conn, "\tether %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
+                ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\r\n<br/>",
+                mac_addr->addr_bytes[0],
+                mac_addr->addr_bytes[1],
+                mac_addr->addr_bytes[2],
+                mac_addr->addr_bytes[3],
+                mac_addr->addr_bytes[4],
+                mac_addr->addr_bytes[5]);
+
+        mg_printf(conn, "\tRX packets %" PRIu64
+                "  bytes %" PRIu64
+                "\r\n<br/>",
+                stats.ipackets,
+                stats.ibytes);
+
+        mg_printf(conn, "\tRX errors %" PRIu64
+                "  missed %" PRIu64
+                "  no-mbuf %" PRIu64
+                "\r\n<br/>",
+                stats.ierrors,
+                stats.imissed,
+                stats.rx_nombuf);
+
+        mg_printf(conn, "\tTX packets %" PRIu64
+                "  bytes %" PRIu64 "\r\n<br/>",
+                stats.opackets,
+                stats.obytes);
+
+        mg_printf(conn, "\tTX errors %" PRIu64
+                "\r\n<br/>",
+                stats.oerrors);
+
+        mg_printf(conn, "\r\n<br/>");
+}
+
+int get_link_tokens(char *buf)
+{
+        char *token;
+        int linkid;
+
+        token = strtok(buf, "/ ");
+        if (strcmp(token, "link")) {
+                return -1;
+        }
+
+        token = strtok(NULL, "/ ");
+        linkid = atoi(token);
+        if (linkid > current_cfg.num_ports) {
+                return -1;
+        }
+
+        return linkid;
+}
+
+int linkls_handler(struct mg_connection *conn, void *cbdata)
+{
+        struct app_params *app = rapp;
+
+       struct app_link_params *p;
+
+       APP_PARAM_FIND_BY_ID(app->link_params, "LINK", *(uint32_t *)cbdata, p);
+       if (p) {
+               print_link_info(p, conn);
+       }
+
+       print_interface_details_rest(conn, *(uint32_t *)cbdata);
+       return 1;
+}
+
+static const char* arp_status[] = {"INCOMPLETE", "COMPLETE", "PROBE", "STALE"};
+
+/* ND IPv6 */
+int nd_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+       const void *next_key;
+       void *next_data;
+       uint32_t iter = 0;
+       uint8_t ii = 0;
+       mg_printf(conn, "----------------------------------------------------");
+       mg_printf(conn, "-------------------------------------------------\n<br/>");
+       mg_printf(conn, "\tport  hw addr            status         ip addr\n<br/>");
+
+       mg_printf(conn, "-----------------------------------------------------");
+       mg_printf(conn, "-------------------------------------------------\n<br/>");
+       while (rte_hash_iterate(nd_hash_handle, &next_key, &next_data, &iter) >=
+                                0) {
+
+               struct nd_entry_data *tmp_nd_data =
+                               (struct nd_entry_data *)next_data;
+               struct nd_key_ipv6 tmp_nd_key;
+               memcpy(&tmp_nd_key, next_key, sizeof(struct nd_key_ipv6));
+               mg_printf(conn, "\t%4d  %02X:%02X:%02X:%02X:%02X:%02X  %10s",
+                                        tmp_nd_data->port,
+                                        tmp_nd_data->eth_addr.addr_bytes[0],
+                                        tmp_nd_data->eth_addr.addr_bytes[1],
+                                        tmp_nd_data->eth_addr.addr_bytes[2],
+                                        tmp_nd_data->eth_addr.addr_bytes[3],
+                                        tmp_nd_data->eth_addr.addr_bytes[4],
+                                        tmp_nd_data->eth_addr.addr_bytes[5],
+                                        arp_status[tmp_nd_data->status]);
+               mg_printf(conn, "\t");
+               for (ii = 0; ii < ND_IPV6_ADDR_SIZE; ii += 2) {
+                       mg_printf(conn, "%02X%02X ", tmp_nd_data->ipv6[ii],
+                                                tmp_nd_data->ipv6[ii + 1]);
+               }
+               mg_printf(conn, "\n<br/>");
+       }
+
+       mg_printf(conn, "\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<br/>",
+                        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,
+                        lib_nd_duplicate_found);
+       mg_printf(conn, "ND table key len is %lu\n\n<br/>", sizeof(struct nd_key_ipv6));
+       return 0;
+}
+
+int arpls_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+       const void *next_key;
+       void *next_data;
+       uint32_t iter = 0, len = 0;
+       char buf[1024];
+        
+       len += sprintf
+       (buf + len, "---------------------- ARP CACHE ---------------------\n<br/>");
+       len += sprintf
+       (buf + len, "------------------------------------------------------\n<br/>");
+       len += sprintf(buf + len, "\tport  hw addr            status     ip addr\n<br/>");
+       len += sprintf
+       (buf + len, "------------------------------------------------------\n<br/>");
+
+       while (rte_hash_iterate(arp_hash_handle, &next_key, &next_data, &iter)
+                                >= 0) {
+
+               struct arp_entry_data *tmp_arp_data =
+                               (struct arp_entry_data *)next_data;
+               struct arp_key_ipv4 tmp_arp_key;
+               memcpy(&tmp_arp_key, next_key, sizeof(struct arp_key_ipv4));
+               len += sprintf
+                       (buf + len, "\t%4d  %02X:%02X:%02X:%02X:%02X:%02X"
+                       "  %10s %d.%d.%d.%d\n<br/>",
+                        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],
+                        tmp_arp_data->eth_addr.addr_bytes[3],
+                        tmp_arp_data->eth_addr.addr_bytes[4],
+                        tmp_arp_data->eth_addr.addr_bytes[5],
+                        arp_status[tmp_arp_data->status],
+                        (tmp_arp_data->ip >> 24),
+                        ((tmp_arp_data->ip & 0x00ff0000) >> 16),
+                        ((tmp_arp_data->ip & 0x0000ff00) >> 8),
+                        ((tmp_arp_data->ip & 0x000000ff)));
+       }
+
+       uint32_t i = 0, j;
+       len += sprintf(buf + len, "\n<br/>IP_Address    Mask          Port\n<br/>");
+       for (j = 0; j < gw_get_num_ports(); j++) {
+               for (i = 0; i < p_route_data[j]->route_ent_cnt; i++) {
+                       len += sprintf(buf + len, "0x%08x \t 0x%08x \t %d\n<br/>",
+                       p_route_data[j]->route_table[i].nh,
+                       p_route_data[j]->route_table[i].mask,
+                       p_route_data[j]->route_table[i].port);
+               }
+       }
+
+       len += sprintf
+                       (buf + len, "\nARP Stats: Total Queries %u, ok_NH %u,"
+                       " no_NH %u, ok_Entry %u, no_Entry %u, PopulateCall %u,"
+                       " Del %u, Dup %u\n<br/>",
+                        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,
+                        lib_arp_duplicate_found);
+
+       len += sprintf(buf + len, "ARP table key len is %lu\n<br/>",
+                        sizeof(struct arp_key_ipv4));
+        mg_printf(conn, "%s\n<br/>", &buf[0]);
+        return 1; 
+}
+
+void get_mac(struct ether_addr *mac_addr, char *buf)
+{
+       uint32_t i = 0, j = 0, k = 0, MAC_NUM_BYTES = 6;
+
+       char byteStr[MAC_NUM_BYTES][3];
+
+       char *token = strtok(buf, " ");
+       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++;
+               }
+               token = strtok(NULL, " ");
+       }
+
+       for (i = 0; i < MAC_NUM_BYTES; i++) {
+               mac_addr->addr_bytes[i] = strtoul(byteStr[i], NULL, 16);
+       }
+}
+
+int arp_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+       char buf[MAX_BUF_SIZE];
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               /* prints arp table */
+               mg_printf(conn, "<html><body>");
+               arpls_handler(conn, cbdata);
+
+               /* prints nd table */
+               nd_handler(conn, cbdata);
+               mg_printf(conn, "</body></html>");
+               return 1;
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                    "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+
+        mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       json_object_object_foreach(jobj, key, val) {
+               if (!strcmp(key, "ipv4")) {
+                       current_arp_parms.ip = rte_bswap32(inet_addr(
+                               json_object_get_string(val)));
+                       current_arp_parms.family = AF_INET;
+               } else if (!strcmp(key, "ipv6")) {
+                       my_inet_pton_ipv6(AF_INET6,
+                       json_object_get_string(val),
+                                &current_arp_parms.ipv6[0]);
+                       current_arp_parms.family = AF_INET6;
+               } else if (!strcmp(key, "action")) {
+                       if (!strcmp(json_object_get_string(val), "add"))
+                               current_arp_parms.action = 1;
+                       else if (!strcmp(json_object_get_string(val), "del"))
+                               current_arp_parms.action = 2;
+                       else if (!strcmp(json_object_get_string(val), "req"))
+                               current_arp_parms.action = 3;
+               } else if (!strcmp(key, "portid")) {
+                       current_arp_parms.portid =
+                                atoi(json_object_get_string(val));
+               } else if (!strcmp(key, "macaddr")) {
+                       get_mac(&current_arp_parms.mac_addr,
+                                strdup(json_object_get_string(val)));
+               }
+       }
+
+        struct arp_key_ipv4 arp_key;
+       struct arp_timer_key *callback_key;
+        struct arp_entry_data *new_arp_data;
+        struct nd_key_ipv6 nd_key;
+        struct nd_entry_data *new_nd_data;
+
+        if (current_arp_parms.family == AF_INET) {
+               switch(current_arp_parms.action) {
+                       case 1:
+                               populate_arp_entry(&current_arp_parms.mac_addr,
+                               current_arp_parms.ip, current_arp_parms.portid,
+                                                STATIC_ARP);
+                               break;
+                       case 2:
+                               callback_key =
+                                (struct arp_timer_key*) rte_malloc(NULL,
+                                       sizeof(struct  arp_timer_key*),
+                               RTE_CACHE_LINE_SIZE);
+                               arp_key.port_id = current_arp_parms.portid;
+                               arp_key.ip = current_arp_parms.ip;
+                               arp_key.filler1 = 0;
+                               arp_key.filler2 = 0;
+                               arp_key.filler3 = 0;
+                               new_arp_data = retrieve_arp_entry(arp_key,
+                                                        STATIC_ARP);
+                               callback_key->port_id = current_arp_parms.portid;
+                               callback_key->ip = current_arp_parms.ip;
+
+                               mg_printf(conn, "removing entry now\n");
+                               remove_arp_entry(new_arp_data, callback_key);
+                               break;
+                       case 3:
+                               arp_key.ip = current_arp_parms.ip;
+                               arp_key.port_id = current_arp_parms.portid;
+                               arp_key.filler1 = 0;
+                               arp_key.filler2 = 0;
+                               arp_key.filler3 = 0;
+
+                               new_arp_data = retrieve_arp_entry(arp_key, STATIC_ARP);
+
+                               if (new_arp_data) {
+                                       mg_printf(conn, "<p>ARP entry exists for"
+                                               " ip 0x%x, port %d</p>",
+                                                current_arp_parms.ip, current_arp_parms.portid);
+                                       return 1;
+                               }
+
+                               mg_printf(conn, "<p>ARP - requesting arp for ip 0x%x, port %d</p>",
+                                       current_arp_parms.ip, current_arp_parms.portid);
+
+                               request_arp(current_arp_parms.portid, current_arp_parms.ip);
+                               break;
+                       default:
+                               break;
+               };
+        } else {
+               switch(current_arp_parms.action) {
+                       case 1:
+                               populate_nd_entry(&current_arp_parms.mac_addr,
+                               current_arp_parms.ipv6, current_arp_parms.portid, STATIC_ND);
+                               break;
+                       case 2:
+                               nd_key.port_id = current_arp_parms.portid;
+                               memcpy(&nd_key.ipv6[0], &current_arp_parms.ipv6[0], 16);
+                               nd_key.filler1 = 0;
+                               nd_key.filler2 = 0;
+                               nd_key.filler3 = 0;
+                               new_nd_data = retrieve_nd_entry(nd_key, STATIC_ND);
+                               remove_nd_entry_ipv6(new_nd_data, &nd_key);
+                       case 3:
+                               mg_printf(conn, "<p>ND REQ is not supported Yet!!!</p>");
+                               break;
+                       default:
+                               break;
+               };
+        }
+
+        mg_printf(conn, "<p>Command Passed</p>");
+        mg_printf(conn, "</body></html>\n");
+       return 1;
+}
+
+int route_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+        uint32_t portid = 0;
+       uint32_t i, j, status;
+       char buf[MAX_BUF_SIZE];
+       uint32_t mask = 0, num = 31;
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<pre>\nIP_Address    Mask          Port\n<br/>");
+
+               for (j = 0; j < gw_get_num_ports(); j++) {
+                       for (i = 0; i < p_route_data[j]->route_ent_cnt; i++) {
+                               mg_printf(conn, "0x%08x \t 0x%08x \t %d\n<br/>",
+                               p_route_data[j]->route_table[i].nh,
+                               p_route_data[j]->route_table[i].mask,
+                               p_route_data[j]->route_table[i].port);
+                       }
+               }
+
+               mg_printf(conn, "\n\nND IPV6 routing table ...\n<br/>");
+               mg_printf(conn, "\nNH_IP_Address                                "
+                               "       Depth          Port \n<br/>");
+               for(uint32_t p = 0; p < gw_get_num_ports(); p++ ) {
+                       for (i = 0; i < p_nd_route_data[p]->nd_route_ent_cnt; i++) {
+                               for (j = 0; j < ND_IPV6_ADDR_SIZE; j += 2) {
+                                       mg_printf(conn, "%02X%02X ",
+                                        p_nd_route_data[p]->nd_route_table[i].nhipv6[j],
+                                       p_nd_route_data[p]->nd_route_table[i].nhipv6[j + 1]);
+                               }
+
+                               mg_printf(conn, "\t%d           %d              "
+                                       "                       \n<br/></pre>",
+                                       p_nd_route_data[p]->nd_route_table[i].depth,
+                                       p_nd_route_data[p]->nd_route_table[i].port);
+                       }
+               }
+
+               return 1;
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                          "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        
+       mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       json_object_object_foreach(jobj, key, val) {
+               if (!strcmp(key, "portid")) {
+                       portid = atoi(json_object_get_string(val));
+                       if (portid > 64) {
+                               mg_printf(conn, "Port not supported!!!\n");
+                               return 1;
+                       } else if (current_route_parms[portid].enable) {
+                               mg_printf(conn, "Already configured\n");
+                       }
+               } else if (!strcmp(key, "nhipv4")) {
+                       current_route_parms[portid].ip =
+                                rte_bswap32(inet_addr(json_object_get_string(val)));
+                       current_route_parms[portid].family = AF_INET;
+               } else if (!strcmp(key, "nhipv6")) {
+                       my_inet_pton_ipv6(AF_INET6,
+                       json_object_get_string(val), &current_route_parms[portid].ipv6[0]);
+                       current_route_parms[portid].family = AF_INET6;
+               } else if (!strcmp(key, "depth")) {
+                       current_route_parms[portid].depth = atoi(json_object_get_string(val));
+                       current_route_parms[portid].enable = 1; 
+               } else if (!strcmp(key, "type")) {
+                       memcpy(current_route_parms[portid].type, json_object_get_string(val), 
+                               strlen(json_object_get_string(val)));
+               } 
+       }
+
+       if (current_route_parms[portid].family == AF_INET) {
+               if (!strcmp(current_route_parms[portid].type, "net"))  {
+                       for (i = 0; i < current_route_parms[portid].depth; i++) {
+                               mask |= (1 << num);
+                               num--;
+                       }
+               } else
+                       mask = 0xFFFFFFFF;
+
+               status = app_routeadd_config_ipv4(rapp, portid,
+                                current_route_parms[portid].ip,
+                                mask);
+               if (status != 0)
+                       mg_printf(conn, "Setting route entry failed\n");
+       } else {
+
+               if (!strcmp(current_route_parms[portid].type, "host"))  {
+                       current_route_parms[portid].depth = 128;
+               }
+               status = app_routeadd_config_ipv6(rapp, portid,
+                        current_route_parms[portid].ipv6,
+                        current_route_parms[portid].depth);
+               if (status != 0)
+                       mg_printf(conn, "Setting route entry failed\n");
+       }
+
+
+        mg_printf(conn, "</body></html>\n");
+        return 1;
+}
+
+int link_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+       int i, status = 0, link = 0, link_read = 0;
+       char buf[MAX_BUF_SIZE];
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>\n");
+               for (i = 0; i < MAX_LINKS; i++) {
+                       if (current_link_parms[i].state)
+                               mg_printf(conn, "link %d is enabled\r\n", i);
+               }
+               mg_printf(conn, "</body></html>\n");
+               return 1;
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                          "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+       mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       json_object_object_foreach(jobj, key, val) {
+               if (!strcmp(key, "linkid")) {
+                       link = atoi(json_object_get_string(val));
+                       mg_printf(conn, "linkid:%d \n", link);
+                       if (link > 64) {
+                               mg_printf(conn, "Link id not supported beyond 64\n");
+                               return 1;
+                       }
+                       current_link_parms[link].id = link;
+                       link_read = 1;
+               } else if (!strcmp(key, "state")) {
+                       if (link_read) {
+                               current_link_parms[link].state =
+                                        atoi(json_object_get_string(val));
+                       }
+                       mg_printf(conn, "state:%d \n", current_link_parms[link].state);
+               } 
+
+       }
+
+
+       if (current_link_parms[link].state == 0) {
+               /* link down */
+               status = app_link_down(rapp, current_link_parms[link].id);
+               if (status != 0) {
+                       mg_printf(conn, "<p>command failed</p>");
+               } else {
+                       mg_printf(conn, "<p>command Passed</p>");
+               }
+       } else if (current_link_parms[link].state == 1) {
+               /* link up */
+               mg_printf(conn, "setting up the link \n");
+               status = app_link_up(rapp, current_link_parms[link].id);
+               if (status != 0) {
+                       mg_printf(conn, "<p>command failed</p>");
+               } else {
+                       mg_printf(conn, "<p>command Passed</p>");
+               }
+
+       }
+
+       sprintf(buf, "/vnf/config/link/%d", link);
+       mg_set_request_handler(ctx, buf, linkid_handler, (void *)&link);
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        return 1;
+}
+
+int linkid_handler(struct mg_connection *conn, void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+       int status = 0;
+       char buf[MAX_BUF_SIZE];
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                       "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                       "close\r\n\r\n");
+               mg_printf(conn, "<html><body>\n");
+               linkls_handler(conn, cbdata);
+               mg_printf(conn, "</body></html>\n");
+               return 1;
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                          "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+        mg_printf(conn, "<html><body>");
+        
+        uint32_t linkid = *(uint32_t *)cbdata;
+        mg_printf(conn, "link id :%d ", linkid);
+
+       if (!current_link_parms[linkid].state) {
+               mg_printf(conn, "<p>link not enabled!! </p>");
+               mg_printf(conn, "</body></html>\n");
+               return 1;
+       }
+               
+       mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       json_object_object_foreach(jobj, key, val) {
+               if (!strcmp(key, "ipv4")) {
+                       current_link_parms[linkid].ip =
+                                rte_bswap32(inet_addr(json_object_get_string(val)));
+                       current_link_parms[linkid].family = AF_INET;
+               } else if (!strcmp(key, "ipv6")) {
+                       my_inet_pton_ipv6(AF_INET6,
+                       json_object_get_string(val), &current_link_parms[linkid].ipv6[0]);
+                       current_link_parms[linkid].family = AF_INET6;
+               } else if (!strcmp(key, "depth")) {
+                       current_link_parms[linkid].depth = atoi(json_object_get_string(val));
+               } 
+       }
+
+
+       /* bring the link down */
+        status = app_link_down(rapp, linkid);
+        if (status != 0) {
+               mg_printf(conn, "<p>command down failed</p>");
+       } else {
+               mg_printf(conn, "<p>command Passed</p>");
+       }
+
+       /* configure the ip address */
+        if (current_link_parms[linkid].family == AF_INET) {
+                       status = app_link_config(rapp, linkid, current_link_parms[linkid].ip,
+                       current_link_parms[linkid].depth);
+       } else {
+                       status = app_link_config_ipv6(rapp, linkid,
+                       current_link_parms[linkid].ipv6, current_link_parms[linkid].depth);
+       }
+
+               if (status != 0) {
+                       mg_printf(conn, "<p>command config failed</p>");
+       } else {
+                       mg_printf(conn, "<p>command Passed</p>");
+       }
+
+       /* bring the link up */
+               status = app_link_up(rapp, linkid);
+               if (status != 0) {
+                       mg_printf(conn, "<p>command up failed</p>");
+       } else {
+                       mg_printf(conn, "<p>command Passed</p>");
+       }
+
+
+        mg_printf(conn, "</body></html>\n");
+        return 1;
+}
+
+void set_vnf_type(const char *type)
+{
+       memcpy(current_cfg.vnf_type, type, strlen(type));
+}
+
+void init_stat_cfg(void)
+{
+       char buf[256] = "98103214:(1, 65535)";
+       uint32_t i;
+
+       current_cfg.num_workers = 4;
+       current_cfg.num_lb = 1;
+       current_cfg.num_ports = 2;
+       current_cfg.hyper_thread = 0;
+       current_cfg.sock_in = 0;
+       current_cfg.sw_lb = 1;
+       memcpy(current_cfg.pkt_type, "ipv4", 4);
+
+       for (i=0;i<MAX_LB;i++) {
+               memcpy(current_cfg.ip_range[i].value, &buf,
+                       sizeof(buf));
+       }
+}
+
+void bind_the_ports(struct mg_connection *conn, char *pci_white_list)
+{
+       char *token;
+       char buf[MAX_BUF_SIZE];
+       int x = 0, ret;
+
+       token = strtok(pci_white_list, " ");
+
+       while(token != NULL) {
+               mg_printf(conn, "%s ****\n", token);
+               sprintf(buf, "$RTE_SDK/usertools/dpdk-devbind.py -u %s", token);
+               ret = system(buf);
+               if (ret)
+                       mg_printf(conn, "wrong parameter sent\n");
+
+               sprintf(buf, "$RTE_SDK/usertools/dpdk-devbind.py -b igb_uio %s", token);
+               ret = system(buf);
+               if (ret)
+                       mg_printf(conn, "wrong parameter sent\n");
+
+               token = strtok(NULL, " ");
+
+               x++;
+       }
+       current_cfg.num_ports = x;
+}
+
+int static_cfg_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        int i;
+       unsigned int len;
+        char buf[MAX_BUF_SIZE];
+
+        const struct mg_request_info *ri = mg_get_request_info(conn);
+
+        if (!strcmp(ri->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "<h2> These are the values set in config</h2>");
+               mg_printf(conn, "<h3> num_workers: %d\n</h3>",
+                                        current_cfg.num_workers);
+               mg_printf(conn, "<h3> num_lb: %d\n</h3>",
+                                        current_cfg.num_lb);
+               mg_printf(conn, "<h3> num_ports: %d\n</h3>",
+                                        current_cfg.num_ports);
+               mg_printf(conn, "<h3> hyper_thread: %d\n</h3>",
+                                        current_cfg.hyper_thread);
+               mg_printf(conn, "<h3> socket_id : %d\n</h3>",
+                                        current_cfg.sock_in);
+               mg_printf(conn, "<h3> sw_lb: %d\n</h3>",
+                                        current_cfg.sw_lb);
+               mg_printf(conn, "<h3> vnf_type: %s\n</h3>",
+                                       current_cfg.vnf_type);
+               mg_printf(conn, "<h3> pkt_type: %s\n</h3>",
+                                        current_cfg.pkt_type);
+               mg_printf(conn, "<h3> pci_white_list: %s\n</h3>",
+                                        current_cfg.pci_white_list);
+               mg_printf(conn, "</body></html>\n");
+               return 1;
+       }
+
+        if (strcmp(ri->request_method, "POST")) {
+                mg_printf(conn,
+                          "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          ri->request_method);
+                return 1; 
+        }
+
+       if (static_cfg_set) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               return 1;
+       }
+               
+        mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       len = 0;
+       struct json_object *values;
+       char *str;
+
+       i = 0;
+       json_object_object_foreach(jobj, key, val) {
+               memcpy(static_cfg[i].key, key, strlen(key));
+               memcpy(static_cfg[i].value, json_object_get_string(val),
+                                strlen(json_object_get_string(val)));
+               sprintf(buf, "public_ip_port_range_%d", pub_ip);
+               if (!strcmp(static_cfg[i].key, buf)) {
+                       memcpy(&current_cfg.ip_range[pub_ip].value,
+                               static_cfg[i].value,
+                                sizeof(static_cfg[i].value));
+                       pub_ip++;
+               }
+               i++;
+       }
+       n_entries1 = i;
+
+       json_object_object_get_ex(jobj, "num_worker", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       memcpy(&current_cfg.ip_range[pub_ip++].value, str,
+                                sizeof(str));
+       }
+
+       json_object_object_get_ex(jobj, "num_worker", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       current_cfg.num_workers = atoi(str);
+       }
+
+       json_object_object_get_ex(jobj, "pkt_type", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       memcpy(&current_cfg.pkt_type, str,
+                                sizeof(current_cfg.pkt_type));
+       }
+
+       json_object_object_get_ex(jobj, "num_lb", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       current_cfg.num_lb = atoi(str);
+       }
+
+       json_object_object_get_ex(jobj, "num_ports", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       current_cfg.num_ports = atoi(str);
+       }
+       
+       json_object_object_get_ex(jobj, "sw_lb", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       current_cfg.sw_lb = atoi(str);
+       }
+
+       json_object_object_get_ex(jobj, "sock_in", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       current_cfg.sock_in = atoi(str);
+       }
+
+       json_object_object_get_ex(jobj, "hyperthread", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       current_cfg.hyper_thread = atoi(str);
+       }
+
+       json_object_object_get_ex(jobj, "vnf_type", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       memcpy(&current_cfg.vnf_type, str,
+                                sizeof(current_cfg.vnf_type));
+       }
+
+       json_object_object_get_ex(jobj, "pci_white_list", &values);
+       if (values) {
+               str = strdup(json_object_get_string(values));
+               if (str)
+                       memcpy(&current_cfg.pci_white_list, str,
+                       sizeof(current_cfg.pci_white_list));
+               mg_printf(conn, " Binding the ports \n");
+               bind_the_ports(conn, &current_cfg.pci_white_list[0]);
+       }
+
+       len = sprintf(buf, "POST DATA RECEIVED\n");
+       
+       mg_printf(conn,
+                 "HTTP/1.1 200 OK\r\n"
+                 "Content-Length: %u\r\n"
+                 "Content-Type: text/plain\r\n"
+                 "Connection: close\r\n\r\n",
+                 len);
+
+       mg_write(conn, buf, len);
+       post_not_received = 0;
+       static_cfg_set++;
+        return 1;
+}
+
+int vnf_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "<h2>These are the methods that are supported</h2>");
+               mg_printf(conn, "<h3> /vnf/config</h3>");
+               mg_printf(conn, "<h3> /vnf/config/arp</h3>");
+               mg_printf(conn, "<h3> /vnf/config/link</h3>");
+               mg_printf(conn, "<h3> /vnf/config/route</h3>");
+               mg_printf(conn, "<h3> /vnf/config/rules(vFW/vACL only)</h3>");
+               mg_printf(conn, "<h3> /vnf/config/rules/load(vFW/vACL only)</h3>");
+               mg_printf(conn, "<h3> /vnf/config/rules/clear(vFW/vACL only)</h3>");
+               mg_printf(conn, "<h3> /vnf/config/nat(vCGNAPT only)</h3>");
+               mg_printf(conn, "<h3> /vnf/config/nat/load(vFW/vACL only)</h3>");
+               mg_printf(conn, "<h3> /vnf/config/dbg</h3>");
+               mg_printf(conn, "<h3> /vnf/config/dbg/pipelines</h3>");
+               mg_printf(conn, "<h3> /vnf/config/dbg/cmd</h3>");
+               mg_printf(conn, "<h3> /vnf/log</h3>");
+               mg_printf(conn, "<h3> /vnf/flowdirector</h3>");
+               mg_printf(conn, "<h3> /vnf/status</h3>");
+               mg_printf(conn, "<h3> /vnf/stats</h3>");
+               mg_printf(conn, "<h3> /vnf/quit</h3>");
+               mg_printf(conn, "</body></html>");
+
+
+               return 1;
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+                mg_printf(conn,
+                          "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+                mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+                mg_printf(conn,
+                          "%s method not allowed in the POST handler\n",
+                          req_info->request_method);
+                return 1; 
+        }
+
+       return 1;
+}
+
+void get_pktq_in_prv(char *buf)
+{
+       int j;
+       uint32_t len = 0;
+       for (j = 0; j < current_cfg.num_ports; j+=2) {
+               len += sprintf(buf + len, "RXQ%d.0 ", j);
+       }
+}
+
+void fix_pipelines_data_types(FILE *f, const char *sect_name, struct rte_cfgfile *tcfg)
+{
+       int i, j, n_entries, tmp = 0;
+       char str[256], str1[40];
+
+       n_entries = rte_cfgfile_section_num_entries(tcfg, sect_name);
+
+       rte_cfgfile_section_entries(tcfg, sect_name, entries, n_entries);
+
+       for (i = 0; i < n_entries; i++) {
+               for (j = 0; j < n_entries1; j++) {
+                       if (strncmp(entries[i].name, static_cfg[i].key,
+                                strlen(entries[i].name)) == 0) {
+                               memcpy(entries[i].value, static_cfg[i].value,
+                                strlen(entries[i].value));
+                               tmp++;
+                       }
+
+                       if (strncmp(entries[i].name, "pkt_type",
+                                 strlen("pkt_type")) == 0) {
+                               memcpy(entries[i].value, current_cfg.pkt_type,
+                                strlen(entries[i].value));
+                               if (!strcmp(current_cfg.pkt_type, "ipv4"))
+                                       memcpy(&traffic_type, "4", 1);
+                               else
+                                       memcpy(&traffic_type, "6", 1);
+                       }
+
+                       if (strncmp(entries[i].name, "traffic_type",
+                                 sizeof("traffic_type")) == 0) {
+                               memcpy(entries[i].value, &traffic_type, 4);
+                       }
+               }
+
+               if (strncmp(entries[i].name, "core", strlen(entries[i].name)) == 0) {
+                       if ((strncmp(sect_name, "MASTER", strlen(sect_name)) == 0) &&
+                               !current_cfg.sock_in) {
+                               continue;
+                       }
+
+                       if ((current_cfg.hyper_thread) && hyper) {
+                               sprintf(str, "s%dc%dh", current_cfg.sock_in,
+                                        sock_cpus[current_cfg.sock_in][sock_index]);
+                               memcpy(entries[i].value, &str, 8);
+                               sock_index++;
+                               hyper = 0;
+                               continue;
+                       }
+       
+                       sprintf(str, "s%dc%d", current_cfg.sock_in,
+                                sock_cpus[current_cfg.sock_in][sock_index]);
+
+                       if (!current_cfg.hyper_thread)
+                               sock_index++;
+                       else
+                               hyper = 1;
+
+                       if (current_cfg.sock_in) {
+                               if (sock_index == sock1)
+                                       sock_index = 1;
+                       } else {
+                               if (sock_index == sock0)
+                                       sock_index = 1;
+                       }
+                       memcpy(entries[i].value, &str, 8);
+               }
+       }
+       num_entries = i;
+
+       if (strncmp(sect_name, "ARPICMP", strlen(sect_name)) == 0) {
+               for (j = 0; j < n_entries1; j++) {
+                       if ((strncmp(static_cfg[j].key, "arp_route_tbl",
+                                strlen(static_cfg[j].key)) == 0) ||
+                               (strncmp(static_cfg[j].key, "nd_route_tbl",
+                                strlen(static_cfg[j].key)) == 0)) {
+                               memcpy(&entries[i].name, &static_cfg[j].key,
+                                        strlen(static_cfg[j].key));
+                               memcpy(&entries[i].value, &static_cfg[j].value,
+                                strlen(static_cfg[j].value));
+                               i++;
+                       }
+               }
+               num_entries = i;
+               /* update pktq_in/pktq_out */
+               for (i=0; i < n_entries; i++) {
+                       memset(str, 0, 256);
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               tmp = (current_cfg.sw_lb)? current_cfg.num_lb: current_cfg.num_workers;
+                               get_swq(tmp, &str[0]);
+                               memcpy(&entries[i].value, &str, strlen(str));
+                               continue;
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               //tmp = (current_cfg.sw_lb)? current_cfg.num_lb: current_cfg.num_workers / 2;
+                               //tmp = (current_cfg.sw_lb)? current_cfg.num_lb: current_cfg.num_ports;
+                               get_txq(0, 1, current_cfg.num_ports, &str[0]);
+                               memcpy(&entries[i].value, &str, strlen(str));
+                               continue;
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_in_prv",
+                                strlen(entries[i].name)) == 0) {
+                               get_pktq_in_prv(&str[0]);
+                               memset(&entries[i].value, 0, sizeof(entries[i].value));
+                               memcpy(&entries[i].value, &str, strlen(str));
+                               continue;
+                       }
+
+                       if (strncmp(entries[i].name, "prv_to_pub_map",
+                                strlen(entries[i].name)) == 0) {
+                               get_prv_to_pub_map(&str[0]);
+                               memcpy(&entries[i].value, &str, strlen(str));
+                               continue;
+                       }
+
+                       if (strncmp(entries[i].name, "prv_que_handler",
+                                strlen(entries[i].name)) == 0) {
+                               get_prv_que_handler(&str[0]);
+                               memcpy(&entries[i].value, &str, strlen(str));
+                               continue;
+                       }
+               }
+       }
+
+       if (strncmp(sect_name, "TXRX-BEGIN", strlen(sect_name)) == 0) {
+               for (i=0; i < n_entries; i++) {
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               get_rxq(0, 1, 2, &str[0]);
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               get_swq(2, &str[0]);
+                               memcpy(loadb_in, str, sizeof(str));
+                               sprintf(str1," SWQ%d", arp_index++);
+                               strcat(str, str1);      
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+               }
+       }
+
+       if (strncmp(sect_name, "LOADB", strlen(sect_name)) == 0) {
+               for (i=0; i < n_entries; i++) {
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               memcpy(entries[i].value, &loadb_in, sizeof(str));
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.num_ports > 2)
+                                       tmp = (current_cfg.num_workers/current_cfg.num_lb * 2);
+                               else
+                                       tmp = current_cfg.num_workers * 2;
+                               start_lb = swq_index;
+                               end_lb = tmp;
+                               start_lbout = start_lb + end_lb;
+                               get_swq(tmp, &str[0]);
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+                       if (strncmp(entries[i].name, "n_vnf_threads",
+                                strlen(entries[i].name)) == 0) {
+                               sprintf(str1, "%d", current_cfg.num_workers/current_cfg.num_lb);
+                               memcpy(entries[i].value, &str1, sizeof(str1));
+                       }
+               }
+       }
+
+       if (strncmp(sect_name, "VACL", strlen(sect_name)) == 0) {
+               for (i=0; i < n_entries; i++) {
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.sw_lb) {
+                                       get_swq_offset(start_lb, 2, &str[0]);
+                                       start_lb += 2;
+                               } else
+                                       get_rxq(workers, 1, 2, &str[0]);
+
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.sw_lb)
+                                       get_swq(2, &str[0]);
+                               else {
+                                       get_txq(workers+1, 1, 2, &str[0]);
+                                       sprintf(str1," SWQ%d", arp_index++);
+                                       strcat(str, str1);
+                               }
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+               }
+
+               workers++;
+               if (current_cfg.sw_lb) {
+                       if (((workers % current_cfg.num_workers/current_cfg.num_lb) == 0) &&
+                                (workers != current_cfg.num_workers)) {
+                               workers = 0;
+                       }
+               } else {
+                       if ((workers % current_cfg.num_workers/current_cfg.num_lb) == 0) {
+                               tx_start_port += 2;
+                               rx_start_port += 2;
+                               workers = 0;
+                       }
+               }
+       }
+
+       if (strncmp(sect_name, "VCGNAPT", strlen(sect_name)) == 0) {
+               for (i=0; i < n_entries; i++) {
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.sw_lb) {
+                                       get_swq_offset(start_lb, 2, &str[0]);
+                                       start_lb += 2;
+                               } else
+                                       get_rxq(workers, 1, 2, &str[0]);
+
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.sw_lb)
+                                       get_swq(2, &str[0]);
+                               else {
+                                       get_txq(workers+1, 1, 2, &str[0]);
+                                       sprintf(str1," SWQ%d", arp_index++);
+                                       strcat(str, str1);
+                               }
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+               }
+
+               if (workers == 0) {
+                       char *token;
+                       sprintf(str1, "vnf_set");
+                       memcpy(entries[i].name, &str1, sizeof(str1));
+                       sprintf(str1, "(3,4,5)");
+                       memcpy(entries[i].value, &str1, sizeof(str1));
+                       num_entries++;
+                       i++;
+
+                       token = strtok(current_cfg.ip_range[ip_range].value, "/");
+                       while(token) {
+                               sprintf(str1, "public_ip_port_range");
+                               memcpy(entries[i].name, &str1, sizeof(str1));
+                               memcpy(entries[i].value, token, strlen(token));
+                               i++;
+                               num_entries++;
+                               token = strtok(NULL, "/");
+                       }
+                       ip_range++;
+               }
+
+               workers++;
+               if (current_cfg.sw_lb) {
+                       if (((workers % (current_cfg.num_workers/current_cfg.num_lb)) == 0) &&
+                                (workers != current_cfg.num_workers)) {
+                               workers = 0;
+                       }
+               } else {
+                       //if (((workers % (current_cfg.num_workers/current_cfg.num_lb)) == 0) &&
+                       //       (workers != current_cfg.num_workers)) {
+                       if (workers == (current_cfg.num_workers/current_cfg.num_lb)) {
+                               tx_start_port += 2;
+                               rx_start_port += 2;
+                               workers = 0;
+                       }
+               }
+       }
+
+       if (strncmp(sect_name, "VFW", strlen(sect_name)) == 0) {
+               for (i=0; i < n_entries; i++) {
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.sw_lb) {
+                                       get_swq_offset(start_lb, 2, &str[0]);
+                                       start_lb += 2;
+                               } else
+                                       get_rxq(workers, 1, 2, &str[0]);
+
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               if (current_cfg.sw_lb)
+                                       get_swq(2, &str[0]);
+                               else {
+                                       get_txq(workers+1, 1, 2, &str[0]);
+                                       sprintf(str1," SWQ%d", arp_index++);
+                                       strcat(str, str1);
+                               }
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+               }
+
+               workers++;
+               if (current_cfg.sw_lb) {
+                       if (((workers % current_cfg.num_workers/current_cfg.num_lb) == 0)
+                                && (workers != current_cfg.num_workers)) {
+                               workers = 0;
+                       }
+               } else {
+                       if (current_cfg.num_ports > 2) {
+                               tx_start_port += 2;
+                               rx_start_port += 2;
+                               workers = 0;
+                       }
+               }
+       }
+
+       if (strncmp(sect_name, "TXRX-END", strlen(sect_name)) == 0) {
+               for (i=0; i < n_entries; i++) {
+                       if (strncmp(entries[i].name, "pktq_in",
+                                strlen(entries[i].name)) == 0) {
+                               get_swq_offset(start_lbout, end_lb, &str[0]);
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+
+                       if (strncmp(entries[i].name, "pktq_out",
+                                strlen(entries[i].name)) == 0) {
+                               get_txq(1, end_lb / 2, 2, &str[0]);
+                               memcpy(entries[i].value, &str, sizeof(str));
+                       }
+               }
+               tx_start_port += 2;
+               rx_start_port += 2;
+       }
+
+       fprintf(f, "[PIPELINE%d]\n", pipenum);
+       for (i=0;i<num_entries;i++) {
+               fprintf(f, "%s = %s\n", entries[i].name, entries[i].value);
+       }
+       fprintf(f, "\n");
+       pipenum++;
+}
+
+void print_to_file(FILE *f, struct rte_cfgfile *tcfg)
+{
+       int i;
+       for (i=0;i<num_pipelines;i++) {
+               fix_pipelines_data_types(f, pipelines[pipe_arr[i]], tcfg);
+       }
+       fclose(f);
+}
+
+int get_vnf_index(void)
+{
+
+       int i;
+
+       for (i = 0; i < PIPE_MAX; i++) {
+               if (strncmp(pipelines[i], current_cfg.vnf_type,
+                                strlen(current_cfg.vnf_type)) == 0)
+                       return i;
+       }
+       return -1;
+}
+
+void build_pipeline(void)
+{
+       int i = 2, j, k, vnf_index;
+
+       pipe_arr[0] = 0;
+       pipe_arr[1] = 1;
+       vnf_index = get_vnf_index();
+       if (vnf_index == -1)
+               printf("Wrong VNF TYPE\n");
+
+       if (vnf_index == VNF_VCGNAPT)
+               pipe_arr[i++] = 2;
+
+       if (!current_cfg.sw_lb) {
+               for (k = 0; k < current_cfg.num_workers; k++)
+                       pipe_arr[i++] = vnf_index;
+               num_pipelines = i;
+               return;
+       }
+
+       for (j = 0; j < current_cfg.num_lb; j++) {
+                       /* put TXRX-BEGIN & LOADB pipelines */
+               pipe_arr[i++] = TXRX_BEGIN;
+               pipe_arr[i++] = LOADB;
+
+               /* place the worker threads */
+               int limit = current_cfg.num_workers / current_cfg.num_lb;
+               for (k = 0; k < limit; k++)
+                       pipe_arr[i++] = vnf_index;
+
+               /* end the TXRX pipeline */
+               pipe_arr[i++] = TXRX_END;
+       }
+       num_pipelines = i;
+}
+
+int set_hash_global_config(struct mg_connection *conn, uint32_t port_id,
+        char *flow_type, const char *hash_func, const char *enable)
+{
+        struct rte_eth_hash_filter_info info;
+        uint32_t ftype, idx, offset;
+        int ret;
+
+        if (rte_eth_dev_filter_supported(port_id,
+                                RTE_ETH_FILTER_HASH) < 0) {
+                mg_printf(conn, "RTE_ETH_FILTER_HASH not supported on port %d\n",
+                                port_id);
+                return 1;
+        }
+        memset(&info, 0, sizeof(info));
+        info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
+        if (!strcmp(hash_func, "toeplitz"))
+                info.info.global_conf.hash_func =
+                        RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+        else if (!strcmp(hash_func, "simple_xor"))
+                info.info.global_conf.hash_func =
+                        RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+        else if (!strcmp(hash_func, "default"))
+                info.info.global_conf.hash_func =
+                        RTE_ETH_HASH_FUNCTION_DEFAULT;
+
+        ftype = str2flowtype(flow_type);
+        idx = ftype / (CHAR_BIT * sizeof(uint32_t));
+        offset = ftype % (CHAR_BIT * sizeof(uint32_t));
+        info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
+        if (!strcmp(enable, "enable"))
+                if(idx < RTE_SYM_HASH_MASK_ARRAY_SIZE)
+                info.info.global_conf.sym_hash_enable_mask[idx] |=
+                        (1UL << offset);
+        ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_HASH,
+                        RTE_ETH_FILTER_SET, &info);
+        if (ret < 0)
+                mg_printf(conn, "Cannot set global hash configurations by port %d\n",
+                                port_id);
+        else
+                mg_printf(conn, "Global hash configurations have been set "
+                                "succcessfully by port %d\n", port_id);
+       return 1;
+}
+
+int flow_director_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+        /* Handler may access the request info using mg_get_request_info */
+        const struct mg_request_info *req_info = mg_get_request_info(conn);
+        uint32_t port_id = 0, tuple = 0;
+        char trans_type[24], buf[MAX_BUF_SIZE];
+       char *str, field0[MAX_SIZE], field1[MAX_SIZE], field2[MAX_SIZE],
+                field3[MAX_SIZE], flow_type[MAX_SIZE];
+
+        if (!strcmp(req_info->request_method, "GET")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               if (flow_dir_cfg)
+                       mg_printf(conn, "<h3> Flow is configured </h3>");
+               else
+                       mg_printf(conn, "<h3> Flow is NOT configured </h3>");
+               mg_printf(conn, "</body></html>");
+               return 1;
+       }
+
+        if (strcmp(req_info->request_method, "POST")) {
+               mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+                  "close\r\n\r\n");
+               mg_printf(conn, "<html><body>");
+               mg_printf(conn, "This method is not supported\n");
+               mg_printf(conn, "</body></html>");
+               return 1;
+
+       }
+
+       mg_read(conn, buf, sizeof(buf));
+       json_object * jobj = json_tokener_parse(buf);
+       json_object_object_foreach(jobj, key, val) {
+               if (!strcmp(key, "trans_type")) {
+                       memcpy(&trans_type, str, sizeof(trans_type));
+                       if (!strcmp(key, "udp")) {
+                               memcpy(field2,"udp-src-port", sizeof("udp-src-port"));
+                               memcpy(field3,"udp-dst-port", sizeof("udp-dst-port"));
+                               if (!strcmp(current_cfg.pkt_type, "ipv4")) {
+                                       memcpy(flow_type,"ipv4-udp", sizeof("ipv4-udp"));
+                                       memcpy(field0,"src-ipv4", sizeof("src-ipv4"));
+                                       memcpy(field1,"dst-ipv4", sizeof("dst-ipv4"));
+                               } else if (!strcmp(current_cfg.pkt_type, "ipv6")) {
+                                       memcpy(flow_type,"ipv6-udp", sizeof("ipv6-udp"));
+                                       memcpy(field0,"src-ipv6", sizeof("src-ipv6"));
+                                       memcpy(field1,"dst-ipv6", sizeof("dst-ipv6"));
+                               }
+                       } else if (!strcmp(key, "tcp")) {
+                               memcpy(field2,"tcp-src-port", sizeof("tcp-src-port"));
+                               memcpy(field3,"tcp-dst-port", sizeof("tcp-dst-port"));
+                               if (!strcmp(current_cfg.pkt_type, "ipv4")) {
+                                       memcpy(flow_type,"ipv4-tcp", sizeof("ipv4-tcp"));
+                                       memcpy(field0,"src-ipv4", sizeof("src-ipv4"));
+                                       memcpy(field1,"dst-ipv4", sizeof("dst-ipv4"));
+                               } else if (!strcmp(current_cfg.pkt_type, "ipv6")) {
+                                       memcpy(flow_type,"ipv6-tcp", sizeof("ipv6-tcp"));
+                                       memcpy(field0,"src-ipv6", sizeof("src-ipv6"));
+                                       memcpy(field1,"dst-ipv6", sizeof("dst-ipv6"));
+                               }
+                       }
+               } else if (!strcmp(key, "tuple")) {
+                       tuple = atoi(json_object_get_string(val));
+                       if ((tuple != 2) || (tuple != 5))
+                               return 1;
+               } 
+       }
+
+       if (tuple == 2) {
+               set_pkt_forwarding_mode("rxonly");
+               for (port_id = 0; port_id < current_cfg.num_ports; port_id++) {
+                       set_sym_hash_per_port(conn, port_id);
+                       set_hash_global_config(conn, port_id, flow_type,
+                        "simple_xor", "enable");
+               }
+
+               for (port_id = 0; port_id < current_cfg.num_ports; port_id+=2) {
+                       set_hash_input_set_2(conn, port_id, "ipv4-udp", "src-ipv4",
+                                "udp-src-port", "add"); 
+                       set_hash_input_set_2(conn, port_id, "ipv4-udp", "dst-ipv4",
+                                "udp-dst-port", "add"); 
+                       set_hash_input_set_2(conn, port_id, "ipv4-udp", "src-ipv6",
+                                "udp-src-port", "add"); 
+                       set_hash_input_set_2(conn, port_id, "ipv4-udp", "dst-ipv6",
+                                "udp-dst-port", "add");
+               }
+       } else if (tuple == 5) {
+               set_pkt_forwarding_mode("rxonly");
+               for (port_id = 0; port_id < current_cfg.num_ports; port_id++) {
+                       set_sym_hash_per_port(conn, port_id);
+                       set_hash_global_config(conn, port_id, flow_type,
+                       "simple_xor", "enable");
+               }
+
+               for (port_id = 0; port_id < current_cfg.num_ports; port_id+=2) {
+                       set_hash_input_set_4(conn, port_id, flow_type, field0, field1,
+                               field2, field3, "add");
+               }
+       }
+       flow_dir_cfg = 1;
+       return 1;
+}
+
+void get_swq_offset(uint8_t start, uint8_t num, char *buf)
+{
+       int i;
+       uint32_t len = 0;
+
+       for (i = start; i < start+num; i++) {
+               sprintf(buf + len, "SWQ%d ", i);
+               len = strlen(buf);
+       }
+}
+
+void get_swq(uint8_t num, char *buf)
+{
+       int i;
+       uint32_t len = 0;
+
+       for (i=0;i<num;i++) {
+               sprintf(buf + len, "SWQ%d ", swq_index++);
+               len = strlen(buf);
+       }
+}
+
+void get_prv_to_pub_map(char *buf)
+{
+       int j;
+       uint32_t len = 0;
+       for (j = 0; j < current_cfg.num_ports; j+=2) {
+               sprintf(buf + len, "(%d,%d)", j, j+1);
+               len = strlen(buf);
+       }
+}
+
+void get_prv_que_handler(char *buf)
+{
+       int j;
+       uint32_t len = 0;
+       sprintf(buf + len, "(");
+       len = strlen(buf);
+       for (j = 0; j < current_cfg.num_ports; j+=2) {
+               sprintf(buf + len, "%d,", j);
+               len = strlen(buf);
+       }
+       sprintf(buf + len, ")");
+}
+
+void get_txq(uint8_t start_q, uint8_t queue_num, uint8_t ports, char *buf)
+{
+       int i, j;
+       uint32_t len = 0;
+       for (i=tx_start_port;i<tx_start_port + ports;i+=2)
+       {
+               for (j=start_q;j<(start_q + queue_num);j++)
+               {
+                       sprintf(buf + len, " TXQ%d.%d TXQ%d.%d", i, j, i+1, j);
+                       len = strlen(buf);
+               }
+       }
+
+}
+
+void get_rxq(uint8_t start_q, uint8_t queue_num, uint8_t ports, char *buf)
+{
+       int i, j;
+       uint32_t len = 0;
+
+       for (i=rx_start_port;i<rx_start_port + ports;i+=2)
+       {
+               for (j=start_q;j<(start_q + queue_num);j++)
+               {
+                       sprintf(buf + len, " RXQ%d.%d RXQ%d.%d", i, j, i+1, j);
+                       len = strlen(buf);
+               }
+       }
+
+}
+
+struct mg_context *
+rest_api_init(struct app_params *app)
+{
+        struct rte_cfgfile *tcfg;
+       FILE *f;
+       char buf[256];
+       const char *options[] = {"listening_ports", "80", NULL};
+       uint32_t i, lcore_id = 0;
+       uint32_t sock, index;
+       
+       /* Server context handle */
+       rapp = app;
+
+       for (lcore_id=0;lcore_id<64;lcore_id++) {
+               //lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
+               sock = eal_cpu_socket_id(lcore_id);
+               index = (sock == 0)? sock0++ : sock1++;
+               sock_cpus[sock][index] = lcore_id;
+       }
+
+
+       /* Initialize the icivetweb library */
+       mg_init_library(0);
+
+       /* Start the server */
+       ctx = mg_start(NULL, 0, options);
+       if (ctx == NULL) {
+               printf("REST server did not start\n");
+               printf("REST services will not be supported.. Try again ");
+               printf("by disabling other webservers\n");
+               goto end;
+       }
+       
+       /* init handlers being called here */
+       init_stat_cfg();
+
+       /* static config handler */
+       mg_set_request_handler(ctx, "/vnf", vnf_handler, 0);
+       mg_set_request_handler(ctx, "/vnf/config", static_cfg_handler, 0);
+       
+       /* arp handler */
+        mg_set_request_handler(ctx, "/vnf/config/arp", arp_handler, 0);
+
+       /* route handler */
+        mg_set_request_handler(ctx, "/vnf/config/route", route_handler, 0);
+
+
+       /* link related handlers */
+        mg_set_request_handler(ctx, "/vnf/config/link", link_handler, 0);
+        //mg_set_request_handler(ctx, "/vnf/config/link/*", linkid_handler, 0);
+
+       /* dbg related handlers */
+        mg_set_request_handler(ctx, "/vnf/config/dbg", dbg_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/config/dbg/pipelines", dbg_pipelines_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/config/dbg/cmd", dbg_cmd_handler, 0);
+        mg_set_request_handler(ctx, "/vnf/config/dbg/run", dbg_run_handler, 0);
+
+        mg_set_request_handler(ctx, "/vnf/quit", cmd_quit_handler, 0);
+
+       printf("Waiting for config input for 30 secs\n");
+       index = 0;
+       while(1) {
+               if (post_not_received == 0 || (index == 30))
+                       break;
+               sleep(1);
+               index++;
+       }
+
+       if (index == 30 && (post_not_received != 0))
+               printf("Input not received for 30 secs, going with default");
+
+       const char *name = "vnf_template.txt";
+        /* Load application configuration file */
+        tcfg = rte_cfgfile_load(name, 0);
+       if (tcfg == NULL)
+               printf("File could not be loaded\n");
+
+//     if (!current_cfg.sw_lb)
+//             current_cfg.num_lb = 1;
+
+       /* build pipelines based on the input given */
+       build_pipeline();
+
+       for (i = 0; i < num_pipelines; i++) {
+               sprintf(buf, "/vnf/config/dbg/pipelines/%d", i);
+               mg_set_request_handler(ctx, buf, dbg_pipelines_id_handler, (void *)&i);
+       }
+
+       /* create a file for writing the config */
+       if (!current_cfg.sw_lb) {
+               mg_set_request_handler(ctx, "/vnf/flowdirector", flow_director_handler, 0);
+               sprintf(buf, "%s_%s_%dP_%dT.cfg", current_cfg.vnf_type, "HWLB",
+                        current_cfg.num_ports, current_cfg.num_workers);
+       } else
+               sprintf(buf, "%s_%s_%dP_%dLB_%dT.cfg", current_cfg.vnf_type, "SWLB",
+                        current_cfg.num_ports, current_cfg.num_lb, current_cfg.num_workers);
+
+       /* create a file which is more readable */
+       f = fopen(buf, "w");
+
+       print_to_file(f, tcfg);
+
+       app->config_file = strdup(buf);
+       app->parser_file = strdup(buf);
+
+       printf("Config file loaded :%s %s\n", app->config_file, traffic_type);
+
+end:
+       return ctx;
+}
index 97f9021..93687fd 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include "vnf_common.h"
+#include "gateway.h"
 #include "pipeline_arpicmp_be.h"
 #ifndef VNF_ACL
 #include "lib_arp.h"
@@ -47,13 +48,12 @@ uint8_t is_port_index_privte(uint16_t phy_port)
 uint32_t get_prv_to_pub_port(uint32_t *ip_addr, uint8_t type)
 {
        uint32_t dest_if = 0xff;
-       struct ether_addr addr;
 
        switch (type) {
        case 4:
        {
                uint32_t nhip;
-               nhip = get_nh(ip_addr[0], &dest_if, &addr);
+               gw_get_nh_port_ipv4(*ip_addr, &dest_if, &nhip);
 
                if (nhip)
                        return dest_if;
@@ -63,7 +63,8 @@ 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], &addr);
+               gw_get_nh_port_ipv6((uint8_t *)ip_addr, &dest_if, nhipv6);
+
                if (dest_if != 0xff)
                        return dest_if;
                return 0xff;
@@ -76,13 +77,13 @@ uint32_t get_prv_to_pub_port(uint32_t *ip_addr, uint8_t type)
 uint32_t get_pub_to_prv_port(uint32_t *ip_addr, uint8_t type)
 {
        uint32_t dest_if = 0xff;
-       struct ether_addr addr;
 
        switch (type) {
        case 4:
        {
                uint32_t nhip;
-               nhip = get_nh(ip_addr[0], &dest_if, &addr);
+
+               gw_get_nh_port_ipv4(*ip_addr, &dest_if, &nhip);
 
                if (nhip)
                        return dest_if;
@@ -92,7 +93,8 @@ 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], &addr);
+
+               gw_get_nh_port_ipv6((uint8_t *)ip_addr, &dest_if, nhipv6);
                if (dest_if != 0xff)
                        return dest_if;
                return 0xff;
index 22a534f..3b70166 100755 (executable)
@@ -25,6 +25,7 @@ HUGEPGSZ=`cat /proc/meminfo  | grep Hugepagesize | cut -d : -f 2 | tr -d ' '`
 MODPROBE="/sbin/modprobe"
 INSMOD="/sbin/insmod"
 DPDK_DOWNLOAD="Not initialized"
+CIVETWEB_DOWNLOAD="Not initialized"
 DPDK_DIR=$VNF_CORE/dpdk
 DPDK_RTE_VER="17.02"
 
@@ -134,6 +135,8 @@ step_2()
        FUNC[4]="install_dpdk"
        TEXT[5]="Setup hugepages"
        FUNC[5]="setup_hugepages"
+       TEXT[6]="Download civetweb"
+       FUNC[6]="download_civetweb_zip"
 }
 get_agreement_download()
 {
@@ -176,7 +179,8 @@ install_libs()
        sudo apt-get update
        sudo apt-get -y install build-essential linux-headers-$(uname -r) git unzip libpcap0.8-dev gcc \
                make libc6 libc6-dev g++-multilib libzmq3-dev libcurl4-openssl-dev net-tools wget gcc unzip \
-                libpcap-dev libncurses-dev libedit-dev pciutils liblua5.2-dev libncursesw5-dev
+                libpcap-dev libncurses-dev libedit-dev pciutils liblua5.2-dev libncursesw5-dev libjson0 \
+               libjson0-dev libssl-dev
        touch .download
 }
 
@@ -197,6 +201,20 @@ download_dpdk_zip()
        mv $VNF_CORE/dpdk-$DPDK_RTE_VER $VNF_CORE/dpdk
 }
 
+download_civetweb_zip()
+{
+       echo "Download CIVETWEB zip"
+       CIVETWEB_DOWNLOAD="https://sourceforge.net/projects/civetweb/files/1.9/CivetWeb_V1.9.zip"
+       if [ ! -e ${CIVETWEB_DOWNLOAD##*/} ] ; then
+               wget ${CIVETWEB_DOWNLOAD}
+       fi
+       unzip -o ${CIVETWEB_DOWNLOAD##*/}
+       mv $VNF_CORE/civetweb-master $VNF_CORE/civetweb
+       pushd $VNF_CORE/civetweb
+       make lib
+       popd
+}
+
 install_dpdk()
 {
        echo "Build DPDK"
@@ -220,7 +238,7 @@ install_dpdk()
                        patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/set-log-level-to-info.patch
        fi
 
-       make -j install T=$RTE_TARGET
+       make -j16 install T=$RTE_TARGET
        if [ $? -ne 0 ] ; then
                echo "Failed to build dpdk, please check the errors."
                return
@@ -309,6 +327,9 @@ non_interactive()
     echo "Download dpdk for VNF build..."
     download_dpdk_zip
 
+    echo "Download civetweb for VNF build..."
+    download_civetweb_zip
+
     echo "Build dpdk..."
     install_dpdk