diff options
Diffstat (limited to 'VNFs/vFW')
-rw-r--r-- | VNFs/vFW/Makefile | 10 | ||||
-rw-r--r-- | VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc | 23 | ||||
-rw-r--r-- | VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc | 12 | ||||
-rw-r--r-- | VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc | 22 | ||||
-rw-r--r-- | VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc | 20 | ||||
-rw-r--r-- | VNFs/vFW/init.c | 2 | ||||
-rw-r--r-- | VNFs/vFW/main.c | 19 | ||||
-rw-r--r-- | VNFs/vFW/pipeline/pipeline_vfw.c | 478 | ||||
-rw-r--r-- | VNFs/vFW/pipeline/pipeline_vfw.h | 15 | ||||
-rw-r--r-- | VNFs/vFW/pipeline/pipeline_vfw_be.c | 448 | ||||
-rw-r--r-- | VNFs/vFW/vnf_template.txt | 82 |
11 files changed, 897 insertions, 234 deletions
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 + |