DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: "Morrissey, Sean" <sean.morrissey@intel.com>,
	Thomas Monjalon <thomas@monjalon.net>
Cc: "dev@dpdk.org" <dev@dpdk.org>,
	"Morrissey, Sean" <sean.morrissey@intel.com>
Subject: RE: [PATCH v4] examples/l3fwd: merge l3fwd-acl into l3fwd
Date: Fri, 8 Apr 2022 17:26:30 +0000	[thread overview]
Message-ID: <DM6PR11MB4491440359F332CB1405176F9AE99@DM6PR11MB4491.namprd11.prod.outlook.com> (raw)
In-Reply-To: <20220406120625.3248258-1-sean.morrissey@intel.com>


Hi Sean,

Few nits, that I didn't spot previously, pls see below.
 
> l3fwd-acl contains duplicate functions to l3fwd.
> For this reason we merge l3fwd-acl code into l3fwd
> with '--lookup acl' cmdline option to run ACL.
> 
> Signed-off-by: Sean Morrissey <sean.morrissey@intel.com>
> ---
>  MAINTAINERS                                   |    2 -
>  doc/guides/rel_notes/release_22_07.rst        |    5 +
>  doc/guides/sample_app_ug/index.rst            |    1 -
>  doc/guides/sample_app_ug/l3_forward.rst       |   63 +-
>  .../sample_app_ug/l3_forward_access_ctrl.rst  |  340 ---
>  examples/l3fwd-acl/Makefile                   |   51 -
>  examples/l3fwd-acl/main.c                     | 2272 -----------------
>  examples/l3fwd-acl/meson.build                |   13 -
>  examples/l3fwd/Makefile                       |    2 +-
>  examples/l3fwd/l3fwd.h                        |   39 +-
>  examples/l3fwd/l3fwd_acl.c                    | 1098 ++++++++
>  examples/l3fwd/l3fwd_acl.h                    |   51 +
>  examples/l3fwd/l3fwd_acl_scalar.h             |  112 +
>  examples/l3fwd/l3fwd_route.h                  |   16 +
>  examples/l3fwd/main.c                         |   65 +-
>  examples/l3fwd/meson.build                    |    3 +-
>  examples/meson.build                          |    1 -
>  17 files changed, 1434 insertions(+), 2700 deletions(-)
>  delete mode 100644 doc/guides/sample_app_ug/l3_forward_access_ctrl.rst
>  delete mode 100644 examples/l3fwd-acl/Makefile
>  delete mode 100644 examples/l3fwd-acl/main.c
>  delete mode 100644 examples/l3fwd-acl/meson.build
>  create mode 100644 examples/l3fwd/l3fwd_acl.c
>  create mode 100644 examples/l3fwd/l3fwd_acl.h
>  create mode 100644 examples/l3fwd/l3fwd_acl_scalar.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 15008c03bc..b29ff8929d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1505,8 +1505,6 @@ F: lib/acl/
>  F: doc/guides/prog_guide/packet_classif_access_ctrl.rst
>  F: app/test-acl/
>  F: app/test/test_acl.*
> -F: examples/l3fwd-acl/
> -F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst
> 
...

> diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
> index ad39496e64..c22cb796f5 100644
> --- a/examples/l3fwd/l3fwd.h
> +++ b/examples/l3fwd/l3fwd.h
> @@ -7,6 +7,7 @@
> 
>  #include <rte_ethdev.h>
>  #include <rte_vect.h>
> +#include <rte_acl.h>
> 
>  #define DO_RFC_1812_CHECKS
> 
> @@ -61,6 +62,12 @@
>  struct parm_cfg {
>  	const char *rule_ipv4_name;
>  	const char *rule_ipv6_name;
> +	enum rte_acl_classify_alg alg;
> +};
> +
> +struct acl_algorithms {
> +	const char *name;
> +	enum rte_acl_classify_alg alg;
>  };
> 
>  struct mbuf_table {
> @@ -80,6 +87,7 @@ struct lcore_conf {
>  	uint16_t tx_port_id[RTE_MAX_ETHPORTS];
>  	uint16_t tx_queue_id[RTE_MAX_ETHPORTS];
>  	struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
> +	struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];

I don't think it is used anywhere.
Probably remains from previous iterations.


>  	void *ipv4_lookup_struct;
>  	void *ipv6_lookup_struct;
>  } __rte_cache_aligned;
> @@ -107,6 +115,8 @@ extern struct lcore_conf lcore_conf[RTE_MAX_LCORE];
> 
>  extern struct parm_cfg parm_config;
> 
> +extern struct acl_algorithms acl_alg[];
> +
>  /* Send burst of packets on an output interface */
>  static inline int
>  send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port)
> @@ -190,10 +200,19 @@ is_valid_ipv4_pkt(struct rte_ipv4_hdr *pkt, uint32_t link_len)
>  }
>  #endif /* DO_RFC_1812_CHECKS */
> 
> +enum rte_acl_classify_alg
> +parse_acl_alg(const char *alg);
> +
> +int
> +usage_acl_alg(char *buf, size_t sz);
> +
>  int
>  init_mem(uint16_t portid, unsigned int nb_mbuf);
> 
> -/* Function pointers for LPM, EM or FIB functionality. */
> +/* Function pointers for ACL, LPM, EM or FIB functionality. */
> +void
> +setup_acl(const int socketid);
> +
>  void
>  setup_lpm(const int socketid);
> 
> @@ -203,12 +222,19 @@ setup_hash(const int socketid);
>  void
>  setup_fib(const int socketid);
> 
> +int
> +acl_check_ptype(int portid);
> +
>  int
>  em_check_ptype(int portid);
> 
>  int
>  lpm_check_ptype(int portid);

Seems not used/defined.

> +uint16_t
> +acl_cb_parse_ptype(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[],
> +		  uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
> +

Same not used/defined.


>  uint16_t
>  em_cb_parse_ptype(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[],
>  		  uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
> @@ -217,6 +243,9 @@ uint16_t
>  lpm_cb_parse_ptype(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[],
>  		   uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
> 
> +int
> +acl_main_loop(__rte_unused void *dummy);
> +
>  int
>  em_main_loop(__rte_unused void *dummy);
> 
> @@ -278,7 +307,13 @@ int
>  fib_event_main_loop_tx_q_burst_vector(__rte_unused void *dummy);
> 
> 
> -/* Return ipv4/ipv6 fwd lookup struct for LPM, EM or FIB. */
> +/* Return ipv4/ipv6 fwd lookup struct for ACL, LPM, EM or FIB. */
> +void *
> +acl_get_ipv4_l3fwd_lookup_struct(const int socketid);
> +
> +void *
> +acl_get_ipv6_l3fwd_lookup_struct(const int socketid);
> +
>  void *
>  em_get_ipv4_l3fwd_lookup_struct(const int socketid);
> 
> diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c
> new file mode 100644
> index 0000000000..e5fe38dba5
> --- /dev/null
> +++ b/examples/l3fwd/l3fwd_acl.c
> @@ -0,0 +1,1098 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2022 Intel Corporation
> + */
> +
> +#include "l3fwd.h"
> +#include "l3fwd_route.h"
> +
> +/*
> + * Rule and trace formats definitions.
> + */
> +
> +enum {
> +	PROTO_FIELD_IPV4,
> +	SRC_FIELD_IPV4,
> +	DST_FIELD_IPV4,
> +	SRCP_FIELD_IPV4,
> +	DSTP_FIELD_IPV4,
> +	NUM_FIELDS_IPV4
> +};
> +
> +/*
> + * That effectively defines order of IPV4VLAN classifications:
> + *  - PROTO
> + *  - VLAN (TAG and DOMAIN)
> + *  - SRC IP ADDRESS
> + *  - DST IP ADDRESS
> + *  - PORTS (SRC and DST)
> + */
> +enum {
> +	RTE_ACL_IPV4VLAN_PROTO,
> +	RTE_ACL_IPV4VLAN_VLAN,
> +	RTE_ACL_IPV4VLAN_SRC,
> +	RTE_ACL_IPV4VLAN_DST,
> +	RTE_ACL_IPV4VLAN_PORTS,
> +	RTE_ACL_IPV4VLAN_NUM
> +};
> +
> +struct acl_algorithms acl_alg[] = {
> +	{
> +		.name = "scalar",
> +		.alg = RTE_ACL_CLASSIFY_SCALAR,
> +	},
> +	{
> +		.name = "sse",
> +		.alg = RTE_ACL_CLASSIFY_SSE,
> +	},
> +	{
> +		.name = "avx2",
> +		.alg = RTE_ACL_CLASSIFY_AVX2,
> +	},
> +	{
> +		.name = "neon",
> +		.alg = RTE_ACL_CLASSIFY_NEON,
> +	},
> +	{
> +		.name = "altivec",
> +		.alg = RTE_ACL_CLASSIFY_ALTIVEC,
> +	},
> +	{
> +		.name = "avx512x16",
> +		.alg = RTE_ACL_CLASSIFY_AVX512X16,
> +	},
> +	{
> +		.name = "avx512x32",
> +		.alg = RTE_ACL_CLASSIFY_AVX512X32,
> +	},
> +};
> +
> +struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_BITMASK,
> +		.size = sizeof(uint8_t),
> +		.field_index = PROTO_FIELD_IPV4,
> +		.input_index = RTE_ACL_IPV4VLAN_PROTO,
> +		.offset = 0,
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = SRC_FIELD_IPV4,
> +		.input_index = RTE_ACL_IPV4VLAN_SRC,
> +		.offset = offsetof(struct rte_ipv4_hdr, src_addr) -
> +			offsetof(struct rte_ipv4_hdr, next_proto_id),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = DST_FIELD_IPV4,
> +		.input_index = RTE_ACL_IPV4VLAN_DST,
> +		.offset = offsetof(struct rte_ipv4_hdr, dst_addr) -
> +			offsetof(struct rte_ipv4_hdr, next_proto_id),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_RANGE,
> +		.size = sizeof(uint16_t),
> +		.field_index = SRCP_FIELD_IPV4,
> +		.input_index = RTE_ACL_IPV4VLAN_PORTS,
> +		.offset = sizeof(struct rte_ipv4_hdr) -
> +			offsetof(struct rte_ipv4_hdr, next_proto_id),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_RANGE,
> +		.size = sizeof(uint16_t),
> +		.field_index = DSTP_FIELD_IPV4,
> +		.input_index = RTE_ACL_IPV4VLAN_PORTS,
> +		.offset = sizeof(struct rte_ipv4_hdr) -
> +			offsetof(struct rte_ipv4_hdr, next_proto_id) +
> +			sizeof(uint16_t),
> +	},
> +};
> +
> +enum {
> +	PROTO_FIELD_IPV6,
> +	SRC1_FIELD_IPV6,
> +	SRC2_FIELD_IPV6,
> +	SRC3_FIELD_IPV6,
> +	SRC4_FIELD_IPV6,
> +	DST1_FIELD_IPV6,
> +	DST2_FIELD_IPV6,
> +	DST3_FIELD_IPV6,
> +	DST4_FIELD_IPV6,
> +	SRCP_FIELD_IPV6,
> +	DSTP_FIELD_IPV6,
> +	NUM_FIELDS_IPV6
> +};
> +
> +struct rte_acl_field_def ipv6_defs[NUM_FIELDS_IPV6] = {
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_BITMASK,
> +		.size = sizeof(uint8_t),
> +		.field_index = PROTO_FIELD_IPV6,
> +		.input_index = PROTO_FIELD_IPV6,
> +		.offset = 0,
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = SRC1_FIELD_IPV6,
> +		.input_index = SRC1_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, src_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = SRC2_FIELD_IPV6,
> +		.input_index = SRC2_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, src_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto) + sizeof(uint32_t),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = SRC3_FIELD_IPV6,
> +		.input_index = SRC3_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, src_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto) +
> +			2 * sizeof(uint32_t),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = SRC4_FIELD_IPV6,
> +		.input_index = SRC4_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, src_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto) +
> +			3 * sizeof(uint32_t),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = DST1_FIELD_IPV6,
> +		.input_index = DST1_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, dst_addr)
> +				- offsetof(struct rte_ipv6_hdr, proto),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = DST2_FIELD_IPV6,
> +		.input_index = DST2_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, dst_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto) + sizeof(uint32_t),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = DST3_FIELD_IPV6,
> +		.input_index = DST3_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, dst_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto) +
> +			2 * sizeof(uint32_t),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_MASK,
> +		.size = sizeof(uint32_t),
> +		.field_index = DST4_FIELD_IPV6,
> +		.input_index = DST4_FIELD_IPV6,
> +		.offset = offsetof(struct rte_ipv6_hdr, dst_addr) -
> +			offsetof(struct rte_ipv6_hdr, proto) +
> +			3 * sizeof(uint32_t),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_RANGE,
> +		.size = sizeof(uint16_t),
> +		.field_index = SRCP_FIELD_IPV6,
> +		.input_index = SRCP_FIELD_IPV6,
> +		.offset = sizeof(struct rte_ipv6_hdr) -
> +			offsetof(struct rte_ipv6_hdr, proto),
> +	},
> +	{
> +		.type = RTE_ACL_FIELD_TYPE_RANGE,
> +		.size = sizeof(uint16_t),
> +		.field_index = DSTP_FIELD_IPV6,
> +		.input_index = SRCP_FIELD_IPV6,
> +		.offset = sizeof(struct rte_ipv6_hdr) -
> +			offsetof(struct rte_ipv6_hdr, proto) + sizeof(uint16_t),
> +	},
> +};
> +
> +enum {
> +	CB_FLD_SRC_ADDR,
> +	CB_FLD_DST_ADDR,
> +	CB_FLD_SRC_PORT_LOW,
> +	CB_FLD_SRC_PORT_DLM,
> +	CB_FLD_SRC_PORT_HIGH,
> +	CB_FLD_DST_PORT_LOW,
> +	CB_FLD_DST_PORT_DLM,
> +	CB_FLD_DST_PORT_HIGH,
> +	CB_FLD_PROTO,
> +	CB_FLD_USERDATA,
> +	CB_FLD_NUM,
> +};
> +
> +RTE_ACL_RULE_DEF(acl4_rule, RTE_DIM(ipv4_defs));
> +RTE_ACL_RULE_DEF(acl6_rule, RTE_DIM(ipv6_defs));
> +
> +struct acl_search_t {
> +	const uint8_t *data_ipv4[MAX_PKT_BURST];
> +	struct rte_mbuf *m_ipv4[MAX_PKT_BURST];
> +	uint32_t res_ipv4[MAX_PKT_BURST];
> +	int num_ipv4;
> +
> +	const uint8_t *data_ipv6[MAX_PKT_BURST];
> +	struct rte_mbuf *m_ipv6[MAX_PKT_BURST];
> +	uint32_t res_ipv6[MAX_PKT_BURST];
> +	int num_ipv6;
> +};
> +
> +static struct {
> +	struct rte_acl_ctx *acx_ipv4[NB_SOCKETS];
> +	struct rte_acl_ctx *acx_ipv6[NB_SOCKETS];
> +#ifdef L3FWDACL_DEBUG
> +	struct acl4_rule *rule_ipv4;
> +	struct acl6_rule *rule_ipv6;
> +#endif
> +} acl_config;
> +
> +static const char cb_port_delim[] = ":";
> +
> +static struct rte_acl_rule *acl_base_ipv4, *route_base_ipv4,
> +		*acl_base_ipv6, *route_base_ipv6;
> +static unsigned int acl_num_ipv4, route_num_ipv4,
> +		acl_num_ipv6, route_num_ipv6;
> +
> +#include "l3fwd_acl.h"
> +
> +#include "l3fwd_acl_scalar.h"
> +
> +/*
> + * Parse IPV6 address, expects the following format:
> + * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X is a hexadecimal digit).
> + */
> +static int
> +parse_ipv6_addr(char *in, uint32_t v[IPV6_ADDR_U32], uint32_t *mask)
> +{
> +	char *sa, *sm, *sv;
> +	const char *dlm =  "/";
> +
> +	sv = NULL;
> +	sa = strtok_r(in, dlm, &sv);
> +	if (sa == NULL)
> +		return -EINVAL;
> +	sm = strtok_r(NULL, dlm, &sv);
> +	if (sm == NULL)
> +		return -EINVAL;
> +
> +	if (inet_pton(AF_INET6, sa, v) != 1)
> +		return -EINVAL;
> +
> +	GET_CB_FIELD(sm, *mask, 0, 128, 0);
> +	return 0;
> +}
> +
> +static int
> +parse_ipv6_net(char *in, struct rte_acl_field field[4])
> +{
> +	int32_t rc;
> +	uint32_t i, v[4];
> +	uint32_t m;
> +	const uint32_t nbu32 = sizeof(uint32_t) * CHAR_BIT;
> +
> +	/* get address. */
> +	rc = parse_ipv6_addr(in, v, &m);
> +	if (rc != 0)
> +		return rc;
> +
> +	/* put all together. */
> +	for (i = 0; i != RTE_DIM(v); i++) {
> +		if (m >= (i + 1) * nbu32)
> +			field[i].mask_range.u32 = nbu32;
> +		else
> +			field[i].mask_range.u32 = m > (i * nbu32) ?
> +				m - (i * 32) : 0;
> +
> +		field[i].value.u32 = v[i];
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +parse_cb_ipv6_rule(char *str, struct rte_acl_rule *v, int has_userdata)
> +{
> +	int i, rc;
> +	char *s, *sp, *in[CB_FLD_NUM];
> +	static const char *dlm = " \t\n";
> +	int dim = has_userdata ? CB_FLD_NUM : CB_FLD_USERDATA;
> +	s = str;
> +
> +	for (i = 0; i != dim; i++, s = NULL) {
> +		in[i] = strtok_r(s, dlm, &sp);
> +		if (in[i] == NULL)
> +			return -EINVAL;
> +	}
> +
> +	rc = parse_ipv6_net(in[CB_FLD_SRC_ADDR], v->field + SRC1_FIELD_IPV6);
> +	if (rc != 0) {
> +		acl_log("failed to read source address/mask: %s\n",
> +			in[CB_FLD_SRC_ADDR]);
> +		return rc;
> +	}
> +
> +	rc = parse_ipv6_net(in[CB_FLD_DST_ADDR], v->field + DST1_FIELD_IPV6);
> +	if (rc != 0) {
> +		acl_log("failed to read destination address/mask: %s\n",
> +			in[CB_FLD_DST_ADDR]);
> +		return rc;
> +	}
> +
> +	/* source port. */
> +	GET_CB_FIELD(in[CB_FLD_SRC_PORT_LOW],
> +		v->field[SRCP_FIELD_IPV6].value.u16,
> +		0, UINT16_MAX, 0);
> +	GET_CB_FIELD(in[CB_FLD_SRC_PORT_HIGH],
> +		v->field[SRCP_FIELD_IPV6].mask_range.u16,
> +		0, UINT16_MAX, 0);
> +
> +	if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim,
> +			sizeof(cb_port_delim)) != 0)
> +		return -EINVAL;
> +
> +	/* destination port. */
> +	GET_CB_FIELD(in[CB_FLD_DST_PORT_LOW],
> +		v->field[DSTP_FIELD_IPV6].value.u16,
> +		0, UINT16_MAX, 0);
> +	GET_CB_FIELD(in[CB_FLD_DST_PORT_HIGH],
> +		v->field[DSTP_FIELD_IPV6].mask_range.u16,
> +		0, UINT16_MAX, 0);
> +
> +	if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim,
> +			sizeof(cb_port_delim)) != 0)
> +		return -EINVAL;
> +
> +	if (v->field[SRCP_FIELD_IPV6].mask_range.u16
> +			< v->field[SRCP_FIELD_IPV6].value.u16
> +			|| v->field[DSTP_FIELD_IPV6].mask_range.u16
> +			< v->field[DSTP_FIELD_IPV6].value.u16)
> +		return -EINVAL;
> +
> +	GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV6].value.u8,
> +		0, UINT8_MAX, '/');
> +	GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV6].mask_range.u8,
> +		0, UINT8_MAX, 0);
> +
> +	if (has_userdata)
> +		GET_CB_FIELD(in[CB_FLD_USERDATA], v->data.userdata,
> +			0, UINT32_MAX, 0);
> +
> +	return 0;
> +}
> +
> +/*
> + * Parse ClassBench rules file.
> + * Expected format:
> + * '@'<src_ipv4_addr>'/'<masklen> <space> \
> + * <dst_ipv4_addr>'/'<masklen> <space> \
> + * <src_port_low> <space> ":" <src_port_high> <space> \
> + * <dst_port_low> <space> ":" <dst_port_high> <space> \
> + * <proto>'/'<mask>
> + */
> +static int
> +parse_ipv4_net(char *in, uint32_t *addr, uint32_t *mask_len)
> +{
> +	char *sa, *sm, *sv;
> +	const char *dlm =  "/";
> +
> +	sv = NULL;
> +	sa = strtok_r(in, dlm, &sv);
> +	if (sa == NULL)
> +		return -EINVAL;
> +	sm = strtok_r(NULL, dlm, &sv);
> +	if (sm == NULL)
> +		return -EINVAL;
> +
> +	if (inet_pton(AF_INET, sa, addr) != 1)
> +		return -EINVAL;
> +
> +	GET_CB_FIELD(sm, *mask_len, 0, 32, 0);
> +	*addr = ntohl(*addr);
> +	return 0;
> +}
> +
> +static int
> +parse_cb_ipv4vlan_rule(char *str, struct rte_acl_rule *v, int has_userdata)
> +{
> +	int i, rc;
> +	char *s, *sp, *in[CB_FLD_NUM];
> +	static const char *dlm = " \t\n";
> +	int dim = has_userdata ? CB_FLD_NUM : CB_FLD_USERDATA;
> +	s = str;
> +
> +	for (i = 0; i != dim; i++, s = NULL) {
> +		in[i] = strtok_r(s, dlm, &sp);
> +		if (in[i] == NULL)
> +			return -EINVAL;
> +	}
> +
> +	rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
> +			&v->field[SRC_FIELD_IPV4].value.u32,
> +			&v->field[SRC_FIELD_IPV4].mask_range.u32);
> +	if (rc != 0) {
> +		acl_log("failed to read source address/mask: %s\n",
> +			in[CB_FLD_SRC_ADDR]);
> +		return rc;
> +	}
> +
> +	rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
> +			&v->field[DST_FIELD_IPV4].value.u32,
> +			&v->field[DST_FIELD_IPV4].mask_range.u32);
> +	if (rc != 0) {
> +		acl_log("failed to read destination address/mask: %s\n",
> +			in[CB_FLD_DST_ADDR]);
> +		return rc;
> +	}
> +
> +	GET_CB_FIELD(in[CB_FLD_SRC_PORT_LOW],
> +		v->field[SRCP_FIELD_IPV4].value.u16,
> +		0, UINT16_MAX, 0);
> +	GET_CB_FIELD(in[CB_FLD_SRC_PORT_HIGH],
> +		v->field[SRCP_FIELD_IPV4].mask_range.u16,
> +		0, UINT16_MAX, 0);
> +
> +	if (strncmp(in[CB_FLD_SRC_PORT_DLM], cb_port_delim,
> +			sizeof(cb_port_delim)) != 0) {
> +		return -EINVAL;
> +	}
> +
> +	GET_CB_FIELD(in[CB_FLD_DST_PORT_LOW],
> +		v->field[DSTP_FIELD_IPV4].value.u16,
> +		0, UINT16_MAX, 0);
> +	GET_CB_FIELD(in[CB_FLD_DST_PORT_HIGH],
> +		v->field[DSTP_FIELD_IPV4].mask_range.u16,
> +		0, UINT16_MAX, 0);
> +
> +	if (strncmp(in[CB_FLD_DST_PORT_DLM], cb_port_delim,
> +			sizeof(cb_port_delim)) != 0) {
> +		return -EINVAL;
> +	}
> +
> +	if (v->field[SRCP_FIELD_IPV4].mask_range.u16
> +			< v->field[SRCP_FIELD_IPV4].value.u16
> +			|| v->field[DSTP_FIELD_IPV4].mask_range.u16
> +			< v->field[DSTP_FIELD_IPV4].value.u16) {
> +		return -EINVAL;
> +	}
> +
> +	GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV4].value.u8,
> +		0, UINT8_MAX, '/');
> +	GET_CB_FIELD(in[CB_FLD_PROTO], v->field[PROTO_FIELD_IPV4].mask_range.u8,
> +		0, UINT8_MAX, 0);
> +
> +	if (has_userdata)
> +		GET_CB_FIELD(in[CB_FLD_USERDATA], v->data.userdata, 0,
> +			UINT32_MAX, 0);
> +
> +	return 0;
> +}
> +
> +static int
> +acl_add_rules(const char *rule_path,
> +		struct rte_acl_rule **proute_base,
> +		unsigned int *proute_num,
> +		struct rte_acl_rule **pacl_base,
> +		unsigned int *pacl_num, uint32_t rule_size,
> +		int (*parser)(char *, struct rte_acl_rule*, int))
> +{
> +	uint8_t *acl_rules, *route_rules;
> +	struct rte_acl_rule *next;
> +	unsigned int acl_num = 0, route_num = 0, total_num = 0;
> +	unsigned int acl_cnt = 0, route_cnt = 0;
> +	char buff[LINE_MAX];
> +	FILE *fh = fopen(rule_path, "rb");
> +	unsigned int i = 0;
> +	int val;
> +
> +	if (fh == NULL)
> +		rte_exit(EXIT_FAILURE, "%s: Open %s failed\n", __func__,
> +			rule_path);
> +
> +	while ((fgets(buff, LINE_MAX, fh) != NULL)) {
> +		if (buff[0] == ROUTE_LEAD_CHAR)
> +			route_num++;
> +		else if (buff[0] == ACL_LEAD_CHAR)
> +			acl_num++;
> +	}
> +
> +	if (route_num == 0)
> +		rte_exit(EXIT_FAILURE, "Not find any route entries in %s!\n",
> +				rule_path);
> +
> +	val = fseek(fh, 0, SEEK_SET);
> +	if (val < 0) {
> +		rte_exit(EXIT_FAILURE, "%s: File seek operation failed\n",
> +			__func__);
> +	}
> +
> +	acl_rules = calloc(acl_num, rule_size);
> +
> +	if (acl_rules == NULL)
> +		rte_exit(EXIT_FAILURE, "%s: failed to malloc memory\n",
> +			__func__);
> +
> +	route_rules = calloc(route_num, rule_size);
> +
> +	if (route_rules == NULL)
> +		rte_exit(EXIT_FAILURE, "%s: failed to malloc memory\n",
> +			__func__);
> +
> +	i = 0;
> +	while (fgets(buff, LINE_MAX, fh) != NULL) {
> +		i++;
> +
> +		if (is_bypass_line(buff))
> +			continue;
> +
> +		char s = buff[0];
> +
> +		/* Route entry */
> +		if (s == ROUTE_LEAD_CHAR)
> +			next = (struct rte_acl_rule *)(route_rules +
> +				route_cnt * rule_size);
> +
> +		/* ACL entry */
> +		else if (s == ACL_LEAD_CHAR)
> +			next = (struct rte_acl_rule *)(acl_rules +
> +				acl_cnt * rule_size);
> +
> +		/* Illegal line */
> +		else
> +			rte_exit(EXIT_FAILURE,
> +				"%s Line %u: should start with leading "
> +				"char %c or %c\n",
> +				rule_path, i, ROUTE_LEAD_CHAR, ACL_LEAD_CHAR);
> +
> +		if (parser(buff + 1, next, s == ROUTE_LEAD_CHAR) != 0)
> +			rte_exit(EXIT_FAILURE,
> +				"%s Line %u: parse rules error\n",
> +				rule_path, i);
> +
> +		if (s == ROUTE_LEAD_CHAR) {
> +			/* Check the forwarding port number */
> +			if ((enabled_port_mask & (1 << next->data.userdata)) ==
> +					0)
> +				rte_exit(EXIT_FAILURE,
> +					"%s Line %u: fwd number illegal:%u\n",
> +					rule_path, i, next->data.userdata);
> +			next->data.userdata += FWD_PORT_SHIFT;
> +			route_cnt++;
> +		} else {
> +			next->data.userdata = ACL_DENY_SIGNATURE + acl_cnt;
> +			acl_cnt++;
> +		}
> +
> +		next->data.priority = RTE_ACL_MAX_PRIORITY - total_num;
> +		next->data.category_mask = -1;
> +		total_num++;
> +	}
> +
> +	fclose(fh);
> +
> +	*pacl_base = (struct rte_acl_rule *)acl_rules;
> +	*pacl_num = acl_num;
> +	*proute_base = (struct rte_acl_rule *)route_rules;
> +	*proute_num = route_cnt;
> +
> +	return 0;
> +}
> +
> +enum rte_acl_classify_alg
> +parse_acl_alg(const char *alg)
> +{
> +	uint32_t i;
> +
> +	for (i = 0; i != RTE_DIM(acl_alg); i++) {
> +		if (strcmp(alg, acl_alg[i].name) == 0)
> +			return acl_alg[i].alg;
> +	}
> +
> +	return RTE_ACL_CLASSIFY_DEFAULT;
> +}
> +
> +int
> +usage_acl_alg(char *buf, size_t sz)
> +{
> +	uint32_t i, n, rc, tn;
> +
> +	n = 0;
> +	tn = 0;
> +	for (i = 0; i < RTE_DIM(acl_alg); i++) {
> +		rc = snprintf(buf + n, sz - n,
> +			i == RTE_DIM(acl_alg) - 1 ? "%s" : "%s|",
> +			acl_alg[i].name);
> +		tn += rc;
> +		if (rc < sz - n)
> +			n += rc;
> +	}
> +
> +	return tn;
> +}
> +
> +static const char *
> +str_acl_alg(enum rte_acl_classify_alg alg)
> +{
> +	uint32_t i;
> +
> +	for (i = 0; i != RTE_DIM(acl_alg); i++) {
> +		if (alg == acl_alg[i].alg)
> +			return acl_alg[i].name;
> +	}
> +
> +	return "default";
> +}
> +
> +static void
> +dump_acl_config(void)
> +{
> +	printf("ACL options are:\n");
> +	printf("rule_ipv4: %s\n", parm_config.rule_ipv4_name);
> +	printf("rule_ipv6: %s\n", parm_config.rule_ipv6_name);
> +	printf("alg: %s\n", str_acl_alg(parm_config.alg));
> +}
> +
> +static int
> +check_acl_config(void)
> +{
> +	if (parm_config.rule_ipv4_name == NULL) {
> +		acl_log("ACL IPv4 rule file not specified\n");
> +		return -1;
> +	} else if (parm_config.rule_ipv6_name == NULL) {
> +		acl_log("ACL IPv6 rule file not specified\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Setup ACL context. 8< */

Looks like some typo within comments.

> +static struct rte_acl_ctx*
> +app_acl_init(struct rte_acl_rule *route_base,
> +		struct rte_acl_rule *acl_base, unsigned int route_num,
> +		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);
> +
> +	/* Create ACL contexts */
> +	snprintf(name, sizeof(name), "%s%d",
> +			ipv6 ? L3FWD_ACL_IPV6_NAME : L3FWD_ACL_IPV4_NAME,
> +			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;
> +
> +	context = rte_acl_create(&acl_param);
> +	if (context == NULL)
> +		rte_exit(EXIT_FAILURE, "Failed to create ACL context\n");
> +
> +	if (parm_config.alg != RTE_ACL_CLASSIFY_DEFAULT &&
> +			rte_acl_set_ctx_classify(context, parm_config.alg) != 0)
> +		rte_exit(EXIT_FAILURE,
> +			"Failed to setup classify method for  ACL context\n");
> +
> +	if (rte_acl_add_rules(context, route_base, route_num) < 0)
> +		rte_exit(EXIT_FAILURE, "add rules failed\n");
> +
> +	if (rte_acl_add_rules(context, acl_base, acl_num) < 0)
> +		rte_exit(EXIT_FAILURE, "add rules failed\n");
> +
> +	/* 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)
> +		rte_exit(EXIT_FAILURE, "Failed to build ACL trie\n");
> +
> +	rte_acl_dump(context);
> +
> +	return context;
> +}
> +/* >8 End of ACL context setup. */

Typo in comments. 


  reply	other threads:[~2022-04-08 17:26 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-25 15:14 [PATCH v1] " Sean Morrissey
2022-03-29 10:28 ` Bruce Richardson
2022-03-29 10:33 ` Ananyev, Konstantin
2022-03-30 14:04 ` [PATCH v2] " Sean Morrissey
2022-04-02 13:53   ` Ananyev, Konstantin
2022-04-06 10:29   ` [PATCH v3] " Sean Morrissey
2022-04-06 11:47     ` David Marchand
2022-04-06 12:06     ` [PATCH v4] " Sean Morrissey
2022-04-08 17:26       ` Ananyev, Konstantin [this message]
2022-04-08 19:01         ` Morrissey, Sean
2022-04-09 11:58           ` Ananyev, Konstantin
2022-04-11  8:41       ` [PATCH v5] " Sean Morrissey
2022-04-11 11:38         ` Ananyev, Konstantin
2022-04-22  9:57         ` [PATCH v6] " Sean Morrissey
2022-06-08  9:50           ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DM6PR11MB4491440359F332CB1405176F9AE99@DM6PR11MB4491.namprd11.prod.outlook.com \
    --to=konstantin.ananyev@intel.com \
    --cc=dev@dpdk.org \
    --cc=sean.morrissey@intel.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).