From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 8454991CB for ; Fri, 15 Jan 2016 13:46:35 +0100 (CET) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 15 Jan 2016 04:46:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,299,1449561600"; d="scan'208";a="891104801" Received: from dpdk06.sh.intel.com ([10.239.128.225]) by orsmga002.jf.intel.com with ESMTP; 15 Jan 2016 04:46:34 -0800 From: Jianfeng Tan To: dev@dpdk.org Date: Fri, 15 Jan 2016 13:45:59 +0800 Message-Id: <1452836759-63540-13-git-send-email-jianfeng.tan@intel.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1452836759-63540-1-git-send-email-jianfeng.tan@intel.com> References: <1451544799-70776-1-git-send-email-jianfeng.tan@intel.com> <1452836759-63540-1-git-send-email-jianfeng.tan@intel.com> Subject: [dpdk-dev] [PATCH v2 12/12] examples/l3fwd: add option to parse ptype X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2016 12:46:36 -0000 As a example to use ptype info, l3fwd needs firstly to use rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will parse and fill the needed packet type. If not, use the newly added option, --parse-ptype, to analyze it in the callback softly. Signed-off-by: Jianfeng Tan --- examples/l3fwd/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c index 5b0c2dd..3c6e1b7 100644 --- a/examples/l3fwd/main.c +++ b/examples/l3fwd/main.c @@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS]; static uint32_t enabled_port_mask = 0; static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */ static int numa_on = 1; /**< NUMA is enabled by default. */ +static int parse_ptype = 0; /**< parse packet type using rx callback */ #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH) static int ipv6 = 0; /**< ipv6 is false by default. */ @@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg) #define CMD_LINE_OPT_IPV6 "ipv6" #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo" #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num" +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype" /* Parse the argument given in the command line of the application */ static int @@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv) {CMD_LINE_OPT_IPV6, 0, 0, 0}, {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0}, {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0}, + {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0}, {NULL, 0, 0, 0} }; @@ -2125,6 +2128,13 @@ parse_args(int argc, char **argv) } } #endif + if (!strncmp(lgopts[option_index].name, + CMD_LINE_OPT_PARSE_PTYPE, + sizeof(CMD_LINE_OPT_PARSE_PTYPE))) { + printf("soft parse-ptype is enabled \n"); + parse_ptype = 1; + } + break; default: @@ -2559,6 +2569,74 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) } } +static int +check_packet_type_ok(int portid) +{ + int i, ret; + uint32_t *ptypes; + int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0; + + ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0); + if (ret <= 0) + return 0; + ptypes = malloc(sizeof(uint32_t) * ret); + rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_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 == 0) + printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid); + + if (ptype_l3_ipv6 == 0) + printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid); + + if (ptype_l3_ipv4 && ptype_l3_ipv6) + return 1; + + return 0; +} +static inline void +parse_packet_type(struct rte_mbuf *m) +{ + struct ether_hdr *eth_hdr; + uint32_t packet_type = 0; + uint16_t ethertype; + + eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); + ethertype = rte_be_to_cpu_16(eth_hdr->ether_type); + switch (ethertype) { + case ETHER_TYPE_IPv4: + packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; + break; + case ETHER_TYPE_IPv6: + packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; + break; + default: + break; + } + + m->packet_type |= packet_type; +} + +static uint16_t +cb_parse_packet_type(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 i; + + for (i = 0; i < nb_pkts; ++i) + parse_packet_type(pkts[i]); +} + int main(int argc, char **argv) { @@ -2672,6 +2750,11 @@ main(int argc, char **argv) rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, " "port=%d\n", ret, portid); + if (!check_packet_type_ok(portid) && !parse_ptype) + rte_exit(EXIT_FAILURE, + "port %d cannot parse packet type, please add --%s\n", + portid, CMD_LINE_OPT_PARSE_PTYPE); + qconf = &lcore_conf[lcore_id]; qconf->tx_queue_id[portid] = queueid; queueid++; @@ -2705,6 +2788,14 @@ main(int argc, char **argv) if (ret < 0) rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d," "port=%d\n", ret, portid); + if (parse_ptype && + !rte_eth_add_rx_callback(portid, queueid, + cb_parse_packet_type, + NULL)) + rte_exit(EXIT_FAILURE, + "Failed to add rx callback: port=%d\n", + portid); + } } -- 2.1.4