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.
17 #include "vnf_common.h"
19 #define ACL_LIB_DEBUG 0
20 static struct rte_acl_field_def field_format_ipv4[] = {
23 .type = RTE_ACL_FIELD_TYPE_BITMASK,
24 .size = sizeof(uint8_t),
27 .offset = sizeof(struct ether_hdr) +
28 offsetof(struct ipv4_hdr, next_proto_id),
31 /* Source IP address (IPv4) */
33 .type = RTE_ACL_FIELD_TYPE_MASK,
34 .size = sizeof(uint32_t),
37 .offset = sizeof(struct ether_hdr) +
38 offsetof(struct ipv4_hdr, src_addr),
41 /* Destination IP address (IPv4) */
43 .type = RTE_ACL_FIELD_TYPE_MASK,
44 .size = sizeof(uint32_t),
47 .offset = sizeof(struct ether_hdr) +
48 offsetof(struct ipv4_hdr, dst_addr),
53 .type = RTE_ACL_FIELD_TYPE_RANGE,
54 .size = sizeof(uint16_t),
57 .offset = sizeof(struct ether_hdr) +
58 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
61 /* Destination Port */
63 .type = RTE_ACL_FIELD_TYPE_RANGE,
64 .size = sizeof(uint16_t),
67 .offset = sizeof(struct ether_hdr) +
68 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
72 #define SIZEOF_VLAN_HDR 4
74 static struct rte_acl_field_def field_format_vlan_ipv4[] = {
77 .type = RTE_ACL_FIELD_TYPE_BITMASK,
78 .size = sizeof(uint8_t),
81 .offset = sizeof(struct ether_hdr) +
82 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, next_proto_id),
85 /* Source IP address (IPv4) */
87 .type = RTE_ACL_FIELD_TYPE_MASK,
88 .size = sizeof(uint32_t),
91 .offset = sizeof(struct ether_hdr) +
92 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, src_addr),
95 /* Destination IP address (IPv4) */
97 .type = RTE_ACL_FIELD_TYPE_MASK,
98 .size = sizeof(uint32_t),
101 .offset = sizeof(struct ether_hdr) +
102 SIZEOF_VLAN_HDR + offsetof(struct ipv4_hdr, dst_addr),
107 .type = RTE_ACL_FIELD_TYPE_RANGE,
108 .size = sizeof(uint16_t),
111 .offset = sizeof(struct ether_hdr) +
113 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
116 /* Destination Port */
118 .type = RTE_ACL_FIELD_TYPE_RANGE,
119 .size = sizeof(uint16_t),
122 .offset = sizeof(struct ether_hdr) +
124 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
128 #define SIZEOF_QINQ_HEADER 8
130 static struct rte_acl_field_def field_format_qinq_ipv4[] = {
133 .type = RTE_ACL_FIELD_TYPE_BITMASK,
134 .size = sizeof(uint8_t),
137 .offset = sizeof(struct ether_hdr) +
138 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, next_proto_id),
141 /* Source IP address (IPv4) */
143 .type = RTE_ACL_FIELD_TYPE_MASK,
144 .size = sizeof(uint32_t),
147 .offset = sizeof(struct ether_hdr) +
148 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, src_addr),
151 /* Destination IP address (IPv4) */
153 .type = RTE_ACL_FIELD_TYPE_MASK,
154 .size = sizeof(uint32_t),
157 .offset = sizeof(struct ether_hdr) +
158 SIZEOF_QINQ_HEADER + offsetof(struct ipv4_hdr, dst_addr),
163 .type = RTE_ACL_FIELD_TYPE_RANGE,
164 .size = sizeof(uint16_t),
167 .offset = sizeof(struct ether_hdr) +
169 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, src_port),
172 /* Destination Port */
174 .type = RTE_ACL_FIELD_TYPE_RANGE,
175 .size = sizeof(uint16_t),
178 .offset = sizeof(struct ether_hdr) +
180 sizeof(struct ipv4_hdr) + offsetof(struct tcp_hdr, dst_port),
184 static struct rte_acl_field_def field_format_ipv6[] = {
187 .type = RTE_ACL_FIELD_TYPE_BITMASK,
188 .size = sizeof(uint8_t),
191 .offset = sizeof(struct ether_hdr) +
192 offsetof(struct ipv6_hdr, proto),
195 /* Source IP address (IPv6) */
197 .type = RTE_ACL_FIELD_TYPE_MASK,
198 .size = sizeof(uint32_t),
201 .offset = sizeof(struct ether_hdr) +
202 offsetof(struct ipv6_hdr, src_addr),
206 .type = RTE_ACL_FIELD_TYPE_MASK,
207 .size = sizeof(uint32_t),
210 .offset = sizeof(struct ether_hdr) +
211 offsetof(struct ipv6_hdr, src_addr) + sizeof(uint32_t),
215 .type = RTE_ACL_FIELD_TYPE_MASK,
216 .size = sizeof(uint32_t),
219 .offset = sizeof(struct ether_hdr) +
220 offsetof(struct ipv6_hdr, src_addr) + 2 * sizeof(uint32_t),
224 .type = RTE_ACL_FIELD_TYPE_MASK,
225 .size = sizeof(uint32_t),
228 .offset = sizeof(struct ether_hdr) +
229 offsetof(struct ipv6_hdr, src_addr) + 3 * sizeof(uint32_t),
232 /* Destination IP address (IPv6) */
234 .type = RTE_ACL_FIELD_TYPE_MASK,
235 .size = sizeof(uint32_t),
238 .offset = sizeof(struct ether_hdr) +
239 offsetof(struct ipv6_hdr, dst_addr),
243 .type = RTE_ACL_FIELD_TYPE_MASK,
244 .size = sizeof(uint32_t),
247 .offset = sizeof(struct ether_hdr) +
248 offsetof(struct ipv6_hdr, dst_addr) + sizeof(uint32_t),
252 .type = RTE_ACL_FIELD_TYPE_MASK,
253 .size = sizeof(uint32_t),
256 .offset = sizeof(struct ether_hdr) +
257 offsetof(struct ipv6_hdr, dst_addr) + 2 * sizeof(uint32_t),
261 .type = RTE_ACL_FIELD_TYPE_MASK,
262 .size = sizeof(uint32_t),
265 .offset = sizeof(struct ether_hdr) +
266 offsetof(struct ipv6_hdr, dst_addr) + 3 * sizeof(uint32_t),
271 .type = RTE_ACL_FIELD_TYPE_RANGE,
272 .size = sizeof(uint16_t),
275 .offset = sizeof(struct ether_hdr) +
276 sizeof(struct ipv6_hdr) + offsetof(struct tcp_hdr, src_port),
279 /* Destination Port */
281 .type = RTE_ACL_FIELD_TYPE_RANGE,
282 .size = sizeof(uint16_t),
285 .offset = sizeof(struct ether_hdr) +
286 sizeof(struct ipv6_hdr) + offsetof(struct tcp_hdr, dst_port),
290 void *lib_acl_create_active_standby_table_ipv4(uint8_t table_num,
291 uint32_t *libacl_n_rules)
293 printf("Create LIBACL active IPV4 Tables rte_socket_id(): %i\n",
296 /* Create IPV4 LIBACL Rule Tables */
297 struct rte_table_acl_params common_ipv4_table_libacl_params = {
298 .name = "LIBACLIPV4A",
299 .n_rules = *libacl_n_rules,
300 .n_rule_fields = RTE_DIM(field_format_ipv4),
303 memcpy(common_ipv4_table_libacl_params.field_format,
304 field_format_ipv4, sizeof(field_format_ipv4));
306 uint32_t ipv4_entry_size = sizeof(struct lib_acl_table_entry);
307 /* Create second IPV4 Table */
309 common_ipv4_table_libacl_params.name = "LIBACLIPV4B";
310 return rte_table_acl_ops.f_create(&common_ipv4_table_libacl_params,
317 void *lib_acl_create_active_standby_table_ipv6(uint8_t table_num,
318 uint32_t *libacl_n_rules)
320 printf("Create LIBACL active IPV6 Tables rte_socket_id(): %i\n",
322 /* Create IPV6 LIBACL Rule Tables */
323 struct rte_table_acl_params common_ipv6_table_libacl_params = {
324 .name = "LIBACLIPV6A",
325 .n_rules = *libacl_n_rules,
326 .n_rule_fields = RTE_DIM(field_format_ipv6),
329 memcpy(common_ipv6_table_libacl_params.field_format,
330 field_format_ipv6, sizeof(field_format_ipv6));
332 uint32_t ipv6_entry_size = sizeof(struct lib_acl_table_entry);
333 /* Create second IPV6 table */
335 common_ipv6_table_libacl_params.name = "LIBACLIPV6B";
336 return rte_table_acl_ops.f_create(&common_ipv6_table_libacl_params,
342 int lib_acl_parse_config(struct lib_acl *plib_acl,
343 char *arg_name, char *arg_value,
344 uint32_t *libacl_n_rules)
346 uint32_t n_rules_present = 0;
347 uint32_t pkt_type_present = 0;
349 plib_acl->n_rules = DEFULT_NUM_RULE;
350 *libacl_n_rules = DEFULT_NUM_RULE;
351 plib_acl->n_rule_fields = RTE_DIM(field_format_ipv4);
352 plib_acl->field_format = field_format_ipv4;
353 plib_acl->field_format_size = sizeof(field_format_ipv4);
354 if (strcmp(arg_name, "n_rules") == 0) {
355 if (n_rules_present) {
356 printf("n_rules_present");
361 plib_acl->n_rules = atoi(arg_value);
362 *libacl_n_rules = atoi(arg_value);
365 if (strcmp(arg_name, "pkt_type") == 0) {
366 if (pkt_type_present) {
370 pkt_type_present = 1;
373 if (strcmp(arg_value, "ipv4") == 0) {
374 plib_acl->n_rule_fields =
375 RTE_DIM(field_format_ipv4);
376 plib_acl->field_format = field_format_ipv4;
377 plib_acl->field_format_size =
378 sizeof(field_format_ipv4);
383 if (strcmp(arg_value, "vlan_ipv4") == 0) {
384 plib_acl->n_rule_fields =
385 RTE_DIM(field_format_vlan_ipv4);
386 plib_acl->field_format =
387 field_format_vlan_ipv4;
388 plib_acl->field_format_size =
389 sizeof(field_format_vlan_ipv4);
394 if (strcmp(arg_value, "qinq_ipv4") == 0) {
395 plib_acl->n_rule_fields =
396 RTE_DIM(field_format_qinq_ipv4);
397 plib_acl->field_format =
398 field_format_qinq_ipv4;
399 plib_acl->field_format_size =
400 sizeof(field_format_qinq_ipv4);
405 if (strcmp(arg_value, "ipv6") == 0) {
406 plib_acl->n_rule_fields =
407 RTE_DIM(field_format_ipv6);
408 plib_acl->field_format = field_format_ipv6;
409 plib_acl->field_format_size =
410 sizeof(field_format_ipv6);
417 /* Parameter not processed in this parse function */
421 * Main packet processing function.
422 * 64 packet bit mask are used to identify which packets to forward.
423 * Performs the following:
424 * - Burst lookup packets in the IPv4 ACL Rule Table.
425 * - Burst lookup packets in the IPv6 ACL Rule Table.
426 * - Lookup Action Table, perform actions.
427 * - Burst lookup Connection Tracking, if enabled.
428 * - Lookup MAC address.
430 * - Packets with bit mask set are forwarded
433 * A pointer to the pipeline.
435 * A pointer to a burst of packets.
437 * Number of packets to process.
439 * A pointer to pipeline specific data.
442 * 0 on success, negative on error.
445 lib_acl_pkt_work_key(struct lib_acl *plib_acl,
446 struct rte_mbuf **pkts, uint64_t pkts_mask,
447 uint64_t *pkts_drop_without_rule,
448 void *plib_acl_rule_table_ipv4_active,
449 void *plib_acl_rule_table_ipv6_active,
450 struct pipeline_action_key *action_array_active,
451 struct action_counter_block (*p_action_counter_table)[action_array_max],
452 uint64_t *conntrack_mask,
453 uint64_t *connexist_mask,
454 int lib_acl_ipv4_enabled, int lib_acl_ipv6_enabled)
457 uint64_t lookup_hit_mask = 0;
458 uint64_t lookup_hit_mask_ipv4 = 0;
459 uint64_t lookup_hit_mask_ipv6 = 0;
460 uint64_t lookup_miss_mask = 0;
464 if (lib_acl_ipv4_enabled) {
466 printf("ACL IPV4 Lookup Mask Before = 0x%"PRIx64"\n",
468 status = rte_table_acl_ops.f_lookup(
469 plib_acl_rule_table_ipv4_active,
470 pkts, pkts_mask, &lookup_hit_mask_ipv4,
471 (void **) plib_acl->plib_acl_entries_ipv4);
473 printf("Lookup failed\n");
475 printf("ACL IPV4 Lookup Mask After = 0x%"PRIx64"\n",
476 lookup_hit_mask_ipv4);
479 if (lib_acl_ipv6_enabled) {
481 printf("ACL IPV6 Lookup Mask Before = 0x%"PRIx64"\n",
483 status = rte_table_acl_ops.f_lookup(
484 plib_acl_rule_table_ipv6_active,
485 pkts, pkts_mask, &lookup_hit_mask_ipv6,
486 (void **) plib_acl->plib_acl_entries_ipv6);
488 printf("Lookup Failed\n");
490 printf("ACL IPV6 Lookup Mask After = 0x%"PRIx64"\n",
491 lookup_hit_mask_ipv6);
494 /* Merge lookup results since we process both IPv4 and IPv6 below */
495 lookup_hit_mask = lookup_hit_mask_ipv4 | lookup_hit_mask_ipv6;
497 printf("ACL Lookup Mask After = 0x%"PRIx64"\n",
500 lookup_miss_mask = pkts_mask & (~lookup_hit_mask);
501 pkts_mask = lookup_hit_mask;
502 *pkts_drop_without_rule += __builtin_popcountll(lookup_miss_mask);
504 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
505 *pkts_drop_without_rule,
506 __builtin_popcountll(lookup_miss_mask));
507 /* bitmap of packets left to process for ARP */
508 uint64_t pkts_to_process = lookup_hit_mask;
510 for (; pkts_to_process;) {
511 uint8_t pos = (uint8_t)__builtin_ctzll(pkts_to_process);
512 /* bitmask representing only this packet */
513 uint64_t pkt_mask = 1LLU << pos;
514 /* remove this packet from remaining list */
515 pkts_to_process &= ~pkt_mask;
516 struct rte_mbuf *pkt = pkts[pos];
518 uint8_t hdr_chk = RTE_MBUF_METADATA_UINT8(pkt, IP_START);
520 hdr_chk = hdr_chk >> IP_VERSION_CHECK;
522 if (hdr_chk == IPv4_HDR_VERSION) {
524 struct lib_acl_table_entry *entry =
525 (struct lib_acl_table_entry *)
526 plib_acl->plib_acl_entries_ipv4[pos];
527 uint16_t phy_port = entry->head.port_id;
528 uint32_t action_id = entry->action_id;
531 printf("action_id = %u\n", action_id);
533 uint32_t dscp_offset = IP_START + IP_HDR_DSCP_OFST;
535 if (action_array_active[action_id].action_bitmap &
536 lib_acl_action_count) {
537 p_action_counter_table
538 [plib_acl->action_counter_index]
539 [action_id].packetCount++;
540 p_action_counter_table
541 [plib_acl->action_counter_index]
542 [action_id].byteCount +=
543 rte_pktmbuf_pkt_len(pkt);
545 printf("Action Count Packet Count: %"
546 PRIu64 " Byte Count: %"
548 , p_action_counter_table
549 [plib_acl->action_counter_index]
550 [action_id].packetCount,
551 p_action_counter_table
552 [plib_acl->action_counter_index]
553 [action_id].byteCount);
556 if (action_array_active[action_id].action_bitmap &
557 lib_acl_action_packet_drop) {
559 /* Drop packet by changing the mask */
561 printf("ACL before drop pkt_mask %"
562 PRIx64", pkt_num %d\n",
564 pkts_mask &= ~(1LLU << pos);
565 (*pkts_drop_without_rule)++;
567 printf("ACL after drop pkt_mask %"PRIx64
568 ", pkt_num %d, packet_drop%"
569 PRIu64"\n", pkts_mask, pos,
570 *pkts_drop_without_rule);
573 if (action_array_active[action_id].action_bitmap &
574 lib_acl_action_fwd) {
575 phy_port = action_array_active[action_id].
577 entry->head.port_id = phy_port;
579 printf("Action FWD Port ID: %"
580 PRIu16"\n", phy_port);
583 if (action_array_active[action_id].action_bitmap &
584 lib_acl_action_nat) {
585 phy_port = action_array_active[action_id].
587 entry->head.port_id = phy_port;
589 printf("Action NAT Port ID: %"
590 PRIu16"\n", phy_port);
593 if (action_array_active[action_id].action_bitmap &
594 lib_acl_action_dscp) {
596 /* Set DSCP priority */
597 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
599 *dscp = action_array_active[action_id].
602 printf("Action DSCP DSCP Priority: %"
606 if (action_array_active[action_id].action_bitmap &
607 lib_acl_action_packet_accept) {
609 printf("Action Accept\n");
611 if (action_array_active[action_id].action_bitmap
612 & lib_acl_action_conntrack) {
614 /* Set conntrack bit for this pkt */
615 *conntrack_mask |= pkt_mask;
617 printf("ACL CT enabled: 0x%"
618 PRIx64" pkt_mask: 0x%"
624 if (action_array_active[action_id].action_bitmap
625 & lib_acl_action_connexist) {
627 /* Set conntrack bit for this pkt */
628 *conntrack_mask |= pkt_mask;
630 /* Set connexist bit for this pkt for
631 * public -> private */
632 /* Private -> public packet will open
634 if (action_array_active[action_id].
636 lib_acl_public_private)
637 *connexist_mask |= pkt_mask;
640 printf("Connexist ENB CT:0x%"
641 PRIx64" connexist: 0x%"
642 PRIx64" pkt_mask: 0x%"
651 if (hdr_chk == IPv6_HDR_VERSION) {
653 struct lib_acl_table_entry *entry =
654 (struct lib_acl_table_entry *)
655 plib_acl->plib_acl_entries_ipv6[pos];
656 uint16_t phy_port = entry->head.port_id;
657 uint32_t action_id = entry->action_id;
660 printf("action_id = %u\n", action_id);
662 if (action_array_active[action_id].action_bitmap &
663 lib_acl_action_count) {
664 p_action_counter_table
665 [plib_acl->action_counter_index]
666 [action_id].packetCount++;
667 p_action_counter_table
668 [plib_acl->action_counter_index]
669 [action_id].byteCount +=
670 rte_pktmbuf_pkt_len(pkt);
672 printf("Action Count Packet Count: %"
673 PRIu64 " Byte Count: %"
675 p_action_counter_table
676 [plib_acl->action_counter_index]
677 [action_id].packetCount,
678 p_action_counter_table
679 [plib_acl->action_counter_index]
680 [action_id].byteCount);
683 if (action_array_active[action_id].action_bitmap &
684 lib_acl_action_packet_drop) {
685 /* Drop packet by changing the mask */
687 printf("ACL before drop pkt_mask %"
688 PRIx64", pkt_num %d\n",
690 pkts_mask &= ~(1LLU << pos);
691 (*pkts_drop_without_rule)++;
693 printf("ACL after drop pkt_mask %"PRIx64
694 ", pkt_num %d, packet_drop %"
695 PRIu64 "\n", pkts_mask, pos,
696 *pkts_drop_without_rule);
700 if (action_array_active[action_id].action_bitmap &
701 lib_acl_action_fwd) {
702 phy_port = action_array_active[action_id].
704 entry->head.port_id = phy_port;
706 printf("Action FWD Port ID: %"
707 PRIu16"\n", phy_port);
710 if (action_array_active[action_id].action_bitmap &
711 lib_acl_action_nat) {
712 phy_port = action_array_active[action_id].
714 entry->head.port_id = phy_port;
716 printf("Action NAT Port ID: %"
717 PRIu16"\n", phy_port);
720 if (action_array_active[action_id].action_bitmap &
721 lib_acl_action_dscp) {
723 /* Set DSCP priority */
724 uint32_t dscp_offset = IP_START +
725 IP_HDR_DSCP_OFST_IPV6;
726 uint16_t *dscp = RTE_MBUF_METADATA_UINT16_PTR(
728 uint16_t temp = *dscp;
729 uint16_t dscp_value = (rte_bswap16(temp) &
733 [action_id].dscp_priority << 2;
734 uint16_t dscp_temp = dscp_store;
736 dscp_temp = dscp_temp << 4;
737 *dscp = rte_bswap16(dscp_temp | dscp_value);
739 printf("Action DSCP DSCP Priority: %"
743 if (action_array_active[action_id].action_bitmap
744 & lib_acl_action_packet_accept) {
746 printf("Action Accept\n");
748 if (action_array_active[action_id].action_bitmap
749 & lib_acl_action_conntrack) {
751 /* Set conntrack bit for this pkt */
752 *conntrack_mask |= pkt_mask;
754 printf("ACL CT enabled: 0x%"
755 PRIx64" pkt_mask: 0x%"
761 if (action_array_active[action_id].action_bitmap
762 & lib_acl_action_connexist) {
764 /* Set conntrack bit for this pkt */
765 *conntrack_mask |= pkt_mask;
767 /* Set connexist bit for this pkt for
768 * public -> private */
769 /* Private -> public packet will open
771 if (action_array_active[action_id].
773 lib_acl_public_private)
774 *connexist_mask |= pkt_mask;
777 printf("Connexist ENB CT:0x%"
778 PRIx64" connexist: 0x%"
779 PRIx64" pkt_mask: 0x%"
791 * Main packet processing function.
792 * 64 packet bit mask are used to identify which packets to forward.
793 * Performs the following:
794 * - Burst lookup packets in the IPv4 ACL Rule Table.
795 * - Lookup Action Table, perform actions.
796 * - Burst lookup Connection Tracking, if enabled.
797 * - Lookup MAC address.
799 * - Packets with bit mask set are forwarded
802 * A pointer to the pipeline.
804 * A pointer to a burst of packets.
806 * Number of packets to process.
808 * A pointer to pipeline specific data.
811 * 0 on success, negative on error.
814 lib_acl_ipv4_pkt_work_key(struct lib_acl *plib_acl,
815 struct rte_mbuf **pkts, uint64_t pkts_mask,
816 uint64_t *pkts_drop_without_rule,
817 void *plib_acl_rule_table_ipv4_active,
818 struct pipeline_action_key *action_array_active,
819 struct action_counter_block (*p_action_counter_table)[action_array_max],
820 uint64_t *conntrack_mask,
821 uint64_t *connexist_mask)
824 uint64_t lookup_hit_mask_ipv4 = 0;
825 uint64_t lookup_miss_mask_ipv4 = 0;
829 printf("ACL IPV4 Lookup Mask Before = 0x%"PRIx64"\n",
831 status = rte_table_acl_ops.f_lookup(
832 plib_acl_rule_table_ipv4_active,
833 pkts, pkts_mask, &lookup_hit_mask_ipv4,
834 (void **) plib_acl->plib_acl_entries_ipv4);
836 printf("Lookup Failed\n");
838 printf("ACL IPV4 Lookup Mask After = 0x%"PRIx64"\n",
839 lookup_hit_mask_ipv4);
841 printf("ACL Lookup Mask After = 0x%"PRIx64"\n",
842 lookup_hit_mask_ipv4);
844 lookup_miss_mask_ipv4 = pkts_mask & (~lookup_hit_mask_ipv4);
845 pkts_mask = lookup_hit_mask_ipv4;
846 *pkts_drop_without_rule += __builtin_popcountll(lookup_miss_mask_ipv4);
848 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
849 *pkts_drop_without_rule,
850 __builtin_popcountll(lookup_miss_mask_ipv4));
851 /* bitmap of packets left to process for ARP */
852 uint64_t pkts_to_process = lookup_hit_mask_ipv4;
854 for (; pkts_to_process;) {
855 uint8_t pos = (uint8_t)__builtin_ctzll(pkts_to_process);
856 /* bitmask representing only this packet */
857 uint64_t pkt_mask = 1LLU << pos;
858 /* remove this packet from remaining list */
859 pkts_to_process &= ~pkt_mask;
860 struct rte_mbuf *pkt = pkts[pos];
864 struct lib_acl_table_entry *entry =
865 (struct lib_acl_table_entry *)
866 plib_acl->plib_acl_entries_ipv4[pos];
867 uint16_t phy_port = entry->head.port_id;
868 uint32_t action_id = entry->action_id;
871 printf("action_id = %u\n", action_id);
873 uint32_t dscp_offset = IP_START + IP_HDR_DSCP_OFST;
875 if (action_array_active[action_id].action_bitmap &
876 lib_acl_action_count) {
877 p_action_counter_table
878 [plib_acl->action_counter_index]
879 [action_id].packetCount++;
880 p_action_counter_table
881 [plib_acl->action_counter_index]
882 [action_id].byteCount +=
883 rte_pktmbuf_pkt_len(pkt);
885 printf("Action Count Packet Count: %"
886 PRIu64 " Byte Count: %"
888 , p_action_counter_table
889 [plib_acl->action_counter_index]
890 [action_id].packetCount,
891 p_action_counter_table
892 [plib_acl->action_counter_index]
893 [action_id].byteCount);
896 if (action_array_active[action_id].action_bitmap &
897 lib_acl_action_packet_drop) {
899 /* Drop packet by changing the mask */
901 printf("ACL before drop pkt_mask %"
902 PRIx64", pkt_num %d\n",
904 pkts_mask &= ~(1LLU << pos);
905 (*pkts_drop_without_rule)++;
907 printf("ACL after drop pkt_mask %" PRIx64
908 ", pkt_num %d, action_packet_drop %"
909 PRIu64 "\n", pkts_mask, pos,
910 *pkts_drop_without_rule);
913 if (action_array_active[action_id].action_bitmap &
914 lib_acl_action_fwd) {
915 phy_port = action_array_active[action_id].
917 entry->head.port_id = phy_port;
919 printf("Action FWD Port ID: %"
920 PRIu16"\n", phy_port);
923 if (action_array_active[action_id].action_bitmap &
924 lib_acl_action_nat) {
925 phy_port = action_array_active[action_id].
927 entry->head.port_id = phy_port;
929 printf("Action NAT Port ID: %"
930 PRIu16"\n", phy_port);
933 if (action_array_active[action_id].action_bitmap &
934 lib_acl_action_dscp) {
936 /* Set DSCP priority */
937 uint8_t *dscp = RTE_MBUF_METADATA_UINT8_PTR(pkt,
939 *dscp = action_array_active[action_id].
942 printf("Action DSCP DSCP Priority: %"
946 if (action_array_active[action_id].action_bitmap &
947 lib_acl_action_packet_accept) {
949 printf("Action Accept\n");
951 if (action_array_active[action_id].action_bitmap
952 & lib_acl_action_conntrack) {
954 /* Set conntrack bit for this pkt */
955 *conntrack_mask |= pkt_mask;
957 printf("ACL CT enabled: 0x%"
958 PRIx64" pkt_mask: 0x%"
964 if (action_array_active[action_id].action_bitmap
965 & lib_acl_action_connexist) {
967 /* Set conntrack bit for this pkt */
968 *conntrack_mask |= pkt_mask;
970 /* Set connexist bit for this pkt for
971 * public -> private */
972 /* Private -> public packet will open
974 if (action_array_active[action_id].
976 lib_acl_public_private)
977 *connexist_mask |= pkt_mask;
980 printf("ACL Connexist ENB CT:0x%"
981 PRIx64" connexist: 0x%"
982 PRIx64" pkt_mask: 0x%"
994 * Main packet processing function.
995 * 64 packet bit mask are used to identify which packets to forward.
996 * Performs the following:
997 * - Burst lookup packets in the IPv6 ACL Rule Table.
998 * - Lookup Action Table, perform actions.
999 * - Burst lookup Connection Tracking, if enabled.
1000 * - Lookup MAC address.
1002 * - Packets with bit mask set are forwarded
1005 * A pointer to the pipeline.
1007 * A pointer to a burst of packets.
1009 * Number of packets to process.
1011 * A pointer to pipeline specific data.
1014 * 0 on success, negative on error.
1017 lib_acl_ipv6_pkt_work_key(struct lib_acl *plib_acl,
1018 struct rte_mbuf **pkts, uint64_t pkts_mask,
1019 uint64_t *pkts_drop_without_rule,
1020 void *plib_acl_rule_table_ipv6_active,
1021 struct pipeline_action_key *action_array_active,
1022 struct action_counter_block (*p_action_counter_table)[action_array_max],
1023 uint64_t *conntrack_mask,
1024 uint64_t *connexist_mask)
1027 uint64_t lookup_hit_mask_ipv6 = 0;
1028 uint64_t lookup_miss_mask_ipv6 = 0;
1033 printf("ACL IPV6 Lookup Mask Before = 0x%"PRIx64"\n",
1035 status = rte_table_acl_ops.f_lookup(
1036 plib_acl_rule_table_ipv6_active,
1037 pkts, pkts_mask, &lookup_hit_mask_ipv6,
1038 (void **) plib_acl->plib_acl_entries_ipv6);
1040 printf("Lookup Failed\n");
1042 printf("ACL IPV6 Lookup Mask After = 0x%"PRIx64"\n",
1043 lookup_hit_mask_ipv6);
1046 printf("ACL Lookup Mask After = 0x%"PRIx64"\n",
1047 lookup_hit_mask_ipv6);
1049 lookup_miss_mask_ipv6 = pkts_mask & (~lookup_hit_mask_ipv6);
1050 pkts_mask = lookup_hit_mask_ipv6;
1051 *pkts_drop_without_rule += __builtin_popcountll(lookup_miss_mask_ipv6);
1053 printf("pkt_work_acl_key pkts_drop: %" PRIu64 " n_pkts: %u\n",
1054 *pkts_drop_without_rule,
1055 __builtin_popcountll(lookup_miss_mask_ipv6));
1056 /* bitmap of packets left to process for ARP */
1057 uint64_t pkts_to_process = lookup_hit_mask_ipv6;
1059 for (; pkts_to_process;) {
1060 uint8_t pos = (uint8_t)__builtin_ctzll(pkts_to_process);
1061 /* bitmask representing only this packet */
1062 uint64_t pkt_mask = 1LLU << pos;
1063 /* remove this packet from remaining list */
1064 pkts_to_process &= ~pkt_mask;
1065 struct rte_mbuf *pkt = pkts[pos];
1068 struct lib_acl_table_entry *entry =
1069 (struct lib_acl_table_entry *)
1070 plib_acl->plib_acl_entries_ipv6[pos];
1071 uint16_t phy_port = entry->head.port_id;
1072 uint32_t action_id = entry->action_id;
1075 printf("action_id = %u\n", action_id);
1077 if (action_array_active[action_id].action_bitmap &
1078 lib_acl_action_count) {
1079 p_action_counter_table
1080 [plib_acl->action_counter_index]
1081 [action_id].packetCount++;
1082 p_action_counter_table
1083 [plib_acl->action_counter_index]
1084 [action_id].byteCount +=
1085 rte_pktmbuf_pkt_len(pkt);
1087 printf("Action Count Packet Count: %"
1088 PRIu64 " Byte Count: %"
1090 p_action_counter_table
1091 [plib_acl->action_counter_index]
1092 [action_id].packetCount,
1093 p_action_counter_table
1094 [plib_acl->action_counter_index]
1095 [action_id].byteCount);
1098 if (action_array_active[action_id].action_bitmap &
1099 lib_acl_action_packet_drop) {
1100 /* Drop packet by changing the mask */
1102 printf("ACL before drop pkt_mask %"
1103 PRIx64", pkt_num %d\n",
1105 pkts_mask &= ~(1LLU << pos);
1106 (*pkts_drop_without_rule)++;
1108 printf("ACL after drop pkt_mask %" PRIx64
1109 ", pkt_num %d, action_packet_drop %"
1110 PRIu64 "\n", pkts_mask, pos,
1111 *pkts_drop_without_rule);
1115 if (action_array_active[action_id].action_bitmap &
1116 lib_acl_action_fwd) {
1117 phy_port = action_array_active[action_id].
1119 entry->head.port_id = phy_port;
1121 printf("Action FWD Port ID: %"
1122 PRIu16"\n", phy_port);
1125 if (action_array_active[action_id].action_bitmap &
1126 lib_acl_action_nat) {
1127 phy_port = action_array_active[action_id].
1129 entry->head.port_id = phy_port;
1131 printf("Action NAT Port ID: %"
1132 PRIu16"\n", phy_port);
1135 if (action_array_active[action_id].action_bitmap &
1136 lib_acl_action_dscp) {
1138 /* Set DSCP priority */
1139 uint32_t dscp_offset = IP_START +
1140 IP_HDR_DSCP_OFST_IPV6;
1141 uint16_t *dscp = RTE_MBUF_METADATA_UINT16_PTR(
1143 uint16_t temp = *dscp;
1144 uint16_t dscp_value = (rte_bswap16(temp) &
1146 uint8_t dscp_store =
1148 [action_id].dscp_priority << 2;
1149 uint16_t dscp_temp = dscp_store;
1151 dscp_temp = dscp_temp << 4;
1152 *dscp = rte_bswap16(dscp_temp | dscp_value);
1154 printf("Action DSCP DSCP Priority: %"
1158 if (action_array_active[action_id].action_bitmap
1159 & lib_acl_action_packet_accept) {
1161 printf("Action Accept\n");
1163 if (action_array_active[action_id].action_bitmap
1164 & lib_acl_action_conntrack) {
1166 /* Set conntrack bit for this pkt */
1167 *conntrack_mask |= pkt_mask;
1169 printf("ACL CT enabled: 0x%"
1170 PRIx64" pkt_mask: 0x%"
1176 if (action_array_active[action_id].action_bitmap
1177 & lib_acl_action_connexist) {
1179 /* Set conntrack bit for this pkt */
1180 *conntrack_mask |= pkt_mask;
1182 /* Set connexist bit for this pkt for
1183 * public -> private */
1184 /* Private -> public packet will open
1186 if (action_array_active[action_id].
1188 lib_acl_public_private)
1189 *connexist_mask |= pkt_mask;
1192 printf("ACL Connexist ENB CT:0x%"
1193 PRIx64" connexist: 0x%"
1194 PRIx64" pkt_mask: 0x%"