2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
19 * Pipeline ACL BE Implementation.
21 * Implementation of Pipeline ACL Back End (BE).
22 * Responsible for packet processing.
27 #include <rte_common.h>
28 #include <rte_malloc.h>
29 #include <rte_ether.h>
32 #include <rte_byteorder.h>
33 #include <rte_table_acl.h>
34 #include <rte_table_stub.h>
35 #include "pipeline_arpicmp_be.h"
36 #include "vnf_common.h"
37 #include "pipeline_common_be.h"
38 #include <rte_pipeline.h>
41 #include <rte_timer.h>
42 #include <rte_cycles.h>
44 #include "pipeline_acl.h"
45 #include "pipeline_acl_be.h"
46 #include "rte_cnxn_tracking.h"
47 #include "pipeline_actions_common.h"
49 #include "lib_icmpv6.h"
50 static uint8_t acl_prv_que_port_index[PIPELINE_MAX_PORT_IN];
51 extern void convert_prefixlen_to_netmask_ipv6(uint32_t depth,
52 uint8_t netmask_ipv6[]);
59 * A structure defining the ACL pipeline per thread data.
63 pipeline_msg_req_handler custom_handlers[PIPELINE_ACL_MSG_REQS];
66 uint32_t n_rule_fields;
67 struct rte_acl_field_def *field_format;
68 uint32_t field_format_size;
70 /* Connection Tracker */
71 struct rte_ct_cnxn_tracker *cnxn_tracker;
72 struct rte_ACL_counter_block *counters;
73 int action_counter_index;
74 /* timestamp retrieved during in-port computations */
75 uint64_t in_port_time_stamp;
80 uint8_t links_map[PIPELINE_MAX_PORT_IN];
81 uint8_t port_out_id[PIPELINE_MAX_PORT_IN];
83 struct acl_table_entry *acl_entries_ipv4[RTE_PORT_IN_BURST_SIZE_MAX];
84 struct acl_table_entry *acl_entries_ipv6[RTE_PORT_IN_BURST_SIZE_MAX];
86 /* Local ARP & ND Tables */
87 struct lib_arp_route_table_entry
88 local_lib_arp_route_table[MAX_ARP_RT_ENTRY];
89 uint8_t local_lib_arp_route_ent_cnt;
90 struct lib_nd_route_table_entry
91 local_lib_nd_route_table[MAX_ND_RT_ENTRY];
92 uint8_t local_lib_nd_route_ent_cnt;
94 } __rte_cache_aligned;
97 * A structure defining the mbuf meta data for ACL.
99 struct mbuf_acl_meta_data {
100 /* output port stored for RTE_PIPELINE_ACTION_PORT_META */
101 uint32_t output_port;
102 /* next hop ip address used by ARP code */
104 } __rte_cache_aligned;
106 #define META_DATA_OFFSET 128
108 struct rte_ACL_counter_block rte_acl_counter_table[MAX_ACL_INSTANCES]
110 int rte_ACL_hi_counter_block_in_use = -1;
112 /* a spin lock used during acl initialization only */
113 rte_spinlock_t rte_ACL_init_lock = RTE_SPINLOCK_INITIALIZER;
116 struct pipeline_action_key *action_array_a;
117 struct pipeline_action_key *action_array_b;
118 struct pipeline_action_key *action_array_active;
119 struct pipeline_action_key *action_array_standby;
120 uint32_t action_array_size;
122 struct action_counter_block
123 action_counter_table[MAX_ACL_INSTANCES][action_array_max]
126 static void *pipeline_acl_msg_req_custom_handler(struct pipeline *p, void *msg);
128 static pipeline_msg_req_handler handlers[] = {
129 [PIPELINE_MSG_REQ_PING] = pipeline_msg_req_ping_handler,
130 [PIPELINE_MSG_REQ_STATS_PORT_IN] =
131 pipeline_msg_req_stats_port_in_handler,
132 [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
133 pipeline_msg_req_stats_port_out_handler,
134 [PIPELINE_MSG_REQ_STATS_TABLE] = pipeline_msg_req_stats_table_handler,
135 [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
136 pipeline_msg_req_port_in_enable_handler,
137 [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
138 pipeline_msg_req_port_in_disable_handler,
139 [PIPELINE_MSG_REQ_CUSTOM] = pipeline_acl_msg_req_custom_handler,
142 static void *pipeline_acl_msg_req_dbg_handler(struct pipeline *p, void *msg);
144 static pipeline_msg_req_handler custom_handlers[] = {
145 [PIPELINE_ACL_MSG_REQ_DBG] = pipeline_acl_msg_req_dbg_handler,
149 uint32_t local_get_nh_ipv4(uint32_t ip,
151 uint32_t *nhip, struct pipeline_acl *p_acl)
155 for (i = 0; i < p_acl->local_lib_arp_route_ent_cnt; i++) {
156 if (((p_acl->local_lib_arp_route_table[i].ip &
157 p_acl->local_lib_arp_route_table[i].mask) ==
158 (ip & p_acl->local_lib_arp_route_table[i].mask))) {
159 *port = p_acl->local_lib_arp_route_table[i].port;
161 *nhip = p_acl->local_lib_arp_route_table[i].nh;
168 static void do_local_nh_ipv4_cache(uint32_t dest_if, struct pipeline_acl *p_acl)
171 /* Search for the entry and do local copy */
174 for (i = 0; i < MAX_ARP_RT_ENTRY; i++) {
175 if (lib_arp_route_table[i].port == dest_if) {
177 struct lib_arp_route_table_entry *lentry =
178 &p_acl->local_lib_arp_route_table
179 [p_acl->local_lib_arp_route_ent_cnt];
181 lentry->ip = lib_arp_route_table[i].ip;
182 lentry->mask = lib_arp_route_table[i].mask;
183 lentry->port = lib_arp_route_table[i].port;
184 lentry->nh = lib_arp_route_table[i].nh;
186 p_acl->local_lib_arp_route_ent_cnt++;
192 static uint32_t local_get_nh_ipv6(uint8_t *ip,
194 uint8_t nhip[], struct pipeline_acl *p_acl)
197 uint8_t netmask_ipv6[16],netip_nd[16],netip_in[16];
198 uint8_t k = 0, l = 0, depthflags = 0, depthflags1 = 0;
199 memset (netmask_ipv6, 0, sizeof(netmask_ipv6));
200 memset (netip_nd, 0, sizeof(netip_nd));
201 memset (netip_in, 0, sizeof(netip_in));
203 for (i = 0; i < p_acl->local_lib_nd_route_ent_cnt; i++) {
205 convert_prefixlen_to_netmask_ipv6
206 (p_acl->local_lib_nd_route_table[i].depth, netmask_ipv6);
208 for (k = 0; k < 16; k++)
209 if (p_acl->local_lib_nd_route_table[i].ipv6[k] &
212 netip_nd[k] = p_acl->
213 local_lib_nd_route_table[i].ipv6[k];
217 for (l = 0; l < 16; l++)
218 if (ip[l] & netmask_ipv6[l]) {
225 if ((depthflags == depthflags1) && (memcmp(netip_nd, netip_in,
226 sizeof(netip_nd)) == 0)){
227 *port = p_acl->local_lib_nd_route_table[i].port;
229 for (j = 0; j < 16; j++)
231 p_acl->local_lib_nd_route_table[i].
241 void do_local_nh_ipv6_cache(uint32_t dest_if, struct pipeline_acl *p_acl)
243 /* Search for the entry and do local copy */
246 for (i = 0; i < MAX_ND_RT_ENTRY; i++) {
248 if (lib_nd_route_table[i].port == dest_if) {
250 struct lib_nd_route_table_entry *lentry =
251 &p_acl->local_lib_nd_route_table
252 [p_acl->local_lib_nd_route_ent_cnt];
254 for (l = 0; l < 16; l++) {
255 lentry->ipv6[l] = lib_nd_route_table[i].ipv6[l];
257 lib_nd_route_table[i].nhipv6[l];
259 lentry->depth = lib_nd_route_table[i].depth;
260 lentry->port = lib_nd_route_table[i].port;
262 p_acl->local_lib_nd_route_ent_cnt++;
268 static uint8_t check_arp_icmp(struct rte_mbuf *pkt,
269 uint64_t pkt_mask, struct pipeline_acl *p_acl)
271 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
272 struct ipv6_hdr *ipv6_h;
273 uint16_t *eth_proto =
274 RTE_MBUF_METADATA_UINT16_PTR(pkt, eth_proto_offset);
275 struct app_link_params *link;
277 //uint32_t *port_out_id = RTE_MBUF_METADATA_UINT32_PTR(pk
278 // offsetof(struct mbuf_acl_meta_dat
280 /* ARP outport number */
281 uint16_t out_port = p_acl->p.n_ports_out - 1;
284 uint32_t prot_offset;
286 link = &myApp->link_params[pkt->port];
288 switch (rte_be_to_cpu_16(*eth_proto)) {
291 rte_pipeline_port_out_packet_insert(p_acl->p.p, out_port, pkt);
294 * Pkt mask should be changed, and not changing the
297 p_acl->arpPktCount++;
302 /* header room + eth hdr size +
303 * src_aadr offset in ip header
305 uint32_t dst_addr_offset = MBUF_HDR_ROOM +
306 ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
307 uint32_t *dst_addr = RTE_MBUF_METADATA_UINT32_PTR(pkt,
309 prot_offset = MBUF_HDR_ROOM + ETH_HDR_SIZE +
310 IP_HDR_PROTOCOL_OFST;
311 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt,
313 if ((*protocol == IP_PROTOCOL_ICMP) &&
314 link->ip == rte_be_to_cpu_32(*dst_addr)) {
316 if (is_phy_port_privte(pkt->port)) {
318 rte_pipeline_port_out_packet_insert
319 (p_acl->p.p, out_port, pkt);
321 * Pkt mask should be changed,
322 * and not changing the drop mask
324 p_acl->arpPktCount++;
336 uint32_t dst_addr_offset = MBUF_HDR_ROOM +
337 ETH_HDR_SIZE + IPV6_HDR_DST_ADR_OFST;
338 uint32_t *dst_addr = RTE_MBUF_METADATA_UINT32_PTR(pkt,
341 uint32_t prot_offset_ipv6 = MBUF_HDR_ROOM +
342 ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
343 struct ipv6_hdr *ipv6_h;
345 ipv6_h = (struct ipv6_hdr *)MBUF_HDR_ROOM +
347 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt,
350 if ((ipv6_h->proto == ICMPV6_PROTOCOL_ID) &&
351 (link->ip == rte_be_to_cpu_32(dst_addr[3]))) {
353 if (is_phy_port_privte(pkt->port)) {
355 rte_pipeline_port_out_packet_insert
356 (p_acl->p.p, out_port, pkt);
358 * Pkt mask should be changed,
359 * and not changing the drop mask
361 p_acl->arpPktCount++;
371 #define IP_START (MBUF_HDR_ROOM + ETH_HDR_SIZE)
374 ipv6_h = (struct ipv6_hdr *)
375 RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
377 if ((ipv6_h->proto == ICMPV6_PROTOCOL_ID) &&
379 rte_be_to_cpu_32(ipv6_h->dst_addr[3]))) {
381 if (is_phy_port_privte(pkt->port)) {
382 rte_pipeline_port_out_packet_insert(
387 p_acl->arpPktCount++;
402 * Print packet for debugging.
405 * A pointer to the packet.
408 void print_pkt_acl(struct rte_mbuf *pkt)
412 printf("Packet Contents:\n");
413 uint8_t *rd = RTE_MBUF_METADATA_UINT8_PTR(pkt, 0);
415 for (i = 0; i < 20; i++) {
416 for (j = 0; j < 20; j++)
417 printf("%02x ", rd[(20 * i) + j]);
423 * Main packet processing function.
424 * 64 packet bit mask are used to identify which packets to forward.
425 * Performs the following:
426 * - Burst lookup packets in the IPv4 ACL Rule Table.
427 * - Burst lookup packets in the IPv6 ACL Rule Table.
428 * - Lookup Action Table, perform actions.
429 * - Burst lookup Connection Tracking, if enabled.
430 * - Lookup MAC address.
432 * - Packets with bit mask set are forwarded
435 * A pointer to the pipeline.
437 * A pointer to a burst of packets.
439 * Number of packets to process.
441 * A pointer to pipeline specific data.
444 * 0 on success, negative on error.
447 pkt_work_acl_key(struct rte_pipeline *p,
448 struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
451 struct pipeline_acl *p_acl = arg;
453 p_acl->counters->pkts_received =
454 p_acl->counters->pkts_received + n_pkts;
456 printf("pkt_work_acl_key pkts_received: %" PRIu64
457 " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
459 uint64_t lookup_hit_mask = 0;
460 uint64_t lookup_hit_mask_ipv4 = 0;
461 uint64_t lookup_hit_mask_ipv6 = 0;
462 uint64_t lookup_miss_mask = 0;
463 uint64_t conntrack_mask = 0;
464 uint64_t connexist_mask = 0;
465 uint32_t dest_address = 0;
468 uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
469 uint64_t keep_mask = pkts_mask;
473 p_acl->in_port_time_stamp = rte_get_tsc_cycles();
475 if (acl_ipv4_enabled) {
477 printf("ACL IPV4 Lookup Mask Before = %p\n",
480 rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
481 pkts_mask, &lookup_hit_mask_ipv4,
483 p_acl->acl_entries_ipv4);
485 printf("ACL IPV4 Lookup Mask After = %p\n",
486 (void *)lookup_hit_mask_ipv4);
489 if (acl_ipv6_enabled) {
491 printf("ACL IPV6 Lookup Mask Before = %p\n",
494 rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
495 pkts_mask, &lookup_hit_mask_ipv6,
497 p_acl->acl_entries_ipv6);
499 printf("ACL IPV6 Lookup Mask After = %p\n",
500 (void *)lookup_hit_mask_ipv6);
503 /* Merge lookup results since we process both IPv4 and IPv6 below */
504 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
506 printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
508 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
509 pkts_mask = lookup_hit_mask;
510 p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
512 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
513 p_acl->counters->pkts_drop,
514 __builtin_popcountll(lookup_miss_mask));
516 uint64_t pkts_to_process = lookup_hit_mask;
517 /* bitmap of packets left to process for ARP */
519 for (; pkts_to_process;) {
520 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
521 uint64_t pkt_mask = 1LLU << pos;
522 /* bitmask representing only this packet */
524 pkts_to_process &= ~pkt_mask;
525 /* remove this packet from remaining list */
526 struct rte_mbuf *pkt = pkts[pos];
529 if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
530 pkts_mask &= ~(1LLU << pos);
535 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
536 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
538 if (hdr_chk == IPv4_HDR_VERSION) {
540 struct acl_table_entry *entry =
541 (struct acl_table_entry *)
542 p_acl->acl_entries_ipv4[pos];
543 uint16_t phy_port = entry->head.port_id;
544 uint32_t action_id = entry->action_id;
547 printf("action_id = %u\n", action_id);
549 uint32_t dscp_offset =
550 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
552 if (action_array_active[action_id].action_bitmap &
555 [p_acl->action_counter_index]
556 [action_id].packetCount++;
558 [p_acl->action_counter_index]
559 [action_id].byteCount +=
560 rte_pktmbuf_pkt_len(pkt);
562 printf("Action Count Packet Count: %"
563 PRIu64 " Byte Count: %" PRIu64
566 [p_acl->action_counter_index]
567 [action_id].packetCount,
569 [p_acl->action_counter_index]
570 [action_id].byteCount);
573 if (action_array_active[action_id].action_bitmap &
574 acl_action_packet_drop) {
576 /* Drop packet by changing the mask */
578 printf("ACL before drop pkt_mask "
579 " %lu, pkt_num %d\n",
581 pkts_mask &= ~(1LLU << pos);
583 printf("ACL after drop pkt_mask "
586 p_acl->counters->pkts_drop++;
589 if (action_array_active[action_id].action_bitmap &
592 action_array_active[action_id].fwd_port;
593 entry->head.port_id = phy_port;
595 printf("Action FWD Port ID: %u\n",
599 if (action_array_active[action_id].action_bitmap &
602 action_array_active[action_id].nat_port;
603 entry->head.port_id = phy_port;
605 printf("Action NAT Port ID: %u\n",
609 if (action_array_active[action_id].action_bitmap &
612 /* Set DSCP priority */
613 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
616 action_array_active[action_id].dscp_priority
620 ("Action DSCP DSCP Priority: %u\n",
624 if (action_array_active[action_id].action_bitmap &
625 acl_action_packet_accept) {
627 printf("Action Accept\n");
629 if (action_array_active[action_id].action_bitmap
630 & acl_action_conntrack) {
632 /* Set conntrack bit for this pkt */
633 conntrack_mask |= pkt_mask;
635 printf("ACL Conntrack enabled: "
637 (void *)conntrack_mask,
641 if (action_array_active[action_id].action_bitmap
642 & acl_action_connexist) {
644 /* Set conntrack bit for this pkt */
645 conntrack_mask |= pkt_mask;
647 /* Set connexist bit for this pkt for public -> private */
648 /* Private -> public packet will open the connection */
649 if (action_array_active
650 [action_id].private_public ==
652 connexist_mask |= pkt_mask;
655 printf("ACL Connexist enabled "
656 "conntrack: %p connexist: %p pkt_mask: %p\n",
657 (void *)conntrack_mask,
658 (void *)connexist_mask,
664 if (hdr_chk == IPv6_HDR_VERSION) {
666 struct acl_table_entry *entry =
667 (struct acl_table_entry *)
668 p_acl->acl_entries_ipv6[pos];
669 uint16_t phy_port = entry->head.port_id;
670 uint32_t action_id = entry->action_id;
673 printf("action_id = %u\n", action_id);
675 if (action_array_active[action_id].action_bitmap &
678 [p_acl->action_counter_index]
679 [action_id].packetCount++;
681 [p_acl->action_counter_index]
682 [action_id].byteCount +=
683 rte_pktmbuf_pkt_len(pkt);
685 printf("Action Count Packet Count: %"
686 PRIu64 " Byte Count: %" PRIu64
689 [p_acl->action_counter_index]
690 [action_id].packetCount,
692 [p_acl->action_counter_index]
693 [action_id].byteCount);
696 if (action_array_active[action_id].action_bitmap &
697 acl_action_packet_drop) {
698 /* Drop packet by changing the mask */
700 printf("ACL before drop pkt_mask "
703 pkts_mask &= ~(1LLU << pos);
705 printf("ACL after drop pkt_mask "
708 p_acl->counters->pkts_drop++;
712 if (action_array_active[action_id].action_bitmap &
715 action_array_active[action_id].fwd_port;
716 entry->head.port_id = phy_port;
718 printf("Action FWD Port ID: %u\n",
722 if (action_array_active[action_id].action_bitmap &
725 action_array_active[action_id].nat_port;
726 entry->head.port_id = phy_port;
728 printf("Action NAT Port ID: %u\n",
732 if (action_array_active[action_id].action_bitmap &
735 /* Set DSCP priority */
736 uint32_t dscp_offset =
737 MBUF_HDR_ROOM + ETH_HDR_SIZE +
738 IP_HDR_DSCP_OFST_IPV6;
740 RTE_MBUF_METADATA_UINT16_PTR(pkt,
742 uint16_t dscp_value =
744 (RTE_MBUF_METADATA_UINT16
745 (pkt, dscp_offset)) & 0XF00F);
747 action_array_active[action_id].dscp_priority
749 uint16_t dscp_temp = dscp_store;
751 dscp_temp = dscp_temp << 4;
752 *dscp = rte_bswap16(dscp_temp | dscp_value);
755 ("Action DSCP DSCP Priority: %u\n",
759 if (action_array_active[action_id].action_bitmap &
760 acl_action_packet_accept) {
762 printf("Action Accept\n");
764 if (action_array_active[action_id].action_bitmap
765 & acl_action_conntrack) {
767 /* Set conntrack bit for this pkt */
768 conntrack_mask |= pkt_mask;
770 printf("ACL Conntrack enabled: "
771 " %p pkt_mask: %p\n",
772 (void *)conntrack_mask,
776 if (action_array_active[action_id].action_bitmap
777 & acl_action_connexist) {
779 /* Set conntrack bit for this pkt */
780 conntrack_mask |= pkt_mask;
782 /* Set connexist bit for this pkt for public -> private */
783 /* Private -> public packet will open the connection */
784 if (action_array_active
785 [action_id].private_public ==
787 connexist_mask |= pkt_mask;
790 printf("ACL Connexist enabled "
791 "conntrack: %p connexist: %p pkt_mask: %p\n",
792 (void *)conntrack_mask,
793 (void *)connexist_mask,
800 /* Only call connection tracker if required */
801 if (conntrack_mask > 0) {
804 ("ACL Call Conntrack Before = %p Connexist = %p\n",
805 (void *)conntrack_mask, (void *)connexist_mask);
807 rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
808 (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
810 printf("ACL Call Conntrack After = %p\n",
811 (void *)conntrack_mask);
813 /* Only change pkt mask for pkts that have conntrack enabled */
814 /* Need to loop through packets to check if conntrack enabled */
815 pkts_to_process = pkts_mask;
816 for (; pkts_to_process;) {
817 uint32_t action_id = 0;
819 (uint8_t) __builtin_ctzll(pkts_to_process);
820 uint64_t pkt_mask = 1LLU << pos;
821 /* bitmask representing only this packet */
823 pkts_to_process &= ~pkt_mask;
824 /* remove this packet from remaining list */
825 struct rte_mbuf *pkt = pkts[pos];
827 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
832 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
833 if (hdr_chk == IPv4_HDR_VERSION) {
834 struct acl_table_entry *entry =
835 (struct acl_table_entry *)
836 p_acl->acl_entries_ipv4[pos];
837 action_id = entry->action_id;
839 struct acl_table_entry *entry =
840 (struct acl_table_entry *)
841 p_acl->acl_entries_ipv6[pos];
842 action_id = entry->action_id;
845 if ((action_array_active[action_id].action_bitmap &
846 acl_action_conntrack)
847 || (action_array_active[action_id].action_bitmap &
848 acl_action_connexist)) {
850 if (conntrack_mask & pkt_mask) {
852 printf("ACL Conntrack Accept "
856 /* Drop packet by changing the mask */
858 printf("ACL Conntrack Drop "
861 pkts_mask &= ~pkt_mask;
862 p_acl->counters->pkts_drop++;
868 pkts_to_process = pkts_mask;
869 /* bitmap of packets left to process for ARP */
871 for (; pkts_to_process;) {
872 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
873 uint64_t pkt_mask = 1LLU << pos;
874 /* bitmask representing only this packet */
876 pkts_to_process &= ~pkt_mask;
877 /* remove this packet from remaining list */
878 struct rte_mbuf *pkt = pkts[pos];
881 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
882 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
884 if (hdr_chk == IPv4_HDR_VERSION) {
886 struct acl_table_entry *entry =
887 (struct acl_table_entry *)
888 p_acl->acl_entries_ipv4[pos];
889 uint16_t phy_port = pkt->port;
890 uint32_t *port_out_id =
891 RTE_MBUF_METADATA_UINT32_PTR(pkt,
898 ("phy_port = %i, links_map[phy_port] = %i\n",
899 phy_port, p_acl->links_map[phy_port]);
901 /* header room + eth hdr size + dst_adr offset in ip header */
902 uint32_t dst_addr_offset =
903 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
905 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
907 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
909 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
910 struct ether_addr hw_addr;
911 uint32_t dest_address = rte_bswap32(*dst_addr);
912 uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
919 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
921 if (is_phy_port_privte(phy_port)) {
922 dest_address = rte_bswap32(*dst_addr);
924 local_get_nh_ipv4(dest_address, &dest_if,
928 get_prv_to_pub_port(&dest_address,
930 do_local_nh_ipv4_cache(dest_if, p_acl);
932 *port_out_id = p_acl->port_out_id[dest_if];
934 dest_address = rte_bswap32(*dst_addr);
936 ret = local_get_nh_ipv4(dest_address, &dest_if,
940 get_pub_to_prv_port(&dest_address,
942 do_local_nh_ipv4_cache(dest_if, p_acl);
944 *port_out_id = p_acl->port_out_id[dest_if];
946 /* port = ACL_PRV_PORT_ID; */
950 ret_mac = get_dest_mac_addr_port
951 (dest_address, &dest_if, &hw_addr);
952 if (ret_mac == ARP_FOUND) {
954 printf("MAC found for ip 0x%x, "
955 "port %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
956 dest_address, phy_port,
957 hw_addr.addr_bytes[0],
958 hw_addr.addr_bytes[1],
959 hw_addr.addr_bytes[2],
960 hw_addr.addr_bytes[3],
961 hw_addr.addr_bytes[4],
962 hw_addr.addr_bytes[5]);
963 printf("Dest MAC before - "
964 "%02x:%02x:%02x:%02x:%02x:%02x\n",
965 eth_dest[0], eth_dest[1],
966 eth_dest[2], eth_dest[3],
967 eth_dest[4], eth_dest[5]);
970 memcpy(eth_dest, &hw_addr,
971 sizeof(struct ether_addr));
973 printf("PktP %p, dest_macP %p\n", pkt,
975 printf("Dest MAC after - "
976 "%02x:%02x:%02x:%02x:%02x:%02x\n",
977 eth_dest[0], eth_dest[1],
978 eth_dest[2], eth_dest[3],
979 eth_dest[4], eth_dest[5]);
981 if (is_phy_port_privte(phy_port))
983 get_link_hw_addr(dest_if),
984 sizeof(struct ether_addr));
987 get_link_hw_addr(dest_if),
988 sizeof(struct ether_addr));
989 p_acl->counters->tpkts_processed++;
990 p_acl->counters->bytes_processed +=
997 printf("ACL requesting ARP for "
999 dest_address, phy_port);
1000 if (ret_mac == ARP_NOT_FOUND)
1001 request_arp(dest_if, *nhip);
1003 /* request_arp(p_acl->links_map[phy_port], *nhip); */
1005 /* Drop packet by changing the mask */
1007 printf("ACL before drop pkt_mask "
1008 "%lu, pkt_num %d\n",
1010 pkts_mask &= ~(1LLU << pos);
1012 printf("ACL after drop pkt_mask "
1013 "%lu, pkt_num %d\n",
1015 p_acl->counters->pkts_drop++;
1019 if (hdr_chk == IPv6_HDR_VERSION) {
1021 struct acl_table_entry *entry =
1022 (struct acl_table_entry *)
1023 p_acl->acl_entries_ipv6[pos];
1024 //uint16_t phy_port = entry->head.port_id;
1025 uint16_t phy_port = pkt->port;
1026 uint32_t *port_out_id =
1027 RTE_MBUF_METADATA_UINT32_PTR(pkt,
1032 /*if (is_phy_port_privte(phy_port))
1033 *port_out_id = ACL_PUB_PORT_ID;
1035 *port_out_id = ACL_PRV_PORT_ID;*/
1037 /* *port_out_id = p_acl->links_map[phy_port]; */
1039 printf("phy_port = %i, "
1040 "links_map[phy_port] = %i\n",
1041 phy_port, p_acl->links_map[phy_port]);
1043 /* header room + eth hdr size + dst_adr offset in ip header */
1044 uint32_t dst_addr_offset =
1045 MBUF_HDR_ROOM + ETH_HDR_SIZE +
1046 IP_HDR_DST_ADR_OFST_IPV6;
1048 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
1050 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
1051 struct ether_addr hw_addr;
1052 uint8_t dest_address[16];
1056 RTE_MBUF_METADATA_UINT8(pkt,
1061 uint8_t *dst_addr[16];
1062 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
1065 for (i = 0; i < 16; i++) {
1067 RTE_MBUF_METADATA_UINT8_PTR(pkt,
1071 memcpy(dest_address, *dst_addr, sizeof(dest_address));
1072 memset(nhip, 0, sizeof(nhip));
1073 ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
1076 if (is_phy_port_privte(phy_port)) {
1078 dest_if = get_prv_to_pub_port((
1081 &dest_address[0], IP_VERSION_6);
1082 do_local_nh_ipv6_cache(dest_if, p_acl);
1084 p_acl->port_out_id[dest_if];
1086 // port = ACL_PUB_PORT_ID;
1090 dest_if = get_pub_to_prv_port((
1093 &dest_address[0], IP_VERSION_6);
1094 do_local_nh_ipv6_cache(dest_if, p_acl);
1096 p_acl->port_out_id[dest_if];
1098 // port = ACL_PRV_PORT_ID;
1102 if (get_dest_mac_address_ipv6_port
1103 (dest_address, &dest_if, &hw_addr, &nhip[0])) {
1105 printf("MAC found for port %d - "
1106 " %02x:%02x:%02x:%02x:%02x:%02x\n",
1107 phy_port, hw_addr.addr_bytes[0],
1108 hw_addr.addr_bytes[1],
1109 hw_addr.addr_bytes[2],
1110 hw_addr.addr_bytes[3],
1111 hw_addr.addr_bytes[4],
1112 hw_addr.addr_bytes[5]);
1113 printf("Dest MAC before - "
1114 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1115 eth_dest[0], eth_dest[1],
1116 eth_dest[2], eth_dest[3],
1117 eth_dest[4], eth_dest[5]);
1119 memcpy(eth_dest, &hw_addr,
1120 sizeof(struct ether_addr));
1122 printf("PktP %p, dest_macP %p\n", pkt,
1124 printf("Dest MAC after - "
1125 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1126 eth_dest[0], eth_dest[1],
1127 eth_dest[2], eth_dest[3],
1128 eth_dest[4], eth_dest[5]);
1130 if (is_phy_port_privte(phy_port))
1132 get_link_hw_addr(dest_if),
1133 sizeof(struct ether_addr));
1136 get_link_hw_addr(dest_if),
1137 sizeof(struct ether_addr));
1139 /* memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]), */
1140 /* sizeof(struct ether_addr)); */
1141 p_acl->counters->tpkts_processed++;
1142 p_acl->counters->bytes_processed +=
1149 /* Request next neighbor for Ipv6 is yet to be done. */
1153 ("ACL requesting ARP for ip %x, port %d\n",
1154 dest_address, phy_port);
1156 /* request_arp(p_acl->links_map[phy_port], *nhip); */
1159 /* Drop packet by changing the mask */
1161 printf("ACL before drop pkt_mask "
1162 "%lu, pkt_num %d\n",
1164 pkts_mask &= ~(1LLU << pos);
1166 printf("ACL after drop pkt_mask "
1167 "%lu, pkt_num %d\n",
1169 p_acl->counters->pkts_drop++;
1175 pkts_drop_mask = keep_mask & ~pkts_mask;
1176 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
1177 keep_mask = pkts_mask;
1179 /* don't bother measuring if traffic very low, might skew stats */
1180 uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
1182 if (packets_this_iteration > 1) {
1183 uint64_t latency_this_iteration =
1184 rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
1186 p_acl->counters->sum_latencies += latency_this_iteration;
1187 p_acl->counters->count_latencies++;
1191 printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
1198 * Main packet processing function.
1199 * 64 packet bit mask are used to identify which packets to forward.
1200 * Performs the following:
1201 * - Burst lookup packets in the IPv4 ACL Rule Table.
1202 * - Burst lookup packets in the IPv6 ACL Rule Table.
1203 * - Lookup Action Table, perform actions.
1204 * - Burst lookup Connection Tracking, if enabled.
1205 * - Lookup MAC address.
1207 * - Packets with bit mask set are forwarded
1210 * A pointer to the pipeline.
1212 * A pointer to a burst of packets.
1214 * Number of packets to process.
1216 * A pointer to pipeline specific data.
1219 * 0 on success, negative on error.
1222 pkt_work_acl_ipv4_key(struct rte_pipeline *p,
1223 struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
1226 struct pipeline_acl *p_acl = arg;
1228 p_acl->counters->pkts_received =
1229 p_acl->counters->pkts_received + n_pkts;
1231 printf("pkt_work_acl_key pkts_received: %" PRIu64
1232 " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
1234 uint64_t lookup_hit_mask = 0;
1235 uint64_t lookup_hit_mask_ipv4 = 0;
1236 uint64_t lookup_hit_mask_ipv6 = 0;
1237 uint64_t lookup_miss_mask = 0;
1238 uint64_t conntrack_mask = 0;
1239 uint64_t connexist_mask = 0;
1240 uint32_t dest_address = 0;
1243 uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
1244 uint64_t keep_mask = pkts_mask;
1248 p_acl->in_port_time_stamp = rte_get_tsc_cycles();
1250 if (acl_ipv4_enabled) {
1252 printf("ACL IPV4 Lookup Mask Before = %p\n",
1255 rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
1256 pkts_mask, &lookup_hit_mask_ipv4,
1258 p_acl->acl_entries_ipv4);
1260 printf("ACL IPV4 Lookup Mask After = %p\n",
1261 (void *)lookup_hit_mask_ipv4);
1264 /* Merge lookup results since we process both IPv4 and IPv6 below */
1265 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
1267 printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
1269 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
1270 pkts_mask = lookup_hit_mask;
1271 p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
1273 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
1274 p_acl->counters->pkts_drop,
1275 __builtin_popcountll(lookup_miss_mask));
1277 uint64_t pkts_to_process = lookup_hit_mask;
1278 /* bitmap of packets left to process for ARP */
1280 for (; pkts_to_process;) {
1281 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
1282 uint64_t pkt_mask = 1LLU << pos;
1283 /* bitmask representing only this packet */
1285 pkts_to_process &= ~pkt_mask;
1286 /* remove this packet from remaining list */
1287 struct rte_mbuf *pkt = pkts[pos];
1290 if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
1291 pkts_mask &= ~(1LLU << pos);
1296 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
1297 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1299 if (hdr_chk == IPv4_HDR_VERSION) {
1300 struct acl_table_entry *entry =
1301 (struct acl_table_entry *)
1302 p_acl->acl_entries_ipv4[pos];
1303 uint16_t phy_port = entry->head.port_id;
1304 uint32_t action_id = entry->action_id;
1307 printf("action_id = %u\n", action_id);
1309 uint32_t dscp_offset =
1310 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
1312 if (action_array_active[action_id].action_bitmap &
1314 action_counter_table
1315 [p_acl->action_counter_index]
1316 [action_id].packetCount++;
1317 action_counter_table
1318 [p_acl->action_counter_index]
1319 [action_id].byteCount +=
1320 rte_pktmbuf_pkt_len(pkt);
1322 printf("Action Count Packet Count: %"
1323 PRIu64 " Byte Count: %" PRIu64
1325 action_counter_table
1326 [p_acl->action_counter_index]
1327 [action_id].packetCount,
1328 action_counter_table
1329 [p_acl->action_counter_index]
1330 [action_id].byteCount);
1333 if (action_array_active[action_id].action_bitmap &
1334 acl_action_packet_drop) {
1336 /* Drop packet by changing the mask */
1338 printf("ACL before drop pkt_mask "
1339 "%lu, pkt_num %d\n",
1341 pkts_mask &= ~(1LLU << pos);
1343 printf("ACL after drop pkt_mask "
1344 " %lu, pkt_num %d\n",
1346 p_acl->counters->pkts_drop++;
1349 if (action_array_active[action_id].action_bitmap &
1352 action_array_active[action_id].fwd_port;
1353 entry->head.port_id = phy_port;
1355 printf("Action FWD Port ID: %u\n",
1359 if (action_array_active[action_id].action_bitmap &
1362 action_array_active[action_id].nat_port;
1363 entry->head.port_id = phy_port;
1365 printf("Action NAT Port ID: %u\n",
1369 if (action_array_active[action_id].action_bitmap &
1372 /* Set DSCP priority */
1373 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
1376 action_array_active[action_id].dscp_priority
1380 ("Action DSCP DSCP Priority: %u\n",
1384 if (action_array_active[action_id].action_bitmap &
1385 acl_action_packet_accept) {
1387 printf("Action Accept\n");
1389 if (action_array_active[action_id].action_bitmap
1390 & acl_action_conntrack) {
1392 /* Set conntrack bit for this pkt */
1393 conntrack_mask |= pkt_mask;
1395 printf("ACL Conntrack "
1396 "enabled: %p pkt_mask: %p\n",
1397 (void *)conntrack_mask,
1401 if (action_array_active[action_id].action_bitmap
1402 & acl_action_connexist) {
1404 /* Set conntrack bit for this pkt */
1405 conntrack_mask |= pkt_mask;
1407 /* Set connexist bit for this pkt for public -> private */
1408 /* Private -> public packet will open the connection */
1409 if (action_array_active
1410 [action_id].private_public ==
1412 connexist_mask |= pkt_mask;
1415 printf("ACL Connexist "
1416 "enabled conntrack: %p connexist: %p pkt_mask: %p\n",
1417 (void *)conntrack_mask,
1418 (void *)connexist_mask,
1424 if (hdr_chk == IPv6_HDR_VERSION) {
1426 struct acl_table_entry *entry =
1427 (struct acl_table_entry *)
1428 p_acl->acl_entries_ipv6[pos];
1429 uint16_t phy_port = entry->head.port_id;
1430 uint32_t action_id = entry->action_id;
1433 printf("action_id = %u\n", action_id);
1435 if (action_array_active[action_id].action_bitmap &
1437 action_counter_table
1438 [p_acl->action_counter_index]
1439 [action_id].packetCount++;
1440 action_counter_table
1441 [p_acl->action_counter_index]
1442 [action_id].byteCount +=
1443 rte_pktmbuf_pkt_len(pkt);
1445 printf("Action Count Packet Count: %"
1446 PRIu64 " Byte Count: %" PRIu64
1448 action_counter_table
1449 [p_acl->action_counter_index]
1450 [action_id].packetCount,
1451 action_counter_table
1452 [p_acl->action_counter_index]
1453 [action_id].byteCount);
1456 if (action_array_active[action_id].action_bitmap &
1457 acl_action_packet_drop) {
1458 /* Drop packet by changing the mask */
1461 ("ACL before drop pkt_mask %lu, pkt_num %d\n",
1463 pkts_mask &= ~(1LLU << pos);
1466 ("ACL after drop pkt_mask %lu, pkt_num %d\n",
1468 p_acl->counters->pkts_drop++;
1472 if (action_array_active[action_id].action_bitmap &
1475 action_array_active[action_id].fwd_port;
1476 entry->head.port_id = phy_port;
1478 printf("Action FWD Port ID: %u\n",
1482 if (action_array_active[action_id].action_bitmap &
1485 action_array_active[action_id].nat_port;
1486 entry->head.port_id = phy_port;
1488 printf("Action NAT Port ID: %u\n",
1492 if (action_array_active[action_id].action_bitmap &
1495 /* Set DSCP priority */
1496 uint32_t dscp_offset =
1497 MBUF_HDR_ROOM + ETH_HDR_SIZE +
1498 IP_HDR_DSCP_OFST_IPV6;
1500 RTE_MBUF_METADATA_UINT16_PTR(pkt,
1502 uint16_t dscp_value =
1504 (RTE_MBUF_METADATA_UINT16
1505 (pkt, dscp_offset)) & 0XF00F);
1506 uint8_t dscp_store =
1507 action_array_active[action_id].dscp_priority
1509 uint16_t dscp_temp = dscp_store;
1511 dscp_temp = dscp_temp << 4;
1512 *dscp = rte_bswap16(dscp_temp | dscp_value);
1515 ("Action DSCP DSCP Priority: %u\n",
1519 if (action_array_active[action_id].action_bitmap &
1520 acl_action_packet_accept) {
1522 printf("Action Accept\n");
1524 if (action_array_active[action_id].action_bitmap
1525 & acl_action_conntrack) {
1527 /* Set conntrack bit for this pkt */
1528 conntrack_mask |= pkt_mask;
1530 printf("ACL Conntrack "
1531 "enabled: %p pkt_mask: %p\n",
1532 (void *)conntrack_mask,
1536 if (action_array_active[action_id].action_bitmap
1537 & acl_action_connexist) {
1539 /* Set conntrack bit for this pkt */
1540 conntrack_mask |= pkt_mask;
1542 /* Set connexist bit for this pkt for public -> private */
1543 /* Private -> public packet will open the connection */
1544 if (action_array_active
1545 [action_id].private_public ==
1547 connexist_mask |= pkt_mask;
1550 printf("ACL Connexist enabled "
1551 "conntrack: %p connexist: %p pkt_mask: %p\n",
1552 (void *)conntrack_mask,
1553 (void *)connexist_mask,
1560 /* Only call connection tracker if required */
1561 if (conntrack_mask > 0) {
1564 ("ACL Call Conntrack Before = %p Connexist = %p\n",
1565 (void *)conntrack_mask, (void *)connexist_mask);
1567 rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
1568 (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
1570 printf("ACL Call Conntrack After = %p\n",
1571 (void *)conntrack_mask);
1573 /* Only change pkt mask for pkts that have conntrack enabled */
1574 /* Need to loop through packets to check if conntrack enabled */
1575 pkts_to_process = pkts_mask;
1576 for (; pkts_to_process;) {
1577 uint32_t action_id = 0;
1579 (uint8_t) __builtin_ctzll(pkts_to_process);
1580 uint64_t pkt_mask = 1LLU << pos;
1581 /* bitmask representing only this packet */
1583 pkts_to_process &= ~pkt_mask;
1584 /* remove this packet from remaining list */
1585 struct rte_mbuf *pkt = pkts[pos];
1587 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
1591 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1592 if (hdr_chk == IPv4_HDR_VERSION) {
1593 struct acl_table_entry *entry =
1594 (struct acl_table_entry *)
1595 p_acl->acl_entries_ipv4[pos];
1596 action_id = entry->action_id;
1598 struct acl_table_entry *entry =
1599 (struct acl_table_entry *)
1600 p_acl->acl_entries_ipv6[pos];
1601 action_id = entry->action_id;
1604 if ((action_array_active[action_id].action_bitmap &
1605 acl_action_conntrack)
1606 || (action_array_active[action_id].action_bitmap &
1607 acl_action_connexist)) {
1609 if (conntrack_mask & pkt_mask) {
1611 printf("ACL Conntrack Accept "
1615 /* Drop packet by changing the mask */
1617 printf("ACL Conntrack Drop "
1620 pkts_mask &= ~pkt_mask;
1621 p_acl->counters->pkts_drop++;
1627 pkts_to_process = pkts_mask;
1628 /* bitmap of packets left to process for ARP */
1630 for (; pkts_to_process;) {
1631 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
1632 uint64_t pkt_mask = 1LLU << pos;
1633 /* bitmask representing only this packet */
1635 pkts_to_process &= ~pkt_mask;
1636 /* remove this packet from remaining list */
1637 struct rte_mbuf *pkt = pkts[pos];
1640 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
1641 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1643 if (hdr_chk == IPv4_HDR_VERSION) {
1645 struct acl_table_entry *entry =
1646 (struct acl_table_entry *)
1647 p_acl->acl_entries_ipv4[pos];
1648 //uint16_t phy_port = entry->head.port_id;
1649 uint16_t phy_port = pkt->port;
1650 uint32_t *port_out_id =
1651 RTE_MBUF_METADATA_UINT32_PTR(pkt,
1656 /* *port_out_id = p_acl->links_map[phy_port]; */
1657 /* if (is_phy_port_privte(phy_port))
1658 *port_out_id = ACL_PUB_PORT_ID;
1660 *port_out_id = ACL_PRV_PORT_ID;*/
1663 ("phy_port = %i, links_map[phy_port] = %i\n",
1664 phy_port, p_acl->links_map[phy_port]);
1666 /* header room + eth hdr size + dst_adr offset in ip header */
1667 uint32_t dst_addr_offset =
1668 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
1669 uint32_t *dst_addr =
1670 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
1672 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
1674 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
1675 struct ether_addr hw_addr;
1676 uint32_t dest_address = rte_bswap32(*dst_addr);
1677 uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
1684 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
1686 if (is_phy_port_privte(phy_port)) {
1687 dest_address = rte_bswap32(*dst_addr);
1689 local_get_nh_ipv4(dest_address, &dest_if,
1693 get_prv_to_pub_port(&dest_address,
1695 do_local_nh_ipv4_cache(dest_if, p_acl);
1697 *port_out_id = p_acl->port_out_id[dest_if];
1699 /* port = ACL_PUB_PORT_ID; */
1701 dest_address = rte_bswap32(*dst_addr);
1703 ret = local_get_nh_ipv4(dest_address, &dest_if,
1707 get_pub_to_prv_port(&dest_address,
1709 do_local_nh_ipv4_cache(dest_if, p_acl);
1711 *port_out_id = p_acl->port_out_id[dest_if];
1713 /* port = ACL_PRV_PORT_ID; */
1716 ret_mac = get_dest_mac_addr_port
1717 (dest_address, &dest_if, &hw_addr);
1719 if (ret_mac == ARP_FOUND) {
1721 printf("MAC found for ip 0x%x, port "
1722 "%d - %02x:%02x:%02x:%02x:%02x:%02x\n",
1723 dest_address, phy_port,
1724 hw_addr.addr_bytes[0],
1725 hw_addr.addr_bytes[1],
1726 hw_addr.addr_bytes[2],
1727 hw_addr.addr_bytes[3],
1728 hw_addr.addr_bytes[4],
1729 hw_addr.addr_bytes[5]);
1730 printf("Dest MAC before - "
1731 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1732 eth_dest[0], eth_dest[1],
1733 eth_dest[2], eth_dest[3],
1734 eth_dest[4], eth_dest[5]);
1737 memcpy(eth_dest, &hw_addr,
1738 sizeof(struct ether_addr));
1740 printf("PktP %p, dest_macP %p\n", pkt,
1742 printf("Dest MAC after - "
1743 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1744 eth_dest[0], eth_dest[1],
1745 eth_dest[2], eth_dest[3],
1746 eth_dest[4], eth_dest[5]);
1748 if (is_phy_port_privte(phy_port))
1750 get_link_hw_addr(dest_if),
1751 sizeof(struct ether_addr));
1754 get_link_hw_addr(dest_if),
1755 sizeof(struct ether_addr));
1756 p_acl->counters->tpkts_processed++;
1757 p_acl->counters->bytes_processed +=
1764 printf("ACL requesting ARP for "
1766 dest_address, phy_port);
1767 if (ret_mac == ARP_NOT_FOUND)
1768 request_arp(dest_if, *nhip);
1770 /* request_arp(p_acl->links_map[phy_port], *nhip); */
1772 /* Drop packet by changing the mask */
1775 ("ACL before drop pkt_mask "
1776 "%lu, pkt_num %d\n",
1778 pkts_mask &= ~(1LLU << pos);
1780 printf("ACL after drop pkt_mask "
1781 "%lu, pkt_num %d\n",
1783 p_acl->counters->pkts_drop++;
1787 if (hdr_chk == IPv6_HDR_VERSION) {
1789 struct acl_table_entry *entry =
1790 (struct acl_table_entry *)
1791 p_acl->acl_entries_ipv6[pos];
1792 uint16_t phy_port = entry->head.port_id;
1793 uint32_t *port_out_id =
1794 RTE_MBUF_METADATA_UINT32_PTR(pkt,
1799 if (is_phy_port_privte(phy_port))
1800 *port_out_id = ACL_PUB_PORT_ID;
1802 *port_out_id = ACL_PRV_PORT_ID;
1804 /* *port_out_id = p_acl->links_map[phy_port]; */
1807 ("phy_port = %i, links_map[phy_port] = %i\n",
1808 phy_port, p_acl->links_map[phy_port]);
1810 /* header room + eth hdr size + dst_adr offset in ip header */
1811 uint32_t dst_addr_offset =
1812 MBUF_HDR_ROOM + ETH_HDR_SIZE +
1813 IP_HDR_DST_ADR_OFST_IPV6;
1815 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
1817 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
1818 struct ether_addr hw_addr;
1819 uint8_t dest_address[16];
1823 RTE_MBUF_METADATA_UINT8(pkt,
1828 uint8_t *dst_addr[16];
1829 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
1832 for (i = 0; i < 16; i++) {
1834 RTE_MBUF_METADATA_UINT8_PTR(pkt,
1838 memcpy(dest_address, *dst_addr, sizeof(dest_address));
1839 memset(nhip, 0, sizeof(nhip));
1840 if (is_phy_port_privte(phy_port))
1841 port = ACL_PUB_PORT_ID;
1843 port = ACL_PRV_PORT_ID;
1845 if (get_dest_mac_address_ipv6_port
1846 (dest_address, port, &hw_addr, &nhip[0])) {
1850 ("MAC found for port %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
1851 phy_port, hw_addr.addr_bytes[0],
1852 hw_addr.addr_bytes[1],
1853 hw_addr.addr_bytes[2],
1854 hw_addr.addr_bytes[3],
1855 hw_addr.addr_bytes[4],
1856 hw_addr.addr_bytes[5]);
1858 ("Dest MAC before - %02x:%02x:%02x:%02x:%02x:%02x\n",
1859 eth_dest[0], eth_dest[1],
1860 eth_dest[2], eth_dest[3],
1861 eth_dest[4], eth_dest[5]);
1863 memcpy(eth_dest, &hw_addr,
1864 sizeof(struct ether_addr));
1866 printf("PktP %p, dest_macP %p\n", pkt,
1869 ("Dest MAC after - %02x:%02x:%02x:%02x:%02x:%02x\n",
1870 eth_dest[0], eth_dest[1],
1871 eth_dest[2], eth_dest[3],
1872 eth_dest[4], eth_dest[5]);
1874 if (is_phy_port_privte(phy_port))
1876 get_link_hw_addr(dest_if),
1877 sizeof(struct ether_addr));
1880 get_link_hw_addr(dest_if),
1881 sizeof(struct ether_addr));
1884 * memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]),
1885 * sizeof(struct ether_addr));
1887 p_acl->counters->tpkts_processed++;
1888 p_acl->counters->bytes_processed +=
1895 /* Request next neighbor for Ipv6 is yet to be done. */
1899 ("ACL requesting ARP for ip %x, port %d\n",
1900 dest_address, phy_port);
1902 /* request_arp(p_acl->links_map[phy_port], *nhip); */
1905 /* Drop packet by changing the mask */
1907 printf("ACL before drop pkt_mask "
1908 " %lu, pkt_num %d\n",
1910 pkts_mask &= ~(1LLU << pos);
1912 printf("ACL after drop pkt_mask "
1913 "%lu, pkt_num %d\n",
1915 p_acl->counters->pkts_drop++;
1922 pkts_drop_mask = keep_mask & ~pkts_mask;
1923 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
1924 keep_mask = pkts_mask;
1926 /* don't bother measuring if traffic very low, might skew stats */
1927 uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
1929 if (packets_this_iteration > 1) {
1930 uint64_t latency_this_iteration =
1931 rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
1932 p_acl->counters->sum_latencies += latency_this_iteration;
1933 p_acl->counters->count_latencies++;
1936 printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
1943 * Main packet processing function.
1944 * 64 packet bit mask are used to identify which packets to forward.
1945 * Performs the following:
1946 * - Burst lookup packets in the IPv4 ACL Rule Table.
1947 * - Burst lookup packets in the IPv6 ACL Rule Table.
1948 * - Lookup Action Table, perform actions.
1949 * - Burst lookup Connection Tracking, if enabled.
1950 * - Lookup MAC address.
1952 * - Packets with bit mask set are forwarded
1955 * A pointer to the pipeline.
1957 * A pointer to a burst of packets.
1959 * Number of packets to process.
1961 * A pointer to pipeline specific data.
1964 * 0 on success, negative on error.
1967 pkt_work_acl_ipv6_key(struct rte_pipeline *p,
1968 struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
1971 struct pipeline_acl *p_acl = arg;
1973 p_acl->counters->pkts_received =
1974 p_acl->counters->pkts_received + n_pkts;
1976 printf("pkt_work_acl_key pkts_received: %" PRIu64
1977 " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
1979 uint64_t lookup_hit_mask = 0;
1980 uint64_t lookup_hit_mask_ipv4 = 0;
1981 uint64_t lookup_hit_mask_ipv6 = 0;
1982 uint64_t lookup_miss_mask = 0;
1983 uint64_t conntrack_mask = 0;
1984 uint64_t connexist_mask = 0;
1985 uint32_t dest_address = 0;
1988 uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
1989 uint64_t keep_mask = pkts_mask;
1993 p_acl->in_port_time_stamp = rte_get_tsc_cycles();
1995 if (acl_ipv6_enabled) {
1997 printf("ACL IPV6 Lookup Mask Before = %p\n",
2000 rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
2001 pkts_mask, &lookup_hit_mask_ipv6,
2003 p_acl->acl_entries_ipv6);
2005 printf("ACL IPV6 Lookup Mask After = %p\n",
2006 (void *)lookup_hit_mask_ipv6);
2009 /* Merge lookup results since we process both IPv4 and IPv6 below */
2010 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
2012 printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
2014 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
2015 pkts_mask = lookup_hit_mask;
2016 p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
2018 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
2019 p_acl->counters->pkts_drop,
2020 __builtin_popcountll(lookup_miss_mask));
2022 uint64_t pkts_to_process = lookup_hit_mask;
2023 /* bitmap of packets left to process for ARP */
2025 for (; pkts_to_process;) {
2026 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
2027 uint64_t pkt_mask = 1LLU << pos;
2028 /* bitmask representing only this packet */
2030 pkts_to_process &= ~pkt_mask;
2031 /* remove this packet from remaining list */
2032 struct rte_mbuf *pkt = pkts[pos];
2035 if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
2036 pkts_mask &= ~(1LLU << pos);
2040 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
2041 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
2043 if (hdr_chk == IPv4_HDR_VERSION) {
2044 struct acl_table_entry *entry =
2045 (struct acl_table_entry *)
2046 p_acl->acl_entries_ipv4[pos];
2047 uint16_t phy_port = entry->head.port_id;
2048 uint32_t action_id = entry->action_id;
2051 printf("action_id = %u\n", action_id);
2053 uint32_t dscp_offset =
2054 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
2056 if (action_array_active[action_id].action_bitmap &
2058 action_counter_table
2059 [p_acl->action_counter_index]
2060 [action_id].packetCount++;
2061 action_counter_table
2062 [p_acl->action_counter_index]
2063 [action_id].byteCount +=
2064 rte_pktmbuf_pkt_len(pkt);
2066 printf("Action Count Packet Count: %"
2067 PRIu64 " Byte Count: %" PRIu64
2069 action_counter_table
2070 [p_acl->action_counter_index]
2071 [action_id].packetCount,
2072 action_counter_table
2073 [p_acl->action_counter_index]
2074 [action_id].byteCount);
2077 if (action_array_active[action_id].action_bitmap &
2078 acl_action_packet_drop) {
2080 /* Drop packet by changing the mask */
2083 ("ACL before drop pkt_mask %lu, pkt_num %d\n",
2085 pkts_mask &= ~(1LLU << pos);
2088 ("ACL after drop pkt_mask %lu, pkt_num %d\n",
2090 p_acl->counters->pkts_drop++;
2093 if (action_array_active[action_id].action_bitmap &
2096 action_array_active[action_id].fwd_port;
2097 entry->head.port_id = phy_port;
2099 printf("Action FWD Port ID: %u\n",
2103 if (action_array_active[action_id].action_bitmap &
2106 action_array_active[action_id].nat_port;
2107 entry->head.port_id = phy_port;
2109 printf("Action NAT Port ID: %u\n",
2113 if (action_array_active[action_id].action_bitmap &
2116 /* Set DSCP priority */
2117 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
2120 action_array_active[action_id].dscp_priority
2124 ("Action DSCP DSCP Priority: %u\n",
2128 if (action_array_active[action_id].action_bitmap &
2129 acl_action_packet_accept) {
2131 printf("Action Accept\n");
2133 if (action_array_active[action_id].action_bitmap
2134 & acl_action_conntrack) {
2136 /* Set conntrack bit for this pkt */
2137 conntrack_mask |= pkt_mask;
2139 printf("ACL Conntrack enabled: "
2140 " %p pkt_mask: %p\n",
2141 (void *)conntrack_mask,
2145 if (action_array_active[action_id].action_bitmap
2146 & acl_action_connexist) {
2148 /* Set conntrack bit for this pkt */
2149 conntrack_mask |= pkt_mask;
2151 /* Set connexist bit for this pkt for public -> private */
2152 /* Private -> public packet will open the connection */
2153 if (action_array_active
2154 [action_id].private_public ==
2156 connexist_mask |= pkt_mask;
2159 printf("ACL Connexist enabled "
2160 "conntrack: %p connexist: %p pkt_mask: %p\n",
2161 (void *)conntrack_mask,
2162 (void *)connexist_mask,
2169 if (hdr_chk == IPv6_HDR_VERSION) {
2171 struct acl_table_entry *entry =
2172 (struct acl_table_entry *)
2173 p_acl->acl_entries_ipv6[pos];
2174 uint16_t phy_port = entry->head.port_id;
2175 uint32_t action_id = entry->action_id;
2178 printf("action_id = %u\n", action_id);
2180 if (action_array_active[action_id].action_bitmap &
2182 action_counter_table
2183 [p_acl->action_counter_index]
2184 [action_id].packetCount++;
2185 action_counter_table
2186 [p_acl->action_counter_index]
2187 [action_id].byteCount +=
2188 rte_pktmbuf_pkt_len(pkt);
2190 printf("Action Count Packet Count: %"
2191 PRIu64 " Byte Count: %" PRIu64
2193 action_counter_table
2194 [p_acl->action_counter_index]
2195 [action_id].packetCount,
2196 action_counter_table
2197 [p_acl->action_counter_index]
2198 [action_id].byteCount);
2201 if (action_array_active[action_id].action_bitmap &
2202 acl_action_packet_drop) {
2203 /* Drop packet by changing the mask */
2205 printf("ACL before drop pkt_mask "
2206 "%lu, pkt_num %d\n",
2208 pkts_mask &= ~(1LLU << pos);
2210 printf("ACL after drop pkt_mask "
2211 "%lu, pkt_num %d\n",
2213 p_acl->counters->pkts_drop++;
2217 if (action_array_active[action_id].action_bitmap &
2220 action_array_active[action_id].fwd_port;
2221 entry->head.port_id = phy_port;
2223 printf("Action FWD Port ID: %u\n",
2227 if (action_array_active[action_id].action_bitmap &
2230 action_array_active[action_id].nat_port;
2231 entry->head.port_id = phy_port;
2233 printf("Action NAT Port ID: %u\n",
2237 if (action_array_active[action_id].action_bitmap &
2240 /* Set DSCP priority */
2241 uint32_t dscp_offset =
2242 MBUF_HDR_ROOM + ETH_HDR_SIZE +
2243 IP_HDR_DSCP_OFST_IPV6;
2245 RTE_MBUF_METADATA_UINT16_PTR(pkt,
2247 uint16_t dscp_value =
2249 (RTE_MBUF_METADATA_UINT16
2250 (pkt, dscp_offset)) & 0XF00F);
2251 uint8_t dscp_store =
2252 action_array_active[action_id].dscp_priority
2254 uint16_t dscp_temp = dscp_store;
2256 dscp_temp = dscp_temp << 4;
2257 *dscp = rte_bswap16(dscp_temp | dscp_value);
2260 ("Action DSCP DSCP Priority: %u\n",
2264 if (action_array_active[action_id].action_bitmap &
2265 acl_action_packet_accept) {
2267 printf("Action Accept\n");
2269 if (action_array_active[action_id].action_bitmap
2270 & acl_action_conntrack) {
2272 /* Set conntrack bit for this pkt */
2273 conntrack_mask |= pkt_mask;
2275 printf("ACL Conntrack enabled: "
2276 " %p pkt_mask: %p\n",
2277 (void *)conntrack_mask,
2281 if (action_array_active[action_id].action_bitmap
2282 & acl_action_connexist) {
2284 /* Set conntrack bit for this pkt */
2285 conntrack_mask |= pkt_mask;
2287 /* Set connexist bit for this pkt for public -> private */
2288 /* Private -> public packet will open the connection */
2289 if (action_array_active
2290 [action_id].private_public ==
2292 connexist_mask |= pkt_mask;
2295 printf("ACL Connexist enabled "
2296 "conntrack: %p connexist: %p pkt_mask: %p\n",
2297 (void *)conntrack_mask,
2298 (void *)connexist_mask,
2304 /* Only call connection tracker if required */
2305 if (conntrack_mask > 0) {
2308 ("ACL Call Conntrack Before = %p Connexist = %p\n",
2309 (void *)conntrack_mask, (void *)connexist_mask);
2311 rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
2312 (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
2314 printf("ACL Call Conntrack After = %p\n",
2315 (void *)conntrack_mask);
2317 /* Only change pkt mask for pkts that have conntrack enabled */
2318 /* Need to loop through packets to check if conntrack enabled */
2319 pkts_to_process = pkts_mask;
2320 for (; pkts_to_process;) {
2321 uint32_t action_id = 0;
2323 (uint8_t) __builtin_ctzll(pkts_to_process);
2324 uint64_t pkt_mask = 1LLU << pos;
2325 /* bitmask representing only this packet */
2327 pkts_to_process &= ~pkt_mask;
2328 /* remove this packet from remaining list */
2329 struct rte_mbuf *pkt = pkts[pos];
2331 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
2335 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
2336 if (hdr_chk == IPv4_HDR_VERSION) {
2337 struct acl_table_entry *entry =
2338 (struct acl_table_entry *)
2339 p_acl->acl_entries_ipv4[pos];
2340 action_id = entry->action_id;
2342 struct acl_table_entry *entry =
2343 (struct acl_table_entry *)
2344 p_acl->acl_entries_ipv6[pos];
2345 action_id = entry->action_id;
2348 if ((action_array_active[action_id].action_bitmap &
2349 acl_action_conntrack)
2350 || (action_array_active[action_id].action_bitmap &
2351 acl_action_connexist)) {
2353 if (conntrack_mask & pkt_mask) {
2355 printf("ACL Conntrack Accept "
2359 /* Drop packet by changing the mask */
2362 ("ACL Conntrack Drop packet = %p\n",
2364 pkts_mask &= ~pkt_mask;
2365 p_acl->counters->pkts_drop++;
2371 pkts_to_process = pkts_mask;
2372 /* bitmap of packets left to process for ARP */
2374 for (; pkts_to_process;) {
2375 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
2376 uint64_t pkt_mask = 1LLU << pos;
2377 /* bitmask representing only this packet */
2379 pkts_to_process &= ~pkt_mask;
2380 /* remove this packet from remaining list */
2381 struct rte_mbuf *pkt = pkts[pos];
2384 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
2385 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
2387 if (hdr_chk == IPv4_HDR_VERSION) {
2389 struct acl_table_entry *entry =
2390 (struct acl_table_entry *)
2391 p_acl->acl_entries_ipv4[pos];
2392 uint16_t phy_port = entry->head.port_id;
2393 uint32_t *port_out_id =
2394 RTE_MBUF_METADATA_UINT32_PTR(pkt,
2399 /* *port_out_id = p_acl->links_map[phy_port]; */
2400 if (is_phy_port_privte(phy_port))
2401 *port_out_id = ACL_PUB_PORT_ID;
2403 *port_out_id = ACL_PRV_PORT_ID;
2406 ("phy_port = %i,links_map[phy_port] = %i\n",
2407 phy_port, p_acl->links_map[phy_port]);
2409 /* header room + eth hdr size + dst_adr offset in ip header */
2410 uint32_t dst_addr_offset =
2411 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
2412 uint32_t *dst_addr =
2413 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
2415 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
2417 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
2418 struct ether_addr hw_addr;
2419 uint32_t dest_address = rte_bswap32(*dst_addr);
2420 uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
2427 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
2429 if (is_phy_port_privte(phy_port)) {
2430 dest_address = rte_bswap32(*dst_addr);
2432 local_get_nh_ipv4(dest_address, &dest_if,
2436 get_prv_to_pub_port(&dest_address,
2438 do_local_nh_ipv4_cache(dest_if, p_acl);
2440 *port_out_id = p_acl->port_out_id[dest_if];
2442 /* port = ACL_PUB_PORT_ID; */
2444 dest_address = rte_bswap32(*dst_addr);
2446 ret = local_get_nh_ipv4(dest_address, &dest_if,
2450 get_pub_to_prv_port(&dest_address,
2452 do_local_nh_ipv4_cache(dest_if, p_acl);
2454 *port_out_id = p_acl->port_out_id[dest_if];
2456 /* port = ACL_PRV_PORT_ID; */
2458 if (get_dest_mac_addr_port
2459 (dest_address, &dest_if, &hw_addr)) {
2461 printf("MAC found for ip 0x%x, port "
2462 " %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
2463 dest_address, phy_port,
2464 hw_addr.addr_bytes[0],
2465 hw_addr.addr_bytes[1],
2466 hw_addr.addr_bytes[2],
2467 hw_addr.addr_bytes[3],
2468 hw_addr.addr_bytes[4],
2469 hw_addr.addr_bytes[5]);
2470 printf("Dest MAC before - "
2471 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2472 eth_dest[0], eth_dest[1],
2473 eth_dest[2], eth_dest[3],
2474 eth_dest[4], eth_dest[5]);
2477 memcpy(eth_dest, &hw_addr,
2478 sizeof(struct ether_addr));
2480 printf("PktP %p, dest_macP %p\n", pkt,
2482 printf("Dest MAC after - "
2483 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2484 eth_dest[0], eth_dest[1],
2485 eth_dest[2], eth_dest[3],
2486 eth_dest[4], eth_dest[5]);
2488 if (is_phy_port_privte(phy_port))
2490 get_link_hw_addr(dest_if),
2491 sizeof(struct ether_addr));
2494 get_link_hw_addr(dest_if),
2495 sizeof(struct ether_addr));
2496 p_acl->counters->tpkts_processed++;
2497 p_acl->counters->bytes_processed +=
2506 printf("ACL requesting ARP for "
2507 " ip %x, port %d\n",
2508 dest_address, phy_port);
2509 if (is_phy_port_privte(phy_port))
2510 request_arp(dest_if, *nhip);
2513 request_arp(dest_if, *nhip);
2515 /* request_arp(p_acl->links_map[phy_port], *nhip); */
2517 /* Drop packet by changing the mask */
2519 printf("ACL before drop pkt_mask "
2520 "%lu, pkt_num %d\n",
2522 pkts_mask &= ~(1LLU << pos);
2524 printf("ACL after drop pkt_mask "
2525 "%lu, pkt_num %d\n",
2527 p_acl->counters->pkts_drop++;
2532 if (hdr_chk == IPv6_HDR_VERSION) {
2534 struct acl_table_entry *entry =
2535 (struct acl_table_entry *)
2536 p_acl->acl_entries_ipv6[pos];
2537 //uint16_t phy_port = entry->head.port_id;
2538 uint16_t phy_port = pkt->port;
2539 uint32_t *port_out_id =
2540 RTE_MBUF_METADATA_UINT32_PTR(pkt,
2545 /* if (is_phy_port_privte(phy_port))
2546 *port_out_id = ACL_PUB_PORT_ID;
2548 *port_out_id = ACL_PRV_PORT_ID;*/
2550 /* *port_out_id = p_acl->links_map[phy_port]; */
2553 ("phy_port = %i,links_map[phy_port] = %i\n",
2554 phy_port, p_acl->links_map[phy_port]);
2556 /* header room + eth hdr size + dst_adr offset in ip header */
2557 uint32_t dst_addr_offset =
2558 MBUF_HDR_ROOM + ETH_HDR_SIZE +
2559 IP_HDR_DST_ADR_OFST_IPV6;
2561 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
2563 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
2564 struct ether_addr hw_addr;
2565 uint8_t dest_address[16];
2569 RTE_MBUF_METADATA_UINT8(pkt,
2574 uint8_t *dst_addr[16];
2575 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
2578 for (i = 0; i < 16; i++) {
2580 RTE_MBUF_METADATA_UINT8_PTR(pkt,
2584 memcpy(dest_address, *dst_addr, sizeof(dest_address));
2585 memset(nhip, 0, sizeof(nhip));
2586 ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
2589 if (is_phy_port_privte(phy_port)) {
2591 dest_if = get_prv_to_pub_port((
2594 &dest_address[0], IP_VERSION_6);
2595 do_local_nh_ipv6_cache(dest_if, p_acl);
2597 // port = ACL_PUB_PORT_ID;
2599 p_acl->port_out_id[dest_if];
2603 dest_if = get_pub_to_prv_port((
2606 &dest_address[0], IP_VERSION_6);
2607 do_local_nh_ipv6_cache(dest_if, p_acl);
2609 // port = ACL_PRV_PORT_ID;
2611 p_acl->port_out_id[dest_if];
2615 if (get_dest_mac_address_ipv6_port
2616 (dest_address, &dest_if, &hw_addr, &nhip[0])) {
2618 printf("MAC found for port %d "
2619 "- %02x:%02x:%02x:%02x:%02x:%02x\n",
2620 phy_port, hw_addr.addr_bytes[0],
2621 hw_addr.addr_bytes[1],
2622 hw_addr.addr_bytes[2],
2623 hw_addr.addr_bytes[3],
2624 hw_addr.addr_bytes[4],
2625 hw_addr.addr_bytes[5]);
2626 printf("Dest MAC before - "
2627 " %02x:%02x:%02x:%02x:%02x:%02x\n",
2628 eth_dest[0], eth_dest[1],
2629 eth_dest[2], eth_dest[3],
2630 eth_dest[4], eth_dest[5]);
2632 memcpy(eth_dest, &hw_addr,
2633 sizeof(struct ether_addr));
2635 printf("PktP %p, dest_macP %p\n", pkt,
2637 printf("Dest MAC after - "
2638 " %02x:%02x:%02x:%02x:%02x:%02x\n",
2639 eth_dest[0], eth_dest[1],
2640 eth_dest[2], eth_dest[3],
2641 eth_dest[4], eth_dest[5]);
2643 if (is_phy_port_privte(phy_port))
2645 get_link_hw_addr(dest_if),
2646 sizeof(struct ether_addr));
2649 get_link_hw_addr(dest_if),
2650 sizeof(struct ether_addr));
2653 * memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]),
2654 * sizeof(struct ether_addr));
2656 p_acl->counters->tpkts_processed++;
2657 p_acl->counters->bytes_processed +=
2664 /* Request next neighbor for Ipv6 is yet to be done. */
2668 ("ACL requesting ARP for ip %x, port %d\n",
2669 dest_address, phy_port);
2671 /* request_arp(p_acl->links_map[phy_port], *nhip); */
2674 /* Drop packet by changing the mask */
2676 printf("ACL before drop pkt_mask "
2677 " %lu, pkt_num %d\n",
2679 pkts_mask &= ~(1LLU << pos);
2681 printf("ACL after drop pkt_mask "
2682 " %lu, pkt_num %d\n",
2684 p_acl->counters->pkts_drop++;
2690 pkts_drop_mask = keep_mask & ~pkts_mask;
2691 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
2692 keep_mask = pkts_mask;
2694 /* don't bother measuring if traffic very low, might skew stats */
2695 uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
2697 if (packets_this_iteration > 1) {
2698 uint64_t latency_this_iteration =
2699 rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
2700 p_acl->counters->sum_latencies += latency_this_iteration;
2701 p_acl->counters->count_latencies++;
2704 printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
2710 static struct rte_acl_field_def field_format_ipv4[] = {
2713 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2714 .size = sizeof(uint8_t),
2717 .offset = sizeof(struct ether_hdr) +
2718 offsetof(struct ipv4_hdr, next_proto_id),
2721 /* Source IP address (IPv4) */
2723 .type = RTE_ACL_FIELD_TYPE_MASK,
2724 .size = sizeof(uint32_t),
2727 .offset = sizeof(struct ether_hdr) +
2728 offsetof(struct ipv4_hdr, src_addr),
2731 /* Destination IP address (IPv4) */
2733 .type = RTE_ACL_FIELD_TYPE_MASK,
2734 .size = sizeof(uint32_t),
2737 .offset = sizeof(struct ether_hdr) +
2738 offsetof(struct ipv4_hdr, dst_addr),
2743 .type = RTE_ACL_FIELD_TYPE_RANGE,
2744 .size = sizeof(uint16_t),
2747 .offset = sizeof(struct ether_hdr) +
2748 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
2751 /* Destination Port */
2753 .type = RTE_ACL_FIELD_TYPE_RANGE,
2754 .size = sizeof(uint16_t),
2757 .offset = sizeof(struct ether_hdr) +
2758 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
2762 #define SIZEOF_VLAN_HDR 4
2764 static struct rte_acl_field_def field_format_vlan_ipv4[] = {
2767 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2768 .size = sizeof(uint8_t),
2771 .offset = sizeof(struct ether_hdr) +
2772 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, next_proto_id),
2775 /* Source IP address (IPv4) */
2777 .type = RTE_ACL_FIELD_TYPE_MASK,
2778 .size = sizeof(uint32_t),
2781 .offset = sizeof(struct ether_hdr) +
2782 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, src_addr),
2785 /* Destination IP address (IPv4) */
2787 .type = RTE_ACL_FIELD_TYPE_MASK,
2788 .size = sizeof(uint32_t),
2791 .offset = sizeof(struct ether_hdr) +
2792 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, dst_addr),
2797 .type = RTE_ACL_FIELD_TYPE_RANGE,
2798 .size = sizeof(uint16_t),
2801 .offset = sizeof(struct ether_hdr) +
2803 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
2806 /* Destination Port */
2808 .type = RTE_ACL_FIELD_TYPE_RANGE,
2809 .size = sizeof(uint16_t),
2812 .offset = sizeof(struct ether_hdr) +
2814 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
2818 #define SIZEOF_QINQ_HEADER 8
2820 static struct rte_acl_field_def field_format_qinq_ipv4[] = {
2823 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2824 .size = sizeof(uint8_t),
2827 .offset = sizeof(struct ether_hdr) +
2828 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, next_proto_id),
2831 /* Source IP address (IPv4) */
2833 .type = RTE_ACL_FIELD_TYPE_MASK,
2834 .size = sizeof(uint32_t),
2837 .offset = sizeof(struct ether_hdr) +
2838 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, src_addr),
2841 /* Destination IP address (IPv4) */
2843 .type = RTE_ACL_FIELD_TYPE_MASK,
2844 .size = sizeof(uint32_t),
2847 .offset = sizeof(struct ether_hdr) +
2848 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, dst_addr),
2853 .type = RTE_ACL_FIELD_TYPE_RANGE,
2854 .size = sizeof(uint16_t),
2857 .offset = sizeof(struct ether_hdr) +
2858 SIZEOF_QINQ_HEADER +
2859 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
2862 /* Destination Port */
2864 .type = RTE_ACL_FIELD_TYPE_RANGE,
2865 .size = sizeof(uint16_t),
2868 .offset = sizeof(struct ether_hdr) +
2869 SIZEOF_QINQ_HEADER +
2870 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
2874 static struct rte_acl_field_def field_format_ipv6[] = {
2877 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2878 .size = sizeof(uint8_t),
2881 .offset = sizeof(struct ether_hdr) +
2882 offsetof(struct ipv6_hdr, proto),
2885 /* Source IP address (IPv6) */
2887 .type = RTE_ACL_FIELD_TYPE_MASK,
2888 .size = sizeof(uint32_t),
2891 .offset = sizeof(struct ether_hdr) +
2892 offsetof(struct ipv6_hdr, src_addr),
2896 .type = RTE_ACL_FIELD_TYPE_MASK,
2897 .size = sizeof(uint32_t),
2900 .offset = sizeof(struct ether_hdr) +
2901 offsetof(struct ipv6_hdr, src_addr) + sizeof(uint32_t),
2906 .type = RTE_ACL_FIELD_TYPE_MASK,
2907 .size = sizeof(uint32_t),
2910 .offset = sizeof(struct ether_hdr) +
2911 offsetof(struct ipv6_hdr, src_addr) + 2 * sizeof(uint32_t),
2916 .type = RTE_ACL_FIELD_TYPE_MASK,
2917 .size = sizeof(uint32_t),
2920 .offset = sizeof(struct ether_hdr) +
2921 offsetof(struct ipv6_hdr, src_addr) + 3 * sizeof(uint32_t),
2925 /* Destination IP address (IPv6) */
2927 .type = RTE_ACL_FIELD_TYPE_MASK,
2928 .size = sizeof(uint32_t),
2931 .offset = sizeof(struct ether_hdr) +
2932 offsetof(struct ipv6_hdr, dst_addr),
2936 .type = RTE_ACL_FIELD_TYPE_MASK,
2937 .size = sizeof(uint32_t),
2940 .offset = sizeof(struct ether_hdr) +
2941 offsetof(struct ipv6_hdr, dst_addr) + sizeof(uint32_t),
2946 .type = RTE_ACL_FIELD_TYPE_MASK,
2947 .size = sizeof(uint32_t),
2950 .offset = sizeof(struct ether_hdr) +
2951 offsetof(struct ipv6_hdr, dst_addr) + 2 * sizeof(uint32_t),
2956 .type = RTE_ACL_FIELD_TYPE_MASK,
2957 .size = sizeof(uint32_t),
2960 .offset = sizeof(struct ether_hdr) +
2961 offsetof(struct ipv6_hdr, dst_addr) + 3 * sizeof(uint32_t),
2967 .type = RTE_ACL_FIELD_TYPE_RANGE,
2968 .size = sizeof(uint16_t),
2971 .offset = sizeof(struct ether_hdr) +
2972 sizeof(struct ipv6_hdr) + offsetof(struct tcp_hdr, src_port),
2975 /* Destination Port */
2977 .type = RTE_ACL_FIELD_TYPE_RANGE,
2978 .size = sizeof(uint16_t),
2981 .offset = sizeof(struct ether_hdr) +
2982 sizeof(struct ipv6_hdr) + offsetof(struct tcp_hdr, dst_port),
2987 * Parse arguments in config file.
2990 * A pointer to the pipeline.
2992 * A pointer to pipeline specific parameters.
2995 * 0 on success, negative on error.
2998 pipeline_acl_parse_args(struct pipeline_acl *p, struct pipeline_params *params)
3000 uint32_t n_rules_present = 0;
3001 uint32_t pkt_type_present = 0;
3003 uint8_t prv_que_handler_present = 0;
3004 uint8_t n_prv_in_port = 0;
3007 p->n_rules = 4 * 1024;
3008 acl_n_rules = 4 * 1024;
3009 p->n_rule_fields = RTE_DIM(field_format_ipv4);
3010 p->field_format = field_format_ipv4;
3011 p->field_format_size = sizeof(field_format_ipv4);
3013 for (i = 0; i < params->n_args; i++) {
3014 char *arg_name = params->args_name[i];
3015 char *arg_value = params->args_value[i];
3017 if (strcmp(arg_name, "n_rules") == 0) {
3018 if (n_rules_present)
3020 n_rules_present = 1;
3022 p->n_rules = atoi(arg_value);
3023 acl_n_rules = atoi(arg_value);
3027 if (strcmp(arg_name, "pkt_type") == 0) {
3028 if (pkt_type_present)
3030 pkt_type_present = 1;
3033 if (strcmp(arg_value, "ipv4") == 0) {
3034 p->n_rule_fields = RTE_DIM(field_format_ipv4);
3035 p->field_format = field_format_ipv4;
3036 p->field_format_size =
3037 sizeof(field_format_ipv4);
3042 if (strcmp(arg_value, "vlan_ipv4") == 0) {
3044 RTE_DIM(field_format_vlan_ipv4);
3045 p->field_format = field_format_vlan_ipv4;
3046 p->field_format_size =
3047 sizeof(field_format_vlan_ipv4);
3052 if (strcmp(arg_value, "qinq_ipv4") == 0) {
3054 RTE_DIM(field_format_qinq_ipv4);
3055 p->field_format = field_format_qinq_ipv4;
3056 p->field_format_size =
3057 sizeof(field_format_qinq_ipv4);
3062 if (strcmp(arg_value, "ipv6") == 0) {
3063 p->n_rule_fields = RTE_DIM(field_format_ipv6);
3064 p->field_format = field_format_ipv6;
3065 p->field_format_size =
3066 sizeof(field_format_ipv6);
3074 if (strcmp(arg_name, "traffic_type") == 0) {
3075 int traffic_type = atoi(arg_value);
3077 if (traffic_type == 0
3078 || !(traffic_type == IPv4_HDR_VERSION
3079 || traffic_type == IPv6_HDR_VERSION)) {
3080 printf("not IPVR4/IPVR6");
3084 p->traffic_type = traffic_type;
3088 if (strcmp(arg_name, "prv_que_handler") == 0) {
3090 if (prv_que_handler_present) {
3091 printf("Duplicate pktq_in_prv ..\n\n");
3094 prv_que_handler_present = 1;
3099 /* get the first token */
3100 token = strtok(arg_value, "(");
3101 token = strtok(token, ")");
3102 token = strtok(token, ",");
3103 printf("***** prv_que_handler *****\n");
3106 printf("string is null\n");
3107 printf("prv_que_handler is invalid\n");
3110 printf("string is :%s\n", token);
3112 while (token != NULL) {
3113 printf(" %s\n", token);
3114 rxport = atoi(token);
3115 acl_prv_que_port_index[n_prv_in_port++] =
3117 token = strtok(NULL, ",");
3120 if (n_prv_in_port == 0) {
3121 printf("VNF common parse err - no prv RX phy port\n");
3128 if (strcmp(arg_name, "n_flows") == 0) {
3129 p->n_flows = atoi(arg_value);
3130 if (p->n_flows == 0)
3133 continue;/* needed when multiple parms are checked */
3142 * Create and initialize Pipeline Back End (BE).
3145 * A pointer to the pipeline.
3147 * A pointer to pipeline specific data.
3150 * A pointer to the pipeline create, NULL on error.
3152 static void *pipeline_acl_init(struct pipeline_params *params,
3153 __rte_unused void *arg)
3156 struct pipeline_acl *p_acl;
3159 /* Check input arguments */
3160 if ((params == NULL) ||
3161 (params->n_ports_in == 0) || (params->n_ports_out == 0))
3164 /* Memory allocation */
3165 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_acl));
3166 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
3167 p_acl = (struct pipeline_acl *)p;
3171 strcpy(p->name, params->name);
3172 p->log_level = params->log_level;
3174 PLOG(p, HIGH, "ACL");
3177 * p_acl->links_map[0] = 0xff;
3178 * p_acl->links_map[1] = 0xff;]
3180 p_acl->traffic_type = MIX;
3181 for (i = 0; i < PIPELINE_MAX_PORT_IN; i++) {
3182 p_acl->links_map[i] = 0xff;
3183 p_acl->port_out_id[i] = 0xff;
3184 acl_prv_que_port_index[i] = 0;
3187 p_acl->pipeline_num = 0xff;
3189 /* if(enable_hwlb || enable_flow_dir) */
3190 // lib_arp_init(params, arg);
3192 p_acl->n_flows = 4096; /* small default value */
3193 /* Create a single firewall instance and initialize. */
3194 p_acl->cnxn_tracker =
3195 rte_zmalloc(NULL, rte_ct_get_cnxn_tracker_size(),
3196 RTE_CACHE_LINE_SIZE);
3198 if (p_acl->cnxn_tracker == NULL)
3202 * Now allocate a counter block entry.It appears that the initialization
3203 * of all instances is serialized on core 0, so no lock is necessary.
3205 struct rte_ACL_counter_block *counter_ptr;
3207 if (rte_ACL_hi_counter_block_in_use == MAX_ACL_INSTANCES) {
3208 /* error, exceeded table bounds */
3212 rte_ACL_hi_counter_block_in_use++;
3213 counter_ptr = &rte_acl_counter_table[rte_ACL_hi_counter_block_in_use];
3214 strcpy(counter_ptr->name, params->name);
3215 p_acl->action_counter_index = rte_ACL_hi_counter_block_in_use;
3217 p_acl->counters = counter_ptr;
3219 rte_ct_initialize_default_timeouts(p_acl->cnxn_tracker);
3220 p_acl->arpPktCount = 0;
3222 /* Parse arguments */
3223 if (pipeline_acl_parse_args(p_acl, params))
3225 /*n_flows already checked, ignore Klockwork issue */
3226 if (p_acl->n_flows > 0) {
3227 rte_ct_initialize_cnxn_tracker(p_acl->cnxn_tracker,
3228 p_acl->n_flows, params->name);
3229 p_acl->counters->ct_counters =
3230 rte_ct_get_counter_address(p_acl->cnxn_tracker);
3232 printf("ACL invalid p_acl->n_flows: %u\n", p_acl->n_flows);
3238 struct rte_pipeline_params pipeline_params = {
3239 .name = params->name,
3240 .socket_id = params->socket_id,
3241 .offset_port_id = META_DATA_OFFSET +
3242 offsetof(struct mbuf_acl_meta_data, output_port),
3245 p->p = rte_pipeline_create(&pipeline_params);
3253 p->n_ports_in = params->n_ports_in;
3254 for (i = 0; i < p->n_ports_in; i++) {
3255 struct rte_pipeline_port_in_params port_params = {
3257 pipeline_port_in_params_get_ops(¶ms->port_in
3260 pipeline_port_in_params_convert(¶ms->port_in
3262 .f_action = pkt_work_acl_key,
3264 .burst_size = params->port_in[i].burst_size,
3266 if (p_acl->traffic_type == IPv4_HDR_VERSION)
3267 port_params.f_action = pkt_work_acl_ipv4_key;
3269 if (p_acl->traffic_type == IPv6_HDR_VERSION)
3270 port_params.f_action = pkt_work_acl_ipv6_key;
3272 int status = rte_pipeline_port_in_create(p->p,
3277 rte_pipeline_free(p->p);
3284 p->n_ports_out = params->n_ports_out;
3285 for (i = 0; i < p->n_ports_out; i++) {
3286 struct rte_pipeline_port_out_params port_params = {
3288 pipeline_port_out_params_get_ops(¶ms->port_out
3291 pipeline_port_out_params_convert(¶ms->port_out
3297 int status = rte_pipeline_port_out_create(p->p,
3299 &p->port_out_id[i]);
3302 rte_pipeline_free(p->p);
3308 int pipeline_num = 0;
3310 int temp = sscanf(params->name, "PIPELINE%d", &pipeline_num);
3311 p_acl->pipeline_num = (uint8_t) pipeline_num;
3312 /* set_phy_outport_map(p_acl->pipeline_num, p_acl->links_map);*/
3313 register_pipeline_Qs(p_acl->pipeline_num, p);
3314 set_link_map(p_acl->pipeline_num, p, p_acl->links_map);
3315 set_outport_id(p_acl->pipeline_num, p, p_acl->port_out_id);
3317 /* If this is the first ACL thread, create common ACL Rule tables */
3318 if (rte_ACL_hi_counter_block_in_use == 0) {
3320 printf("Create ACL Tables rte_socket_id(): %i\n",
3323 /* Create IPV4 ACL Rule Tables */
3324 struct rte_table_acl_params common_ipv4_table_acl_params = {
3326 .n_rules = acl_n_rules,
3327 .n_rule_fields = RTE_DIM(field_format_ipv4),
3330 memcpy(common_ipv4_table_acl_params.field_format,
3331 field_format_ipv4, sizeof(field_format_ipv4));
3333 uint32_t ipv4_entry_size = sizeof(struct acl_table_entry);
3335 acl_rule_table_ipv4_active =
3336 rte_table_acl_ops.f_create(&common_ipv4_table_acl_params,
3340 if (acl_rule_table_ipv4_active == NULL) {
3342 ("Failed to create common ACL IPV4A Rule table\n");
3343 rte_pipeline_free(p->p);
3348 /* Create second IPV4 Table */
3349 common_ipv4_table_acl_params.name = "ACLIPV4B";
3350 acl_rule_table_ipv4_standby =
3351 rte_table_acl_ops.f_create(&common_ipv4_table_acl_params,
3355 if (acl_rule_table_ipv4_standby == NULL) {
3357 ("Failed to create common ACL IPV4B Rule table\n");
3358 rte_pipeline_free(p->p);
3363 /* Create IPV6 ACL Rule Tables */
3364 struct rte_table_acl_params common_ipv6_table_acl_params = {
3366 .n_rules = acl_n_rules,
3367 .n_rule_fields = RTE_DIM(field_format_ipv6),
3370 memcpy(common_ipv6_table_acl_params.field_format,
3371 field_format_ipv6, sizeof(field_format_ipv6));
3373 uint32_t ipv6_entry_size = sizeof(struct acl_table_entry);
3375 acl_rule_table_ipv6_active =
3376 rte_table_acl_ops.f_create(&common_ipv6_table_acl_params,
3380 if (acl_rule_table_ipv6_active == NULL) {
3382 ("Failed to create common ACL IPV6A Rule table\n");
3383 rte_pipeline_free(p->p);
3388 /* Create second IPV6 table */
3389 common_ipv6_table_acl_params.name = "ACLIPV6B";
3390 acl_rule_table_ipv6_standby =
3391 rte_table_acl_ops.f_create(&common_ipv6_table_acl_params,
3395 if (acl_rule_table_ipv6_standby == NULL) {
3397 ("Failed to create common ACL IPV6B Rule table\n");
3398 rte_pipeline_free(p->p);
3408 struct rte_pipeline_table_params table_params = {
3409 .ops = &rte_table_stub_ops,
3411 .f_action_hit = NULL,
3412 .f_action_miss = NULL,
3414 .action_data_size = 0,
3417 int status = rte_pipeline_table_create(p->p,
3422 rte_pipeline_free(p->p);
3427 struct rte_pipeline_table_entry default_entry = {
3428 .action = RTE_PIPELINE_ACTION_PORT_META
3431 struct rte_pipeline_table_entry *default_entry_ptr;
3433 status = rte_pipeline_table_default_entry_add(p->p,
3436 &default_entry_ptr);
3439 rte_pipeline_free(p->p);
3445 /* Connecting input ports to tables */
3446 for (i = 0; i < p->n_ports_in; i++) {
3447 int status = rte_pipeline_port_in_connect_to_table(p->p,
3454 rte_pipeline_free(p->p);
3460 /* Enable input ports */
3461 for (i = 0; i < p->n_ports_in; i++) {
3462 int status = rte_pipeline_port_in_enable(p->p,
3466 rte_pipeline_free(p->p);
3472 /* Check pipeline consistency */
3473 if (rte_pipeline_check(p->p) < 0) {
3474 rte_pipeline_free(p->p);
3479 /* Message queues */
3480 p->n_msgq = params->n_msgq;
3481 for (i = 0; i < p->n_msgq; i++)
3482 p->msgq_in[i] = params->msgq_in[i];
3483 for (i = 0; i < p->n_msgq; i++)
3484 p->msgq_out[i] = params->msgq_out[i];
3486 /* Message handlers */
3487 memcpy(p->handlers, handlers, sizeof(p->handlers));
3488 memcpy(p_acl->custom_handlers,
3489 custom_handlers, sizeof(p_acl->custom_handlers));
3495 * Free resources and delete pipeline.
3498 * A pointer to the pipeline.
3501 * 0 on success, negative on error.
3503 static int pipeline_acl_free(void *pipeline)
3505 struct pipeline *p = (struct pipeline *)pipeline;
3507 /* Check input arguments */
3511 /* Free resources */
3512 rte_pipeline_free(p->p);
3518 * Callback function to map input/output ports.
3521 * A pointer to the pipeline.
3525 * A pointer to the Output port.
3528 * 0 on success, negative on error.
3531 pipeline_acl_track(void *pipeline,
3532 __rte_unused uint32_t port_in, uint32_t *port_out)
3534 struct pipeline *p = (struct pipeline *)pipeline;
3536 /* Check input arguments */
3537 if ((p == NULL) || (port_in >= p->n_ports_in) || (port_out == NULL))
3540 if (p->n_ports_in == 1) {
3549 * Callback function to process timers.
3552 * A pointer to the pipeline.
3555 * 0 on success, negative on error.
3557 static int pipeline_acl_timer(void *pipeline)
3560 struct pipeline *p = (struct pipeline *)pipeline;
3561 struct pipeline_acl *p_acl = (struct pipeline_acl *)pipeline;
3563 pipeline_msg_req_handle(p);
3564 rte_pipeline_flush(p->p);
3566 rte_ct_handle_expired_timers(p_acl->cnxn_tracker);
3572 * Callback function to process CLI commands from FE.
3575 * A pointer to the pipeline.
3577 * A pointer to command specific data.
3580 * A pointer to message handler on success,
3581 * pipeline_msg_req_invalid_hander on error.
3583 void *pipeline_acl_msg_req_custom_handler(struct pipeline *p, void *msg)
3585 struct pipeline_acl *p_acl = (struct pipeline_acl *)p;
3586 struct pipeline_custom_msg_req *req = msg;
3587 pipeline_msg_req_handler f_handle;
3589 f_handle = (req->subtype < PIPELINE_ACL_MSG_REQS) ?
3590 p_acl->custom_handlers[req->subtype] :
3591 pipeline_msg_req_invalid_handler;
3593 if (f_handle == NULL)
3594 f_handle = pipeline_msg_req_invalid_handler;
3596 return f_handle(p, req);
3600 * Handler for DBG CLI command.
3603 * A pointer to the pipeline.
3605 * A pointer to command specific data.
3608 * A pointer to response message.
3609 * Response message contains status.
3611 void *pipeline_acl_msg_req_dbg_handler(struct pipeline *p, void *msg)
3614 struct pipeline_acl_dbg_msg_req *req = msg;
3615 struct pipeline_acl_dbg_msg_rsp *rsp = msg;
3617 if (req->dbg == 0) {
3618 printf("DBG turned OFF\n");
3621 } else if (req->dbg == 1) {
3622 printf("DBG turned ON\n");
3626 printf("Invalid DBG setting\n");
3633 struct pipeline_be_ops pipeline_acl_be_ops = {
3634 .f_init = pipeline_acl_init,
3635 .f_free = pipeline_acl_free,
3637 .f_timer = pipeline_acl_timer,
3638 .f_track = pipeline_acl_track,