Exemple #1
0
static int
rte_table_acl_build(struct rte_table_acl *acl, struct rte_acl_ctx **acl_ctx)
{
	struct rte_acl_ctx *ctx = NULL;
	uint32_t n_rules, i;
	int status;

	/* Create low level ACL table */
	ctx = rte_acl_create(&acl->acl_params);
	if (ctx == NULL) {
		RTE_LOG(ERR, TABLE, "%s: Cannot create low level ACL table\n",
			__func__);
		return -1;
	}

	/* Add rules to low level ACL table */
	n_rules = 0;
	for (i = 1; i < acl->n_rules; i++) {
		if (acl->acl_rule_list[i] != NULL) {
			status = rte_acl_add_rules(ctx, acl->acl_rule_list[i],
				1);
			if (status != 0) {
				RTE_LOG(ERR, TABLE,
				"%s: Cannot add rule to low level ACL table\n",
					__func__);
				rte_acl_free(ctx);
				return -1;
			}

			n_rules++;
		}
	}

	if (n_rules == 0) {
		rte_acl_free(ctx);
		*acl_ctx = NULL;
		return 0;
	}

	/* Build low level ACl table */
	status = rte_acl_build(ctx, &acl->cfg);
	if (status != 0) {
		RTE_LOG(ERR, TABLE,
			"%s: Cannot build the low level ACL table\n",
			__func__);
		rte_acl_free(ctx);
		return -1;
	}

	rte_acl_dump(ctx);

	*acl_ctx = ctx;
	return 0;
}
Exemple #2
0
static struct rte_acl_ctx *
setup_acl(struct rte_acl_rule *acl_base, unsigned int acl_num, int ipv6,
	  int socketid)
{
	char name[PATH_MAX];
	struct rte_acl_param acl_param;
	struct rte_acl_config acl_build_param;
	struct rte_acl_ctx *context;
	int dim = ipv6 ? RTE_DIM(ipv6_defs) : RTE_DIM(ipv4_defs);
	static uint32_t ctx_count[NB_SOCKETS] = {0};

	if (!acl_num)
		return NULL;

	/* Create ACL contexts */
	snprintf(name, sizeof(name), "%s%d-%d",
		 ipv6 ? L3FWD_ACL_IPV6_NAME : L3FWD_ACL_IPV4_NAME, socketid, ctx_count[socketid]++);

	acl_param.name = name;
	acl_param.socket_id = socketid;
	acl_param.rule_size = RTE_ACL_RULE_SZ(dim);
	acl_param.max_rule_num = MAX_ACL_RULE_NUM;

	if ((context = rte_acl_create(&acl_param)) == NULL) {
		acl_log("Failed to create ACL context\n");
		goto err;
	}

	if (acl_parm_config.aclavx2 &&
	    rte_acl_set_ctx_classify(context, RTE_ACL_CLASSIFY_AVX2) != 0) {
		acl_log("Failed to setup classify method for  ACL context\n");
		goto err;
	}

	if (rte_acl_add_rules(context, acl_base, acl_num) < 0) {
		acl_log("add rules failed\n");
		goto err;
	}

	/* Perform builds */
	memset(&acl_build_param, 0, sizeof(acl_build_param));

	acl_build_param.num_categories = DEFAULT_MAX_CATEGORIES;
	acl_build_param.num_fields = dim;
	memcpy(&acl_build_param.defs, ipv6 ? ipv6_defs : ipv4_defs,
	       ipv6 ? sizeof(ipv6_defs) : sizeof(ipv4_defs));

	if (rte_acl_build(context, &acl_build_param) != 0) {
		acl_log("Failed to build ACL trie\n");
		goto err;
	}

	rte_acl_dump(context);

	return context;
err:
	rte_acl_free(context);
	return NULL;
}
struct rte_acl_ctx * mg_5tuple_create_filter(int socket_id, uint32_t num_rules){

  // FIXME: is prm on stack OK? or does this have to be on HEAP?
  struct rte_acl_param prm = {
      .name = "ACL_5tuple_filter",
      .socket_id = socket_id,
      .rule_size = RTE_ACL_RULE_SZ(RTE_DIM(ipv4_defs)),
      /* number of fields per rule. */
      .max_rule_num = num_rules, /* maximum number of rules in the AC context. */
  };

  return rte_acl_create(&prm);
}

void mg_5tuple_destruct_filter(struct rte_acl_ctx * acl){
  rte_acl_free(acl);
}
Exemple #4
0
static int
rte_table_acl_free(void *table)
{
	struct rte_table_acl *acl = (struct rte_table_acl *) table;

	/* Check input parameters */
	if (table == NULL) {
		RTE_LOG(ERR, TABLE, "%s: table parameter is NULL\n", __func__);
		return -EINVAL;
	}

	/* Free previously allocated resources */
	if (acl->ctx != NULL)
		rte_acl_free(acl->ctx);

	rte_free(acl);

	return 0;
}
Exemple #5
0
static int
rte_table_acl_entry_delete(
	void *table,
	void *key,
	int *key_found,
	void *entry)
{
	struct rte_table_acl *acl = (struct rte_table_acl *) table;
	struct rte_table_acl_rule_delete_params *rule =
		(struct rte_table_acl_rule_delete_params *) key;
	struct rte_acl_rule *deleted_rule = NULL;
	struct rte_acl_ctx *ctx;
	uint32_t pos, pos_valid, i;
	int status;

	/* Check input parameters */
	if (table == NULL) {
		RTE_LOG(ERR, TABLE, "%s: table parameter is NULL\n", __func__);
		return -EINVAL;
	}
	if (key == NULL) {
		RTE_LOG(ERR, TABLE, "%s: key parameter is NULL\n", __func__);
		return -EINVAL;
	}
	if (key_found == NULL) {
		RTE_LOG(ERR, TABLE, "%s: key_found parameter is NULL\n",
			__func__);
		return -EINVAL;
	}

	/* Look for the rule in the table */
	pos = 0;
	pos_valid = 0;
	for (i = 1; i < acl->n_rules; i++) {
		if (acl->acl_rule_list[i] != NULL) {
			/* Compare the key fields */
			status = memcmp(&acl->acl_rule_list[i]->field[0],
				&rule->field_value[0], acl->cfg.num_fields *
				sizeof(struct rte_acl_field));

			/* Rule found: remove from table */
			if (status == 0) {
				pos = i;
				pos_valid = 1;

				deleted_rule = acl->acl_rule_list[i];
				acl->acl_rule_list[i] = NULL;
			}
		}
	}

	/* Return if rule not found */
	if (pos_valid == 0) {
		*key_found = 0;
		return 0;
	}

	/* Build low level ACL table */
	acl->name_id ^= 1;
	acl->acl_params.name = acl->name[acl->name_id];
	status = rte_table_acl_build(acl, &ctx);
	if (status != 0) {
		/* Roll back changes */
		acl->acl_rule_list[pos] = deleted_rule;
		acl->name_id ^= 1;

		return -EINVAL;
	}

	/* Commit changes */
	if (acl->ctx != NULL)
		rte_acl_free(acl->ctx);

	acl->ctx = ctx;
	*key_found = 1;
	if (entry != NULL)
		memcpy(entry, &acl->memory[pos * acl->entry_size],
			acl->entry_size);

	return 0;
}
Exemple #6
0
static int
rte_table_acl_entry_add(
	void *table,
	void *key,
	void *entry,
	int *key_found,
	void **entry_ptr)
{
	struct rte_table_acl *acl = (struct rte_table_acl *) table;
	struct rte_table_acl_rule_add_params *rule =
		(struct rte_table_acl_rule_add_params *) key;
	struct rte_pipeline_acl_rule acl_rule;
	struct rte_acl_rule *rule_location;
	struct rte_acl_ctx *ctx;
	uint32_t free_pos, free_pos_valid, i;
	int status;

	/* Check input parameters */
	if (table == NULL) {
		RTE_LOG(ERR, TABLE, "%s: table parameter is NULL\n", __func__);
		return -EINVAL;
	}
	if (key == NULL) {
		RTE_LOG(ERR, TABLE, "%s: key parameter is NULL\n", __func__);
		return -EINVAL;
	}
	if (entry == NULL) {
		RTE_LOG(ERR, TABLE, "%s: entry parameter is NULL\n", __func__);
		return -EINVAL;
	}
	if (key_found == NULL) {
		RTE_LOG(ERR, TABLE, "%s: key_found parameter is NULL\n",
			__func__);
		return -EINVAL;
	}
	if (entry_ptr == NULL) {
		RTE_LOG(ERR, TABLE, "%s: entry_ptr parameter is NULL\n",
			__func__);
		return -EINVAL;
	}
	if (rule->priority > RTE_ACL_MAX_PRIORITY) {
		RTE_LOG(ERR, TABLE, "%s: Priority is too high\n", __func__);
		return -EINVAL;
	}

	/* Setup rule data structure */
	memset(&acl_rule, 0, sizeof(acl_rule));
	acl_rule.data.category_mask = 1;
	acl_rule.data.priority = RTE_ACL_MAX_PRIORITY - rule->priority;
	acl_rule.data.userdata = 0; /* To be set up later */
	memcpy(&acl_rule.field[0],
		&rule->field_value[0],
		acl->cfg.num_fields * sizeof(struct rte_acl_field));

	/* Look to see if the rule exists already in the table */
	free_pos = 0;
	free_pos_valid = 0;
	for (i = 1; i < acl->n_rules; i++) {
		if (acl->acl_rule_list[i] == NULL) {
			if (free_pos_valid == 0) {
				free_pos = i;
				free_pos_valid = 1;
			}

			continue;
		}

		/* Compare the key fields */
		status = memcmp(&acl->acl_rule_list[i]->field[0],
			&rule->field_value[0],
			acl->cfg.num_fields * sizeof(struct rte_acl_field));

		/* Rule found: update data associated with the rule */
		if (status == 0) {
			*key_found = 1;
			*entry_ptr = &acl->memory[i * acl->entry_size];
			memcpy(*entry_ptr, entry, acl->entry_size);

			return 0;
		}
	}

	/* Return if max rules */
	if (free_pos_valid == 0) {
		RTE_LOG(ERR, TABLE, "%s: Max number of rules reached\n",
			__func__);
		return -ENOSPC;
	}

	/* Add the new rule to the rule set */
	acl_rule.data.userdata = free_pos;
	rule_location = (struct rte_acl_rule *)
		&acl->acl_rule_memory[free_pos * acl->acl_params.rule_size];
	memcpy(rule_location, &acl_rule, acl->acl_params.rule_size);
	acl->acl_rule_list[free_pos] = rule_location;

	/* Build low level ACL table */
	acl->name_id ^= 1;
	acl->acl_params.name = acl->name[acl->name_id];
	status = rte_table_acl_build(acl, &ctx);
	if (status != 0) {
		/* Roll back changes */
		acl->acl_rule_list[free_pos] = NULL;
		acl->name_id ^= 1;

		return -EINVAL;
	}

	/* Commit changes */
	if (acl->ctx != NULL)
		rte_acl_free(acl->ctx);
	acl->ctx = ctx;
	*key_found = 0;
	*entry_ptr = &acl->memory[free_pos * acl->entry_size];
	memcpy(*entry_ptr, entry, acl->entry_size);

	return 0;
}