diff options
Diffstat (limited to 'VNFs')
34 files changed, 3656 insertions, 2622 deletions
diff --git a/VNFs/UDP_Replay/Makefile b/VNFs/UDP_Replay/Makefile index e2375779..08fcbba4 100644 --- a/VNFs/UDP_Replay/Makefile +++ b/VNFs/UDP_Replay/Makefile @@ -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) diff --git a/VNFs/UDP_Replay/main.c b/VNFs/UDP_Replay/main.c index 1b37c181..587057fc 100644 --- a/VNFs/UDP_Replay/main.c +++ b/VNFs/UDP_Replay/main.c @@ -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; diff --git a/VNFs/vACL/Makefile b/VNFs/vACL/Makefile index febfc7b6..0995f905 100644 --- a/VNFs/vACL/Makefile +++ b/VNFs/vACL/Makefile @@ -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 diff --git a/VNFs/vACL/config/IPv4_hwlb_acl.tc b/VNFs/vACL/config/IPv4_hwlb_acl.tc index 79b48ed3..b8e2b152 100644 --- a/VNFs/vACL/config/IPv4_hwlb_acl.tc +++ b/VNFs/vACL/config/IPv4_hwlb_acl.tc @@ -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 diff --git a/VNFs/vACL/config/IPv4_swlb_acl.tc b/VNFs/vACL/config/IPv4_swlb_acl.tc index 7274847a..f736fc4a 100644 --- a/VNFs/vACL/config/IPv4_swlb_acl.tc +++ b/VNFs/vACL/config/IPv4_swlb_acl.tc @@ -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 diff --git a/VNFs/vACL/config/IPv6_hwlb_acl.tc b/VNFs/vACL/config/IPv6_hwlb_acl.tc index 41761108..da43b8d8 100644 --- a/VNFs/vACL/config/IPv6_hwlb_acl.tc +++ b/VNFs/vACL/config/IPv6_hwlb_acl.tc @@ -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 diff --git a/VNFs/vACL/config/IPv6_swlb_acl.tc b/VNFs/vACL/config/IPv6_swlb_acl.tc index c964609a..8ffc3cc3 100644 --- a/VNFs/vACL/config/IPv6_swlb_acl.tc +++ b/VNFs/vACL/config/IPv6_swlb_acl.tc @@ -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 diff --git a/VNFs/vACL/main.c b/VNFs/vACL/main.c index 9ebf6fc3..a6ba00b6 100644 --- a/VNFs/vACL/main.c +++ b/VNFs/vACL/main.c @@ -15,12 +15,14 @@ */ #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; } diff --git a/VNFs/vACL/pipeline/pipeline_acl.c b/VNFs/vACL/pipeline/pipeline_acl.c index 1a4ed4f5..f1935622 100644 --- a/VNFs/vACL/pipeline/pipeline_acl.c +++ b/VNFs/vACL/pipeline/pipeline_acl.c @@ -49,6 +49,13 @@ #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); + +} diff --git a/VNFs/vACL/pipeline/pipeline_acl.h b/VNFs/vACL/pipeline/pipeline_acl.h index 80a85cae..93b92c45 100644 --- a/VNFs/vACL/pipeline/pipeline_acl.h +++ b/VNFs/vACL/pipeline/pipeline_acl.h @@ -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. diff --git a/VNFs/vACL/pipeline/pipeline_acl_be.c b/VNFs/vACL/pipeline/pipeline_acl_be.c index b6e6076d..d3fa0519 100644 --- a/VNFs/vACL/pipeline/pipeline_acl_be.c +++ b/VNFs/vACL/pipeline/pipeline_acl_be.c @@ -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 index 00000000..ed8253be --- /dev/null +++ b/VNFs/vACL/vnf_template.txt @@ -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/VNFs/vCGNAPT/Makefile b/VNFs/vCGNAPT/Makefile index e349f627..41cacfb7 100644 --- a/VNFs/vCGNAPT/Makefile +++ b/VNFs/vCGNAPT/Makefile @@ -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 diff --git a/VNFs/vCGNAPT/config/sample_hwlb_2port_2WT.tc b/VNFs/vCGNAPT/config/sample_hwlb_2port_2WT.tc index 47ee0633..3cb90c9a 100644 --- a/VNFs/vCGNAPT/config/sample_hwlb_2port_2WT.tc +++ b/VNFs/vCGNAPT/config/sample_hwlb_2port_2WT.tc @@ -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 diff --git a/VNFs/vCGNAPT/config/sample_swlb_2port_2WT.tc b/VNFs/vCGNAPT/config/sample_swlb_2port_2WT.tc index 05ed058d..d7465690 100644 --- a/VNFs/vCGNAPT/config/sample_swlb_2port_2WT.tc +++ b/VNFs/vCGNAPT/config/sample_swlb_2port_2WT.tc @@ -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 diff --git a/VNFs/vCGNAPT/init.c b/VNFs/vCGNAPT/init.c index 76621d51..d61e419c 100644 --- a/VNFs/vCGNAPT/init.c +++ b/VNFs/vCGNAPT/init.c @@ -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"); diff --git a/VNFs/vCGNAPT/main.c b/VNFs/vCGNAPT/main.c index 9ebf6fc3..83fc37ff 100644 --- a/VNFs/vCGNAPT/main.c +++ b/VNFs/vCGNAPT/main.c @@ -15,12 +15,14 @@ */ #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; } diff --git a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.c b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.c index fb0b95d1..0c6bf48d 100644 --- a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.c +++ b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.c @@ -29,6 +29,12 @@ #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, diff --git a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.h b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.h index 5491648a..6497de27 100644 --- a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.h +++ b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt.h @@ -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 diff --git a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.c b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.c index eb0aca96..7758c5b3 100644 --- a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.c +++ b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.c @@ -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); } /** diff --git a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.h b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.h index 943d0fc7..7fde0c5a 100644 --- a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.h +++ b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_be.h @@ -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; diff --git a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_common.h b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_common.h index 4f4253cd..a7cd88a4 100644 --- a/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_common.h +++ b/VNFs/vCGNAPT/pipeline/pipeline_cgnapt_common.h @@ -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 index 00000000..385c5312 --- /dev/null +++ b/VNFs/vCGNAPT/vnf_template.txt @@ -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 + diff --git a/VNFs/vFW/Makefile b/VNFs/vFW/Makefile index c96246b9..b011eca2 100644 --- a/VNFs/vFW/Makefile +++ b/VNFs/vFW/Makefile @@ -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 diff --git a/VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc b/VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc index 46355bee..b27c66fa 100644 --- a/VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc +++ b/VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc @@ -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 diff --git a/VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc b/VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc index f20796ac..35bb519d 100644 --- a/VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc +++ b/VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc @@ -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 diff --git a/VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc b/VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc index 392320e3..ff502e55 100644 --- a/VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc +++ b/VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc @@ -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 diff --git a/VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc b/VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc index d85e17b9..b9dd226b 100644 --- a/VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc +++ b/VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc @@ -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 diff --git a/VNFs/vFW/init.c b/VNFs/vFW/init.c index 4e98b335..0edc5e32 100644 --- a/VNFs/vFW/init.c +++ b/VNFs/vFW/init.c @@ -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]; diff --git a/VNFs/vFW/main.c b/VNFs/vFW/main.c index 9ebf6fc3..aec04ac5 100644 --- a/VNFs/vFW/main.c +++ b/VNFs/vFW/main.c @@ -15,12 +15,15 @@ */ #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; } diff --git a/VNFs/vFW/pipeline/pipeline_vfw.c b/VNFs/vFW/pipeline/pipeline_vfw.c index f235bc59..df94b5f7 100644 --- a/VNFs/vFW/pipeline/pipeline_vfw.c +++ b/VNFs/vFW/pipeline/pipeline_vfw.c @@ -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> @@ -45,10 +46,16 @@ #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, diff --git a/VNFs/vFW/pipeline/pipeline_vfw.h b/VNFs/vFW/pipeline/pipeline_vfw.h index 3b1b25f0..96e7ad33 100644 --- a/VNFs/vFW/pipeline/pipeline_vfw.h +++ b/VNFs/vFW/pipeline/pipeline_vfw.h @@ -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 diff --git a/VNFs/vFW/pipeline/pipeline_vfw_be.c b/VNFs/vFW/pipeline/pipeline_vfw_be.c index fed424e5..f0eab34b 100644 --- a/VNFs/vFW/pipeline/pipeline_vfw_be.c +++ b/VNFs/vFW/pipeline/pipeline_vfw_be.c @@ -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 index 00000000..ed8253be --- /dev/null +++ b/VNFs/vFW/vnf_template.txt @@ -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 + |