summaryrefslogtreecommitdiffstats
path: root/VNFs/vFW
diff options
context:
space:
mode:
Diffstat (limited to 'VNFs/vFW')
-rw-r--r--VNFs/vFW/Makefile10
-rw-r--r--VNFs/vFW/config/VFW_HWLB_MultiPortPair_script.tc23
-rw-r--r--VNFs/vFW/config/VFW_HWLB_SinglePortPair_script.tc12
-rw-r--r--VNFs/vFW/config/VFW_SWLB_MultiPortPair_script.tc22
-rw-r--r--VNFs/vFW/config/VFW_SWLB_SinglePortPair_script.tc20
-rw-r--r--VNFs/vFW/init.c2
-rw-r--r--VNFs/vFW/main.c19
-rw-r--r--VNFs/vFW/pipeline/pipeline_vfw.c478
-rw-r--r--VNFs/vFW/pipeline/pipeline_vfw.h15
-rw-r--r--VNFs/vFW/pipeline/pipeline_vfw_be.c448
-rw-r--r--VNFs/vFW/vnf_template.txt82
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
+