examples/ip_pipeline: add bulk update of firewall rules
Added two new cli commands to firewall pipeline. Commands bulk add and bulk delete takes as argument a file with rules to add/delete. The file is parsed, and then rules are passed to backend functions which add/delete records from pipeline tables. Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This commit is contained in:
parent
48f2543cf0
commit
67ebdbef0c
@ -51,6 +51,8 @@
|
||||
#include "pipeline_common_fe.h"
|
||||
#include "pipeline_firewall.h"
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
struct app_pipeline_firewall_rule {
|
||||
struct pipeline_firewall_key key;
|
||||
int32_t priority;
|
||||
@ -73,6 +75,18 @@ struct app_pipeline_firewall {
|
||||
void *default_rule_entry_ptr;
|
||||
};
|
||||
|
||||
struct app_pipeline_add_bulk_params {
|
||||
struct pipeline_firewall_key *keys;
|
||||
uint32_t n_keys;
|
||||
uint32_t *priorities;
|
||||
uint32_t *port_ids;
|
||||
};
|
||||
|
||||
struct app_pipeline_del_bulk_params {
|
||||
struct pipeline_firewall_key *keys;
|
||||
uint32_t n_keys;
|
||||
};
|
||||
|
||||
static void
|
||||
print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
|
||||
{
|
||||
@ -256,6 +270,358 @@ app_pipeline_firewall_key_check_and_normalize(struct pipeline_firewall_key *key)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
app_pipeline_add_bulk_parse_file(char *filename,
|
||||
struct app_pipeline_add_bulk_params *params)
|
||||
{
|
||||
FILE *f;
|
||||
char file_buf[BUF_SIZE];
|
||||
uint32_t i;
|
||||
int status = 0;
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL)
|
||||
return -1;
|
||||
|
||||
params->n_keys = 0;
|
||||
while (fgets(file_buf, BUF_SIZE, f) != NULL)
|
||||
params->n_keys++;
|
||||
rewind(f);
|
||||
|
||||
if (params->n_keys == 0) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
params->keys = rte_malloc(NULL,
|
||||
params->n_keys * sizeof(struct pipeline_firewall_key),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (params->keys == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
params->priorities = rte_malloc(NULL,
|
||||
params->n_keys * sizeof(uint32_t),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (params->priorities == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
params->port_ids = rte_malloc(NULL,
|
||||
params->n_keys * sizeof(uint32_t),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (params->port_ids == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (fgets(file_buf, BUF_SIZE, f) != NULL) {
|
||||
char *str;
|
||||
|
||||
str = strtok(file_buf, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->priorities[i] = atoi(str);
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<16;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<8;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip_mask = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_port_from = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_port_to = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_port_from = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_port_to = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.proto = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
/* Need to add 2 to str to skip leading 0x */
|
||||
params->keys[i].key.ipv4_5tuple.proto_mask = strtol(str+2, NULL, 16);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->port_ids[i] = atoi(str);
|
||||
params->keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
end:
|
||||
fclose(f);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
app_pipeline_del_bulk_parse_file(char *filename,
|
||||
struct app_pipeline_del_bulk_params *params)
|
||||
{
|
||||
FILE *f;
|
||||
char file_buf[BUF_SIZE];
|
||||
uint32_t i;
|
||||
int status = 0;
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL)
|
||||
return -1;
|
||||
|
||||
params->n_keys = 0;
|
||||
while (fgets(file_buf, BUF_SIZE, f) != NULL)
|
||||
params->n_keys++;
|
||||
rewind(f);
|
||||
|
||||
if (params->n_keys == 0) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
params->keys = rte_malloc(NULL,
|
||||
params->n_keys * sizeof(struct pipeline_firewall_key),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (params->keys == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (fgets(file_buf, BUF_SIZE, f) != NULL) {
|
||||
char *str;
|
||||
|
||||
str = strtok(file_buf, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<16;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<8;
|
||||
|
||||
str = strtok(NULL, " .");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_ip_mask = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_port_from = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.src_port_to = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_port_from = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.dst_port_to = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
params->keys[i].key.ipv4_5tuple.proto = atoi(str);
|
||||
|
||||
str = strtok(NULL, " ");
|
||||
if (str == NULL) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
/* Need to add 2 to str to skip leading 0x */
|
||||
params->keys[i].key.ipv4_5tuple.proto_mask = strtol(str+2, NULL, 16);
|
||||
|
||||
params->keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < params->n_keys; i++) {
|
||||
if (app_pipeline_firewall_key_check_and_normalize(¶ms->keys[i]) != 0) {
|
||||
status = -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
fclose(f);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
app_pipeline_firewall_add_rule(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
@ -406,6 +772,332 @@ app_pipeline_firewall_delete_rule(struct app_params *app,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
app_pipeline_firewall_add_bulk(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
struct pipeline_firewall_key *keys,
|
||||
uint32_t n_keys,
|
||||
uint32_t *priorities,
|
||||
uint32_t *port_ids)
|
||||
{
|
||||
struct app_pipeline_firewall *p;
|
||||
struct pipeline_firewall_add_bulk_msg_req *req;
|
||||
struct pipeline_firewall_add_bulk_msg_rsp *rsp;
|
||||
|
||||
struct app_pipeline_firewall_rule **rules;
|
||||
int *new_rules;
|
||||
|
||||
int *keys_found;
|
||||
void **entries_ptr;
|
||||
|
||||
uint32_t i;
|
||||
int status = 0;
|
||||
|
||||
/* Check input arguments */
|
||||
if (app == NULL)
|
||||
return -1;
|
||||
|
||||
p = app_pipeline_data_fe(app, pipeline_id);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
rules = rte_malloc(NULL,
|
||||
n_keys * sizeof(struct app_pipeline_firewall_rule *),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (rules == NULL)
|
||||
return -1;
|
||||
|
||||
new_rules = rte_malloc(NULL,
|
||||
n_keys * sizeof(int),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (new_rules == NULL) {
|
||||
rte_free(rules);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check data integrity and add to rule list */
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
if (port_ids[i] >= p->n_ports_out) {
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
|
||||
new_rules[i] = (rules[i] == NULL);
|
||||
if (rules[i] == NULL) {
|
||||
rules[i] = rte_malloc(NULL, sizeof(rules[i]),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
|
||||
if (rules[i] == NULL) {
|
||||
uint32_t j;
|
||||
|
||||
for (j = 0; j <= i; j++)
|
||||
if (new_rules[j])
|
||||
rte_free(rules[j]);
|
||||
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keys_found = rte_malloc(NULL,
|
||||
n_keys * sizeof(int),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (keys_found == NULL) {
|
||||
uint32_t j;
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
if (new_rules[j])
|
||||
rte_free(rules[j]);
|
||||
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
return -1;
|
||||
}
|
||||
|
||||
entries_ptr = rte_malloc(NULL,
|
||||
n_keys * sizeof(struct rte_pipeline_table_entry *),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (entries_ptr == NULL) {
|
||||
uint32_t j;
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
if (new_rules[j])
|
||||
rte_free(rules[j]);
|
||||
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
rte_free(keys_found);
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
entries_ptr[i] = rte_malloc(NULL,
|
||||
sizeof(struct rte_pipeline_table_entry),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
|
||||
if (entries_ptr[i] == NULL) {
|
||||
uint32_t j;
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
if (new_rules[j])
|
||||
rte_free(rules[j]);
|
||||
|
||||
for (j = 0; j <= i; j++)
|
||||
rte_free(entries_ptr[j]);
|
||||
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
rte_free(keys_found);
|
||||
rte_free(entries_ptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate and write request */
|
||||
req = app_msg_alloc(app);
|
||||
if (req == NULL) {
|
||||
uint32_t j;
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
if (new_rules[j])
|
||||
rte_free(rules[j]);
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
rte_free(entries_ptr[j]);
|
||||
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
rte_free(keys_found);
|
||||
rte_free(entries_ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
req->type = PIPELINE_MSG_REQ_CUSTOM;
|
||||
req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_BULK;
|
||||
|
||||
req->keys = keys;
|
||||
req->n_keys = n_keys;
|
||||
req->port_ids = port_ids;
|
||||
req->priorities = priorities;
|
||||
req->keys_found = keys_found;
|
||||
req->entries_ptr = entries_ptr;
|
||||
|
||||
/* Send request and wait for response */
|
||||
rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
|
||||
if (rsp == NULL) {
|
||||
uint32_t j;
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
if (new_rules[j])
|
||||
rte_free(rules[j]);
|
||||
|
||||
for (j = 0; j < n_keys; j++)
|
||||
rte_free(entries_ptr[j]);
|
||||
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
rte_free(keys_found);
|
||||
rte_free(entries_ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->status) {
|
||||
for (i = 0; i < n_keys; i++)
|
||||
if (new_rules[i])
|
||||
rte_free(rules[i]);
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
rte_free(entries_ptr[i]);
|
||||
|
||||
status = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
if (entries_ptr[i] == NULL ||
|
||||
((new_rules[i] == 0) && (keys_found[i] == 0)) ||
|
||||
((new_rules[i] == 1) && (keys_found[i] == 1))) {
|
||||
for (i = 0; i < n_keys; i++)
|
||||
if (new_rules[i])
|
||||
rte_free(rules[i]);
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
rte_free(entries_ptr[i]);
|
||||
|
||||
status = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
memcpy(&rules[i]->key, &keys[i], sizeof(keys[i]));
|
||||
rules[i]->priority = priorities[i];
|
||||
rules[i]->port_id = port_ids[i];
|
||||
rules[i]->entry_ptr = entries_ptr[i];
|
||||
|
||||
/* Commit rule */
|
||||
if (new_rules[i]) {
|
||||
TAILQ_INSERT_TAIL(&p->rules, rules[i], node);
|
||||
p->n_rules++;
|
||||
}
|
||||
|
||||
print_firewall_ipv4_rule(rules[i]);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
app_msg_free(app, rsp);
|
||||
rte_free(rules);
|
||||
rte_free(new_rules);
|
||||
rte_free(keys_found);
|
||||
rte_free(entries_ptr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
app_pipeline_firewall_delete_bulk(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
struct pipeline_firewall_key *keys,
|
||||
uint32_t n_keys)
|
||||
{
|
||||
struct app_pipeline_firewall *p;
|
||||
struct pipeline_firewall_del_bulk_msg_req *req;
|
||||
struct pipeline_firewall_del_bulk_msg_rsp *rsp;
|
||||
|
||||
struct app_pipeline_firewall_rule **rules;
|
||||
int *keys_found;
|
||||
|
||||
uint32_t i;
|
||||
int status = 0;
|
||||
|
||||
/* Check input arguments */
|
||||
if (app == NULL)
|
||||
return -1;
|
||||
|
||||
p = app_pipeline_data_fe(app, pipeline_id);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
rules = rte_malloc(NULL,
|
||||
n_keys * sizeof(struct app_pipeline_firewall_rule *),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (rules == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
|
||||
}
|
||||
|
||||
keys_found = rte_malloc(NULL,
|
||||
n_keys * sizeof(int),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (keys_found == NULL) {
|
||||
rte_free(rules);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate and write request */
|
||||
req = app_msg_alloc(app);
|
||||
if (req == NULL) {
|
||||
rte_free(rules);
|
||||
rte_free(keys_found);
|
||||
return -1;
|
||||
}
|
||||
|
||||
req->type = PIPELINE_MSG_REQ_CUSTOM;
|
||||
req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_BULK;
|
||||
|
||||
req->keys = keys;
|
||||
req->n_keys = n_keys;
|
||||
req->keys_found = keys_found;
|
||||
|
||||
/* Send request and wait for response */
|
||||
rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
|
||||
if (rsp == NULL) {
|
||||
rte_free(rules);
|
||||
rte_free(keys_found);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->status) {
|
||||
status = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
if (keys_found[i] == 0) {
|
||||
status = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
TAILQ_REMOVE(&p->rules, rules[i], node);
|
||||
p->n_rules--;
|
||||
rte_free(rules[i]);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
app_msg_free(app, rsp);
|
||||
rte_free(rules);
|
||||
rte_free(keys_found);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
app_pipeline_firewall_add_default_rule(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
@ -794,6 +1486,170 @@ cmdline_parse_inst_t cmd_firewall_del_ipv4 = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* p firewall add bulk
|
||||
*/
|
||||
|
||||
struct cmd_firewall_add_bulk_result {
|
||||
cmdline_fixed_string_t p_string;
|
||||
uint32_t pipeline_id;
|
||||
cmdline_fixed_string_t firewall_string;
|
||||
cmdline_fixed_string_t add_string;
|
||||
cmdline_fixed_string_t bulk_string;
|
||||
cmdline_fixed_string_t file_path;
|
||||
};
|
||||
|
||||
static void
|
||||
cmd_firewall_add_bulk_parsed(
|
||||
void *parsed_result,
|
||||
__attribute__((unused)) struct cmdline *cl,
|
||||
void *data)
|
||||
{
|
||||
struct cmd_firewall_add_bulk_result *params = parsed_result;
|
||||
struct app_params *app = data;
|
||||
int status;
|
||||
|
||||
struct app_pipeline_add_bulk_params add_bulk_params;
|
||||
|
||||
status = app_pipeline_add_bulk_parse_file(params->file_path, &add_bulk_params);
|
||||
if (status != 0) {
|
||||
printf("Command failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
status = app_pipeline_firewall_add_bulk(app, params->pipeline_id, add_bulk_params.keys,
|
||||
add_bulk_params.n_keys, add_bulk_params.priorities, add_bulk_params.port_ids);
|
||||
if (status != 0) {
|
||||
printf("Command failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
rte_free(add_bulk_params.keys);
|
||||
rte_free(add_bulk_params.priorities);
|
||||
rte_free(add_bulk_params.port_ids);
|
||||
}
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_add_bulk_p_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result, p_string,
|
||||
"p");
|
||||
|
||||
cmdline_parse_token_num_t cmd_firewall_add_bulk_pipeline_id =
|
||||
TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_bulk_result, pipeline_id,
|
||||
UINT32);
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_add_bulk_firewall_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
|
||||
firewall_string, "firewall");
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_add_bulk_add_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
|
||||
add_string, "add");
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_add_bulk_bulk_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
|
||||
bulk_string, "bulk");
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_add_bulk_file_path_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
|
||||
file_path, NULL);
|
||||
|
||||
cmdline_parse_inst_t cmd_firewall_add_bulk = {
|
||||
.f = cmd_firewall_add_bulk_parsed,
|
||||
.data = NULL,
|
||||
.help_str = "Firewall rule add bulk",
|
||||
.tokens = {
|
||||
(void *) &cmd_firewall_add_bulk_p_string,
|
||||
(void *) &cmd_firewall_add_bulk_pipeline_id,
|
||||
(void *) &cmd_firewall_add_bulk_firewall_string,
|
||||
(void *) &cmd_firewall_add_bulk_add_string,
|
||||
(void *) &cmd_firewall_add_bulk_bulk_string,
|
||||
(void *) &cmd_firewall_add_bulk_file_path_string,
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* p firewall del bulk
|
||||
*/
|
||||
|
||||
struct cmd_firewall_del_bulk_result {
|
||||
cmdline_fixed_string_t p_string;
|
||||
uint32_t pipeline_id;
|
||||
cmdline_fixed_string_t firewall_string;
|
||||
cmdline_fixed_string_t del_string;
|
||||
cmdline_fixed_string_t bulk_string;
|
||||
cmdline_fixed_string_t file_path;
|
||||
};
|
||||
|
||||
static void
|
||||
cmd_firewall_del_bulk_parsed(
|
||||
void *parsed_result,
|
||||
__attribute__((unused)) struct cmdline *cl,
|
||||
void *data)
|
||||
{
|
||||
struct cmd_firewall_del_bulk_result *params = parsed_result;
|
||||
struct app_params *app = data;
|
||||
int status;
|
||||
|
||||
struct app_pipeline_del_bulk_params del_bulk_params;
|
||||
|
||||
status = app_pipeline_del_bulk_parse_file(params->file_path, &del_bulk_params);
|
||||
if (status != 0) {
|
||||
printf("Command failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
status = app_pipeline_firewall_delete_bulk(app, params->pipeline_id,
|
||||
del_bulk_params.keys, del_bulk_params.n_keys);
|
||||
if (status != 0) {
|
||||
printf("Command failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
rte_free(del_bulk_params.keys);
|
||||
}
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_del_bulk_p_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result, p_string,
|
||||
"p");
|
||||
|
||||
cmdline_parse_token_num_t cmd_firewall_del_bulk_pipeline_id =
|
||||
TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_bulk_result, pipeline_id,
|
||||
UINT32);
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_del_bulk_firewall_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
|
||||
firewall_string, "firewall");
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_del_bulk_add_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
|
||||
del_string, "del");
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_del_bulk_bulk_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
|
||||
bulk_string, "bulk");
|
||||
|
||||
cmdline_parse_token_string_t cmd_firewall_del_bulk_file_path_string =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
|
||||
file_path, NULL);
|
||||
|
||||
cmdline_parse_inst_t cmd_firewall_del_bulk = {
|
||||
.f = cmd_firewall_del_bulk_parsed,
|
||||
.data = NULL,
|
||||
.help_str = "Firewall rule del bulk",
|
||||
.tokens = {
|
||||
(void *) &cmd_firewall_del_bulk_p_string,
|
||||
(void *) &cmd_firewall_del_bulk_pipeline_id,
|
||||
(void *) &cmd_firewall_del_bulk_firewall_string,
|
||||
(void *) &cmd_firewall_del_bulk_add_string,
|
||||
(void *) &cmd_firewall_del_bulk_bulk_string,
|
||||
(void *) &cmd_firewall_del_bulk_file_path_string,
|
||||
NULL,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* p firewall add default
|
||||
*/
|
||||
@ -984,6 +1840,8 @@ cmdline_parse_inst_t cmd_firewall_ls = {
|
||||
static cmdline_parse_ctx_t pipeline_cmds[] = {
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_add_ipv4,
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_del_ipv4,
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_add_bulk,
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_del_bulk,
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_add_default,
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_del_default,
|
||||
(cmdline_parse_inst_t *) &cmd_firewall_ls,
|
||||
|
@ -49,6 +49,20 @@ app_pipeline_firewall_delete_rule(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
struct pipeline_firewall_key *key);
|
||||
|
||||
int
|
||||
app_pipeline_firewall_add_bulk(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
struct pipeline_firewall_key *keys,
|
||||
uint32_t n_keys,
|
||||
uint32_t *priorities,
|
||||
uint32_t *port_ids);
|
||||
|
||||
int
|
||||
app_pipeline_firewall_delete_bulk(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
struct pipeline_firewall_key *keys,
|
||||
uint32_t n_keys);
|
||||
|
||||
int
|
||||
app_pipeline_firewall_add_default_rule(struct app_params *app,
|
||||
uint32_t pipeline_id,
|
||||
|
@ -79,6 +79,12 @@ pipeline_firewall_msg_req_add_handler(struct pipeline *p, void *msg);
|
||||
static void *
|
||||
pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg);
|
||||
|
||||
static void *
|
||||
pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg);
|
||||
|
||||
static void *
|
||||
pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg);
|
||||
|
||||
static void *
|
||||
pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg);
|
||||
|
||||
@ -90,6 +96,10 @@ static pipeline_msg_req_handler custom_handlers[] = {
|
||||
pipeline_firewall_msg_req_add_handler,
|
||||
[PIPELINE_FIREWALL_MSG_REQ_DEL] =
|
||||
pipeline_firewall_msg_req_del_handler,
|
||||
[PIPELINE_FIREWALL_MSG_REQ_ADD_BULK] =
|
||||
pipeline_firewall_msg_req_add_bulk_handler,
|
||||
[PIPELINE_FIREWALL_MSG_REQ_DEL_BULK] =
|
||||
pipeline_firewall_msg_req_del_bulk_handler,
|
||||
[PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT] =
|
||||
pipeline_firewall_msg_req_add_default_handler,
|
||||
[PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT] =
|
||||
@ -698,6 +708,153 @@ pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg)
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static void *
|
||||
pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg)
|
||||
{
|
||||
struct pipeline_firewall_add_bulk_msg_req *req = msg;
|
||||
struct pipeline_firewall_add_bulk_msg_rsp *rsp = msg;
|
||||
|
||||
struct rte_table_acl_rule_add_params *params[req->n_keys];
|
||||
struct firewall_table_entry *entries[req->n_keys];
|
||||
|
||||
uint32_t i, n_keys;
|
||||
|
||||
n_keys = req->n_keys;
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
entries[i] = rte_malloc(NULL,
|
||||
sizeof(struct firewall_table_entry),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (entries[i] == NULL) {
|
||||
rsp->status = -1;
|
||||
return rsp;
|
||||
}
|
||||
|
||||
params[i] = rte_malloc(NULL,
|
||||
sizeof(struct rte_table_acl_rule_add_params),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (params[i] == NULL) {
|
||||
rsp->status = -1;
|
||||
return rsp;
|
||||
}
|
||||
|
||||
entries[i]->head.action = RTE_PIPELINE_ACTION_PORT;
|
||||
entries[i]->head.port_id = p->port_out_id[req->port_ids[i]];
|
||||
|
||||
switch (req->keys[i].type) {
|
||||
case PIPELINE_FIREWALL_IPV4_5TUPLE:
|
||||
params[i]->priority = req->priorities[i];
|
||||
params[i]->field_value[0].value.u8 =
|
||||
req->keys[i].key.ipv4_5tuple.proto;
|
||||
params[i]->field_value[0].mask_range.u8 =
|
||||
req->keys[i].key.ipv4_5tuple.proto_mask;
|
||||
params[i]->field_value[1].value.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.src_ip;
|
||||
params[i]->field_value[1].mask_range.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.src_ip_mask;
|
||||
params[i]->field_value[2].value.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_ip;
|
||||
params[i]->field_value[2].mask_range.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_ip_mask;
|
||||
params[i]->field_value[3].value.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.src_port_from;
|
||||
params[i]->field_value[3].mask_range.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.src_port_to;
|
||||
params[i]->field_value[4].value.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_port_from;
|
||||
params[i]->field_value[4].mask_range.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_port_to;
|
||||
break;
|
||||
|
||||
default:
|
||||
rsp->status = -1; /* Error */
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
rte_free(entries[i]);
|
||||
rte_free(params[i]);
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
}
|
||||
|
||||
rsp->status = rte_pipeline_table_entry_add_bulk(p->p, p->table_id[0],
|
||||
(void *)params, (struct rte_pipeline_table_entry **)entries,
|
||||
n_keys, req->keys_found,
|
||||
(struct rte_pipeline_table_entry **)req->entries_ptr);
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
rte_free(entries[i]);
|
||||
rte_free(params[i]);
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static void *
|
||||
pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg)
|
||||
{
|
||||
struct pipeline_firewall_del_bulk_msg_req *req = msg;
|
||||
struct pipeline_firewall_del_bulk_msg_rsp *rsp = msg;
|
||||
|
||||
struct rte_table_acl_rule_delete_params *params[req->n_keys];
|
||||
|
||||
uint32_t i, n_keys;
|
||||
|
||||
n_keys = req->n_keys;
|
||||
|
||||
for (i = 0; i < n_keys; i++) {
|
||||
params[i] = rte_malloc(NULL,
|
||||
sizeof(struct rte_table_acl_rule_delete_params),
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (params[i] == NULL) {
|
||||
rsp->status = -1;
|
||||
return rsp;
|
||||
}
|
||||
|
||||
switch (req->keys[i].type) {
|
||||
case PIPELINE_FIREWALL_IPV4_5TUPLE:
|
||||
params[i]->field_value[0].value.u8 =
|
||||
req->keys[i].key.ipv4_5tuple.proto;
|
||||
params[i]->field_value[0].mask_range.u8 =
|
||||
req->keys[i].key.ipv4_5tuple.proto_mask;
|
||||
params[i]->field_value[1].value.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.src_ip;
|
||||
params[i]->field_value[1].mask_range.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.src_ip_mask;
|
||||
params[i]->field_value[2].value.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_ip;
|
||||
params[i]->field_value[2].mask_range.u32 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_ip_mask;
|
||||
params[i]->field_value[3].value.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.src_port_from;
|
||||
params[i]->field_value[3].mask_range.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.src_port_to;
|
||||
params[i]->field_value[4].value.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_port_from;
|
||||
params[i]->field_value[4].mask_range.u16 =
|
||||
req->keys[i].key.ipv4_5tuple.dst_port_to;
|
||||
break;
|
||||
|
||||
default:
|
||||
rsp->status = -1; /* Error */
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
rte_free(params[i]);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
}
|
||||
|
||||
rsp->status = rte_pipeline_table_entry_delete_bulk(p->p, p->table_id[0],
|
||||
(void **)¶ms, n_keys, req->keys_found, NULL);
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
rte_free(params[i]);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
void *
|
||||
pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg)
|
||||
{
|
||||
|
@ -63,6 +63,8 @@ struct pipeline_firewall_key {
|
||||
enum pipeline_firewall_msg_req_type {
|
||||
PIPELINE_FIREWALL_MSG_REQ_ADD = 0,
|
||||
PIPELINE_FIREWALL_MSG_REQ_DEL,
|
||||
PIPELINE_FIREWALL_MSG_REQ_ADD_BULK,
|
||||
PIPELINE_FIREWALL_MSG_REQ_DEL_BULK,
|
||||
PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT,
|
||||
PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT,
|
||||
PIPELINE_FIREWALL_MSG_REQS
|
||||
@ -105,6 +107,42 @@ struct pipeline_firewall_del_msg_rsp {
|
||||
int key_found;
|
||||
};
|
||||
|
||||
/*
|
||||
* MSG ADD BULK
|
||||
*/
|
||||
struct pipeline_firewall_add_bulk_msg_req {
|
||||
enum pipeline_msg_req_type type;
|
||||
enum pipeline_firewall_msg_req_type subtype;
|
||||
|
||||
struct pipeline_firewall_key *keys;
|
||||
uint32_t n_keys;
|
||||
|
||||
uint32_t *priorities;
|
||||
uint32_t *port_ids;
|
||||
int *keys_found;
|
||||
void **entries_ptr;
|
||||
};
|
||||
struct pipeline_firewall_add_bulk_msg_rsp {
|
||||
int status;
|
||||
};
|
||||
|
||||
/*
|
||||
* MSG DEL BULK
|
||||
*/
|
||||
struct pipeline_firewall_del_bulk_msg_req {
|
||||
enum pipeline_msg_req_type type;
|
||||
enum pipeline_firewall_msg_req_type subtype;
|
||||
|
||||
/* key */
|
||||
struct pipeline_firewall_key *keys;
|
||||
uint32_t n_keys;
|
||||
int *keys_found;
|
||||
};
|
||||
|
||||
struct pipeline_firewall_del_bulk_msg_rsp {
|
||||
int status;
|
||||
};
|
||||
|
||||
/*
|
||||
* MSG ADD DEFAULT
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user