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_cycles.h>
11 #include <rte_malloc.h>
15 #include "rte_table_action.h"
17 #define rte_htons rte_cpu_to_be_16
18 #define rte_htonl rte_cpu_to_be_32
20 #define rte_ntohs rte_be_to_cpu_16
21 #define rte_ntohl rte_be_to_cpu_32
24 * RTE_TABLE_ACTION_FWD
26 #define fwd_data rte_pipeline_table_entry
29 fwd_apply(struct fwd_data *data,
30 struct rte_table_action_fwd_params *p)
32 data->action = p->action;
34 if (p->action == RTE_PIPELINE_ACTION_PORT)
35 data->port_id = p->id;
37 if (p->action == RTE_PIPELINE_ACTION_TABLE)
38 data->table_id = p->id;
44 * RTE_TABLE_ACTION_MTR
47 mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
49 if ((mtr->alg == RTE_TABLE_ACTION_METER_SRTCM) ||
50 ((mtr->n_tc != 1) && (mtr->n_tc != 4)) ||
51 (mtr->n_bytes_enabled != 0))
56 #define MBUF_SCHED_QUEUE_TC_COLOR(queue, tc, color) \
57 ((uint16_t)((((uint64_t)(queue)) & 0x3) | \
58 ((((uint64_t)(tc)) & 0x3) << 2) | \
59 ((((uint64_t)(color)) & 0x3) << 4)))
61 #define MBUF_SCHED_COLOR(sched, color) \
62 (((sched) & (~0x30LLU)) | ((color) << 4))
64 struct mtr_trtcm_data {
65 struct rte_meter_trtcm trtcm;
66 uint64_t stats[e_RTE_METER_COLORS];
67 } __attribute__((__packed__));
69 #define MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data) \
70 (((data)->stats[e_RTE_METER_GREEN] & 0xF8LLU) >> 3)
73 mtr_trtcm_data_meter_profile_id_set(struct mtr_trtcm_data *data,
76 data->stats[e_RTE_METER_GREEN] &= ~0xF8LLU;
77 data->stats[e_RTE_METER_GREEN] |= (profile_id % 32) << 3;
80 #define MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color)\
81 (((data)->stats[(color)] & 4LLU) >> 2)
83 #define MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color)\
84 ((enum rte_meter_color)((data)->stats[(color)] & 3LLU))
87 mtr_trtcm_data_policer_action_set(struct mtr_trtcm_data *data,
88 enum rte_meter_color color,
89 enum rte_table_action_policer action)
91 if (action == RTE_TABLE_ACTION_POLICER_DROP) {
92 data->stats[color] |= 4LLU;
94 data->stats[color] &= ~7LLU;
95 data->stats[color] |= color & 3LLU;
100 mtr_trtcm_data_stats_get(struct mtr_trtcm_data *data,
101 enum rte_meter_color color)
103 return data->stats[color] >> 8;
107 mtr_trtcm_data_stats_reset(struct mtr_trtcm_data *data,
108 enum rte_meter_color color)
110 data->stats[color] &= 0xFFLU;
113 #define MTR_TRTCM_DATA_STATS_INC(data, color) \
114 ((data)->stats[(color)] += (1LLU << 8))
117 mtr_data_size(struct rte_table_action_mtr_config *mtr)
119 return mtr->n_tc * sizeof(struct mtr_trtcm_data);
122 struct dscp_table_entry_data {
123 enum rte_meter_color color;
125 uint16_t queue_tc_color;
128 struct dscp_table_data {
129 struct dscp_table_entry_data entry[64];
132 struct meter_profile_data {
133 struct rte_meter_trtcm_profile profile;
138 static struct meter_profile_data *
139 meter_profile_data_find(struct meter_profile_data *mp,
145 for (i = 0; i < mp_size; i++) {
146 struct meter_profile_data *mp_data = &mp[i];
148 if (mp_data->valid && (mp_data->profile_id == profile_id))
155 static struct meter_profile_data *
156 meter_profile_data_find_unused(struct meter_profile_data *mp,
161 for (i = 0; i < mp_size; i++) {
162 struct meter_profile_data *mp_data = &mp[i];
172 mtr_apply_check(struct rte_table_action_mtr_params *p,
173 struct rte_table_action_mtr_config *cfg,
174 struct meter_profile_data *mp,
179 if (p->tc_mask > RTE_LEN2MASK(cfg->n_tc, uint32_t))
182 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
183 struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
184 struct meter_profile_data *mp_data;
186 if ((p->tc_mask & (1LLU << i)) == 0)
189 mp_data = meter_profile_data_find(mp,
191 p_tc->meter_profile_id);
200 mtr_apply(struct mtr_trtcm_data *data,
201 struct rte_table_action_mtr_params *p,
202 struct rte_table_action_mtr_config *cfg,
203 struct meter_profile_data *mp,
209 /* Check input arguments */
210 status = mtr_apply_check(p, cfg, mp, mp_size);
215 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
216 struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
217 struct mtr_trtcm_data *data_tc = &data[i];
218 struct meter_profile_data *mp_data;
220 if ((p->tc_mask & (1LLU << i)) == 0)
224 mp_data = meter_profile_data_find(mp,
226 p_tc->meter_profile_id);
230 memset(data_tc, 0, sizeof(*data_tc));
233 status = rte_meter_trtcm_config(&data_tc->trtcm,
239 mtr_trtcm_data_meter_profile_id_set(data_tc,
242 /* Policer actions */
243 mtr_trtcm_data_policer_action_set(data_tc,
245 p_tc->policer[e_RTE_METER_GREEN]);
247 mtr_trtcm_data_policer_action_set(data_tc,
249 p_tc->policer[e_RTE_METER_YELLOW]);
251 mtr_trtcm_data_policer_action_set(data_tc,
253 p_tc->policer[e_RTE_METER_RED]);
259 static __rte_always_inline uint64_t
260 pkt_work_mtr(struct rte_mbuf *mbuf,
261 struct mtr_trtcm_data *data,
262 struct dscp_table_data *dscp_table,
263 struct meter_profile_data *mp,
266 uint16_t total_length)
268 uint64_t drop_mask, sched;
269 uint64_t *sched_ptr = (uint64_t *) &mbuf->hash.sched;
270 struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
271 enum rte_meter_color color_in, color_meter, color_policer;
275 color_in = dscp_entry->color;
277 mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
281 color_meter = rte_meter_trtcm_color_aware_check(
289 MTR_TRTCM_DATA_STATS_INC(data, color_meter);
292 drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
294 MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
295 *sched_ptr = MBUF_SCHED_COLOR(sched, color_policer);
301 * RTE_TABLE_ACTION_TM
304 tm_cfg_check(struct rte_table_action_tm_config *tm)
306 if ((tm->n_subports_per_port == 0) ||
307 (rte_is_power_of_2(tm->n_subports_per_port) == 0) ||
308 (tm->n_subports_per_port > UINT16_MAX) ||
309 (tm->n_pipes_per_subport == 0) ||
310 (rte_is_power_of_2(tm->n_pipes_per_subport) == 0))
317 uint16_t queue_tc_color;
320 } __attribute__((__packed__));
323 tm_apply_check(struct rte_table_action_tm_params *p,
324 struct rte_table_action_tm_config *cfg)
326 if ((p->subport_id >= cfg->n_subports_per_port) ||
327 (p->pipe_id >= cfg->n_pipes_per_subport))
334 tm_apply(struct tm_data *data,
335 struct rte_table_action_tm_params *p,
336 struct rte_table_action_tm_config *cfg)
340 /* Check input arguments */
341 status = tm_apply_check(p, cfg);
346 data->queue_tc_color = 0;
347 data->subport = (uint16_t) p->subport_id;
348 data->pipe = p->pipe_id;
353 static __rte_always_inline void
354 pkt_work_tm(struct rte_mbuf *mbuf,
355 struct tm_data *data,
356 struct dscp_table_data *dscp_table,
359 struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
360 struct tm_data *sched_ptr = (struct tm_data *) &mbuf->hash.sched;
361 struct tm_data sched;
364 sched.queue_tc_color = dscp_entry->queue_tc_color;
372 action_valid(enum rte_table_action_type action)
375 case RTE_TABLE_ACTION_FWD:
376 case RTE_TABLE_ACTION_MTR:
377 case RTE_TABLE_ACTION_TM:
385 #define RTE_TABLE_ACTION_MAX 64
388 uint64_t action_mask;
389 struct rte_table_action_common_config common;
390 struct rte_table_action_mtr_config mtr;
391 struct rte_table_action_tm_config tm;
395 action_cfg_size(enum rte_table_action_type action)
398 case RTE_TABLE_ACTION_MTR:
399 return sizeof(struct rte_table_action_mtr_config);
400 case RTE_TABLE_ACTION_TM:
401 return sizeof(struct rte_table_action_tm_config);
408 action_cfg_get(struct ap_config *ap_config,
409 enum rte_table_action_type type)
412 case RTE_TABLE_ACTION_MTR:
413 return &ap_config->mtr;
415 case RTE_TABLE_ACTION_TM:
416 return &ap_config->tm;
424 action_cfg_set(struct ap_config *ap_config,
425 enum rte_table_action_type type,
428 void *dst = action_cfg_get(ap_config, type);
431 memcpy(dst, action_cfg, action_cfg_size(type));
433 ap_config->action_mask |= 1LLU << type;
437 size_t offset[RTE_TABLE_ACTION_MAX];
442 action_data_size(enum rte_table_action_type action,
443 struct ap_config *ap_config)
446 case RTE_TABLE_ACTION_FWD:
447 return sizeof(struct fwd_data);
449 case RTE_TABLE_ACTION_MTR:
450 return mtr_data_size(&ap_config->mtr);
452 case RTE_TABLE_ACTION_TM:
453 return sizeof(struct tm_data);
462 action_data_offset_set(struct ap_data *ap_data,
463 struct ap_config *ap_config)
465 uint64_t action_mask = ap_config->action_mask;
469 memset(ap_data->offset, 0, sizeof(ap_data->offset));
472 for (action = 0; action < RTE_TABLE_ACTION_MAX; action++)
473 if (action_mask & (1LLU << action)) {
474 ap_data->offset[action] = offset;
475 offset += action_data_size((enum rte_table_action_type)action,
479 ap_data->total_size = offset;
482 struct rte_table_action_profile {
483 struct ap_config cfg;
488 struct rte_table_action_profile *
489 rte_table_action_profile_create(struct rte_table_action_common_config *common)
491 struct rte_table_action_profile *ap;
493 /* Check input arguments */
497 /* Memory allocation */
498 ap = calloc(1, sizeof(struct rte_table_action_profile));
503 memcpy(&ap->cfg.common, common, sizeof(*common));
510 rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
511 enum rte_table_action_type type,
516 /* Check input arguments */
517 if ((profile == NULL) ||
519 (action_valid(type) == 0) ||
520 (profile->cfg.action_mask & (1LLU << type)) ||
521 ((action_cfg_size(type) == 0) && action_config) ||
522 (action_cfg_size(type) && (action_config == NULL)))
526 case RTE_TABLE_ACTION_MTR:
527 status = mtr_cfg_check(action_config);
530 case RTE_TABLE_ACTION_TM:
531 status = tm_cfg_check(action_config);
543 action_cfg_set(&profile->cfg, type, action_config);
549 rte_table_action_profile_freeze(struct rte_table_action_profile *profile)
554 profile->cfg.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
555 action_data_offset_set(&profile->data, &profile->cfg);
562 rte_table_action_profile_free(struct rte_table_action_profile *profile)
574 #define METER_PROFILES_MAX 32
576 struct rte_table_action {
577 struct ap_config cfg;
579 struct dscp_table_data dscp_table;
580 struct meter_profile_data mp[METER_PROFILES_MAX];
583 struct rte_table_action *
584 rte_table_action_create(struct rte_table_action_profile *profile,
587 struct rte_table_action *action;
589 /* Check input arguments */
590 if ((profile == NULL) ||
591 (profile->frozen == 0))
594 /* Memory allocation */
595 action = rte_zmalloc_socket(NULL,
596 sizeof(struct rte_table_action),
603 memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
604 memcpy(&action->data, &profile->data, sizeof(profile->data));
609 static __rte_always_inline void *
610 action_data_get(void *data,
611 struct rte_table_action *action,
612 enum rte_table_action_type type)
614 size_t offset = action->data.offset[type];
615 uint8_t *data_bytes = data;
617 return &data_bytes[offset];
621 rte_table_action_apply(struct rte_table_action *action,
623 enum rte_table_action_type type,
628 /* Check input arguments */
629 if ((action == NULL) ||
631 (action_valid(type) == 0) ||
632 ((action->cfg.action_mask & (1LLU << type)) == 0) ||
633 (action_params == NULL))
637 action_data = action_data_get(data, action, type);
640 case RTE_TABLE_ACTION_FWD:
641 return fwd_apply(action_data,
644 case RTE_TABLE_ACTION_MTR:
645 return mtr_apply(action_data,
649 RTE_DIM(action->mp));
651 case RTE_TABLE_ACTION_TM:
652 return tm_apply(action_data,
662 rte_table_action_dscp_table_update(struct rte_table_action *action,
664 struct rte_table_action_dscp_table *table)
668 /* Check input arguments */
669 if ((action == NULL) ||
670 ((action->cfg.action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
671 (1LLU << RTE_TABLE_ACTION_TM))) == 0) ||
676 for (i = 0; i < RTE_DIM(table->entry); i++) {
677 struct dscp_table_entry_data *data =
678 &action->dscp_table.entry[i];
679 struct rte_table_action_dscp_table_entry *entry =
681 uint16_t queue_tc_color =
682 MBUF_SCHED_QUEUE_TC_COLOR(entry->tc_queue_id,
686 if ((dscp_mask & (1LLU << i)) == 0)
689 data->color = entry->color;
690 data->tc = entry->tc_id;
691 data->queue_tc_color = queue_tc_color;
698 rte_table_action_meter_profile_add(struct rte_table_action *action,
699 uint32_t meter_profile_id,
700 struct rte_table_action_meter_profile *profile)
702 struct meter_profile_data *mp_data;
705 /* Check input arguments */
706 if ((action == NULL) ||
707 ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
711 if (profile->alg != RTE_TABLE_ACTION_METER_TRTCM)
714 mp_data = meter_profile_data_find(action->mp,
720 mp_data = meter_profile_data_find_unused(action->mp,
721 RTE_DIM(action->mp));
725 /* Install new profile */
726 status = rte_meter_trtcm_profile_config(&mp_data->profile,
731 mp_data->profile_id = meter_profile_id;
738 rte_table_action_meter_profile_delete(struct rte_table_action *action,
739 uint32_t meter_profile_id)
741 struct meter_profile_data *mp_data;
743 /* Check input arguments */
744 if ((action == NULL) ||
745 ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0))
748 mp_data = meter_profile_data_find(action->mp,
754 /* Uninstall profile */
761 rte_table_action_meter_read(struct rte_table_action *action,
764 struct rte_table_action_mtr_counters *stats,
767 struct mtr_trtcm_data *mtr_data;
770 /* Check input arguments */
771 if ((action == NULL) ||
772 ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
774 (tc_mask > RTE_LEN2MASK(action->cfg.mtr.n_tc, uint32_t)))
777 mtr_data = action_data_get(data, action, RTE_TABLE_ACTION_MTR);
781 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
782 struct rte_table_action_mtr_counters_tc *dst =
784 struct mtr_trtcm_data *src = &mtr_data[i];
786 if ((tc_mask & (1 << i)) == 0)
789 dst->n_packets[e_RTE_METER_GREEN] =
790 mtr_trtcm_data_stats_get(src, e_RTE_METER_GREEN);
792 dst->n_packets[e_RTE_METER_YELLOW] =
793 mtr_trtcm_data_stats_get(src, e_RTE_METER_YELLOW);
795 dst->n_packets[e_RTE_METER_RED] =
796 mtr_trtcm_data_stats_get(src, e_RTE_METER_RED);
798 dst->n_packets_valid = 1;
799 dst->n_bytes_valid = 0;
802 stats->tc_mask = tc_mask;
807 for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
808 struct mtr_trtcm_data *src = &mtr_data[i];
810 if ((tc_mask & (1 << i)) == 0)
813 mtr_trtcm_data_stats_reset(src, e_RTE_METER_GREEN);
814 mtr_trtcm_data_stats_reset(src, e_RTE_METER_YELLOW);
815 mtr_trtcm_data_stats_reset(src, e_RTE_METER_RED);
822 static __rte_always_inline uint64_t
823 pkt_work(struct rte_mbuf *mbuf,
824 struct rte_pipeline_table_entry *table_entry,
826 struct rte_table_action *action,
827 struct ap_config *cfg)
829 uint64_t drop_mask = 0;
831 uint32_t ip_offset = action->cfg.common.ip_offset;
832 void *ip = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ip_offset);
835 uint16_t total_length;
837 if (cfg->common.ip_version) {
838 struct ipv4_hdr *hdr = ip;
840 dscp = hdr->type_of_service >> 2;
841 total_length = rte_ntohs(hdr->total_length);
843 struct ipv6_hdr *hdr = ip;
845 dscp = (rte_ntohl(hdr->vtc_flow) & 0x0F600000) >> 18;
847 rte_ntohs(hdr->payload_len) + sizeof(struct ipv6_hdr);
850 if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
852 action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR);
854 drop_mask |= pkt_work_mtr(mbuf,
863 if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
865 action_data_get(table_entry, action, RTE_TABLE_ACTION_TM);
876 static __rte_always_inline uint64_t
877 pkt4_work(struct rte_mbuf **mbufs,
878 struct rte_pipeline_table_entry **table_entries,
880 struct rte_table_action *action,
881 struct ap_config *cfg)
883 uint64_t drop_mask0 = 0;
884 uint64_t drop_mask1 = 0;
885 uint64_t drop_mask2 = 0;
886 uint64_t drop_mask3 = 0;
888 struct rte_mbuf *mbuf0 = mbufs[0];
889 struct rte_mbuf *mbuf1 = mbufs[1];
890 struct rte_mbuf *mbuf2 = mbufs[2];
891 struct rte_mbuf *mbuf3 = mbufs[3];
893 struct rte_pipeline_table_entry *table_entry0 = table_entries[0];
894 struct rte_pipeline_table_entry *table_entry1 = table_entries[1];
895 struct rte_pipeline_table_entry *table_entry2 = table_entries[2];
896 struct rte_pipeline_table_entry *table_entry3 = table_entries[3];
898 uint32_t ip_offset = action->cfg.common.ip_offset;
899 void *ip0 = RTE_MBUF_METADATA_UINT32_PTR(mbuf0, ip_offset);
900 void *ip1 = RTE_MBUF_METADATA_UINT32_PTR(mbuf1, ip_offset);
901 void *ip2 = RTE_MBUF_METADATA_UINT32_PTR(mbuf2, ip_offset);
902 void *ip3 = RTE_MBUF_METADATA_UINT32_PTR(mbuf3, ip_offset);
904 uint32_t dscp0, dscp1, dscp2, dscp3;
905 uint16_t total_length0, total_length1, total_length2, total_length3;
907 if (cfg->common.ip_version) {
908 struct ipv4_hdr *hdr0 = ip0;
909 struct ipv4_hdr *hdr1 = ip1;
910 struct ipv4_hdr *hdr2 = ip2;
911 struct ipv4_hdr *hdr3 = ip3;
913 dscp0 = hdr0->type_of_service >> 2;
914 dscp1 = hdr1->type_of_service >> 2;
915 dscp2 = hdr2->type_of_service >> 2;
916 dscp3 = hdr3->type_of_service >> 2;
918 total_length0 = rte_ntohs(hdr0->total_length);
919 total_length1 = rte_ntohs(hdr1->total_length);
920 total_length2 = rte_ntohs(hdr2->total_length);
921 total_length3 = rte_ntohs(hdr3->total_length);
923 struct ipv6_hdr *hdr0 = ip0;
924 struct ipv6_hdr *hdr1 = ip1;
925 struct ipv6_hdr *hdr2 = ip2;
926 struct ipv6_hdr *hdr3 = ip3;
928 dscp0 = (rte_ntohl(hdr0->vtc_flow) & 0x0F600000) >> 18;
929 dscp1 = (rte_ntohl(hdr1->vtc_flow) & 0x0F600000) >> 18;
930 dscp2 = (rte_ntohl(hdr2->vtc_flow) & 0x0F600000) >> 18;
931 dscp3 = (rte_ntohl(hdr3->vtc_flow) & 0x0F600000) >> 18;
934 rte_ntohs(hdr0->payload_len) + sizeof(struct ipv6_hdr);
936 rte_ntohs(hdr1->payload_len) + sizeof(struct ipv6_hdr);
938 rte_ntohs(hdr2->payload_len) + sizeof(struct ipv6_hdr);
940 rte_ntohs(hdr3->payload_len) + sizeof(struct ipv6_hdr);
943 if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
945 action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR);
947 action_data_get(table_entry1, action, RTE_TABLE_ACTION_MTR);
949 action_data_get(table_entry2, action, RTE_TABLE_ACTION_MTR);
951 action_data_get(table_entry3, action, RTE_TABLE_ACTION_MTR);
953 drop_mask0 |= pkt_work_mtr(mbuf0,
961 drop_mask1 |= pkt_work_mtr(mbuf1,
969 drop_mask2 |= pkt_work_mtr(mbuf2,
977 drop_mask3 |= pkt_work_mtr(mbuf3,
986 if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
988 action_data_get(table_entry0, action, RTE_TABLE_ACTION_TM);
990 action_data_get(table_entry1, action, RTE_TABLE_ACTION_TM);
992 action_data_get(table_entry2, action, RTE_TABLE_ACTION_TM);
994 action_data_get(table_entry3, action, RTE_TABLE_ACTION_TM);
1003 &action->dscp_table,
1008 &action->dscp_table,
1013 &action->dscp_table,
1023 static __rte_always_inline int
1024 ah(struct rte_pipeline *p,
1025 struct rte_mbuf **pkts,
1027 struct rte_pipeline_table_entry **entries,
1028 struct rte_table_action *action,
1029 struct ap_config *cfg)
1031 uint64_t pkts_drop_mask = 0;
1034 if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR))
1037 if ((pkts_mask & (pkts_mask + 1)) == 0) {
1038 uint64_t n_pkts = __builtin_popcountll(pkts_mask);
1041 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {
1044 drop_mask = pkt4_work(&pkts[i],
1050 pkts_drop_mask |= drop_mask << i;
1053 for ( ; i < n_pkts; i++) {
1056 drop_mask = pkt_work(pkts[i],
1062 pkts_drop_mask |= drop_mask << i;
1065 for ( ; pkts_mask; ) {
1066 uint32_t pos = __builtin_ctzll(pkts_mask);
1067 uint64_t pkt_mask = 1LLU << pos;
1070 drop_mask = pkt_work(pkts[pos],
1076 pkts_mask &= ~pkt_mask;
1077 pkts_drop_mask |= drop_mask << pos;
1080 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
1086 ah_default(struct rte_pipeline *p,
1087 struct rte_mbuf **pkts,
1089 struct rte_pipeline_table_entry **entries,
1092 struct rte_table_action *action = arg;
1102 static rte_pipeline_table_action_handler_hit
1103 ah_selector(struct rte_table_action *action)
1105 if (action->cfg.action_mask == (1LLU << RTE_TABLE_ACTION_FWD))
1112 rte_table_action_table_params_get(struct rte_table_action *action,
1113 struct rte_pipeline_table_params *params)
1115 rte_pipeline_table_action_handler_hit f_action_hit;
1116 uint32_t total_size;
1118 /* Check input arguments */
1119 if ((action == NULL) ||
1123 f_action_hit = ah_selector(action);
1124 total_size = rte_align32pow2(action->data.total_size);
1126 /* Fill in params */
1127 params->f_action_hit = f_action_hit;
1128 params->f_action_miss = NULL;
1129 params->arg_ah = (f_action_hit) ? action : NULL;
1130 params->action_data_size = total_size -
1131 sizeof(struct rte_pipeline_table_entry);
1137 rte_table_action_free(struct rte_table_action *action)