199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2010-2018 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson
5e9fd1ebfSTyler Retzlaff #include <stdalign.h>
699a2dd95SBruce Richardson #include <stdlib.h>
799a2dd95SBruce Richardson #include <string.h>
899a2dd95SBruce Richardson
999a2dd95SBruce Richardson #include <rte_common.h>
1099a2dd95SBruce Richardson #include <rte_malloc.h>
1199a2dd95SBruce Richardson
1299a2dd95SBruce Richardson #include "rte_port_in_action.h"
1399a2dd95SBruce Richardson
1499a2dd95SBruce Richardson /**
1599a2dd95SBruce Richardson * RTE_PORT_IN_ACTION_FLTR
1699a2dd95SBruce Richardson */
1799a2dd95SBruce Richardson static int
fltr_cfg_check(struct rte_port_in_action_fltr_config * cfg)1899a2dd95SBruce Richardson fltr_cfg_check(struct rte_port_in_action_fltr_config *cfg)
1999a2dd95SBruce Richardson {
2099a2dd95SBruce Richardson if (cfg == NULL)
2199a2dd95SBruce Richardson return -1;
2299a2dd95SBruce Richardson
2399a2dd95SBruce Richardson return 0;
2499a2dd95SBruce Richardson }
2599a2dd95SBruce Richardson
2699a2dd95SBruce Richardson struct fltr_data {
2799a2dd95SBruce Richardson uint32_t port_id;
2899a2dd95SBruce Richardson };
2999a2dd95SBruce Richardson
3099a2dd95SBruce Richardson static void
fltr_init(struct fltr_data * data,struct rte_port_in_action_fltr_config * cfg)3199a2dd95SBruce Richardson fltr_init(struct fltr_data *data,
3299a2dd95SBruce Richardson struct rte_port_in_action_fltr_config *cfg)
3399a2dd95SBruce Richardson {
3499a2dd95SBruce Richardson data->port_id = cfg->port_id;
3599a2dd95SBruce Richardson }
3699a2dd95SBruce Richardson
3799a2dd95SBruce Richardson static int
fltr_apply(struct fltr_data * data,struct rte_port_in_action_fltr_params * p)3899a2dd95SBruce Richardson fltr_apply(struct fltr_data *data,
3999a2dd95SBruce Richardson struct rte_port_in_action_fltr_params *p)
4099a2dd95SBruce Richardson {
4199a2dd95SBruce Richardson /* Check input arguments */
4299a2dd95SBruce Richardson if (p == NULL)
4399a2dd95SBruce Richardson return -1;
4499a2dd95SBruce Richardson
4599a2dd95SBruce Richardson data->port_id = p->port_id;
4699a2dd95SBruce Richardson
4799a2dd95SBruce Richardson return 0;
4899a2dd95SBruce Richardson }
4999a2dd95SBruce Richardson
5099a2dd95SBruce Richardson /**
5199a2dd95SBruce Richardson * RTE_PORT_IN_ACTION_LB
5299a2dd95SBruce Richardson */
5399a2dd95SBruce Richardson static int
lb_cfg_check(struct rte_port_in_action_lb_config * cfg)5499a2dd95SBruce Richardson lb_cfg_check(struct rte_port_in_action_lb_config *cfg)
5599a2dd95SBruce Richardson {
5699a2dd95SBruce Richardson if ((cfg == NULL) ||
5799a2dd95SBruce Richardson (cfg->key_size < RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN) ||
5899a2dd95SBruce Richardson (cfg->key_size > RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX) ||
5999a2dd95SBruce Richardson (!rte_is_power_of_2(cfg->key_size)) ||
6099a2dd95SBruce Richardson (cfg->f_hash == NULL))
6199a2dd95SBruce Richardson return -1;
6299a2dd95SBruce Richardson
6399a2dd95SBruce Richardson return 0;
6499a2dd95SBruce Richardson }
6599a2dd95SBruce Richardson
6699a2dd95SBruce Richardson struct lb_data {
6799a2dd95SBruce Richardson uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
6899a2dd95SBruce Richardson };
6999a2dd95SBruce Richardson
7099a2dd95SBruce Richardson static void
lb_init(struct lb_data * data,struct rte_port_in_action_lb_config * cfg)7199a2dd95SBruce Richardson lb_init(struct lb_data *data,
7299a2dd95SBruce Richardson struct rte_port_in_action_lb_config *cfg)
7399a2dd95SBruce Richardson {
7499a2dd95SBruce Richardson memcpy(data->port_id, cfg->port_id, sizeof(cfg->port_id));
7599a2dd95SBruce Richardson }
7699a2dd95SBruce Richardson
7799a2dd95SBruce Richardson static int
lb_apply(struct lb_data * data,struct rte_port_in_action_lb_params * p)7899a2dd95SBruce Richardson lb_apply(struct lb_data *data,
7999a2dd95SBruce Richardson struct rte_port_in_action_lb_params *p)
8099a2dd95SBruce Richardson {
8199a2dd95SBruce Richardson /* Check input arguments */
8299a2dd95SBruce Richardson if (p == NULL)
8399a2dd95SBruce Richardson return -1;
8499a2dd95SBruce Richardson
8599a2dd95SBruce Richardson memcpy(data->port_id, p->port_id, sizeof(p->port_id));
8699a2dd95SBruce Richardson
8799a2dd95SBruce Richardson return 0;
8899a2dd95SBruce Richardson }
8999a2dd95SBruce Richardson
9099a2dd95SBruce Richardson /**
9199a2dd95SBruce Richardson * Action profile
9299a2dd95SBruce Richardson */
9399a2dd95SBruce Richardson static int
action_valid(enum rte_port_in_action_type action)9499a2dd95SBruce Richardson action_valid(enum rte_port_in_action_type action)
9599a2dd95SBruce Richardson {
9699a2dd95SBruce Richardson switch (action) {
9799a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
9899a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
9999a2dd95SBruce Richardson return 1;
10099a2dd95SBruce Richardson default:
10199a2dd95SBruce Richardson return 0;
10299a2dd95SBruce Richardson }
10399a2dd95SBruce Richardson }
10499a2dd95SBruce Richardson
10599a2dd95SBruce Richardson #define RTE_PORT_IN_ACTION_MAX 64
10699a2dd95SBruce Richardson
10799a2dd95SBruce Richardson struct ap_config {
10899a2dd95SBruce Richardson uint64_t action_mask;
10999a2dd95SBruce Richardson struct rte_port_in_action_fltr_config fltr;
11099a2dd95SBruce Richardson struct rte_port_in_action_lb_config lb;
11199a2dd95SBruce Richardson };
11299a2dd95SBruce Richardson
11399a2dd95SBruce Richardson static size_t
action_cfg_size(enum rte_port_in_action_type action)11499a2dd95SBruce Richardson action_cfg_size(enum rte_port_in_action_type action)
11599a2dd95SBruce Richardson {
11699a2dd95SBruce Richardson switch (action) {
11799a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
11899a2dd95SBruce Richardson return sizeof(struct rte_port_in_action_fltr_config);
11999a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
12099a2dd95SBruce Richardson return sizeof(struct rte_port_in_action_lb_config);
12199a2dd95SBruce Richardson default:
12299a2dd95SBruce Richardson return 0;
12399a2dd95SBruce Richardson }
12499a2dd95SBruce Richardson }
12599a2dd95SBruce Richardson
12699a2dd95SBruce Richardson static void*
action_cfg_get(struct ap_config * ap_config,enum rte_port_in_action_type type)12799a2dd95SBruce Richardson action_cfg_get(struct ap_config *ap_config,
12899a2dd95SBruce Richardson enum rte_port_in_action_type type)
12999a2dd95SBruce Richardson {
13099a2dd95SBruce Richardson switch (type) {
13199a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
13299a2dd95SBruce Richardson return &ap_config->fltr;
13399a2dd95SBruce Richardson
13499a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
13599a2dd95SBruce Richardson return &ap_config->lb;
13699a2dd95SBruce Richardson
13799a2dd95SBruce Richardson default:
13899a2dd95SBruce Richardson return NULL;
13999a2dd95SBruce Richardson }
14099a2dd95SBruce Richardson }
14199a2dd95SBruce Richardson
14299a2dd95SBruce Richardson static void
action_cfg_set(struct ap_config * ap_config,enum rte_port_in_action_type type,void * action_cfg)14399a2dd95SBruce Richardson action_cfg_set(struct ap_config *ap_config,
14499a2dd95SBruce Richardson enum rte_port_in_action_type type,
14599a2dd95SBruce Richardson void *action_cfg)
14699a2dd95SBruce Richardson {
14799a2dd95SBruce Richardson void *dst = action_cfg_get(ap_config, type);
14899a2dd95SBruce Richardson
14999a2dd95SBruce Richardson if (dst)
15099a2dd95SBruce Richardson memcpy(dst, action_cfg, action_cfg_size(type));
15199a2dd95SBruce Richardson
15299a2dd95SBruce Richardson ap_config->action_mask |= 1LLU << type;
15399a2dd95SBruce Richardson }
15499a2dd95SBruce Richardson
15599a2dd95SBruce Richardson struct ap_data {
15699a2dd95SBruce Richardson size_t offset[RTE_PORT_IN_ACTION_MAX];
15799a2dd95SBruce Richardson size_t total_size;
15899a2dd95SBruce Richardson };
15999a2dd95SBruce Richardson
16099a2dd95SBruce Richardson static size_t
action_data_size(enum rte_port_in_action_type action,struct ap_config * ap_config __rte_unused)16199a2dd95SBruce Richardson action_data_size(enum rte_port_in_action_type action,
16299a2dd95SBruce Richardson struct ap_config *ap_config __rte_unused)
16399a2dd95SBruce Richardson {
16499a2dd95SBruce Richardson switch (action) {
16599a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
16699a2dd95SBruce Richardson return sizeof(struct fltr_data);
16799a2dd95SBruce Richardson
16899a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
16999a2dd95SBruce Richardson return sizeof(struct lb_data);
17099a2dd95SBruce Richardson
17199a2dd95SBruce Richardson default:
17299a2dd95SBruce Richardson return 0;
17399a2dd95SBruce Richardson }
17499a2dd95SBruce Richardson }
17599a2dd95SBruce Richardson
17699a2dd95SBruce Richardson static void
action_data_offset_set(struct ap_data * ap_data,struct ap_config * ap_config)17799a2dd95SBruce Richardson action_data_offset_set(struct ap_data *ap_data,
17899a2dd95SBruce Richardson struct ap_config *ap_config)
17999a2dd95SBruce Richardson {
18099a2dd95SBruce Richardson uint64_t action_mask = ap_config->action_mask;
18199a2dd95SBruce Richardson size_t offset;
18299a2dd95SBruce Richardson uint32_t action;
18399a2dd95SBruce Richardson
18499a2dd95SBruce Richardson memset(ap_data->offset, 0, sizeof(ap_data->offset));
18599a2dd95SBruce Richardson
18699a2dd95SBruce Richardson offset = 0;
18799a2dd95SBruce Richardson for (action = 0; action < RTE_PORT_IN_ACTION_MAX; action++)
18899a2dd95SBruce Richardson if (action_mask & (1LLU << action)) {
18999a2dd95SBruce Richardson ap_data->offset[action] = offset;
19099a2dd95SBruce Richardson offset += action_data_size((enum rte_port_in_action_type)action,
19199a2dd95SBruce Richardson ap_config);
19299a2dd95SBruce Richardson }
19399a2dd95SBruce Richardson
19499a2dd95SBruce Richardson ap_data->total_size = offset;
19599a2dd95SBruce Richardson }
19699a2dd95SBruce Richardson
19799a2dd95SBruce Richardson struct rte_port_in_action_profile {
19899a2dd95SBruce Richardson struct ap_config cfg;
19999a2dd95SBruce Richardson struct ap_data data;
20099a2dd95SBruce Richardson int frozen;
20199a2dd95SBruce Richardson };
20299a2dd95SBruce Richardson
20399a2dd95SBruce Richardson struct rte_port_in_action_profile *
rte_port_in_action_profile_create(uint32_t socket_id)20499a2dd95SBruce Richardson rte_port_in_action_profile_create(uint32_t socket_id)
20599a2dd95SBruce Richardson {
20699a2dd95SBruce Richardson struct rte_port_in_action_profile *ap;
20799a2dd95SBruce Richardson
20899a2dd95SBruce Richardson /* Memory allocation */
20999a2dd95SBruce Richardson ap = rte_zmalloc_socket(NULL,
21099a2dd95SBruce Richardson sizeof(struct rte_port_in_action_profile),
21199a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE,
21299a2dd95SBruce Richardson socket_id);
21399a2dd95SBruce Richardson if (ap == NULL)
21499a2dd95SBruce Richardson return NULL;
21599a2dd95SBruce Richardson
21699a2dd95SBruce Richardson return ap;
21799a2dd95SBruce Richardson }
21899a2dd95SBruce Richardson
21999a2dd95SBruce Richardson int
rte_port_in_action_profile_action_register(struct rte_port_in_action_profile * profile,enum rte_port_in_action_type type,void * action_config)22099a2dd95SBruce Richardson rte_port_in_action_profile_action_register(struct rte_port_in_action_profile *profile,
22199a2dd95SBruce Richardson enum rte_port_in_action_type type,
22299a2dd95SBruce Richardson void *action_config)
22399a2dd95SBruce Richardson {
22499a2dd95SBruce Richardson int status;
22599a2dd95SBruce Richardson
22699a2dd95SBruce Richardson /* Check input arguments */
22799a2dd95SBruce Richardson if ((profile == NULL) ||
22899a2dd95SBruce Richardson profile->frozen ||
22999a2dd95SBruce Richardson (action_valid(type) == 0) ||
23099a2dd95SBruce Richardson (profile->cfg.action_mask & (1LLU << type)) ||
23199a2dd95SBruce Richardson ((action_cfg_size(type) == 0) && action_config) ||
23299a2dd95SBruce Richardson (action_cfg_size(type) && (action_config == NULL)))
23399a2dd95SBruce Richardson return -EINVAL;
23499a2dd95SBruce Richardson
23599a2dd95SBruce Richardson switch (type) {
23699a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
23799a2dd95SBruce Richardson status = fltr_cfg_check(action_config);
23899a2dd95SBruce Richardson break;
23999a2dd95SBruce Richardson
24099a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
24199a2dd95SBruce Richardson status = lb_cfg_check(action_config);
24299a2dd95SBruce Richardson break;
24399a2dd95SBruce Richardson
24499a2dd95SBruce Richardson default:
24599a2dd95SBruce Richardson status = 0;
24699a2dd95SBruce Richardson break;
24799a2dd95SBruce Richardson }
24899a2dd95SBruce Richardson
24999a2dd95SBruce Richardson if (status)
25099a2dd95SBruce Richardson return status;
25199a2dd95SBruce Richardson
25299a2dd95SBruce Richardson /* Action enable */
25399a2dd95SBruce Richardson action_cfg_set(&profile->cfg, type, action_config);
25499a2dd95SBruce Richardson
25599a2dd95SBruce Richardson return 0;
25699a2dd95SBruce Richardson }
25799a2dd95SBruce Richardson
25899a2dd95SBruce Richardson int
rte_port_in_action_profile_freeze(struct rte_port_in_action_profile * profile)25999a2dd95SBruce Richardson rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile)
26099a2dd95SBruce Richardson {
26199a2dd95SBruce Richardson if (profile->frozen)
26299a2dd95SBruce Richardson return -EBUSY;
26399a2dd95SBruce Richardson
26499a2dd95SBruce Richardson action_data_offset_set(&profile->data, &profile->cfg);
26599a2dd95SBruce Richardson profile->frozen = 1;
26699a2dd95SBruce Richardson
26799a2dd95SBruce Richardson return 0;
26899a2dd95SBruce Richardson }
26999a2dd95SBruce Richardson
27099a2dd95SBruce Richardson int
rte_port_in_action_profile_free(struct rte_port_in_action_profile * profile)27199a2dd95SBruce Richardson rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile)
27299a2dd95SBruce Richardson {
27399a2dd95SBruce Richardson if (profile == NULL)
27499a2dd95SBruce Richardson return 0;
27599a2dd95SBruce Richardson
27699a2dd95SBruce Richardson free(profile);
27799a2dd95SBruce Richardson return 0;
27899a2dd95SBruce Richardson }
27999a2dd95SBruce Richardson
28099a2dd95SBruce Richardson /**
28199a2dd95SBruce Richardson * Action
28299a2dd95SBruce Richardson */
28399a2dd95SBruce Richardson struct rte_port_in_action {
28499a2dd95SBruce Richardson struct ap_config cfg;
28599a2dd95SBruce Richardson struct ap_data data;
286*8d765993STyler Retzlaff alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
28799a2dd95SBruce Richardson };
28899a2dd95SBruce Richardson
28999a2dd95SBruce Richardson static __rte_always_inline void *
action_data_get(struct rte_port_in_action * action,enum rte_port_in_action_type type)29099a2dd95SBruce Richardson action_data_get(struct rte_port_in_action *action,
29199a2dd95SBruce Richardson enum rte_port_in_action_type type)
29299a2dd95SBruce Richardson {
29399a2dd95SBruce Richardson size_t offset = action->data.offset[type];
29499a2dd95SBruce Richardson
29599a2dd95SBruce Richardson return &action->memory[offset];
29699a2dd95SBruce Richardson }
29799a2dd95SBruce Richardson
29899a2dd95SBruce Richardson static void
action_data_init(struct rte_port_in_action * action,enum rte_port_in_action_type type)29999a2dd95SBruce Richardson action_data_init(struct rte_port_in_action *action,
30099a2dd95SBruce Richardson enum rte_port_in_action_type type)
30199a2dd95SBruce Richardson {
30299a2dd95SBruce Richardson void *data = action_data_get(action, type);
30399a2dd95SBruce Richardson
30499a2dd95SBruce Richardson switch (type) {
30599a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
30699a2dd95SBruce Richardson fltr_init(data, &action->cfg.fltr);
30799a2dd95SBruce Richardson return;
30899a2dd95SBruce Richardson
30999a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
31099a2dd95SBruce Richardson lb_init(data, &action->cfg.lb);
31199a2dd95SBruce Richardson return;
31299a2dd95SBruce Richardson
31399a2dd95SBruce Richardson default:
31499a2dd95SBruce Richardson return;
31599a2dd95SBruce Richardson }
31699a2dd95SBruce Richardson }
31799a2dd95SBruce Richardson
31899a2dd95SBruce Richardson struct rte_port_in_action *
rte_port_in_action_create(struct rte_port_in_action_profile * profile,uint32_t socket_id)31999a2dd95SBruce Richardson rte_port_in_action_create(struct rte_port_in_action_profile *profile,
32099a2dd95SBruce Richardson uint32_t socket_id)
32199a2dd95SBruce Richardson {
32299a2dd95SBruce Richardson struct rte_port_in_action *action;
32399a2dd95SBruce Richardson size_t size;
32499a2dd95SBruce Richardson uint32_t i;
32599a2dd95SBruce Richardson
32699a2dd95SBruce Richardson /* Check input arguments */
32799a2dd95SBruce Richardson if ((profile == NULL) ||
32899a2dd95SBruce Richardson (profile->frozen == 0))
32999a2dd95SBruce Richardson return NULL;
33099a2dd95SBruce Richardson
33199a2dd95SBruce Richardson /* Memory allocation */
33299a2dd95SBruce Richardson size = sizeof(struct rte_port_in_action) + profile->data.total_size;
33399a2dd95SBruce Richardson size = RTE_CACHE_LINE_ROUNDUP(size);
33499a2dd95SBruce Richardson
33599a2dd95SBruce Richardson action = rte_zmalloc_socket(NULL,
33699a2dd95SBruce Richardson size,
33799a2dd95SBruce Richardson RTE_CACHE_LINE_SIZE,
33899a2dd95SBruce Richardson socket_id);
33999a2dd95SBruce Richardson if (action == NULL)
34099a2dd95SBruce Richardson return NULL;
34199a2dd95SBruce Richardson
34299a2dd95SBruce Richardson /* Initialization */
34399a2dd95SBruce Richardson memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
34499a2dd95SBruce Richardson memcpy(&action->data, &profile->data, sizeof(profile->data));
34599a2dd95SBruce Richardson
34699a2dd95SBruce Richardson for (i = 0; i < RTE_PORT_IN_ACTION_MAX; i++)
34799a2dd95SBruce Richardson if (action->cfg.action_mask & (1LLU << i))
34899a2dd95SBruce Richardson action_data_init(action,
34999a2dd95SBruce Richardson (enum rte_port_in_action_type)i);
35099a2dd95SBruce Richardson
35199a2dd95SBruce Richardson return action;
35299a2dd95SBruce Richardson }
35399a2dd95SBruce Richardson
35499a2dd95SBruce Richardson int
rte_port_in_action_apply(struct rte_port_in_action * action,enum rte_port_in_action_type type,void * action_params)35599a2dd95SBruce Richardson rte_port_in_action_apply(struct rte_port_in_action *action,
35699a2dd95SBruce Richardson enum rte_port_in_action_type type,
35799a2dd95SBruce Richardson void *action_params)
35899a2dd95SBruce Richardson {
35999a2dd95SBruce Richardson void *action_data;
36099a2dd95SBruce Richardson
36199a2dd95SBruce Richardson /* Check input arguments */
36299a2dd95SBruce Richardson if ((action == NULL) ||
36399a2dd95SBruce Richardson (action_valid(type) == 0) ||
36499a2dd95SBruce Richardson ((action->cfg.action_mask & (1LLU << type)) == 0) ||
36599a2dd95SBruce Richardson (action_params == NULL))
36699a2dd95SBruce Richardson return -EINVAL;
36799a2dd95SBruce Richardson
36899a2dd95SBruce Richardson /* Data update */
36999a2dd95SBruce Richardson action_data = action_data_get(action, type);
37099a2dd95SBruce Richardson
37199a2dd95SBruce Richardson switch (type) {
37299a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_FLTR:
37399a2dd95SBruce Richardson return fltr_apply(action_data,
37499a2dd95SBruce Richardson action_params);
37599a2dd95SBruce Richardson
37699a2dd95SBruce Richardson case RTE_PORT_IN_ACTION_LB:
37799a2dd95SBruce Richardson return lb_apply(action_data,
37899a2dd95SBruce Richardson action_params);
37999a2dd95SBruce Richardson
38099a2dd95SBruce Richardson default:
38199a2dd95SBruce Richardson return -EINVAL;
38299a2dd95SBruce Richardson }
38399a2dd95SBruce Richardson }
38499a2dd95SBruce Richardson
38599a2dd95SBruce Richardson static int
ah_filter_on_match(struct rte_pipeline * p,struct rte_mbuf ** pkts,uint32_t n_pkts,void * arg)38699a2dd95SBruce Richardson ah_filter_on_match(struct rte_pipeline *p,
38799a2dd95SBruce Richardson struct rte_mbuf **pkts,
38899a2dd95SBruce Richardson uint32_t n_pkts,
38999a2dd95SBruce Richardson void *arg)
39099a2dd95SBruce Richardson {
39199a2dd95SBruce Richardson struct rte_port_in_action *action = arg;
39299a2dd95SBruce Richardson struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
39399a2dd95SBruce Richardson uint64_t *key_mask = (uint64_t *) cfg->key_mask;
39499a2dd95SBruce Richardson uint64_t *key = (uint64_t *) cfg->key;
39599a2dd95SBruce Richardson uint32_t key_offset = cfg->key_offset;
39699a2dd95SBruce Richardson struct fltr_data *data = action_data_get(action,
39799a2dd95SBruce Richardson RTE_PORT_IN_ACTION_FLTR);
39899a2dd95SBruce Richardson uint32_t i;
39999a2dd95SBruce Richardson
40099a2dd95SBruce Richardson for (i = 0; i < n_pkts; i++) {
40199a2dd95SBruce Richardson struct rte_mbuf *pkt = pkts[i];
40299a2dd95SBruce Richardson uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
40399a2dd95SBruce Richardson key_offset);
40499a2dd95SBruce Richardson
40599a2dd95SBruce Richardson uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
40699a2dd95SBruce Richardson uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
40799a2dd95SBruce Richardson uint64_t or = xor0 | xor1;
40899a2dd95SBruce Richardson
40999a2dd95SBruce Richardson if (or == 0) {
41099a2dd95SBruce Richardson rte_pipeline_ah_packet_hijack(p, 1LLU << i);
41199a2dd95SBruce Richardson rte_pipeline_port_out_packet_insert(p,
41299a2dd95SBruce Richardson data->port_id, pkt);
41399a2dd95SBruce Richardson }
41499a2dd95SBruce Richardson }
41599a2dd95SBruce Richardson
41699a2dd95SBruce Richardson return 0;
41799a2dd95SBruce Richardson }
41899a2dd95SBruce Richardson
41999a2dd95SBruce Richardson static int
ah_filter_on_mismatch(struct rte_pipeline * p,struct rte_mbuf ** pkts,uint32_t n_pkts,void * arg)42099a2dd95SBruce Richardson ah_filter_on_mismatch(struct rte_pipeline *p,
42199a2dd95SBruce Richardson struct rte_mbuf **pkts,
42299a2dd95SBruce Richardson uint32_t n_pkts,
42399a2dd95SBruce Richardson void *arg)
42499a2dd95SBruce Richardson {
42599a2dd95SBruce Richardson struct rte_port_in_action *action = arg;
42699a2dd95SBruce Richardson struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
42799a2dd95SBruce Richardson uint64_t *key_mask = (uint64_t *) cfg->key_mask;
42899a2dd95SBruce Richardson uint64_t *key = (uint64_t *) cfg->key;
42999a2dd95SBruce Richardson uint32_t key_offset = cfg->key_offset;
43099a2dd95SBruce Richardson struct fltr_data *data = action_data_get(action,
43199a2dd95SBruce Richardson RTE_PORT_IN_ACTION_FLTR);
43299a2dd95SBruce Richardson uint32_t i;
43399a2dd95SBruce Richardson
43499a2dd95SBruce Richardson for (i = 0; i < n_pkts; i++) {
43599a2dd95SBruce Richardson struct rte_mbuf *pkt = pkts[i];
43699a2dd95SBruce Richardson uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
43799a2dd95SBruce Richardson key_offset);
43899a2dd95SBruce Richardson
43999a2dd95SBruce Richardson uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
44099a2dd95SBruce Richardson uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
44199a2dd95SBruce Richardson uint64_t or = xor0 | xor1;
44299a2dd95SBruce Richardson
44399a2dd95SBruce Richardson if (or) {
44499a2dd95SBruce Richardson rte_pipeline_ah_packet_hijack(p, 1LLU << i);
44599a2dd95SBruce Richardson rte_pipeline_port_out_packet_insert(p,
44699a2dd95SBruce Richardson data->port_id, pkt);
44799a2dd95SBruce Richardson }
44899a2dd95SBruce Richardson }
44999a2dd95SBruce Richardson
45099a2dd95SBruce Richardson return 0;
45199a2dd95SBruce Richardson }
45299a2dd95SBruce Richardson
45399a2dd95SBruce Richardson static int
ah_lb(struct rte_pipeline * p,struct rte_mbuf ** pkts,uint32_t n_pkts,void * arg)45499a2dd95SBruce Richardson ah_lb(struct rte_pipeline *p,
45599a2dd95SBruce Richardson struct rte_mbuf **pkts,
45699a2dd95SBruce Richardson uint32_t n_pkts,
45799a2dd95SBruce Richardson void *arg)
45899a2dd95SBruce Richardson {
45999a2dd95SBruce Richardson struct rte_port_in_action *action = arg;
46099a2dd95SBruce Richardson struct rte_port_in_action_lb_config *cfg = &action->cfg.lb;
46199a2dd95SBruce Richardson struct lb_data *data = action_data_get(action, RTE_PORT_IN_ACTION_LB);
46299a2dd95SBruce Richardson uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);
46399a2dd95SBruce Richardson uint32_t i;
46499a2dd95SBruce Richardson
46599a2dd95SBruce Richardson rte_pipeline_ah_packet_hijack(p, pkt_mask);
46699a2dd95SBruce Richardson
46799a2dd95SBruce Richardson for (i = 0; i < n_pkts; i++) {
46899a2dd95SBruce Richardson struct rte_mbuf *pkt = pkts[i];
46999a2dd95SBruce Richardson uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
47099a2dd95SBruce Richardson cfg->key_offset);
47199a2dd95SBruce Richardson
47299a2dd95SBruce Richardson uint64_t digest = cfg->f_hash(pkt_key,
47399a2dd95SBruce Richardson cfg->key_mask,
47499a2dd95SBruce Richardson cfg->key_size,
47599a2dd95SBruce Richardson cfg->seed);
47699a2dd95SBruce Richardson uint64_t pos = digest & (RTE_PORT_IN_ACTION_LB_TABLE_SIZE - 1);
47799a2dd95SBruce Richardson uint32_t port_id = data->port_id[pos];
47899a2dd95SBruce Richardson
47999a2dd95SBruce Richardson rte_pipeline_port_out_packet_insert(p, port_id, pkt);
48099a2dd95SBruce Richardson }
48199a2dd95SBruce Richardson
48299a2dd95SBruce Richardson return 0;
48399a2dd95SBruce Richardson }
48499a2dd95SBruce Richardson
48599a2dd95SBruce Richardson static rte_pipeline_port_in_action_handler
ah_selector(struct rte_port_in_action * action)48699a2dd95SBruce Richardson ah_selector(struct rte_port_in_action *action)
48799a2dd95SBruce Richardson {
48899a2dd95SBruce Richardson if (action->cfg.action_mask == 0)
48999a2dd95SBruce Richardson return NULL;
49099a2dd95SBruce Richardson
49199a2dd95SBruce Richardson if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_FLTR)
49299a2dd95SBruce Richardson return (action->cfg.fltr.filter_on_match) ?
49399a2dd95SBruce Richardson ah_filter_on_match : ah_filter_on_mismatch;
49499a2dd95SBruce Richardson
49599a2dd95SBruce Richardson if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_LB)
49699a2dd95SBruce Richardson return ah_lb;
49799a2dd95SBruce Richardson
49899a2dd95SBruce Richardson return NULL;
49999a2dd95SBruce Richardson }
50099a2dd95SBruce Richardson
50199a2dd95SBruce Richardson int
rte_port_in_action_params_get(struct rte_port_in_action * action,struct rte_pipeline_port_in_params * params)50299a2dd95SBruce Richardson rte_port_in_action_params_get(struct rte_port_in_action *action,
50399a2dd95SBruce Richardson struct rte_pipeline_port_in_params *params)
50499a2dd95SBruce Richardson {
50599a2dd95SBruce Richardson rte_pipeline_port_in_action_handler f_action;
50699a2dd95SBruce Richardson
50799a2dd95SBruce Richardson /* Check input arguments */
50899a2dd95SBruce Richardson if ((action == NULL) ||
50999a2dd95SBruce Richardson (params == NULL))
51099a2dd95SBruce Richardson return -EINVAL;
51199a2dd95SBruce Richardson
51299a2dd95SBruce Richardson f_action = ah_selector(action);
51399a2dd95SBruce Richardson
51499a2dd95SBruce Richardson /* Fill in params */
51599a2dd95SBruce Richardson params->f_action = f_action;
51699a2dd95SBruce Richardson params->arg_ah = (f_action) ? action : NULL;
51799a2dd95SBruce Richardson
51899a2dd95SBruce Richardson return 0;
51999a2dd95SBruce Richardson }
52099a2dd95SBruce Richardson
52199a2dd95SBruce Richardson int
rte_port_in_action_free(struct rte_port_in_action * action)52299a2dd95SBruce Richardson rte_port_in_action_free(struct rte_port_in_action *action)
52399a2dd95SBruce Richardson {
52499a2dd95SBruce Richardson if (action == NULL)
52599a2dd95SBruce Richardson return 0;
52699a2dd95SBruce Richardson
52799a2dd95SBruce Richardson rte_free(action);
52899a2dd95SBruce Richardson
52999a2dd95SBruce Richardson return 0;
53099a2dd95SBruce Richardson }
531