Hi, 

> -----Original Message-----
> From: Ashish Jain [mailto:ashish.j...@nxp.com]
> Sent: Thursday, April 20, 2017 8:18 AM
> To: dev@dpdk.org; Ananyev, Konstantin <konstantin.anan...@intel.com>
> Subject: [PATCH] examples/ip_fragmentation: add fragmentation size support
> 
> Adding support for determining fragmentation size for both
> ipv4 and ipv6 traffic dynamically through command line.
> It is helpful in testing to configure different fragmentation
> sizes and validate the packets.
> 
> Signed-off-by: Ashish Jain <ashish.j...@nxp.com>
> Signed-off-by: Hemant Agrawal <hemant.agra...@nxp.com>
> ---
>  examples/ip_fragmentation/main.c | 89 
> ++++++++++++++++++++++++++++++++++++----
>  1 file changed, 81 insertions(+), 8 deletions(-)
> 
> diff --git a/examples/ip_fragmentation/main.c 
> b/examples/ip_fragmentation/main.c
> index 815b225..436755b 100644
> --- a/examples/ip_fragmentation/main.c
> +++ b/examples/ip_fragmentation/main.c
> @@ -94,6 +94,16 @@
>  #define      IPV6_DEFAULT_PAYLOAD    (IPV6_MTU_DEFAULT - sizeof(struct 
> ipv6_hdr))
> 
>  /*
> + * Configure fragmentation size for IPv4 and IPv6 packets
> + */
> +static uint32_t frag_size_v4 = IPV4_MTU_DEFAULT;
> +static uint32_t frag_size_v6 = IPV6_MTU_DEFAULT;
> +#define MIN_IPV4_FRAG_SIZE 64
> +#define MAX_IPV4_FRAG_SIZE 9600
> +#define MIN_IPV6_FRAG_SIZE 1280
> +#define MAX_IPV6_FRAG_SIZE 9600
> +
> +/*
>   * Max number of fragments per packet expected - defined by config file.
>   */
>  #define      MAX_PACKET_FRAG RTE_LIBRTE_IP_FRAG_MAX_FRAG
> @@ -299,14 +309,14 @@ struct rte_lpm6_config lpm6_config = {
>               }
> 
>               /* if we don't need to do any fragmentation */
> -             if (likely (IPV4_MTU_DEFAULT >= m->pkt_len)) {
> +             if (likely (frag_size_v4 >= m->pkt_len)) {
>                       qconf->tx_mbufs[port_out].m_table[len] = m;
>                       len2 = 1;
>               } else {
>                       len2 = rte_ipv4_fragment_packet(m,
>                               &qconf->tx_mbufs[port_out].m_table[len],
>                               (uint16_t)(MBUF_TABLE_SIZE - len),
> -                             IPV4_MTU_DEFAULT,
> +                             frag_size_v4,
>                               rxq->direct_pool, rxq->indirect_pool);
> 
>                       /* Free input packet */
> @@ -336,14 +346,14 @@ struct rte_lpm6_config lpm6_config = {
>               }
> 
>               /* if we don't need to do any fragmentation */
> -             if (likely (IPV6_MTU_DEFAULT >= m->pkt_len)) {
> +             if (likely (frag_size_v6 >= m->pkt_len)) {
>                       qconf->tx_mbufs[port_out].m_table[len] = m;
>                       len2 = 1;
>               } else {
>                       len2 = rte_ipv6_fragment_packet(m,
>                               &qconf->tx_mbufs[port_out].m_table[len],
>                               (uint16_t)(MBUF_TABLE_SIZE - len),
> -                             IPV6_MTU_DEFAULT,
> +                             frag_size_v6,
>                               rxq->direct_pool, rxq->indirect_pool);
> 
>                       /* Free input packet */
> @@ -489,8 +499,14 @@ struct rte_lpm6_config lpm6_config = {
>  {
>       printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
>              "  -p PORTMASK: hexadecimal bitmask of ports to configure\n"
> -            "  -q NQ: number of queue (=ports) per lcore (default is 1)\n",
> -            prgname);
> +            "  -q NQ: number of queue (=ports) per lcore (default is 1)\n"
> +            "  --frag_size_v4=<num>:optional,IPv4 fragment size in decimal"
> +            ",Condition:(frag_size_v4 - 20) should be a multiple of 8,"
> +            " default is %d \n"
> +            "  --frag_size_v6=<num>:optional,IPv6 fragment size in decimal"
> +            ",Condition:(frag_size_v6 - 40) should be a multiple of 8,"
> +            " default is %d\n",
> +            prgname, frag_size_v4, frag_size_v6);
>  }
> 
>  static int
> @@ -528,6 +544,29 @@ struct rte_lpm6_config lpm6_config = {
>       return n;
>  }
> 
> +static int
> +parse_frag_size(const char *str, uint32_t min, uint32_t max,
> +             uint8_t hdr_size, uint32_t *val)
> +{
> +     char *end;
> +     uint64_t v;
> +
> +     /* parse decimal string */
> +     errno = 0;
> +     v = strtoul(str, &end, 10);
> +     if (errno != 0 || *end != '\0')
> +             return -EINVAL;
> +
> +     if (v < min || v > max)
> +             return -EINVAL;
> +
> +     if ((v - hdr_size) % 8)
> +             return -EINVAL;
> +
> +     *val = (uint32_t)v;
> +     return 0;
> +}
> +
>  /* Parse the argument given in the command line of the application */
>  static int
>  parse_args(int argc, char **argv)
> @@ -537,6 +576,8 @@ struct rte_lpm6_config lpm6_config = {
>       int option_index;
>       char *prgname = argv[0];
>       static struct option lgopts[] = {
> +             {"frag_size_v4", 1, 0, 0},
> +             {"frag_size_v6", 1, 0, 0},
>               {NULL, 0, 0, 0}
>       };
> 
> @@ -568,8 +609,40 @@ struct rte_lpm6_config lpm6_config = {
> 
>               /* long options */
>               case 0:
> -                     print_usage(prgname);
> -                     return -1;
> +                     if (!strncmp(lgopts[option_index].name,
> +                             "frag_size_v4", 12)) {


Why just not strcmp() here?

> +                             ret = parse_frag_size(optarg,
> +                                             MIN_IPV4_FRAG_SIZE,
> +                                             MAX_IPV4_FRAG_SIZE,
> +                                             sizeof(struct ipv4_hdr),
> +                                             &frag_size_v4);
> +                             if (ret) {
> +                                     printf("invalid value: \"%s\" for "
> +                                             "parameter %s\n",
> +                                             optarg,
> +                                             lgopts[option_index].name);
> +                                     print_usage(prgname);
> +                                     return ret;
> +                             }
> +                     }
> +                     if (!strncmp(lgopts[option_index].name,
> +                             "frag_size_v6", 12)) {
> +                             ret = parse_frag_size(optarg,
> +                                             MIN_IPV6_FRAG_SIZE,
> +                                             MAX_IPV6_FRAG_SIZE,
> +                                             sizeof(struct ipv6_hdr),
> +                                             &frag_size_v6);
> +                             if (ret) {
> +                                     printf("invalid value: \"%s\" for "
> +                                             "parameter %s\n",
> +                                             optarg,
> +                                             lgopts[option_index].name);
> +                                     print_usage(prgname);
> +                                     return ret;
> +                             }
> +                     }
> +
> +                     break;

Hmm, why do we need that break here?
Konstantin


> 
>               default:
>                       print_usage(prgname);
> --
> 1.9.1

Reply via email to