Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, January 15, 2016 5:46 AM
> To: dev at dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> Subject: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
> 
> 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 <jianfeng.tan at intel.com>
> ---
>  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;
> +     }


I think you forgot to do: free(ptypes);
Also, formally speaking malloc can fail here, so probably need to check 
malloc() return value,
or just allocate ptypes[] on the stack - would be easier.

> +
> +     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;

That's enough for LPM, for EM, don't we need to be sure there are no extensions
in the IP header? 

Konstantin

> +     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

Reply via email to