1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
8 #include <rte_common.h>
9 #include <rte_byteorder.h>
10 #include <rte_malloc.h>
11 #include <rte_memcpy.h>
13 #include "rte_port_in_action.h"
16 * RTE_PORT_IN_ACTION_FLTR
19 fltr_cfg_check(struct rte_port_in_action_fltr_config
*cfg
)
32 fltr_init(struct fltr_data
*data
,
33 struct rte_port_in_action_fltr_config
*cfg
)
35 data
->port_id
= cfg
->port_id
;
39 fltr_apply(struct fltr_data
*data
,
40 struct rte_port_in_action_fltr_params
*p
)
42 /* Check input arguments */
46 data
->port_id
= p
->port_id
;
52 * RTE_PORT_IN_ACTION_LB
55 lb_cfg_check(struct rte_port_in_action_lb_config
*cfg
)
58 (cfg
->key_size
< RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN
) ||
59 (cfg
->key_size
> RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX
) ||
60 (!rte_is_power_of_2(cfg
->key_size
)) ||
61 (cfg
->f_hash
== NULL
))
68 uint32_t port_id
[RTE_PORT_IN_ACTION_LB_TABLE_SIZE
];
72 lb_init(struct lb_data
*data
,
73 struct rte_port_in_action_lb_config
*cfg
)
75 memcpy(data
->port_id
, cfg
->port_id
, sizeof(cfg
->port_id
));
79 lb_apply(struct lb_data
*data
,
80 struct rte_port_in_action_lb_params
*p
)
82 /* Check input arguments */
86 memcpy(data
->port_id
, p
->port_id
, sizeof(p
->port_id
));
95 action_valid(enum rte_port_in_action_type action
)
98 case RTE_PORT_IN_ACTION_FLTR
:
99 case RTE_PORT_IN_ACTION_LB
:
106 #define RTE_PORT_IN_ACTION_MAX 64
109 uint64_t action_mask
;
110 struct rte_port_in_action_fltr_config fltr
;
111 struct rte_port_in_action_lb_config lb
;
115 action_cfg_size(enum rte_port_in_action_type action
)
118 case RTE_PORT_IN_ACTION_FLTR
:
119 return sizeof(struct rte_port_in_action_fltr_config
);
120 case RTE_PORT_IN_ACTION_LB
:
121 return sizeof(struct rte_port_in_action_lb_config
);
128 action_cfg_get(struct ap_config
*ap_config
,
129 enum rte_port_in_action_type type
)
132 case RTE_PORT_IN_ACTION_FLTR
:
133 return &ap_config
->fltr
;
135 case RTE_PORT_IN_ACTION_LB
:
136 return &ap_config
->lb
;
144 action_cfg_set(struct ap_config
*ap_config
,
145 enum rte_port_in_action_type type
,
148 void *dst
= action_cfg_get(ap_config
, type
);
151 memcpy(dst
, action_cfg
, action_cfg_size(type
));
153 ap_config
->action_mask
|= 1LLU << type
;
157 size_t offset
[RTE_PORT_IN_ACTION_MAX
];
162 action_data_size(enum rte_port_in_action_type action
,
163 struct ap_config
*ap_config __rte_unused
)
166 case RTE_PORT_IN_ACTION_FLTR
:
167 return sizeof(struct fltr_data
);
169 case RTE_PORT_IN_ACTION_LB
:
170 return sizeof(struct lb_data
);
178 action_data_offset_set(struct ap_data
*ap_data
,
179 struct ap_config
*ap_config
)
181 uint64_t action_mask
= ap_config
->action_mask
;
185 memset(ap_data
->offset
, 0, sizeof(ap_data
->offset
));
188 for (action
= 0; action
< RTE_PORT_IN_ACTION_MAX
; action
++)
189 if (action_mask
& (1LLU << action
)) {
190 ap_data
->offset
[action
] = offset
;
191 offset
+= action_data_size((enum rte_port_in_action_type
)action
,
195 ap_data
->total_size
= offset
;
198 struct rte_port_in_action_profile
{
199 struct ap_config cfg
;
204 struct rte_port_in_action_profile
*
205 rte_port_in_action_profile_create(uint32_t socket_id
)
207 struct rte_port_in_action_profile
*ap
;
209 /* Memory allocation */
210 ap
= rte_zmalloc_socket(NULL
,
211 sizeof(struct rte_port_in_action_profile
),
221 rte_port_in_action_profile_action_register(struct rte_port_in_action_profile
*profile
,
222 enum rte_port_in_action_type type
,
227 /* Check input arguments */
228 if ((profile
== NULL
) ||
230 (action_valid(type
) == 0) ||
231 (profile
->cfg
.action_mask
& (1LLU << type
)) ||
232 ((action_cfg_size(type
) == 0) && action_config
) ||
233 (action_cfg_size(type
) && (action_config
== NULL
)))
237 case RTE_PORT_IN_ACTION_FLTR
:
238 status
= fltr_cfg_check(action_config
);
241 case RTE_PORT_IN_ACTION_LB
:
242 status
= lb_cfg_check(action_config
);
254 action_cfg_set(&profile
->cfg
, type
, action_config
);
260 rte_port_in_action_profile_freeze(struct rte_port_in_action_profile
*profile
)
265 action_data_offset_set(&profile
->data
, &profile
->cfg
);
272 rte_port_in_action_profile_free(struct rte_port_in_action_profile
*profile
)
284 struct rte_port_in_action
{
285 struct ap_config cfg
;
287 uint8_t memory
[0] __rte_cache_aligned
;
290 static __rte_always_inline
void *
291 action_data_get(struct rte_port_in_action
*action
,
292 enum rte_port_in_action_type type
)
294 size_t offset
= action
->data
.offset
[type
];
296 return &action
->memory
[offset
];
300 action_data_init(struct rte_port_in_action
*action
,
301 enum rte_port_in_action_type type
)
303 void *data
= action_data_get(action
, type
);
306 case RTE_PORT_IN_ACTION_FLTR
:
307 fltr_init(data
, &action
->cfg
.fltr
);
310 case RTE_PORT_IN_ACTION_LB
:
311 lb_init(data
, &action
->cfg
.lb
);
319 struct rte_port_in_action
*
320 rte_port_in_action_create(struct rte_port_in_action_profile
*profile
,
323 struct rte_port_in_action
*action
;
327 /* Check input arguments */
328 if ((profile
== NULL
) ||
329 (profile
->frozen
== 0))
332 /* Memory allocation */
333 size
= sizeof(struct rte_port_in_action
) + profile
->data
.total_size
;
334 size
= RTE_CACHE_LINE_ROUNDUP(size
);
336 action
= rte_zmalloc_socket(NULL
,
344 memcpy(&action
->cfg
, &profile
->cfg
, sizeof(profile
->cfg
));
345 memcpy(&action
->data
, &profile
->data
, sizeof(profile
->data
));
347 for (i
= 0; i
< RTE_PORT_IN_ACTION_MAX
; i
++)
348 if (action
->cfg
.action_mask
& (1LLU << i
))
349 action_data_init(action
,
350 (enum rte_port_in_action_type
)i
);
356 rte_port_in_action_apply(struct rte_port_in_action
*action
,
357 enum rte_port_in_action_type type
,
362 /* Check input arguments */
363 if ((action
== NULL
) ||
364 (action_valid(type
) == 0) ||
365 ((action
->cfg
.action_mask
& (1LLU << type
)) == 0) ||
366 (action_params
== NULL
))
370 action_data
= action_data_get(action
, type
);
373 case RTE_PORT_IN_ACTION_FLTR
:
374 return fltr_apply(action_data
,
377 case RTE_PORT_IN_ACTION_LB
:
378 return lb_apply(action_data
,
387 ah_filter_on_match(struct rte_pipeline
*p
,
388 struct rte_mbuf
**pkts
,
392 struct rte_port_in_action
*action
= arg
;
393 struct rte_port_in_action_fltr_config
*cfg
= &action
->cfg
.fltr
;
394 uint64_t *key_mask
= (uint64_t *) cfg
->key_mask
;
395 uint64_t *key
= (uint64_t *) cfg
->key
;
396 uint32_t key_offset
= cfg
->key_offset
;
397 struct fltr_data
*data
= action_data_get(action
,
398 RTE_PORT_IN_ACTION_FLTR
);
401 for (i
= 0; i
< n_pkts
; i
++) {
402 struct rte_mbuf
*pkt
= pkts
[i
];
403 uint64_t *pkt_key
= RTE_MBUF_METADATA_UINT64_PTR(pkt
,
406 uint64_t xor0
= (pkt_key
[0] & key_mask
[0]) ^ key
[0];
407 uint64_t xor1
= (pkt_key
[1] & key_mask
[1]) ^ key
[1];
408 uint64_t or = xor0
| xor1
;
411 rte_pipeline_ah_packet_hijack(p
, 1LLU << i
);
412 rte_pipeline_port_out_packet_insert(p
,
421 ah_filter_on_mismatch(struct rte_pipeline
*p
,
422 struct rte_mbuf
**pkts
,
426 struct rte_port_in_action
*action
= arg
;
427 struct rte_port_in_action_fltr_config
*cfg
= &action
->cfg
.fltr
;
428 uint64_t *key_mask
= (uint64_t *) cfg
->key_mask
;
429 uint64_t *key
= (uint64_t *) cfg
->key
;
430 uint32_t key_offset
= cfg
->key_offset
;
431 struct fltr_data
*data
= action_data_get(action
,
432 RTE_PORT_IN_ACTION_FLTR
);
435 for (i
= 0; i
< n_pkts
; i
++) {
436 struct rte_mbuf
*pkt
= pkts
[i
];
437 uint64_t *pkt_key
= RTE_MBUF_METADATA_UINT64_PTR(pkt
,
440 uint64_t xor0
= (pkt_key
[0] & key_mask
[0]) ^ key
[0];
441 uint64_t xor1
= (pkt_key
[1] & key_mask
[1]) ^ key
[1];
442 uint64_t or = xor0
| xor1
;
445 rte_pipeline_ah_packet_hijack(p
, 1LLU << i
);
446 rte_pipeline_port_out_packet_insert(p
,
455 ah_lb(struct rte_pipeline
*p
,
456 struct rte_mbuf
**pkts
,
460 struct rte_port_in_action
*action
= arg
;
461 struct rte_port_in_action_lb_config
*cfg
= &action
->cfg
.lb
;
462 struct lb_data
*data
= action_data_get(action
, RTE_PORT_IN_ACTION_LB
);
463 uint64_t pkt_mask
= RTE_LEN2MASK(n_pkts
, uint64_t);
466 rte_pipeline_ah_packet_hijack(p
, pkt_mask
);
468 for (i
= 0; i
< n_pkts
; i
++) {
469 struct rte_mbuf
*pkt
= pkts
[i
];
470 uint8_t *pkt_key
= RTE_MBUF_METADATA_UINT8_PTR(pkt
,
473 uint64_t digest
= cfg
->f_hash(pkt_key
,
477 uint64_t pos
= digest
& (RTE_PORT_IN_ACTION_LB_TABLE_SIZE
- 1);
478 uint32_t port_id
= data
->port_id
[pos
];
480 rte_pipeline_port_out_packet_insert(p
, port_id
, pkt
);
486 static rte_pipeline_port_in_action_handler
487 ah_selector(struct rte_port_in_action
*action
)
489 if (action
->cfg
.action_mask
== 0)
492 if (action
->cfg
.action_mask
== 1LLU << RTE_PORT_IN_ACTION_FLTR
)
493 return (action
->cfg
.fltr
.filter_on_match
) ?
494 ah_filter_on_match
: ah_filter_on_mismatch
;
496 if (action
->cfg
.action_mask
== 1LLU << RTE_PORT_IN_ACTION_LB
)
503 rte_port_in_action_params_get(struct rte_port_in_action
*action
,
504 struct rte_pipeline_port_in_params
*params
)
506 rte_pipeline_port_in_action_handler f_action
;
508 /* Check input arguments */
509 if ((action
== NULL
) ||
513 f_action
= ah_selector(action
);
516 params
->f_action
= f_action
;
517 params
->arg_ah
= (f_action
) ? action
: NULL
;
523 rte_port_in_action_free(struct rte_port_in_action
*action
)