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,
147 uint64_t arp_pkts_mask;
150 uint32_t local_get_nh_ipv4(uint32_t ip,
152 uint32_t *nhip, struct pipeline_acl *p_acl)
156 for (i = 0; i < p_acl->local_lib_arp_route_ent_cnt; i++) {
157 if (((p_acl->local_lib_arp_route_table[i].ip &
158 p_acl->local_lib_arp_route_table[i].mask) ==
159 (ip & p_acl->local_lib_arp_route_table[i].mask))) {
160 *port = p_acl->local_lib_arp_route_table[i].port;
162 *nhip = p_acl->local_lib_arp_route_table[i].nh;
169 static void do_local_nh_ipv4_cache(uint32_t dest_if, struct pipeline_acl *p_acl)
172 /* Search for the entry and do local copy */
175 for (i = 0; i < MAX_ARP_RT_ENTRY; i++) {
176 if (lib_arp_route_table[i].port == dest_if) {
178 struct lib_arp_route_table_entry *lentry =
179 &p_acl->local_lib_arp_route_table
180 [p_acl->local_lib_arp_route_ent_cnt];
182 lentry->ip = lib_arp_route_table[i].ip;
183 lentry->mask = lib_arp_route_table[i].mask;
184 lentry->port = lib_arp_route_table[i].port;
185 lentry->nh = lib_arp_route_table[i].nh;
187 p_acl->local_lib_arp_route_ent_cnt++;
193 static uint32_t local_get_nh_ipv6(uint8_t *ip,
195 uint8_t nhip[], struct pipeline_acl *p_acl)
198 uint8_t netmask_ipv6[16],netip_nd[16],netip_in[16];
199 uint8_t k = 0, l = 0, depthflags = 0, depthflags1 = 0;
200 memset (netmask_ipv6, 0, sizeof(netmask_ipv6));
201 memset (netip_nd, 0, sizeof(netip_nd));
202 memset (netip_in, 0, sizeof(netip_in));
204 for (i = 0; i < p_acl->local_lib_nd_route_ent_cnt; i++) {
206 convert_prefixlen_to_netmask_ipv6
207 (p_acl->local_lib_nd_route_table[i].depth, netmask_ipv6);
209 for (k = 0; k < 16; k++)
210 if (p_acl->local_lib_nd_route_table[i].ipv6[k] &
213 netip_nd[k] = p_acl->
214 local_lib_nd_route_table[i].ipv6[k];
218 for (l = 0; l < 16; l++)
219 if (ip[l] & netmask_ipv6[l]) {
226 if ((depthflags == depthflags1) && (memcmp(netip_nd, netip_in,
227 sizeof(netip_nd)) == 0)){
228 *port = p_acl->local_lib_nd_route_table[i].port;
230 for (j = 0; j < 16; j++)
232 p_acl->local_lib_nd_route_table[i].
242 void do_local_nh_ipv6_cache(uint32_t dest_if, struct pipeline_acl *p_acl)
244 /* Search for the entry and do local copy */
247 for (i = 0; i < MAX_ND_RT_ENTRY; i++) {
249 if (lib_nd_route_table[i].port == dest_if) {
251 struct lib_nd_route_table_entry *lentry =
252 &p_acl->local_lib_nd_route_table
253 [p_acl->local_lib_nd_route_ent_cnt];
255 for (l = 0; l < 16; l++) {
256 lentry->ipv6[l] = lib_nd_route_table[i].ipv6[l];
258 lib_nd_route_table[i].nhipv6[l];
260 lentry->depth = lib_nd_route_table[i].depth;
261 lentry->port = lib_nd_route_table[i].port;
263 p_acl->local_lib_nd_route_ent_cnt++;
269 static uint8_t check_arp_icmp(struct rte_mbuf *pkt,
270 uint64_t pkt_mask, struct pipeline_acl *p_acl)
272 uint32_t eth_proto_offset = MBUF_HDR_ROOM + 12;
273 struct ipv6_hdr *ipv6_h;
274 uint16_t *eth_proto =
275 RTE_MBUF_METADATA_UINT16_PTR(pkt, eth_proto_offset);
276 struct app_link_params *link;
278 //uint32_t *port_out_id = RTE_MBUF_METADATA_UINT32_PTR(pk
279 // offsetof(struct mbuf_acl_meta_dat
281 /* ARP outport number */
282 uint16_t out_port = p_acl->p.n_ports_out - 1;
285 uint32_t prot_offset;
287 link = &myApp->link_params[pkt->port];
289 switch (rte_be_to_cpu_16(*eth_proto)) {
292 rte_pipeline_port_out_packet_insert(p_acl->p.p, out_port, pkt);
295 * Pkt mask should be changed, and not changing the
298 p_acl->arpPktCount++;
303 /* header room + eth hdr size +
304 * src_aadr offset in ip header
306 uint32_t dst_addr_offset = MBUF_HDR_ROOM +
307 ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
308 uint32_t *dst_addr = RTE_MBUF_METADATA_UINT32_PTR(pkt,
310 prot_offset = MBUF_HDR_ROOM + ETH_HDR_SIZE +
311 IP_HDR_PROTOCOL_OFST;
312 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt,
314 if ((*protocol == IP_PROTOCOL_ICMP) &&
315 link->ip == rte_be_to_cpu_32(*dst_addr)) {
317 if (is_phy_port_privte(pkt->port)) {
319 rte_pipeline_port_out_packet_insert
320 (p_acl->p.p, out_port, pkt);
322 * Pkt mask should be changed,
323 * and not changing the drop mask
325 p_acl->arpPktCount++;
337 uint32_t dst_addr_offset = MBUF_HDR_ROOM +
338 ETH_HDR_SIZE + IPV6_HDR_DST_ADR_OFST;
339 uint32_t *dst_addr = RTE_MBUF_METADATA_UINT32_PTR(pkt,
342 uint32_t prot_offset_ipv6 = MBUF_HDR_ROOM +
343 ETH_HDR_SIZE + IPV6_HDR_PROTOCOL_OFST;
344 struct ipv6_hdr *ipv6_h;
346 ipv6_h = (struct ipv6_hdr *)MBUF_HDR_ROOM +
348 protocol = RTE_MBUF_METADATA_UINT8_PTR(pkt,
351 if ((ipv6_h->proto == ICMPV6_PROTOCOL_ID) &&
352 (link->ip == rte_be_to_cpu_32(dst_addr[3]))) {
354 if (is_phy_port_privte(pkt->port)) {
356 rte_pipeline_port_out_packet_insert
357 (p_acl->p.p, out_port, pkt);
359 * Pkt mask should be changed,
360 * and not changing the drop mask
362 p_acl->arpPktCount++;
372 #define IP_START (MBUF_HDR_ROOM + ETH_HDR_SIZE)
375 ipv6_h = (struct ipv6_hdr *)
376 RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
378 if ((ipv6_h->proto == ICMPV6_PROTOCOL_ID) &&
380 rte_be_to_cpu_32(ipv6_h->dst_addr[3]))) {
382 if (is_phy_port_privte(pkt->port)) {
383 rte_pipeline_port_out_packet_insert(
388 p_acl->arpPktCount++;
403 * Print packet for debugging.
406 * A pointer to the packet.
409 void print_pkt_acl(struct rte_mbuf *pkt)
413 printf("Packet Contents:\n");
414 uint8_t *rd = RTE_MBUF_METADATA_UINT8_PTR(pkt, 0);
416 for (i = 0; i < 20; i++) {
417 for (j = 0; j < 20; j++)
418 printf("%02x ", rd[(20 * i) + j]);
424 * Main packet processing function.
425 * 64 packet bit mask are used to identify which packets to forward.
426 * Performs the following:
427 * - Burst lookup packets in the IPv4 ACL Rule Table.
428 * - Burst lookup packets in the IPv6 ACL Rule Table.
429 * - Lookup Action Table, perform actions.
430 * - Burst lookup Connection Tracking, if enabled.
431 * - Lookup MAC address.
433 * - Packets with bit mask set are forwarded
436 * A pointer to the pipeline.
438 * A pointer to a burst of packets.
440 * Number of packets to process.
442 * A pointer to pipeline specific data.
445 * 0 on success, negative on error.
448 pkt_work_acl_key(struct rte_pipeline *p,
449 struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
452 struct pipeline_acl *p_acl = arg;
454 p_acl->counters->pkts_received =
455 p_acl->counters->pkts_received + n_pkts;
457 printf("pkt_work_acl_key pkts_received: %" PRIu64
458 " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
460 uint64_t lookup_hit_mask = 0;
461 uint64_t lookup_hit_mask_ipv4 = 0;
462 uint64_t lookup_hit_mask_ipv6 = 0;
463 uint64_t lookup_miss_mask = 0;
464 uint64_t conntrack_mask = 0;
465 uint64_t connexist_mask = 0;
466 uint32_t dest_address = 0;
470 uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
471 uint64_t keep_mask = pkts_mask;
475 p_acl->in_port_time_stamp = rte_get_tsc_cycles();
477 if (acl_ipv4_enabled) {
479 printf("ACL IPV4 Lookup Mask Before = %p\n",
482 rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
483 pkts_mask, &lookup_hit_mask_ipv4,
485 p_acl->acl_entries_ipv4);
487 printf("ACL IPV4 Lookup Mask After = %p\n",
488 (void *)lookup_hit_mask_ipv4);
491 if (acl_ipv6_enabled) {
493 printf("ACL IPV6 Lookup Mask Before = %p\n",
496 rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
497 pkts_mask, &lookup_hit_mask_ipv6,
499 p_acl->acl_entries_ipv6);
501 printf("ACL IPV6 Lookup Mask After = %p\n",
502 (void *)lookup_hit_mask_ipv6);
505 /* Merge lookup results since we process both IPv4 and IPv6 below */
506 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
508 printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
510 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
511 pkts_mask = lookup_hit_mask;
512 p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
514 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
515 p_acl->counters->pkts_drop,
516 __builtin_popcountll(lookup_miss_mask));
518 uint64_t pkts_to_process = lookup_hit_mask;
519 /* bitmap of packets left to process for ARP */
521 for (; pkts_to_process;) {
522 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
523 uint64_t pkt_mask = 1LLU << pos;
524 /* bitmask representing only this packet */
526 pkts_to_process &= ~pkt_mask;
527 /* remove this packet from remaining list */
528 struct rte_mbuf *pkt = pkts[pos];
531 if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
532 pkts_mask &= ~(1LLU << pos);
537 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
538 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
540 if (hdr_chk == IPv4_HDR_VERSION) {
542 struct acl_table_entry *entry =
543 (struct acl_table_entry *)
544 p_acl->acl_entries_ipv4[pos];
545 uint16_t phy_port = entry->head.port_id;
546 uint32_t action_id = entry->action_id;
549 printf("action_id = %u\n", action_id);
551 uint32_t dscp_offset =
552 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
554 if (action_array_active[action_id].action_bitmap &
557 [p_acl->action_counter_index]
558 [action_id].packetCount++;
560 [p_acl->action_counter_index]
561 [action_id].byteCount +=
562 rte_pktmbuf_pkt_len(pkt);
564 printf("Action Count Packet Count: %"
565 PRIu64 " Byte Count: %" PRIu64
568 [p_acl->action_counter_index]
569 [action_id].packetCount,
571 [p_acl->action_counter_index]
572 [action_id].byteCount);
575 if (action_array_active[action_id].action_bitmap &
576 acl_action_packet_drop) {
578 /* Drop packet by changing the mask */
580 printf("ACL before drop pkt_mask "
581 " %lu, pkt_num %d\n",
583 pkts_mask &= ~(1LLU << pos);
585 printf("ACL after drop pkt_mask "
588 p_acl->counters->pkts_drop++;
591 if (action_array_active[action_id].action_bitmap &
594 action_array_active[action_id].fwd_port;
595 entry->head.port_id = phy_port;
597 printf("Action FWD Port ID: %u\n",
601 if (action_array_active[action_id].action_bitmap &
604 action_array_active[action_id].nat_port;
605 entry->head.port_id = phy_port;
607 printf("Action NAT Port ID: %u\n",
611 if (action_array_active[action_id].action_bitmap &
614 /* Set DSCP priority */
615 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
618 action_array_active[action_id].dscp_priority
622 ("Action DSCP DSCP Priority: %u\n",
626 if (action_array_active[action_id].action_bitmap &
627 acl_action_packet_accept) {
629 printf("Action Accept\n");
631 if (action_array_active[action_id].action_bitmap
632 & acl_action_conntrack) {
634 /* Set conntrack bit for this pkt */
635 conntrack_mask |= pkt_mask;
637 printf("ACL Conntrack enabled: "
639 (void *)conntrack_mask,
643 if (action_array_active[action_id].action_bitmap
644 & acl_action_connexist) {
646 /* Set conntrack bit for this pkt */
647 conntrack_mask |= pkt_mask;
649 /* Set connexist bit for this pkt for public -> private */
650 /* Private -> public packet will open the connection */
651 if (action_array_active
652 [action_id].private_public ==
654 connexist_mask |= pkt_mask;
657 printf("ACL Connexist enabled "
658 "conntrack: %p connexist: %p pkt_mask: %p\n",
659 (void *)conntrack_mask,
660 (void *)connexist_mask,
666 if (hdr_chk == IPv6_HDR_VERSION) {
668 struct acl_table_entry *entry =
669 (struct acl_table_entry *)
670 p_acl->acl_entries_ipv6[pos];
671 uint16_t phy_port = entry->head.port_id;
672 uint32_t action_id = entry->action_id;
675 printf("action_id = %u\n", action_id);
677 if (action_array_active[action_id].action_bitmap &
680 [p_acl->action_counter_index]
681 [action_id].packetCount++;
683 [p_acl->action_counter_index]
684 [action_id].byteCount +=
685 rte_pktmbuf_pkt_len(pkt);
687 printf("Action Count Packet Count: %"
688 PRIu64 " Byte Count: %" PRIu64
691 [p_acl->action_counter_index]
692 [action_id].packetCount,
694 [p_acl->action_counter_index]
695 [action_id].byteCount);
698 if (action_array_active[action_id].action_bitmap &
699 acl_action_packet_drop) {
700 /* Drop packet by changing the mask */
702 printf("ACL before drop pkt_mask "
705 pkts_mask &= ~(1LLU << pos);
707 printf("ACL after drop pkt_mask "
710 p_acl->counters->pkts_drop++;
714 if (action_array_active[action_id].action_bitmap &
717 action_array_active[action_id].fwd_port;
718 entry->head.port_id = phy_port;
720 printf("Action FWD Port ID: %u\n",
724 if (action_array_active[action_id].action_bitmap &
727 action_array_active[action_id].nat_port;
728 entry->head.port_id = phy_port;
730 printf("Action NAT Port ID: %u\n",
734 if (action_array_active[action_id].action_bitmap &
737 /* Set DSCP priority */
738 uint32_t dscp_offset =
739 MBUF_HDR_ROOM + ETH_HDR_SIZE +
740 IP_HDR_DSCP_OFST_IPV6;
742 RTE_MBUF_METADATA_UINT16_PTR(pkt,
744 uint16_t dscp_value =
746 (RTE_MBUF_METADATA_UINT16
747 (pkt, dscp_offset)) & 0XF00F);
749 action_array_active[action_id].dscp_priority
751 uint16_t dscp_temp = dscp_store;
753 dscp_temp = dscp_temp << 4;
754 *dscp = rte_bswap16(dscp_temp | dscp_value);
757 ("Action DSCP DSCP Priority: %u\n",
761 if (action_array_active[action_id].action_bitmap &
762 acl_action_packet_accept) {
764 printf("Action Accept\n");
766 if (action_array_active[action_id].action_bitmap
767 & acl_action_conntrack) {
769 /* Set conntrack bit for this pkt */
770 conntrack_mask |= pkt_mask;
772 printf("ACL Conntrack enabled: "
773 " %p pkt_mask: %p\n",
774 (void *)conntrack_mask,
778 if (action_array_active[action_id].action_bitmap
779 & acl_action_connexist) {
781 /* Set conntrack bit for this pkt */
782 conntrack_mask |= pkt_mask;
784 /* Set connexist bit for this pkt for public -> private */
785 /* Private -> public packet will open the connection */
786 if (action_array_active
787 [action_id].private_public ==
789 connexist_mask |= pkt_mask;
792 printf("ACL Connexist enabled "
793 "conntrack: %p connexist: %p pkt_mask: %p\n",
794 (void *)conntrack_mask,
795 (void *)connexist_mask,
802 /* Only call connection tracker if required */
803 if (conntrack_mask > 0) {
806 ("ACL Call Conntrack Before = %p Connexist = %p\n",
807 (void *)conntrack_mask, (void *)connexist_mask);
809 rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
810 (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
812 printf("ACL Call Conntrack After = %p\n",
813 (void *)conntrack_mask);
815 /* Only change pkt mask for pkts that have conntrack enabled */
816 /* Need to loop through packets to check if conntrack enabled */
817 pkts_to_process = pkts_mask;
818 for (; pkts_to_process;) {
819 uint32_t action_id = 0;
821 (uint8_t) __builtin_ctzll(pkts_to_process);
822 uint64_t pkt_mask = 1LLU << pos;
823 /* bitmask representing only this packet */
825 pkts_to_process &= ~pkt_mask;
826 /* remove this packet from remaining list */
827 struct rte_mbuf *pkt = pkts[pos];
829 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
834 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
835 if (hdr_chk == IPv4_HDR_VERSION) {
836 struct acl_table_entry *entry =
837 (struct acl_table_entry *)
838 p_acl->acl_entries_ipv4[pos];
839 action_id = entry->action_id;
841 struct acl_table_entry *entry =
842 (struct acl_table_entry *)
843 p_acl->acl_entries_ipv6[pos];
844 action_id = entry->action_id;
847 if ((action_array_active[action_id].action_bitmap &
848 acl_action_conntrack)
849 || (action_array_active[action_id].action_bitmap &
850 acl_action_connexist)) {
852 if (conntrack_mask & pkt_mask) {
854 printf("ACL Conntrack Accept "
858 /* Drop packet by changing the mask */
860 printf("ACL Conntrack Drop "
863 pkts_mask &= ~pkt_mask;
864 p_acl->counters->pkts_drop++;
870 pkts_to_process = pkts_mask;
871 /* bitmap of packets left to process for ARP */
873 for (; pkts_to_process;) {
874 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
875 uint64_t pkt_mask = 1LLU << pos;
876 /* bitmask representing only this packet */
878 pkts_to_process &= ~pkt_mask;
879 /* remove this packet from remaining list */
880 struct rte_mbuf *pkt = pkts[pos];
883 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
884 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
886 if (hdr_chk == IPv4_HDR_VERSION) {
888 struct acl_table_entry *entry =
889 (struct acl_table_entry *)
890 p_acl->acl_entries_ipv4[pos];
891 uint16_t phy_port = pkt->port;
892 uint32_t *port_out_id =
893 RTE_MBUF_METADATA_UINT32_PTR(pkt,
900 ("phy_port = %i, links_map[phy_port] = %i\n",
901 phy_port, p_acl->links_map[phy_port]);
903 /* header room + eth hdr size + dst_adr offset in ip header */
904 uint32_t dst_addr_offset =
905 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
907 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
909 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
911 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
912 struct ether_addr hw_addr;
913 uint32_t dest_address = rte_bswap32(*dst_addr);
914 uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
921 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
923 struct arp_entry_data *ret_arp_data = NULL;
924 ret_arp_data = get_dest_mac_addr_port
925 (dest_address, &dest_if, (struct ether_addr *) eth_dest);
926 *port_out_id = p_acl->port_out_id[dest_if];
927 if (arp_cache_dest_mac_present(dest_if)) {
928 ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src);
929 arp_data_ptr[dest_if]->n_last_update = time(NULL);
931 if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
932 printf("sending buffered packets\n");
933 arp_send_buffered_pkts(ret_arp_data,
934 (struct ether_addr *)eth_dest, *port_out_id);
938 if (unlikely(ret_arp_data == NULL)) {
940 printf("%s: NHIP Not Found, "
941 "outport_id: %d\n", __func__,
945 pkts_mask &= ~(1LLU << pos);
947 printf("ACL after drop pkt_mask "
950 p_acl->counters->pkts_drop++;
954 if (ret_arp_data->status == INCOMPLETE ||
955 ret_arp_data->status == PROBE) {
956 if (ret_arp_data->num_pkts >= NUM_DESC) {
958 pkts_mask &= ~(1LLU << pos);
960 printf("ACL after drop pkt_mask "
963 p_acl->counters->pkts_drop++;
966 arp_pkts_mask |= pkt_mask;
967 arp_queue_unresolved_packet(ret_arp_data, pkt);
973 } /* end of if (hdr_chk == IPv4_HDR_VERSION) */
975 if (hdr_chk == IPv6_HDR_VERSION) {
977 struct acl_table_entry *entry =
978 (struct acl_table_entry *)
979 p_acl->acl_entries_ipv6[pos];
980 //uint16_t phy_port = entry->head.port_id;
981 uint16_t phy_port = pkt->port;
982 uint32_t *port_out_id =
983 RTE_MBUF_METADATA_UINT32_PTR(pkt,
988 /*if (is_phy_port_privte(phy_port))
989 *port_out_id = ACL_PUB_PORT_ID;
991 *port_out_id = ACL_PRV_PORT_ID;*/
993 /* *port_out_id = p_acl->links_map[phy_port]; */
995 printf("phy_port = %i, "
996 "links_map[phy_port] = %i\n",
997 phy_port, p_acl->links_map[phy_port]);
999 /* header room + eth hdr size + dst_adr offset in ip header */
1000 uint32_t dst_addr_offset =
1001 MBUF_HDR_ROOM + ETH_HDR_SIZE +
1002 IP_HDR_DST_ADR_OFST_IPV6;
1004 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
1006 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
1007 struct ether_addr hw_addr;
1008 uint8_t dest_address[16];
1012 RTE_MBUF_METADATA_UINT8(pkt,
1017 uint8_t *dst_addr[16];
1018 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
1021 for (i = 0; i < 16; i++) {
1023 RTE_MBUF_METADATA_UINT8_PTR(pkt,
1027 memcpy(dest_address, *dst_addr, sizeof(dest_address));
1028 memset(nhip, 0, sizeof(nhip));
1029 ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
1032 if (is_phy_port_privte(phy_port)) {
1034 dest_if = get_prv_to_pub_port((
1037 &dest_address[0], IP_VERSION_6);
1038 do_local_nh_ipv6_cache(dest_if, p_acl);
1040 p_acl->port_out_id[dest_if];
1042 // port = ACL_PUB_PORT_ID;
1046 dest_if = get_pub_to_prv_port((
1049 &dest_address[0], IP_VERSION_6);
1050 do_local_nh_ipv6_cache(dest_if, p_acl);
1052 p_acl->port_out_id[dest_if];
1054 // port = ACL_PRV_PORT_ID;
1058 if (get_dest_mac_address_ipv6_port
1059 (dest_address, &dest_if, &hw_addr, &nhip[0])) {
1061 printf("MAC found for port %d - "
1062 " %02x:%02x:%02x:%02x:%02x:%02x\n",
1063 phy_port, hw_addr.addr_bytes[0],
1064 hw_addr.addr_bytes[1],
1065 hw_addr.addr_bytes[2],
1066 hw_addr.addr_bytes[3],
1067 hw_addr.addr_bytes[4],
1068 hw_addr.addr_bytes[5]);
1069 printf("Dest MAC before - "
1070 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1071 eth_dest[0], eth_dest[1],
1072 eth_dest[2], eth_dest[3],
1073 eth_dest[4], eth_dest[5]);
1075 memcpy(eth_dest, &hw_addr,
1076 sizeof(struct ether_addr));
1078 printf("PktP %p, dest_macP %p\n", pkt,
1080 printf("Dest MAC after - "
1081 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1082 eth_dest[0], eth_dest[1],
1083 eth_dest[2], eth_dest[3],
1084 eth_dest[4], eth_dest[5]);
1086 if (is_phy_port_privte(phy_port))
1088 get_link_hw_addr(dest_if),
1089 sizeof(struct ether_addr));
1092 get_link_hw_addr(dest_if),
1093 sizeof(struct ether_addr));
1095 /* memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]), */
1096 /* sizeof(struct ether_addr)); */
1097 p_acl->counters->tpkts_processed++;
1098 p_acl->counters->bytes_processed +=
1105 /* Request next neighbor for Ipv6 is yet to be done. */
1109 ("ACL requesting ARP for ip %x, port %d\n",
1110 dest_address, phy_port);
1112 /* request_arp(p_acl->links_map[phy_port], *nhip); */
1115 /* Drop packet by changing the mask */
1117 printf("ACL before drop pkt_mask "
1118 "%lu, pkt_num %d\n",
1120 pkts_mask &= ~(1LLU << pos);
1122 printf("ACL after drop pkt_mask "
1123 "%lu, pkt_num %d\n",
1125 p_acl->counters->pkts_drop++;
1131 pkts_drop_mask = keep_mask & ~pkts_mask;
1132 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
1133 keep_mask = pkts_mask;
1135 if (arp_pkts_mask) {
1136 keep_mask &= ~(arp_pkts_mask);
1137 rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
1140 /* don't bother measuring if traffic very low, might skew stats */
1141 uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
1143 if (packets_this_iteration > 1) {
1144 uint64_t latency_this_iteration =
1145 rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
1147 p_acl->counters->sum_latencies += latency_this_iteration;
1148 p_acl->counters->count_latencies++;
1152 printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
1159 * Main packet processing function.
1160 * 64 packet bit mask are used to identify which packets to forward.
1161 * Performs the following:
1162 * - Burst lookup packets in the IPv4 ACL Rule Table.
1163 * - Burst lookup packets in the IPv6 ACL Rule Table.
1164 * - Lookup Action Table, perform actions.
1165 * - Burst lookup Connection Tracking, if enabled.
1166 * - Lookup MAC address.
1168 * - Packets with bit mask set are forwarded
1171 * A pointer to the pipeline.
1173 * A pointer to a burst of packets.
1175 * Number of packets to process.
1177 * A pointer to pipeline specific data.
1180 * 0 on success, negative on error.
1183 pkt_work_acl_ipv4_key(struct rte_pipeline *p,
1184 struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
1187 struct pipeline_acl *p_acl = arg;
1189 p_acl->counters->pkts_received =
1190 p_acl->counters->pkts_received + n_pkts;
1192 printf("pkt_work_acl_key pkts_received: %" PRIu64
1193 " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
1195 uint64_t lookup_hit_mask = 0;
1196 uint64_t lookup_hit_mask_ipv4 = 0;
1197 uint64_t lookup_hit_mask_ipv6 = 0;
1198 uint64_t lookup_miss_mask = 0;
1199 uint64_t conntrack_mask = 0;
1200 uint64_t connexist_mask = 0;
1201 uint32_t dest_address = 0;
1205 uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
1206 uint64_t keep_mask = pkts_mask;
1210 p_acl->in_port_time_stamp = rte_get_tsc_cycles();
1212 if (acl_ipv4_enabled) {
1214 printf("ACL IPV4 Lookup Mask Before = %p\n",
1217 rte_table_acl_ops.f_lookup(acl_rule_table_ipv4_active, pkts,
1218 pkts_mask, &lookup_hit_mask_ipv4,
1220 p_acl->acl_entries_ipv4);
1222 printf("ACL IPV4 Lookup Mask After = %p\n",
1223 (void *)lookup_hit_mask_ipv4);
1226 /* Merge lookup results since we process both IPv4 and IPv6 below */
1227 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
1229 printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
1231 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
1232 pkts_mask = lookup_hit_mask;
1233 p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
1235 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
1236 p_acl->counters->pkts_drop,
1237 __builtin_popcountll(lookup_miss_mask));
1239 uint64_t pkts_to_process = lookup_hit_mask;
1240 /* bitmap of packets left to process for ARP */
1242 for (; pkts_to_process;) {
1243 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
1244 uint64_t pkt_mask = 1LLU << pos;
1245 /* bitmask representing only this packet */
1247 pkts_to_process &= ~pkt_mask;
1248 /* remove this packet from remaining list */
1249 struct rte_mbuf *pkt = pkts[pos];
1252 if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
1253 pkts_mask &= ~(1LLU << pos);
1258 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
1259 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1261 if (hdr_chk == IPv4_HDR_VERSION) {
1262 struct acl_table_entry *entry =
1263 (struct acl_table_entry *)
1264 p_acl->acl_entries_ipv4[pos];
1265 uint16_t phy_port = entry->head.port_id;
1266 uint32_t action_id = entry->action_id;
1269 printf("action_id = %u\n", action_id);
1271 uint32_t dscp_offset =
1272 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
1274 if (action_array_active[action_id].action_bitmap &
1276 action_counter_table
1277 [p_acl->action_counter_index]
1278 [action_id].packetCount++;
1279 action_counter_table
1280 [p_acl->action_counter_index]
1281 [action_id].byteCount +=
1282 rte_pktmbuf_pkt_len(pkt);
1284 printf("Action Count Packet Count: %"
1285 PRIu64 " Byte Count: %" PRIu64
1287 action_counter_table
1288 [p_acl->action_counter_index]
1289 [action_id].packetCount,
1290 action_counter_table
1291 [p_acl->action_counter_index]
1292 [action_id].byteCount);
1295 if (action_array_active[action_id].action_bitmap &
1296 acl_action_packet_drop) {
1298 /* Drop packet by changing the mask */
1300 printf("ACL before drop pkt_mask "
1301 "%lu, pkt_num %d\n",
1303 pkts_mask &= ~(1LLU << pos);
1305 printf("ACL after drop pkt_mask "
1306 " %lu, pkt_num %d\n",
1308 p_acl->counters->pkts_drop++;
1311 if (action_array_active[action_id].action_bitmap &
1314 action_array_active[action_id].fwd_port;
1315 entry->head.port_id = phy_port;
1317 printf("Action FWD Port ID: %u\n",
1321 if (action_array_active[action_id].action_bitmap &
1324 action_array_active[action_id].nat_port;
1325 entry->head.port_id = phy_port;
1327 printf("Action NAT Port ID: %u\n",
1331 if (action_array_active[action_id].action_bitmap &
1334 /* Set DSCP priority */
1335 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
1338 action_array_active[action_id].dscp_priority
1342 ("Action DSCP DSCP Priority: %u\n",
1346 if (action_array_active[action_id].action_bitmap &
1347 acl_action_packet_accept) {
1349 printf("Action Accept\n");
1351 if (action_array_active[action_id].action_bitmap
1352 & acl_action_conntrack) {
1354 /* Set conntrack bit for this pkt */
1355 conntrack_mask |= pkt_mask;
1357 printf("ACL Conntrack "
1358 "enabled: %p pkt_mask: %p\n",
1359 (void *)conntrack_mask,
1363 if (action_array_active[action_id].action_bitmap
1364 & acl_action_connexist) {
1366 /* Set conntrack bit for this pkt */
1367 conntrack_mask |= pkt_mask;
1369 /* Set connexist bit for this pkt for public -> private */
1370 /* Private -> public packet will open the connection */
1371 if (action_array_active
1372 [action_id].private_public ==
1374 connexist_mask |= pkt_mask;
1377 printf("ACL Connexist "
1378 "enabled conntrack: %p connexist: %p pkt_mask: %p\n",
1379 (void *)conntrack_mask,
1380 (void *)connexist_mask,
1386 if (hdr_chk == IPv6_HDR_VERSION) {
1388 struct acl_table_entry *entry =
1389 (struct acl_table_entry *)
1390 p_acl->acl_entries_ipv6[pos];
1391 uint16_t phy_port = entry->head.port_id;
1392 uint32_t action_id = entry->action_id;
1395 printf("action_id = %u\n", action_id);
1397 if (action_array_active[action_id].action_bitmap &
1399 action_counter_table
1400 [p_acl->action_counter_index]
1401 [action_id].packetCount++;
1402 action_counter_table
1403 [p_acl->action_counter_index]
1404 [action_id].byteCount +=
1405 rte_pktmbuf_pkt_len(pkt);
1407 printf("Action Count Packet Count: %"
1408 PRIu64 " Byte Count: %" PRIu64
1410 action_counter_table
1411 [p_acl->action_counter_index]
1412 [action_id].packetCount,
1413 action_counter_table
1414 [p_acl->action_counter_index]
1415 [action_id].byteCount);
1418 if (action_array_active[action_id].action_bitmap &
1419 acl_action_packet_drop) {
1420 /* Drop packet by changing the mask */
1423 ("ACL before drop pkt_mask %lu, pkt_num %d\n",
1425 pkts_mask &= ~(1LLU << pos);
1428 ("ACL after drop pkt_mask %lu, pkt_num %d\n",
1430 p_acl->counters->pkts_drop++;
1434 if (action_array_active[action_id].action_bitmap &
1437 action_array_active[action_id].fwd_port;
1438 entry->head.port_id = phy_port;
1440 printf("Action FWD Port ID: %u\n",
1444 if (action_array_active[action_id].action_bitmap &
1447 action_array_active[action_id].nat_port;
1448 entry->head.port_id = phy_port;
1450 printf("Action NAT Port ID: %u\n",
1454 if (action_array_active[action_id].action_bitmap &
1457 /* Set DSCP priority */
1458 uint32_t dscp_offset =
1459 MBUF_HDR_ROOM + ETH_HDR_SIZE +
1460 IP_HDR_DSCP_OFST_IPV6;
1462 RTE_MBUF_METADATA_UINT16_PTR(pkt,
1464 uint16_t dscp_value =
1466 (RTE_MBUF_METADATA_UINT16
1467 (pkt, dscp_offset)) & 0XF00F);
1468 uint8_t dscp_store =
1469 action_array_active[action_id].dscp_priority
1471 uint16_t dscp_temp = dscp_store;
1473 dscp_temp = dscp_temp << 4;
1474 *dscp = rte_bswap16(dscp_temp | dscp_value);
1477 ("Action DSCP DSCP Priority: %u\n",
1481 if (action_array_active[action_id].action_bitmap &
1482 acl_action_packet_accept) {
1484 printf("Action Accept\n");
1486 if (action_array_active[action_id].action_bitmap
1487 & acl_action_conntrack) {
1489 /* Set conntrack bit for this pkt */
1490 conntrack_mask |= pkt_mask;
1492 printf("ACL Conntrack "
1493 "enabled: %p pkt_mask: %p\n",
1494 (void *)conntrack_mask,
1498 if (action_array_active[action_id].action_bitmap
1499 & acl_action_connexist) {
1501 /* Set conntrack bit for this pkt */
1502 conntrack_mask |= pkt_mask;
1504 /* Set connexist bit for this pkt for public -> private */
1505 /* Private -> public packet will open the connection */
1506 if (action_array_active
1507 [action_id].private_public ==
1509 connexist_mask |= pkt_mask;
1512 printf("ACL Connexist enabled "
1513 "conntrack: %p connexist: %p pkt_mask: %p\n",
1514 (void *)conntrack_mask,
1515 (void *)connexist_mask,
1522 /* Only call connection tracker if required */
1523 if (conntrack_mask > 0) {
1526 ("ACL Call Conntrack Before = %p Connexist = %p\n",
1527 (void *)conntrack_mask, (void *)connexist_mask);
1529 rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
1530 (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
1532 printf("ACL Call Conntrack After = %p\n",
1533 (void *)conntrack_mask);
1535 /* Only change pkt mask for pkts that have conntrack enabled */
1536 /* Need to loop through packets to check if conntrack enabled */
1537 pkts_to_process = pkts_mask;
1538 for (; pkts_to_process;) {
1539 uint32_t action_id = 0;
1541 (uint8_t) __builtin_ctzll(pkts_to_process);
1542 uint64_t pkt_mask = 1LLU << pos;
1543 /* bitmask representing only this packet */
1545 pkts_to_process &= ~pkt_mask;
1546 /* remove this packet from remaining list */
1547 struct rte_mbuf *pkt = pkts[pos];
1549 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
1553 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1554 if (hdr_chk == IPv4_HDR_VERSION) {
1555 struct acl_table_entry *entry =
1556 (struct acl_table_entry *)
1557 p_acl->acl_entries_ipv4[pos];
1558 action_id = entry->action_id;
1560 struct acl_table_entry *entry =
1561 (struct acl_table_entry *)
1562 p_acl->acl_entries_ipv6[pos];
1563 action_id = entry->action_id;
1566 if ((action_array_active[action_id].action_bitmap &
1567 acl_action_conntrack)
1568 || (action_array_active[action_id].action_bitmap &
1569 acl_action_connexist)) {
1571 if (conntrack_mask & pkt_mask) {
1573 printf("ACL Conntrack Accept "
1577 /* Drop packet by changing the mask */
1579 printf("ACL Conntrack Drop "
1582 pkts_mask &= ~pkt_mask;
1583 p_acl->counters->pkts_drop++;
1589 pkts_to_process = pkts_mask;
1590 /* bitmap of packets left to process for ARP */
1592 for (; pkts_to_process;) {
1593 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
1594 uint64_t pkt_mask = 1LLU << pos;
1595 /* bitmask representing only this packet */
1597 pkts_to_process &= ~pkt_mask;
1598 /* remove this packet from remaining list */
1599 struct rte_mbuf *pkt = pkts[pos];
1602 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
1603 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1605 if (hdr_chk == IPv4_HDR_VERSION) {
1607 struct acl_table_entry *entry =
1608 (struct acl_table_entry *)
1609 p_acl->acl_entries_ipv4[pos];
1610 //uint16_t phy_port = entry->head.port_id;
1611 uint16_t phy_port = pkt->port;
1612 uint32_t *port_out_id =
1613 RTE_MBUF_METADATA_UINT32_PTR(pkt,
1618 /* *port_out_id = p_acl->links_map[phy_port]; */
1619 /* if (is_phy_port_privte(phy_port))
1620 *port_out_id = ACL_PUB_PORT_ID;
1622 *port_out_id = ACL_PRV_PORT_ID;*/
1625 ("phy_port = %i, links_map[phy_port] = %i\n",
1626 phy_port, p_acl->links_map[phy_port]);
1628 /* header room + eth hdr size + dst_adr offset in ip header */
1629 uint32_t dst_addr_offset =
1630 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
1631 uint32_t *dst_addr =
1632 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
1634 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
1636 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
1637 struct ether_addr hw_addr;
1638 uint32_t dest_address = rte_bswap32(*dst_addr);
1639 uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
1646 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
1648 if (is_phy_port_privte(phy_port)) {
1649 dest_address = rte_bswap32(*dst_addr);
1651 local_get_nh_ipv4(dest_address, &dest_if,
1655 get_prv_to_pub_port(&dest_address,
1657 do_local_nh_ipv4_cache(dest_if, p_acl);
1659 *port_out_id = p_acl->port_out_id[dest_if];
1661 /* port = ACL_PUB_PORT_ID; */
1663 dest_address = rte_bswap32(*dst_addr);
1665 ret = local_get_nh_ipv4(dest_address, &dest_if,
1669 get_pub_to_prv_port(&dest_address,
1671 do_local_nh_ipv4_cache(dest_if, p_acl);
1673 *port_out_id = p_acl->port_out_id[dest_if];
1675 /* port = ACL_PRV_PORT_ID; */
1677 struct arp_entry_data *ret_arp_data = NULL;
1678 ret_arp_data = get_dest_mac_addr_port
1679 (dest_address, &dest_if, (struct ether_addr *)eth_dest);
1680 *port_out_id = p_acl->port_out_id[dest_if];
1682 if (arp_cache_dest_mac_present(dest_if)) {
1683 ether_addr_copy(get_link_hw_addr(dest_if), (struct ether_addr *)eth_src);
1684 arp_data_ptr[dest_if]->n_last_update = time(NULL);
1686 if (unlikely(ret_arp_data && ret_arp_data->num_pkts)) {
1687 printf("sending buffered packets\n");
1688 arp_send_buffered_pkts(ret_arp_data,
1689 (struct ether_addr *)eth_dest, *port_out_id);
1693 if (unlikely(ret_arp_data == NULL)) {
1695 printf("%s: NHIP Not Found, "
1696 "outport_id: %d\n", __func__,
1700 pkts_mask &= ~(1LLU << pos);
1702 printf("ACL after drop pkt_mask "
1703 "%lu, pkt_num %d\n",
1705 p_acl->counters->pkts_drop++;
1709 if (ret_arp_data->status == INCOMPLETE ||
1710 ret_arp_data->status == PROBE) {
1711 if (ret_arp_data->num_pkts >= NUM_DESC) {
1713 pkts_mask &= ~(1LLU << pos);
1715 printf("ACL after drop pkt_mask "
1716 "%lu, pkt_num %d\n",
1718 p_acl->counters->pkts_drop++;
1721 arp_pkts_mask |= pkt_mask;
1722 arp_queue_unresolved_packet(ret_arp_data, pkt);
1729 if (hdr_chk == IPv6_HDR_VERSION) {
1731 struct acl_table_entry *entry =
1732 (struct acl_table_entry *)
1733 p_acl->acl_entries_ipv6[pos];
1734 uint16_t phy_port = entry->head.port_id;
1735 uint32_t *port_out_id =
1736 RTE_MBUF_METADATA_UINT32_PTR(pkt,
1741 if (is_phy_port_privte(phy_port))
1742 *port_out_id = ACL_PUB_PORT_ID;
1744 *port_out_id = ACL_PRV_PORT_ID;
1746 /* *port_out_id = p_acl->links_map[phy_port]; */
1749 ("phy_port = %i, links_map[phy_port] = %i\n",
1750 phy_port, p_acl->links_map[phy_port]);
1752 /* header room + eth hdr size + dst_adr offset in ip header */
1753 uint32_t dst_addr_offset =
1754 MBUF_HDR_ROOM + ETH_HDR_SIZE +
1755 IP_HDR_DST_ADR_OFST_IPV6;
1757 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
1759 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
1760 struct ether_addr hw_addr;
1761 uint8_t dest_address[16];
1765 RTE_MBUF_METADATA_UINT8(pkt,
1770 uint8_t *dst_addr[16];
1771 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
1774 for (i = 0; i < 16; i++) {
1776 RTE_MBUF_METADATA_UINT8_PTR(pkt,
1780 memcpy(dest_address, *dst_addr, sizeof(dest_address));
1781 memset(nhip, 0, sizeof(nhip));
1782 if (is_phy_port_privte(phy_port))
1783 port = ACL_PUB_PORT_ID;
1785 port = ACL_PRV_PORT_ID;
1787 if (get_dest_mac_address_ipv6_port
1788 (dest_address, port, &hw_addr, &nhip[0])) {
1792 ("MAC found for port %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
1793 phy_port, hw_addr.addr_bytes[0],
1794 hw_addr.addr_bytes[1],
1795 hw_addr.addr_bytes[2],
1796 hw_addr.addr_bytes[3],
1797 hw_addr.addr_bytes[4],
1798 hw_addr.addr_bytes[5]);
1800 ("Dest MAC before - %02x:%02x:%02x:%02x:%02x:%02x\n",
1801 eth_dest[0], eth_dest[1],
1802 eth_dest[2], eth_dest[3],
1803 eth_dest[4], eth_dest[5]);
1805 memcpy(eth_dest, &hw_addr,
1806 sizeof(struct ether_addr));
1808 printf("PktP %p, dest_macP %p\n", pkt,
1811 ("Dest MAC after - %02x:%02x:%02x:%02x:%02x:%02x\n",
1812 eth_dest[0], eth_dest[1],
1813 eth_dest[2], eth_dest[3],
1814 eth_dest[4], eth_dest[5]);
1816 if (is_phy_port_privte(phy_port))
1818 get_link_hw_addr(dest_if),
1819 sizeof(struct ether_addr));
1822 get_link_hw_addr(dest_if),
1823 sizeof(struct ether_addr));
1826 * memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]),
1827 * sizeof(struct ether_addr));
1829 p_acl->counters->tpkts_processed++;
1830 p_acl->counters->bytes_processed +=
1837 /* Request next neighbor for Ipv6 is yet to be done. */
1841 ("ACL requesting ARP for ip %x, port %d\n",
1842 dest_address, phy_port);
1844 /* request_arp(p_acl->links_map[phy_port], *nhip); */
1847 /* Drop packet by changing the mask */
1849 printf("ACL before drop pkt_mask "
1850 " %lu, pkt_num %d\n",
1852 pkts_mask &= ~(1LLU << pos);
1854 printf("ACL after drop pkt_mask "
1855 "%lu, pkt_num %d\n",
1857 p_acl->counters->pkts_drop++;
1864 pkts_drop_mask = keep_mask & ~pkts_mask;
1865 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
1866 keep_mask = pkts_mask;
1868 if (arp_pkts_mask) {
1869 keep_mask &= ~(arp_pkts_mask);
1870 rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
1873 /* don't bother measuring if traffic very low, might skew stats */
1874 uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
1876 if (packets_this_iteration > 1) {
1877 uint64_t latency_this_iteration =
1878 rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
1879 p_acl->counters->sum_latencies += latency_this_iteration;
1880 p_acl->counters->count_latencies++;
1883 printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
1890 * Main packet processing function.
1891 * 64 packet bit mask are used to identify which packets to forward.
1892 * Performs the following:
1893 * - Burst lookup packets in the IPv4 ACL Rule Table.
1894 * - Burst lookup packets in the IPv6 ACL Rule Table.
1895 * - Lookup Action Table, perform actions.
1896 * - Burst lookup Connection Tracking, if enabled.
1897 * - Lookup MAC address.
1899 * - Packets with bit mask set are forwarded
1902 * A pointer to the pipeline.
1904 * A pointer to a burst of packets.
1906 * Number of packets to process.
1908 * A pointer to pipeline specific data.
1911 * 0 on success, negative on error.
1914 pkt_work_acl_ipv6_key(struct rte_pipeline *p,
1915 struct rte_mbuf **pkts, uint32_t n_pkts, void *arg)
1918 struct pipeline_acl *p_acl = arg;
1920 p_acl->counters->pkts_received =
1921 p_acl->counters->pkts_received + n_pkts;
1923 printf("pkt_work_acl_key pkts_received: %" PRIu64
1924 " n_pkts: %u\n", p_acl->counters->pkts_received, n_pkts);
1926 uint64_t lookup_hit_mask = 0;
1927 uint64_t lookup_hit_mask_ipv4 = 0;
1928 uint64_t lookup_hit_mask_ipv6 = 0;
1929 uint64_t lookup_miss_mask = 0;
1930 uint64_t conntrack_mask = 0;
1931 uint64_t connexist_mask = 0;
1932 uint32_t dest_address = 0;
1936 uint64_t pkts_drop_mask, pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
1937 uint64_t keep_mask = pkts_mask;
1941 p_acl->in_port_time_stamp = rte_get_tsc_cycles();
1943 if (acl_ipv6_enabled) {
1945 printf("ACL IPV6 Lookup Mask Before = %p\n",
1948 rte_table_acl_ops.f_lookup(acl_rule_table_ipv6_active, pkts,
1949 pkts_mask, &lookup_hit_mask_ipv6,
1951 p_acl->acl_entries_ipv6);
1953 printf("ACL IPV6 Lookup Mask After = %p\n",
1954 (void *)lookup_hit_mask_ipv6);
1957 /* Merge lookup results since we process both IPv4 and IPv6 below */
1958 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
1960 printf("ACL Lookup Mask After = %p\n", (void *)lookup_hit_mask);
1962 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
1963 pkts_mask = lookup_hit_mask;
1964 p_acl->counters->pkts_drop += __builtin_popcountll(lookup_miss_mask);
1966 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
1967 p_acl->counters->pkts_drop,
1968 __builtin_popcountll(lookup_miss_mask));
1970 uint64_t pkts_to_process = lookup_hit_mask;
1971 /* bitmap of packets left to process for ARP */
1973 for (; pkts_to_process;) {
1974 uint8_t pos = (uint8_t) __builtin_ctzll(pkts_to_process);
1975 uint64_t pkt_mask = 1LLU << pos;
1976 /* bitmask representing only this packet */
1978 pkts_to_process &= ~pkt_mask;
1979 /* remove this packet from remaining list */
1980 struct rte_mbuf *pkt = pkts[pos];
1983 if (!check_arp_icmp(pkt, pkt_mask, p_acl)) {
1984 pkts_mask &= ~(1LLU << pos);
1988 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
1989 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
1991 if (hdr_chk == IPv4_HDR_VERSION) {
1992 struct acl_table_entry *entry =
1993 (struct acl_table_entry *)
1994 p_acl->acl_entries_ipv4[pos];
1995 uint16_t phy_port = entry->head.port_id;
1996 uint32_t action_id = entry->action_id;
1999 printf("action_id = %u\n", action_id);
2001 uint32_t dscp_offset =
2002 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DSCP_OFST;
2004 if (action_array_active[action_id].action_bitmap &
2006 action_counter_table
2007 [p_acl->action_counter_index]
2008 [action_id].packetCount++;
2009 action_counter_table
2010 [p_acl->action_counter_index]
2011 [action_id].byteCount +=
2012 rte_pktmbuf_pkt_len(pkt);
2014 printf("Action Count Packet Count: %"
2015 PRIu64 " Byte Count: %" PRIu64
2017 action_counter_table
2018 [p_acl->action_counter_index]
2019 [action_id].packetCount,
2020 action_counter_table
2021 [p_acl->action_counter_index]
2022 [action_id].byteCount);
2025 if (action_array_active[action_id].action_bitmap &
2026 acl_action_packet_drop) {
2028 /* Drop packet by changing the mask */
2031 ("ACL before drop pkt_mask %lu, pkt_num %d\n",
2033 pkts_mask &= ~(1LLU << pos);
2036 ("ACL after drop pkt_mask %lu, pkt_num %d\n",
2038 p_acl->counters->pkts_drop++;
2041 if (action_array_active[action_id].action_bitmap &
2044 action_array_active[action_id].fwd_port;
2045 entry->head.port_id = phy_port;
2047 printf("Action FWD Port ID: %u\n",
2051 if (action_array_active[action_id].action_bitmap &
2054 action_array_active[action_id].nat_port;
2055 entry->head.port_id = phy_port;
2057 printf("Action NAT Port ID: %u\n",
2061 if (action_array_active[action_id].action_bitmap &
2064 /* Set DSCP priority */
2065 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
2068 action_array_active[action_id].dscp_priority
2072 ("Action DSCP DSCP Priority: %u\n",
2076 if (action_array_active[action_id].action_bitmap &
2077 acl_action_packet_accept) {
2079 printf("Action Accept\n");
2081 if (action_array_active[action_id].action_bitmap
2082 & acl_action_conntrack) {
2084 /* Set conntrack bit for this pkt */
2085 conntrack_mask |= pkt_mask;
2087 printf("ACL Conntrack enabled: "
2088 " %p pkt_mask: %p\n",
2089 (void *)conntrack_mask,
2093 if (action_array_active[action_id].action_bitmap
2094 & acl_action_connexist) {
2096 /* Set conntrack bit for this pkt */
2097 conntrack_mask |= pkt_mask;
2099 /* Set connexist bit for this pkt for public -> private */
2100 /* Private -> public packet will open the connection */
2101 if (action_array_active
2102 [action_id].private_public ==
2104 connexist_mask |= pkt_mask;
2107 printf("ACL Connexist enabled "
2108 "conntrack: %p connexist: %p pkt_mask: %p\n",
2109 (void *)conntrack_mask,
2110 (void *)connexist_mask,
2117 if (hdr_chk == IPv6_HDR_VERSION) {
2119 struct acl_table_entry *entry =
2120 (struct acl_table_entry *)
2121 p_acl->acl_entries_ipv6[pos];
2122 uint16_t phy_port = entry->head.port_id;
2123 uint32_t action_id = entry->action_id;
2126 printf("action_id = %u\n", action_id);
2128 if (action_array_active[action_id].action_bitmap &
2130 action_counter_table
2131 [p_acl->action_counter_index]
2132 [action_id].packetCount++;
2133 action_counter_table
2134 [p_acl->action_counter_index]
2135 [action_id].byteCount +=
2136 rte_pktmbuf_pkt_len(pkt);
2138 printf("Action Count Packet Count: %"
2139 PRIu64 " Byte Count: %" PRIu64
2141 action_counter_table
2142 [p_acl->action_counter_index]
2143 [action_id].packetCount,
2144 action_counter_table
2145 [p_acl->action_counter_index]
2146 [action_id].byteCount);
2149 if (action_array_active[action_id].action_bitmap &
2150 acl_action_packet_drop) {
2151 /* Drop packet by changing the mask */
2153 printf("ACL before drop pkt_mask "
2154 "%lu, pkt_num %d\n",
2156 pkts_mask &= ~(1LLU << pos);
2158 printf("ACL after drop pkt_mask "
2159 "%lu, pkt_num %d\n",
2161 p_acl->counters->pkts_drop++;
2165 if (action_array_active[action_id].action_bitmap &
2168 action_array_active[action_id].fwd_port;
2169 entry->head.port_id = phy_port;
2171 printf("Action FWD Port ID: %u\n",
2175 if (action_array_active[action_id].action_bitmap &
2178 action_array_active[action_id].nat_port;
2179 entry->head.port_id = phy_port;
2181 printf("Action NAT Port ID: %u\n",
2185 if (action_array_active[action_id].action_bitmap &
2188 /* Set DSCP priority */
2189 uint32_t dscp_offset =
2190 MBUF_HDR_ROOM + ETH_HDR_SIZE +
2191 IP_HDR_DSCP_OFST_IPV6;
2193 RTE_MBUF_METADATA_UINT16_PTR(pkt,
2195 uint16_t dscp_value =
2197 (RTE_MBUF_METADATA_UINT16
2198 (pkt, dscp_offset)) & 0XF00F);
2199 uint8_t dscp_store =
2200 action_array_active[action_id].dscp_priority
2202 uint16_t dscp_temp = dscp_store;
2204 dscp_temp = dscp_temp << 4;
2205 *dscp = rte_bswap16(dscp_temp | dscp_value);
2208 ("Action DSCP DSCP Priority: %u\n",
2212 if (action_array_active[action_id].action_bitmap &
2213 acl_action_packet_accept) {
2215 printf("Action Accept\n");
2217 if (action_array_active[action_id].action_bitmap
2218 & acl_action_conntrack) {
2220 /* Set conntrack bit for this pkt */
2221 conntrack_mask |= pkt_mask;
2223 printf("ACL Conntrack enabled: "
2224 " %p pkt_mask: %p\n",
2225 (void *)conntrack_mask,
2229 if (action_array_active[action_id].action_bitmap
2230 & acl_action_connexist) {
2232 /* Set conntrack bit for this pkt */
2233 conntrack_mask |= pkt_mask;
2235 /* Set connexist bit for this pkt for public -> private */
2236 /* Private -> public packet will open the connection */
2237 if (action_array_active
2238 [action_id].private_public ==
2240 connexist_mask |= pkt_mask;
2243 printf("ACL Connexist enabled "
2244 "conntrack: %p connexist: %p pkt_mask: %p\n",
2245 (void *)conntrack_mask,
2246 (void *)connexist_mask,
2252 /* Only call connection tracker if required */
2253 if (conntrack_mask > 0) {
2256 ("ACL Call Conntrack Before = %p Connexist = %p\n",
2257 (void *)conntrack_mask, (void *)connexist_mask);
2259 rte_ct_cnxn_tracker_batch_lookup_with_new_cnxn_control
2260 (p_acl->cnxn_tracker, pkts, conntrack_mask, connexist_mask);
2262 printf("ACL Call Conntrack After = %p\n",
2263 (void *)conntrack_mask);
2265 /* Only change pkt mask for pkts that have conntrack enabled */
2266 /* Need to loop through packets to check if conntrack enabled */
2267 pkts_to_process = pkts_mask;
2268 for (; pkts_to_process;) {
2269 uint32_t action_id = 0;
2271 (uint8_t) __builtin_ctzll(pkts_to_process);
2272 uint64_t pkt_mask = 1LLU << pos;
2273 /* bitmask representing only this packet */
2275 pkts_to_process &= ~pkt_mask;
2276 /* remove this packet from remaining list */
2277 struct rte_mbuf *pkt = pkts[pos];
2279 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt,
2283 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
2284 if (hdr_chk == IPv4_HDR_VERSION) {
2285 struct acl_table_entry *entry =
2286 (struct acl_table_entry *)
2287 p_acl->acl_entries_ipv4[pos];
2288 action_id = entry->action_id;
2290 struct acl_table_entry *entry =
2291 (struct acl_table_entry *)
2292 p_acl->acl_entries_ipv6[pos];
2293 action_id = entry->action_id;
2296 if ((action_array_active[action_id].action_bitmap &
2297 acl_action_conntrack)
2298 || (action_array_active[action_id].action_bitmap &
2299 acl_action_connexist)) {
2301 if (conntrack_mask & pkt_mask) {
2303 printf("ACL Conntrack Accept "
2307 /* Drop packet by changing the mask */
2310 ("ACL Conntrack Drop packet = %p\n",
2312 pkts_mask &= ~pkt_mask;
2313 p_acl->counters->pkts_drop++;
2319 pkts_to_process = pkts_mask;
2320 /* bitmap of packets left to process for ARP */
2322 for (; pkts_to_process;) {
2323 uint8_t pos = (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];
2332 RTE_MBUF_METADATA_UINT8(pkt, MBUF_HDR_ROOM + ETH_HDR_SIZE);
2333 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
2335 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 uint16_t phy_port = entry->head.port_id;
2341 uint32_t *port_out_id =
2342 RTE_MBUF_METADATA_UINT32_PTR(pkt,
2347 /* *port_out_id = p_acl->links_map[phy_port]; */
2348 if (is_phy_port_privte(phy_port))
2349 *port_out_id = ACL_PUB_PORT_ID;
2351 *port_out_id = ACL_PRV_PORT_ID;
2354 ("phy_port = %i,links_map[phy_port] = %i\n",
2355 phy_port, p_acl->links_map[phy_port]);
2357 /* header room + eth hdr size + dst_adr offset in ip header */
2358 uint32_t dst_addr_offset =
2359 MBUF_HDR_ROOM + ETH_HDR_SIZE + IP_HDR_DST_ADR_OFST;
2360 uint32_t *dst_addr =
2361 RTE_MBUF_METADATA_UINT32_PTR(pkt, dst_addr_offset);
2363 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
2365 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
2366 struct ether_addr hw_addr;
2367 uint32_t dest_address = rte_bswap32(*dst_addr);
2368 uint32_t *nhip = RTE_MBUF_METADATA_UINT32_PTR(pkt,
2375 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
2377 if (is_phy_port_privte(phy_port)) {
2378 dest_address = rte_bswap32(*dst_addr);
2380 local_get_nh_ipv4(dest_address, &dest_if,
2384 get_prv_to_pub_port(&dest_address,
2386 do_local_nh_ipv4_cache(dest_if, p_acl);
2388 *port_out_id = p_acl->port_out_id[dest_if];
2390 /* port = ACL_PUB_PORT_ID; */
2392 dest_address = rte_bswap32(*dst_addr);
2394 ret = local_get_nh_ipv4(dest_address, &dest_if,
2398 get_pub_to_prv_port(&dest_address,
2400 do_local_nh_ipv4_cache(dest_if, p_acl);
2402 *port_out_id = p_acl->port_out_id[dest_if];
2404 /* port = ACL_PRV_PORT_ID; */
2406 if (get_dest_mac_addr_port
2407 (dest_address, &dest_if, &hw_addr)) {
2409 printf("MAC found for ip 0x%x, port "
2410 " %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
2411 dest_address, phy_port,
2412 hw_addr.addr_bytes[0],
2413 hw_addr.addr_bytes[1],
2414 hw_addr.addr_bytes[2],
2415 hw_addr.addr_bytes[3],
2416 hw_addr.addr_bytes[4],
2417 hw_addr.addr_bytes[5]);
2418 printf("Dest MAC before - "
2419 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2420 eth_dest[0], eth_dest[1],
2421 eth_dest[2], eth_dest[3],
2422 eth_dest[4], eth_dest[5]);
2425 memcpy(eth_dest, &hw_addr,
2426 sizeof(struct ether_addr));
2428 printf("PktP %p, dest_macP %p\n", pkt,
2430 printf("Dest MAC after - "
2431 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2432 eth_dest[0], eth_dest[1],
2433 eth_dest[2], eth_dest[3],
2434 eth_dest[4], eth_dest[5]);
2436 if (is_phy_port_privte(phy_port))
2438 get_link_hw_addr(dest_if),
2439 sizeof(struct ether_addr));
2442 get_link_hw_addr(dest_if),
2443 sizeof(struct ether_addr));
2444 p_acl->counters->tpkts_processed++;
2445 p_acl->counters->bytes_processed +=
2454 printf("ACL requesting ARP for "
2455 " ip %x, port %d\n",
2456 dest_address, phy_port);
2457 if (is_phy_port_privte(phy_port))
2458 request_arp(dest_if, *nhip);
2461 request_arp(dest_if, *nhip);
2463 /* request_arp(p_acl->links_map[phy_port], *nhip); */
2465 /* Drop packet by changing the mask */
2467 printf("ACL before drop pkt_mask "
2468 "%lu, pkt_num %d\n",
2470 pkts_mask &= ~(1LLU << pos);
2472 printf("ACL after drop pkt_mask "
2473 "%lu, pkt_num %d\n",
2475 p_acl->counters->pkts_drop++;
2480 if (hdr_chk == IPv6_HDR_VERSION) {
2482 struct acl_table_entry *entry =
2483 (struct acl_table_entry *)
2484 p_acl->acl_entries_ipv6[pos];
2485 //uint16_t phy_port = entry->head.port_id;
2486 uint16_t phy_port = pkt->port;
2487 uint32_t *port_out_id =
2488 RTE_MBUF_METADATA_UINT32_PTR(pkt,
2493 /* if (is_phy_port_privte(phy_port))
2494 *port_out_id = ACL_PUB_PORT_ID;
2496 *port_out_id = ACL_PRV_PORT_ID;*/
2498 /* *port_out_id = p_acl->links_map[phy_port]; */
2501 ("phy_port = %i,links_map[phy_port] = %i\n",
2502 phy_port, p_acl->links_map[phy_port]);
2504 /* header room + eth hdr size + dst_adr offset in ip header */
2505 uint32_t dst_addr_offset =
2506 MBUF_HDR_ROOM + ETH_HDR_SIZE +
2507 IP_HDR_DST_ADR_OFST_IPV6;
2509 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM);
2511 RTE_MBUF_METADATA_UINT8_PTR(pkt, MBUF_HDR_ROOM + 6);
2512 struct ether_addr hw_addr;
2513 uint8_t dest_address[16];
2517 RTE_MBUF_METADATA_UINT8(pkt,
2522 uint8_t *dst_addr[16];
2523 uint32_t packet_length = rte_pktmbuf_pkt_len(pkt);
2526 for (i = 0; i < 16; i++) {
2528 RTE_MBUF_METADATA_UINT8_PTR(pkt,
2532 memcpy(dest_address, *dst_addr, sizeof(dest_address));
2533 memset(nhip, 0, sizeof(nhip));
2534 ret = local_get_nh_ipv6(&dest_address[0], &dest_if,
2537 if (is_phy_port_privte(phy_port)) {
2539 dest_if = get_prv_to_pub_port((
2542 &dest_address[0], IP_VERSION_6);
2543 do_local_nh_ipv6_cache(dest_if, p_acl);
2545 // port = ACL_PUB_PORT_ID;
2547 p_acl->port_out_id[dest_if];
2551 dest_if = get_pub_to_prv_port((
2554 &dest_address[0], IP_VERSION_6);
2555 do_local_nh_ipv6_cache(dest_if, p_acl);
2557 // port = ACL_PRV_PORT_ID;
2559 p_acl->port_out_id[dest_if];
2563 if (get_dest_mac_address_ipv6_port
2564 (dest_address, &dest_if, &hw_addr, &nhip[0])) {
2566 printf("MAC found for port %d "
2567 "- %02x:%02x:%02x:%02x:%02x:%02x\n",
2568 phy_port, hw_addr.addr_bytes[0],
2569 hw_addr.addr_bytes[1],
2570 hw_addr.addr_bytes[2],
2571 hw_addr.addr_bytes[3],
2572 hw_addr.addr_bytes[4],
2573 hw_addr.addr_bytes[5]);
2574 printf("Dest MAC before - "
2575 " %02x:%02x:%02x:%02x:%02x:%02x\n",
2576 eth_dest[0], eth_dest[1],
2577 eth_dest[2], eth_dest[3],
2578 eth_dest[4], eth_dest[5]);
2580 memcpy(eth_dest, &hw_addr,
2581 sizeof(struct ether_addr));
2583 printf("PktP %p, dest_macP %p\n", pkt,
2585 printf("Dest MAC after - "
2586 " %02x:%02x:%02x:%02x:%02x:%02x\n",
2587 eth_dest[0], eth_dest[1],
2588 eth_dest[2], eth_dest[3],
2589 eth_dest[4], eth_dest[5]);
2591 if (is_phy_port_privte(phy_port))
2593 get_link_hw_addr(dest_if),
2594 sizeof(struct ether_addr));
2597 get_link_hw_addr(dest_if),
2598 sizeof(struct ether_addr));
2601 * memcpy(eth_src, get_link_hw_addr(p_acl->links_map[phy_port]),
2602 * sizeof(struct ether_addr));
2604 p_acl->counters->tpkts_processed++;
2605 p_acl->counters->bytes_processed +=
2612 /* Request next neighbor for Ipv6 is yet to be done. */
2616 ("ACL requesting ARP for ip %x, port %d\n",
2617 dest_address, phy_port);
2619 /* request_arp(p_acl->links_map[phy_port], *nhip); */
2622 /* Drop packet by changing the mask */
2624 printf("ACL before drop pkt_mask "
2625 " %lu, pkt_num %d\n",
2627 pkts_mask &= ~(1LLU << pos);
2629 printf("ACL after drop pkt_mask "
2630 " %lu, pkt_num %d\n",
2632 p_acl->counters->pkts_drop++;
2638 pkts_drop_mask = keep_mask & ~pkts_mask;
2639 rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
2640 keep_mask = pkts_mask;
2642 if (arp_pkts_mask) {
2643 keep_mask &= ~(arp_pkts_mask);
2644 rte_pipeline_ah_packet_hijack(p, arp_pkts_mask);
2647 /* don't bother measuring if traffic very low, might skew stats */
2648 uint32_t packets_this_iteration = __builtin_popcountll(pkts_mask);
2650 if (packets_this_iteration > 1) {
2651 uint64_t latency_this_iteration =
2652 rte_get_tsc_cycles() - p_acl->in_port_time_stamp;
2653 p_acl->counters->sum_latencies += latency_this_iteration;
2654 p_acl->counters->count_latencies++;
2657 printf("Leaving pkt_work_acl_key pkts_mask = %p\n",
2663 static struct rte_acl_field_def field_format_ipv4[] = {
2666 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2667 .size = sizeof(uint8_t),
2670 .offset = sizeof(struct ether_hdr) +
2671 offsetof(struct ipv4_hdr, next_proto_id),
2674 /* Source IP address (IPv4) */
2676 .type = RTE_ACL_FIELD_TYPE_MASK,
2677 .size = sizeof(uint32_t),
2680 .offset = sizeof(struct ether_hdr) +
2681 offsetof(struct ipv4_hdr, src_addr),
2684 /* Destination IP address (IPv4) */
2686 .type = RTE_ACL_FIELD_TYPE_MASK,
2687 .size = sizeof(uint32_t),
2690 .offset = sizeof(struct ether_hdr) +
2691 offsetof(struct ipv4_hdr, dst_addr),
2696 .type = RTE_ACL_FIELD_TYPE_RANGE,
2697 .size = sizeof(uint16_t),
2700 .offset = sizeof(struct ether_hdr) +
2701 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
2704 /* Destination Port */
2706 .type = RTE_ACL_FIELD_TYPE_RANGE,
2707 .size = sizeof(uint16_t),
2710 .offset = sizeof(struct ether_hdr) +
2711 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
2715 #define SIZEOF_VLAN_HDR 4
2717 static struct rte_acl_field_def field_format_vlan_ipv4[] = {
2720 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2721 .size = sizeof(uint8_t),
2724 .offset = sizeof(struct ether_hdr) +
2725 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, next_proto_id),
2728 /* Source IP address (IPv4) */
2730 .type = RTE_ACL_FIELD_TYPE_MASK,
2731 .size = sizeof(uint32_t),
2734 .offset = sizeof(struct ether_hdr) +
2735 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, src_addr),
2738 /* Destination IP address (IPv4) */
2740 .type = RTE_ACL_FIELD_TYPE_MASK,
2741 .size = sizeof(uint32_t),
2744 .offset = sizeof(struct ether_hdr) +
2745 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, dst_addr),
2750 .type = RTE_ACL_FIELD_TYPE_RANGE,
2751 .size = sizeof(uint16_t),
2754 .offset = sizeof(struct ether_hdr) +
2756 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
2759 /* Destination Port */
2761 .type = RTE_ACL_FIELD_TYPE_RANGE,
2762 .size = sizeof(uint16_t),
2765 .offset = sizeof(struct ether_hdr) +
2767 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
2771 #define SIZEOF_QINQ_HEADER 8
2773 static struct rte_acl_field_def field_format_qinq_ipv4[] = {
2776 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2777 .size = sizeof(uint8_t),
2780 .offset = sizeof(struct ether_hdr) +
2781 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, next_proto_id),
2784 /* Source IP address (IPv4) */
2786 .type = RTE_ACL_FIELD_TYPE_MASK,
2787 .size = sizeof(uint32_t),
2790 .offset = sizeof(struct ether_hdr) +
2791 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, src_addr),
2794 /* Destination IP address (IPv4) */
2796 .type = RTE_ACL_FIELD_TYPE_MASK,
2797 .size = sizeof(uint32_t),
2800 .offset = sizeof(struct ether_hdr) +
2801 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, dst_addr),
2806 .type = RTE_ACL_FIELD_TYPE_RANGE,
2807 .size = sizeof(uint16_t),
2810 .offset = sizeof(struct ether_hdr) +
2811 SIZEOF_QINQ_HEADER +
2812 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
2815 /* Destination Port */
2817 .type = RTE_ACL_FIELD_TYPE_RANGE,
2818 .size = sizeof(uint16_t),
2821 .offset = sizeof(struct ether_hdr) +
2822 SIZEOF_QINQ_HEADER +
2823 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
2827 static struct rte_acl_field_def field_format_ipv6[] = {
2830 .type = RTE_ACL_FIELD_TYPE_BITMASK,
2831 .size = sizeof(uint8_t),
2834 .offset = sizeof(struct ether_hdr) +
2835 offsetof(struct ipv6_hdr, proto),
2838 /* Source IP address (IPv6) */
2840 .type = RTE_ACL_FIELD_TYPE_MASK,
2841 .size = sizeof(uint32_t),
2844 .offset = sizeof(struct ether_hdr) +
2845 offsetof(struct ipv6_hdr, src_addr),
2849 .type = RTE_ACL_FIELD_TYPE_MASK,
2850 .size = sizeof(uint32_t),
2853 .offset = sizeof(struct ether_hdr) +
2854 offsetof(struct ipv6_hdr, src_addr) + sizeof(uint32_t),
2859 .type = RTE_ACL_FIELD_TYPE_MASK,
2860 .size = sizeof(uint32_t),
2863 .offset = sizeof(struct ether_hdr) +
2864 offsetof(struct ipv6_hdr, src_addr) + 2 * sizeof(uint32_t),
2869 .type = RTE_ACL_FIELD_TYPE_MASK,
2870 .size = sizeof(uint32_t),
2873 .offset = sizeof(struct ether_hdr) +
2874 offsetof(struct ipv6_hdr, src_addr) + 3 * sizeof(uint32_t),
2878 /* Destination IP address (IPv6) */
2880 .type = RTE_ACL_FIELD_TYPE_MASK,
2881 .size = sizeof(uint32_t),
2884 .offset = sizeof(struct ether_hdr) +
2885 offsetof(struct ipv6_hdr, dst_addr),
2889 .type = RTE_ACL_FIELD_TYPE_MASK,
2890 .size = sizeof(uint32_t),
2893 .offset = sizeof(struct ether_hdr) +
2894 offsetof(struct ipv6_hdr, dst_addr) + sizeof(uint32_t),
2899 .type = RTE_ACL_FIELD_TYPE_MASK,
2900 .size = sizeof(uint32_t),
2903 .offset = sizeof(struct ether_hdr) +
2904 offsetof(struct ipv6_hdr, dst_addr) + 2 * sizeof(uint32_t),
2909 .type = RTE_ACL_FIELD_TYPE_MASK,
2910 .size = sizeof(uint32_t),
2913 .offset = sizeof(struct ether_hdr) +
2914 offsetof(struct ipv6_hdr, dst_addr) + 3 * sizeof(uint32_t),
2920 .type = RTE_ACL_FIELD_TYPE_RANGE,
2921 .size = sizeof(uint16_t),
2924 .offset = sizeof(struct ether_hdr) +
2925 sizeof(struct ipv6_hdr) + offsetof(struct tcp_hdr, src_port),
2928 /* Destination Port */
2930 .type = RTE_ACL_FIELD_TYPE_RANGE,
2931 .size = sizeof(uint16_t),
2934 .offset = sizeof(struct ether_hdr) +
2935 sizeof(struct ipv6_hdr) + offsetof(struct tcp_hdr, dst_port),
2940 * Parse arguments in config file.
2943 * A pointer to the pipeline.
2945 * A pointer to pipeline specific parameters.
2948 * 0 on success, negative on error.
2951 pipeline_acl_parse_args(struct pipeline_acl *p, struct pipeline_params *params)
2953 uint32_t n_rules_present = 0;
2954 uint32_t pkt_type_present = 0;
2956 uint8_t prv_que_handler_present = 0;
2957 uint8_t n_prv_in_port = 0;
2960 p->n_rules = 4 * 1024;
2961 acl_n_rules = 4 * 1024;
2962 p->n_rule_fields = RTE_DIM(field_format_ipv4);
2963 p->field_format = field_format_ipv4;
2964 p->field_format_size = sizeof(field_format_ipv4);
2966 for (i = 0; i < params->n_args; i++) {
2967 char *arg_name = params->args_name[i];
2968 char *arg_value = params->args_value[i];
2970 if (strcmp(arg_name, "n_rules") == 0) {
2971 if (n_rules_present)
2973 n_rules_present = 1;
2975 p->n_rules = atoi(arg_value);
2976 acl_n_rules = atoi(arg_value);
2980 if (strcmp(arg_name, "pkt_type") == 0) {
2981 if (pkt_type_present)
2983 pkt_type_present = 1;
2986 if (strcmp(arg_value, "ipv4") == 0) {
2987 p->n_rule_fields = RTE_DIM(field_format_ipv4);
2988 p->field_format = field_format_ipv4;
2989 p->field_format_size =
2990 sizeof(field_format_ipv4);
2995 if (strcmp(arg_value, "vlan_ipv4") == 0) {
2997 RTE_DIM(field_format_vlan_ipv4);
2998 p->field_format = field_format_vlan_ipv4;
2999 p->field_format_size =
3000 sizeof(field_format_vlan_ipv4);
3005 if (strcmp(arg_value, "qinq_ipv4") == 0) {
3007 RTE_DIM(field_format_qinq_ipv4);
3008 p->field_format = field_format_qinq_ipv4;
3009 p->field_format_size =
3010 sizeof(field_format_qinq_ipv4);
3015 if (strcmp(arg_value, "ipv6") == 0) {
3016 p->n_rule_fields = RTE_DIM(field_format_ipv6);
3017 p->field_format = field_format_ipv6;
3018 p->field_format_size =
3019 sizeof(field_format_ipv6);
3027 if (strcmp(arg_name, "traffic_type") == 0) {
3028 int traffic_type = atoi(arg_value);
3030 if (traffic_type == 0
3031 || !(traffic_type == IPv4_HDR_VERSION
3032 || traffic_type == IPv6_HDR_VERSION)) {
3033 printf("not IPVR4/IPVR6");
3037 p->traffic_type = traffic_type;
3041 if (strcmp(arg_name, "prv_que_handler") == 0) {
3043 if (prv_que_handler_present) {
3044 printf("Duplicate pktq_in_prv ..\n\n");
3047 prv_que_handler_present = 1;
3052 /* get the first token */
3053 token = strtok(arg_value, "(");
3054 token = strtok(token, ")");
3055 token = strtok(token, ",");
3056 printf("***** prv_que_handler *****\n");
3059 printf("string is null\n");
3060 printf("prv_que_handler is invalid\n");
3063 printf("string is :%s\n", token);
3065 while (token != NULL) {
3066 printf(" %s\n", token);
3067 rxport = atoi(token);
3068 acl_prv_que_port_index[n_prv_in_port++] =
3070 token = strtok(NULL, ",");
3073 if (n_prv_in_port == 0) {
3074 printf("VNF common parse err - no prv RX phy port\n");
3081 if (strcmp(arg_name, "n_flows") == 0) {
3082 p->n_flows = atoi(arg_value);
3083 if (p->n_flows == 0)
3086 continue;/* needed when multiple parms are checked */
3095 * Create and initialize Pipeline Back End (BE).
3098 * A pointer to the pipeline.
3100 * A pointer to pipeline specific data.
3103 * A pointer to the pipeline create, NULL on error.
3105 static void *pipeline_acl_init(struct pipeline_params *params,
3106 __rte_unused void *arg)
3109 struct pipeline_acl *p_acl;
3112 /* Check input arguments */
3113 if ((params == NULL) ||
3114 (params->n_ports_in == 0) || (params->n_ports_out == 0))
3117 /* Memory allocation */
3118 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_acl));
3119 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
3120 p_acl = (struct pipeline_acl *)p;
3124 strcpy(p->name, params->name);
3125 p->log_level = params->log_level;
3127 PLOG(p, HIGH, "ACL");
3130 * p_acl->links_map[0] = 0xff;
3131 * p_acl->links_map[1] = 0xff;]
3133 p_acl->traffic_type = MIX;
3134 for (i = 0; i < PIPELINE_MAX_PORT_IN; i++) {
3135 p_acl->links_map[i] = 0xff;
3136 p_acl->port_out_id[i] = 0xff;
3137 acl_prv_que_port_index[i] = 0;
3140 p_acl->pipeline_num = 0xff;
3142 /* if(enable_hwlb || enable_flow_dir) */
3143 // lib_arp_init(params, arg);
3145 p_acl->n_flows = 4096; /* small default value */
3146 /* Create a single firewall instance and initialize. */
3147 p_acl->cnxn_tracker =
3148 rte_zmalloc(NULL, rte_ct_get_cnxn_tracker_size(),
3149 RTE_CACHE_LINE_SIZE);
3151 if (p_acl->cnxn_tracker == NULL)
3155 * Now allocate a counter block entry.It appears that the initialization
3156 * of all instances is serialized on core 0, so no lock is necessary.
3158 struct rte_ACL_counter_block *counter_ptr;
3160 if (rte_ACL_hi_counter_block_in_use == MAX_ACL_INSTANCES) {
3161 /* error, exceeded table bounds */
3165 rte_ACL_hi_counter_block_in_use++;
3166 counter_ptr = &rte_acl_counter_table[rte_ACL_hi_counter_block_in_use];
3167 strcpy(counter_ptr->name, params->name);
3168 p_acl->action_counter_index = rte_ACL_hi_counter_block_in_use;
3170 p_acl->counters = counter_ptr;
3172 rte_ct_initialize_default_timeouts(p_acl->cnxn_tracker);
3173 p_acl->arpPktCount = 0;
3175 /* Parse arguments */
3176 if (pipeline_acl_parse_args(p_acl, params))
3178 /*n_flows already checked, ignore Klockwork issue */
3179 if (p_acl->n_flows > 0) {
3180 rte_ct_initialize_cnxn_tracker(p_acl->cnxn_tracker,
3181 p_acl->n_flows, params->name);
3182 p_acl->counters->ct_counters =
3183 rte_ct_get_counter_address(p_acl->cnxn_tracker);
3185 printf("ACL invalid p_acl->n_flows: %u\n", p_acl->n_flows);
3191 struct rte_pipeline_params pipeline_params = {
3192 .name = params->name,
3193 .socket_id = params->socket_id,
3194 .offset_port_id = META_DATA_OFFSET +
3195 offsetof(struct mbuf_acl_meta_data, output_port),
3198 p->p = rte_pipeline_create(&pipeline_params);
3206 p->n_ports_in = params->n_ports_in;
3207 for (i = 0; i < p->n_ports_in; i++) {
3208 struct rte_pipeline_port_in_params port_params = {
3210 pipeline_port_in_params_get_ops(¶ms->port_in
3213 pipeline_port_in_params_convert(¶ms->port_in
3215 .f_action = pkt_work_acl_key,
3217 .burst_size = params->port_in[i].burst_size,
3219 if (p_acl->traffic_type == IPv4_HDR_VERSION)
3220 port_params.f_action = pkt_work_acl_ipv4_key;
3222 if (p_acl->traffic_type == IPv6_HDR_VERSION)
3223 port_params.f_action = pkt_work_acl_ipv6_key;
3225 int status = rte_pipeline_port_in_create(p->p,
3230 rte_pipeline_free(p->p);
3237 p->n_ports_out = params->n_ports_out;
3238 for (i = 0; i < p->n_ports_out; i++) {
3239 struct rte_pipeline_port_out_params port_params = {
3241 pipeline_port_out_params_get_ops(¶ms->port_out
3244 pipeline_port_out_params_convert(¶ms->port_out
3250 int status = rte_pipeline_port_out_create(p->p,
3252 &p->port_out_id[i]);
3255 rte_pipeline_free(p->p);
3261 int pipeline_num = 0;
3263 int temp = sscanf(params->name, "PIPELINE%d", &pipeline_num);
3264 p_acl->pipeline_num = (uint8_t) pipeline_num;
3265 /* set_phy_outport_map(p_acl->pipeline_num, p_acl->links_map);*/
3266 register_pipeline_Qs(p_acl->pipeline_num, p);
3267 set_link_map(p_acl->pipeline_num, p, p_acl->links_map);
3268 set_outport_id(p_acl->pipeline_num, p, p_acl->port_out_id);
3270 /* If this is the first ACL thread, create common ACL Rule tables */
3271 if (rte_ACL_hi_counter_block_in_use == 0) {
3273 printf("Create ACL Tables rte_socket_id(): %i\n",
3276 /* Create IPV4 ACL Rule Tables */
3277 struct rte_table_acl_params common_ipv4_table_acl_params = {
3279 .n_rules = acl_n_rules,
3280 .n_rule_fields = RTE_DIM(field_format_ipv4),
3283 memcpy(common_ipv4_table_acl_params.field_format,
3284 field_format_ipv4, sizeof(field_format_ipv4));
3286 uint32_t ipv4_entry_size = sizeof(struct acl_table_entry);
3288 acl_rule_table_ipv4_active =
3289 rte_table_acl_ops.f_create(&common_ipv4_table_acl_params,
3293 if (acl_rule_table_ipv4_active == NULL) {
3295 ("Failed to create common ACL IPV4A Rule table\n");
3296 rte_pipeline_free(p->p);
3301 /* Create second IPV4 Table */
3302 common_ipv4_table_acl_params.name = "ACLIPV4B";
3303 acl_rule_table_ipv4_standby =
3304 rte_table_acl_ops.f_create(&common_ipv4_table_acl_params,
3308 if (acl_rule_table_ipv4_standby == NULL) {
3310 ("Failed to create common ACL IPV4B Rule table\n");
3311 rte_pipeline_free(p->p);
3316 /* Create IPV6 ACL Rule Tables */
3317 struct rte_table_acl_params common_ipv6_table_acl_params = {
3319 .n_rules = acl_n_rules,
3320 .n_rule_fields = RTE_DIM(field_format_ipv6),
3323 memcpy(common_ipv6_table_acl_params.field_format,
3324 field_format_ipv6, sizeof(field_format_ipv6));
3326 uint32_t ipv6_entry_size = sizeof(struct acl_table_entry);
3328 acl_rule_table_ipv6_active =
3329 rte_table_acl_ops.f_create(&common_ipv6_table_acl_params,
3333 if (acl_rule_table_ipv6_active == NULL) {
3335 ("Failed to create common ACL IPV6A Rule table\n");
3336 rte_pipeline_free(p->p);
3341 /* Create second IPV6 table */
3342 common_ipv6_table_acl_params.name = "ACLIPV6B";
3343 acl_rule_table_ipv6_standby =
3344 rte_table_acl_ops.f_create(&common_ipv6_table_acl_params,
3348 if (acl_rule_table_ipv6_standby == NULL) {
3350 ("Failed to create common ACL IPV6B Rule table\n");
3351 rte_pipeline_free(p->p);
3361 struct rte_pipeline_table_params table_params = {
3362 .ops = &rte_table_stub_ops,
3364 .f_action_hit = NULL,
3365 .f_action_miss = NULL,
3367 .action_data_size = 0,
3370 int status = rte_pipeline_table_create(p->p,
3375 rte_pipeline_free(p->p);
3380 struct rte_pipeline_table_entry default_entry = {
3381 .action = RTE_PIPELINE_ACTION_PORT_META
3384 struct rte_pipeline_table_entry *default_entry_ptr;
3386 status = rte_pipeline_table_default_entry_add(p->p,
3389 &default_entry_ptr);
3392 rte_pipeline_free(p->p);
3398 /* Connecting input ports to tables */
3399 for (i = 0; i < p->n_ports_in; i++) {
3400 int status = rte_pipeline_port_in_connect_to_table(p->p,
3407 rte_pipeline_free(p->p);
3413 /* Enable input ports */
3414 for (i = 0; i < p->n_ports_in; i++) {
3415 int status = rte_pipeline_port_in_enable(p->p,
3419 rte_pipeline_free(p->p);
3425 /* Check pipeline consistency */
3426 if (rte_pipeline_check(p->p) < 0) {
3427 rte_pipeline_free(p->p);
3432 /* Message queues */
3433 p->n_msgq = params->n_msgq;
3434 for (i = 0; i < p->n_msgq; i++)
3435 p->msgq_in[i] = params->msgq_in[i];
3436 for (i = 0; i < p->n_msgq; i++)
3437 p->msgq_out[i] = params->msgq_out[i];
3439 /* Message handlers */
3440 memcpy(p->handlers, handlers, sizeof(p->handlers));
3441 memcpy(p_acl->custom_handlers,
3442 custom_handlers, sizeof(p_acl->custom_handlers));
3448 * Free resources and delete pipeline.
3451 * A pointer to the pipeline.
3454 * 0 on success, negative on error.
3456 static int pipeline_acl_free(void *pipeline)
3458 struct pipeline *p = (struct pipeline *)pipeline;
3460 /* Check input arguments */
3464 /* Free resources */
3465 rte_pipeline_free(p->p);
3471 * Callback function to map input/output ports.
3474 * A pointer to the pipeline.
3478 * A pointer to the Output port.
3481 * 0 on success, negative on error.
3484 pipeline_acl_track(void *pipeline,
3485 __rte_unused uint32_t port_in, uint32_t *port_out)
3487 struct pipeline *p = (struct pipeline *)pipeline;
3489 /* Check input arguments */
3490 if ((p == NULL) || (port_in >= p->n_ports_in) || (port_out == NULL))
3493 if (p->n_ports_in == 1) {
3502 * Callback function to process timers.
3505 * A pointer to the pipeline.
3508 * 0 on success, negative on error.
3510 static int pipeline_acl_timer(void *pipeline)
3513 struct pipeline *p = (struct pipeline *)pipeline;
3514 struct pipeline_acl *p_acl = (struct pipeline_acl *)pipeline;
3516 pipeline_msg_req_handle(p);
3517 rte_pipeline_flush(p->p);
3519 rte_ct_handle_expired_timers(p_acl->cnxn_tracker);
3525 * Callback function to process CLI commands from FE.
3528 * A pointer to the pipeline.
3530 * A pointer to command specific data.
3533 * A pointer to message handler on success,
3534 * pipeline_msg_req_invalid_hander on error.
3536 void *pipeline_acl_msg_req_custom_handler(struct pipeline *p, void *msg)
3538 struct pipeline_acl *p_acl = (struct pipeline_acl *)p;
3539 struct pipeline_custom_msg_req *req = msg;
3540 pipeline_msg_req_handler f_handle;
3542 f_handle = (req->subtype < PIPELINE_ACL_MSG_REQS) ?
3543 p_acl->custom_handlers[req->subtype] :
3544 pipeline_msg_req_invalid_handler;
3546 if (f_handle == NULL)
3547 f_handle = pipeline_msg_req_invalid_handler;
3549 return f_handle(p, req);
3553 * Handler for DBG CLI command.
3556 * A pointer to the pipeline.
3558 * A pointer to command specific data.
3561 * A pointer to response message.
3562 * Response message contains status.
3564 void *pipeline_acl_msg_req_dbg_handler(struct pipeline *p, void *msg)
3567 struct pipeline_acl_dbg_msg_req *req = msg;
3568 struct pipeline_acl_dbg_msg_rsp *rsp = msg;
3570 if (req->dbg == 0) {
3571 printf("DBG turned OFF\n");
3574 } else if (req->dbg == 1) {
3575 printf("DBG turned ON\n");
3579 printf("Invalid DBG setting\n");
3586 struct pipeline_be_ops pipeline_acl_be_ops = {
3587 .f_init = pipeline_acl_init,
3588 .f_free = pipeline_acl_free,
3590 .f_timer = pipeline_acl_timer,
3591 .f_track = pipeline_acl_track,