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.
next prev parent 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).