Add new option parse-ptype in this sample in case of pmd driver not provide packet type info. If this option enabled, packet type will be analyzed in Rx callback function.
Signed-off-by: Jianfeng Tan <jianfeng....@intel.com> Signed-off-by: Yong Liu <yong....@intel.com> diff --git a/examples/l3fwd-acl/main.c b/examples/l3fwd-acl/main.c index 3cfbb40..dfa9031 100644 --- a/examples/l3fwd-acl/main.c +++ b/examples/l3fwd-acl/main.c @@ -200,6 +200,7 @@ struct lcore_params { #define OPTION_RULE_IPV4 "rule_ipv4" #define OPTION_RULE_IPV6 "rule_ipv6" #define OPTION_SCALAR "scalar" +#define OPTION_PARSE_PTYPE "parse-ptype" #define ACL_DENY_SIGNATURE 0xf0000000 #define RTE_LOGTYPE_L3FWDACL RTE_LOGTYPE_USER3 #define acl_log(format, ...) RTE_LOG(ERR, L3FWDACL, format, ##__VA_ARGS__) @@ -470,6 +471,7 @@ struct acl_search_t { const char *rule_ipv4_name; const char *rule_ipv6_name; int scalar; + int parse_ptype; } parm_config; const char cb_port_delim[] = ":"; @@ -1563,7 +1565,9 @@ struct lcore_conf { "character '%c'.\n" " --"OPTION_RULE_IPV6"=FILE: specify the ipv6 rules " "entries file.\n" - " --"OPTION_SCALAR": Use scalar function to do lookup\n", + " --"OPTION_SCALAR": Use scalar function to do lookup.\n" + " --"OPTION_PARSE_PTYPE": Set to use software to analyze " + "packet type.\n", prgname, ACL_LEAD_CHAR, ROUTE_LEAD_CHAR); } @@ -1671,6 +1675,7 @@ struct lcore_conf { {OPTION_RULE_IPV4, 1, 0, 0}, {OPTION_RULE_IPV6, 1, 0, 0}, {OPTION_SCALAR, 0, 0, 0}, + {OPTION_PARSE_PTYPE, 0, 0, 0}, {NULL, 0, 0, 0} }; @@ -1763,6 +1768,12 @@ struct lcore_conf { OPTION_SCALAR, sizeof(OPTION_SCALAR))) parm_config.scalar = 1; + if (!strncmp(lgopts[option_index].name, + OPTION_PARSE_PTYPE, + sizeof(OPTION_PARSE_PTYPE))) { + printf("soft parse-ptype is enabled\n"); + parm_config.parse_ptype = 1; + } break; @@ -1828,6 +1839,74 @@ struct lcore_conf { return 0; } +static inline void +parse_ptype_one(struct rte_mbuf *m) +{ + struct ether_hdr *eth_hdr; + uint32_t packet_type = RTE_PTYPE_UNKNOWN; + uint16_t ether_type; + + eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); + ether_type = eth_hdr->ether_type; + if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) + packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; + else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6)) + packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; + + m->packet_type = packet_type; +} + +static uint16_t +cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused, + struct rte_mbuf *pkts[], uint16_t nb_pkts, + uint16_t max_pkts __rte_unused, + void *user_param __rte_unused) +{ + unsigned int i; + + for (i = 0; i < nb_pkts; ++i) + parse_ptype_one(pkts[i]); + + return nb_pkts; +} + +static int +add_cb_parse_ptype(uint8_t portid, uint16_t queueid) +{ + printf("Port %d: softly parse packet type info\n", portid); + if (rte_eth_add_rx_callback(portid, queueid, cb_parse_ptype, NULL)) + return 0; + + printf("Failed to add rx callback: port=%d\n", portid); + return -1; +} + +static int check_ptype(uint8_t portid) +{ + int i, ret; + int ptype_l3_ipv4 = 0; + int ptype_l3_ipv6 = 0; + uint32_t ptype_mask = RTE_PTYPE_L3_MASK; + + ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, NULL, 0); + if (ret <= 0) + return 0; + + uint32_t ptypes[ret]; + ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, ptypes, ret); + for (i = 0; i < ret; ++i) { + if (ptypes[i] & RTE_PTYPE_L3_IPV4) + ptype_l3_ipv4 = 1; + if (ptypes[i] & RTE_PTYPE_L3_IPV6) + ptype_l3_ipv6 = 1; + } + + if (ptype_l3_ipv4 && ptype_l3_ipv6) + return 1; + + return 0; +} + /* Check the link status of all ports in up to 9s, and print them finally */ static void check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) @@ -2039,7 +2118,15 @@ struct lcore_conf { rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d," "port=%d\n", ret, portid); - } + + if (parm_config.parse_ptype) { + if (add_cb_parse_ptype(portid, queueid) < 0) + rte_exit(EXIT_FAILURE, + "Fail to add ptype cb\n"); + } else if (!check_ptype(portid)) + rte_exit(EXIT_FAILURE, + "PMD can not provide needed ptypes\n"); + } } printf("\n"); -- 1.9.1