summaryrefslogtreecommitdiffstats
path: root/VNFs/vACL
diff options
context:
space:
mode:
authorVishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>2017-09-25 03:36:02 +0530
committerAnand B Jyoti <anand.b.jyoti@intel.com>2017-09-27 03:29:36 +0530
commit98b9571f6720a0da06b1d430e7338a0734023232 (patch)
tree35224c83fa80c0f6dd297c9cee52f5894ade3c56 /VNFs/vACL
parentd451d3d2e6423523c300488f33adb4e593d6d2cb (diff)
REST_API: rest api client implementation
JIRA: SAMPLEVNF-78 This patch implements rest api's for VNF clients. This comprises of * vnf api's for common functionality * vnf api's for CGNAPT * vnf api's for VFW Change-Id: I56d22c64bf3ee5b0a2e536da8169ac7583499041 Signed-off-by: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>
Diffstat (limited to 'VNFs/vACL')
-rw-r--r--VNFs/vACL/Makefile10
-rw-r--r--VNFs/vACL/main.c18
-rw-r--r--VNFs/vACL/pipeline/pipeline_acl.c297
-rw-r--r--VNFs/vACL/pipeline/pipeline_acl.h4
-rw-r--r--VNFs/vACL/vnf_template.txt82
5 files changed, 409 insertions, 2 deletions
diff --git a/VNFs/vACL/Makefile b/VNFs/vACL/Makefile
index bba5a6bc..0995f905 100644
--- a/VNFs/vACL/Makefile
+++ b/VNFs/vACL/Makefile
@@ -30,7 +30,6 @@ include $(RTE_SDK)/mk/rte.vars.mk
# binary name
APP = vACL
-
VPATH += $(VNF_CORE)/common/vnf_common
VPATH += $(VNF_CORE)/common/VIL/conntrack
VPATH += $(VNF_CORE)/common/VIL/pipeline_common
@@ -54,7 +53,7 @@ INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_master/*.h)
INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_passthrough/*.h)
INC += $(wildcard $(VNF_CORE)/common/VIL/pipeline_txrx/*.h)
INC += $(wildcard $(VNF_CORE)/common/VIL/l2l3_stack/*.h)
-INC += $(wildcard $(VNF_CORE)/common/VIL/gateway/*.h
+INC += $(wildcard $(VNF_CORE)/common/VIL/gateway/*.h)
CFLAGS += -I$(SRCDIR) -mrtm -mhle -I$(SRCDIR)/pipeline -I$(VNF_CORE)/common/vnf_common
CFLAGS += -I$(VNF_CORE)/common/VIL/l2l3_stack -I$(VNF_CORE)/common/VIL/conntrack
@@ -64,9 +63,16 @@ CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_txrx
CFLAGS += -I$(VNF_CORE)/common/VIL/pipeline_arpicmp
CFLAGS += -I$(VNF_CORE)/common/VIL/gateway
+TOP = $(RTE_SDK)/../civetweb
+CFLAGS += -I$(TOP)/include $(COPT) -DUSE_WEBSOCKET -DUSE_IPV6 -DUSE_SSL_DH=1
+CFLAGS += -DREST_API_SUPPORT
+LDFLAGS += -ljson -lcrypto -lssl
+LDFLAGS += -L$(RTE_SDK)/../civetweb/ -lcivetweb
+
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := main.c
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += rest_api.c
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse_tm.c
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_check.c
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += init.c
diff --git a/VNFs/vACL/main.c b/VNFs/vACL/main.c
index 9ebf6fc3..a6ba00b6 100644
--- a/VNFs/vACL/main.c
+++ b/VNFs/vACL/main.c
@@ -15,12 +15,14 @@
*/
#include "app.h"
+#include "pipeline_acl.h"
static struct app_params app;
int
main(int argc, char **argv)
{
+ struct mg_context *ctx = NULL;
rte_openlog_stream(stderr);
/* Config */
@@ -28,6 +30,12 @@ main(int argc, char **argv)
app_config_args(&app, argc, argv);
+ if (is_rest_support()) {
+ /* initialize the rest api */
+ set_vnf_type("VACL");
+ ctx = rest_api_init(&app);
+ }
+
app_config_preproc(&app);
app_config_parse(&app, app.parser_file);
@@ -40,11 +48,21 @@ main(int argc, char **argv)
/* Init */
app_init(&app);
+ if (is_rest_support() && (ctx != NULL)) {
+ /* rest api's for cgnapt */
+ rest_api_acl_init(ctx, &app);
+ }
+
/* Run-time */
rte_eal_mp_remote_launch(
app_thread,
(void *) &app,
CALL_MASTER);
+ if (is_rest_support() && (ctx != NULL)) {
+ mg_stop(ctx);
+ printf("Civet server stopped.\n");
+ }
+
return 0;
}
diff --git a/VNFs/vACL/pipeline/pipeline_acl.c b/VNFs/vACL/pipeline/pipeline_acl.c
index 1a4ed4f5..f1935622 100644
--- a/VNFs/vACL/pipeline/pipeline_acl.c
+++ b/VNFs/vACL/pipeline/pipeline_acl.c
@@ -49,6 +49,13 @@
#include "pipeline_acl_be.h"
#include "rte_cnxn_tracking.h"
+int acl_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int acl_clear_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+int acl_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
+uint32_t rules_loaded = 0;
+extern struct cmdline *pipe_cl;
+struct app_params *myapp;
+
/**
* A structure defining the ACL rule for the TAILQ Tables.
*/
@@ -4176,3 +4183,293 @@ struct pipeline_type pipeline_acl = {
.be_ops = &pipeline_acl_be_ops,
.fe_ops = &pipeline_acl_fe_ops,
};
+
+void all_acl_stats(struct mg_connection *conn)
+{
+
+ struct app_params *app = myapp;
+ int i, j;
+ struct rte_ACL_counter_block acl_counter_sums;
+ struct rte_CT_counter_block ct_counter_sums;
+ struct rte_CT_counter_block *ct_counters;
+ struct action_counter_block action_counter_sum[action_array_max];
+
+ memset(&acl_counter_sums, 0, sizeof(acl_counter_sums));
+ memset(&ct_counter_sums, 0, sizeof(ct_counter_sums));
+
+ mg_printf(conn,
+ "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+ "close\r\n\r\n");
+ mg_printf(conn, "<html><body>");
+ mg_printf(conn, "ACL Stats\n");
+ for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
+ struct rte_ACL_counter_block *acl_ctrs =
+ &rte_acl_counter_table[i];
+ ct_counters = rte_acl_counter_table[i].ct_counters;
+ mg_printf(conn, "acl entry[%i] tpkts_processed: %" PRIu64
+ ", pkts_drop: %" PRIu64 ", pkts_received: %" PRIu64
+ ", bytes_processed: %" PRIu64 "\n", i,
+ acl_ctrs->tpkts_processed, acl_ctrs->pkts_drop,
+ acl_ctrs->pkts_received, acl_ctrs->bytes_processed);
+
+ acl_counter_sums.tpkts_processed += acl_ctrs->tpkts_processed;
+ acl_counter_sums.bytes_processed += acl_ctrs->bytes_processed;
+ acl_counter_sums.pkts_drop += acl_ctrs->pkts_drop;
+ acl_counter_sums.pkts_received += acl_ctrs->pkts_received;
+ ct_counter_sums.pkts_forwarded += ct_counters->pkts_forwarded;
+ ct_counter_sums.pkts_drop += ct_counters->pkts_drop;
+ }
+
+ mg_printf(conn, "ACL TOTAL: tpkts_processed: %" PRIu64 ", pkts_drop: %" PRIu64
+ ", pkts_received: %" PRIu64 ", bytes_processed: %" PRIu64 "\n\n",
+ acl_counter_sums.tpkts_processed,
+ acl_counter_sums.pkts_drop,
+ acl_counter_sums.pkts_received,
+ acl_counter_sums.bytes_processed);
+
+ mg_printf(conn, "CT TOTAL: ct_packets_forwarded: %" PRIu64
+ ", ct_packets_dropped: %" PRIu64 "\n\n",
+ ct_counter_sums.pkts_forwarded, ct_counter_sums.pkts_drop);
+
+ for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
+ for (j = 0; j < action_array_max; j++) {
+ if (action_array_active[j].action_bitmap &
+ acl_action_count) {
+ action_counter_sum[j].packetCount +=
+ action_counter_table[i][j].packetCount;
+ action_counter_sum[j].byteCount +=
+ action_counter_table[i][j].byteCount;
+ }
+ }
+ }
+
+ for (j = 0; j < action_array_max; j++) {
+ if (action_array_active[j].action_bitmap & acl_action_count)
+ mg_printf(conn, "Action ID: %02u, packetCount: %" PRIu64
+ ", byteCount: %" PRIu64 "\n", j,
+ action_counter_sum[j].packetCount,
+ action_counter_sum[j].byteCount);
+ }
+ mg_printf(conn, "<p>Command Passed</p>");
+ mg_printf(conn, "</body></html>\n");
+}
+
+int acl_stats_handler(struct mg_connection *conn, void *cbdata)
+{
+ uint32_t num_links = 0, len = 0;
+ char buf[1024];
+ const struct mg_request_info *ri = mg_get_request_info(conn);
+ struct app_params *app = myapp;
+ int i;
+
+ if (!strcmp(ri->request_method, "GET")) {
+ all_acl_stats(conn);
+ mg_printf(conn, "%s\n", &buf[0]);
+ return 1;
+ }
+
+ if (strcmp(ri->request_method, "POST")) {
+ mg_printf(conn,
+ "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
+ mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
+ mg_printf(conn,
+ "%s method not allowed in the GET handler\n",
+ ri->request_method);
+ }
+
+ for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
+ rte_acl_counter_table[i].tpkts_processed = 0;
+ rte_acl_counter_table[i].bytes_processed = 0;
+ rte_acl_counter_table[i].pkts_drop = 0;
+ rte_acl_counter_table[i].pkts_received = 0;
+ rte_acl_counter_table[i].pkts_drop_ttl = 0;
+ rte_acl_counter_table[i].pkts_drop_bad_size = 0;
+ rte_acl_counter_table[i].pkts_drop_fragmented = 0;
+ rte_acl_counter_table[i].pkts_drop_without_arp_entry = 0;
+ rte_acl_counter_table[i].ct_counters->pkts_forwarded = 0;
+ rte_acl_counter_table[i].ct_counters->pkts_drop = 0;
+ }
+
+ memset(&action_counter_table, 0, sizeof(action_counter_table));
+
+ mg_printf(conn, "%s\n", &buf[0]);
+ return 1;
+
+}
+
+int acl_version_handler(struct mg_connection *conn, void *cbdata)
+{
+ const struct mg_request_info *req_info = mg_get_request_info(conn);
+
+ mg_printf(conn,
+ "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+ "close\r\n\r\n");
+ mg_printf(conn, "<html><body>");
+ mg_printf(conn, "<p>Command Passed</p>");
+ mg_printf(conn, "</body></html>\n");
+
+ return 1;
+}
+
+int acl_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+
+ const struct mg_request_info *req_info = mg_get_request_info(conn);
+ if (strcmp(req_info->request_method, "GET")) {
+ mg_printf(conn, "Only GET method allowed");
+ return 1;
+ }
+
+ mg_printf(conn,
+ "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+ "close\r\n\r\n");
+ mg_printf(conn, "<html><body>");
+ mg_printf(conn, "<h2> These are the methods that are supported </h2>");
+ mg_printf(conn, "<h3> /load </h3>");
+ mg_printf(conn, "<h3> /clear </h3>");
+ mg_printf(conn, "<html><body>");
+
+ mg_printf(conn, "</body></html>\n");
+
+ return 1;
+}
+
+static int acl_field_found(const char *key,
+ const char *filename,
+ char *path,
+ size_t pathlen,
+ void *user_data)
+{
+ struct mg_connection *conn = (struct mg_connection *)user_data;
+
+ mg_printf(conn, "\r\n\r\n%s:\r\n", key);
+ mg_printf(conn, "Inside vfw_field_found %s \n", filename);
+
+ if (filename && *filename) {
+ snprintf(path, pathlen, "/tmp/%s", filename);
+ struct app_params *app = myapp;
+ int status;
+ int fd;
+
+ mg_printf(conn, "path: %s\n", path);
+
+ /* Make sure the file exists before clearing rules and actions */
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ mg_printf(conn, "Cannot open file \"%s\"\n", filename);
+ return FORM_FIELD_STORAGE_GET;
+ }
+ close(fd);
+
+ return FORM_FIELD_STORAGE_STORE;
+ }
+
+ return FORM_FIELD_STORAGE_GET;
+}
+
+static int acl_field_get(const char *key, const char *value, size_t valuelen,
+ void *user_data)
+{
+ struct mg_connection *conn = (struct mg_connection *)user_data;
+
+ if (key[0]) {
+ mg_printf(conn, "%s = ", key);
+ }
+ mg_write(conn, value, valuelen);
+
+ return 0;
+}
+
+static int acl_field_stored(const char *path, long long file_size,
+ void *user_data)
+{
+ struct mg_connection *conn = (struct mg_connection *)user_data;
+ int status;
+
+ mg_printf(conn,
+ "stored as %s (%lu bytes)\r\n\r\n",
+ path,
+ (unsigned long)file_size);
+
+ /* Clear all rules and actions */
+ status = app_pipeline_acl_clearrules(myapp);
+
+ if (status != 0) {
+ mg_printf(conn, "Command failed\n");
+ return 1;
+ }
+
+ /* Process commands in script file */
+ app_loadrules_file(pipe_cl->ctx, path);
+ rules_loaded = 1;
+
+ return 0;
+}
+
+int acl_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+ /* Handler may access the request info using mg_get_request_info */
+ int ret;
+ const struct mg_request_info *req_info = mg_get_request_info(conn);
+ struct mg_form_data_handler fdh = {acl_field_found, acl_field_get,
+ acl_field_stored, 0};
+
+ /* It would be possible to check the request info here before calling
+ * mg_handle_form_request. */
+ (void)req_info;
+
+ mg_printf(conn,
+ "HTTP/1.1 200 OK\r\nContent-Type: "
+ "text/plain\r\nConnection: close\r\n\r\n");
+
+ if (!strcmp(req_info->request_method, "GET")) {
+ mg_printf(conn, "Rule file is %s\n", rules_loaded? "LOADED":"NOT LOADED");
+ }
+
+ if (strcmp(req_info->request_method, "PUT")) {
+ mg_printf(conn, "Only PUT method allowed");
+ return 1;
+ }
+
+ fdh.user_data = (void *)conn;
+
+ /* Call the form handler */
+ mg_printf(conn, "Form data:");
+ ret = mg_handle_form_request(conn, &fdh);
+ mg_printf(conn, "\r\n%i fields found", ret);
+
+ return 1;
+}
+
+int acl_clear_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
+{
+ struct app_params *app = myapp;
+ int status;
+ mg_printf(conn,
+ "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+ "close\r\n\r\n");
+ mg_printf(conn, "<html><body>");
+ status = app_pipeline_acl_clearrules(app);
+
+ if (status != 0) {
+ mg_printf(conn, "Command failed\n");
+ return 1;
+ }
+
+ mg_printf(conn, "Command Success\n");
+ mg_printf(conn, "</body></html>\n");
+ return 1;
+}
+
+void rest_api_acl_init(struct mg_context *ctx, struct app_params *app)
+{
+ myapp = app;
+
+ /* vCGNAPT commands */
+ mg_set_request_handler(ctx, "/vnf/config/rules", acl_rules_handler, 0);
+ mg_set_request_handler(ctx, "/vnf/config/rules/load", acl_load_rules_handler, 0);
+ mg_set_request_handler(ctx, "/vnf/config/rules/clear", acl_clear_rules_handler, 0);
+ mg_set_request_handler(ctx, "/vnf/status", acl_version_handler, 0);
+ mg_set_request_handler(ctx, "/vnf/stats", acl_stats_handler, 0);
+
+}
diff --git a/VNFs/vACL/pipeline/pipeline_acl.h b/VNFs/vACL/pipeline/pipeline_acl.h
index 80a85cae..93b92c45 100644
--- a/VNFs/vACL/pipeline/pipeline_acl.h
+++ b/VNFs/vACL/pipeline/pipeline_acl.h
@@ -28,6 +28,8 @@
#include "pipeline.h"
#include "pipeline_acl_be.h"
+#include <civetweb.h>
+#include <json/json.h>
/* ACL IPV4 and IPV6 enable flags for debugging (Default both on) */
extern int acl_ipv4_enabled;
@@ -47,6 +49,8 @@ extern void *acl_rule_table_ipv6_standby;
#define acl_delete_command 1
#define IPV6_32BIT_LENGTH 4
+void rest_api_acl_init(struct mg_context *ctx, struct app_params *app);
+
/**
* Add ACL rule to the ACL rule table.
* Rules are added standby table.
diff --git a/VNFs/vACL/vnf_template.txt b/VNFs/vACL/vnf_template.txt
new file mode 100644
index 00000000..ed8253be
--- /dev/null
+++ b/VNFs/vACL/vnf_template.txt
@@ -0,0 +1,82 @@
+[MASTER]
+type = MASTER
+core = 0
+
+[ARPICMP]
+type = ARPICMP
+core = 1
+pktq_in = SWQ0
+pktq_out = TXQ0.0 TXQ1.0
+pktq_in_prv = RXQ0.0
+prv_to_pub_map = (0,1)
+prv_que_handler = (0)
+
+[TIMER]
+type = TIMER
+core = 2
+n_flows = 1048576
+
+[TXRX-BEGIN]
+type = TXRX
+core = 2
+pktq_in = RXQ0.0 RXQ1.0
+pktq_out = SWQ0 SWQ1 SWQ2
+pipeline_txrx_type = RXRX
+dest_if_offset=176
+
+[TXRX-END]
+type = TXRX
+core = 5
+pktq_in = SWQ5 SWQ6
+pktq_out = TXQ0.1 TXQ1.1
+pipeline_txrx_type = TXTX
+
+[LOADB]
+type = LOADB
+core = 3
+pktq_in = SWQ0 SWQ1
+pktq_out = SWQ3 SWQ4
+outport_offset = 136
+phyport_offset = 204
+n_vnf_threads = 1
+prv_que_handler = (0)
+
+[VACL]
+type = ACL
+core = 4
+pktq_in = SWQ3 SWQ4
+pktq_out = SWQ5 SWQ6
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+
+[VCGNAPT]
+type = CGNAPT
+core = 3
+pktq_in = RXQ0.0 RXQ1.0
+pktq_out = TXQ0.1 TXQ1.1 SWQ0
+phyport_offset = 204
+n_flows = 1048576
+key_offset = 192;64
+key_size = 8
+hash_offset = 200;72
+timer_period = 100
+max_clients_per_ip = 65535
+max_port_per_client = 10
+public_ip_port_range = 98103214:(1, 65535)
+vnf_set = (3,4,5)
+pkt_type = ipv4
+cgnapt_meta_offset = 128
+prv_que_handler = (0,)
+
+[VFW]
+type = VFW
+core = s0c4
+pktq_in = SWQ3 SWQ4
+pktq_out = SWQ7 SWQ8;TXQ0.0 TXQ1.0
+n_rules = 10000
+n_flows = 1000000
+pkt_type = ipv6
+traffic_type = 6
+tcp_time_wait = 10
+