Steven Whitehouse writes:
 > Here is the updated patch. If you are happy with this, then will you send
 > it on to Dave, or should I do that?


 Hello! 

 Yes the minor problem with the "return code" is fixed as:
 Result: OK: mpls=0001000a,0002000a,0000000a

 So I'll guess Dave will apply it. 

 Signed-off-by: Robert Olsson <[EMAIL PROTECTED]>
 
 Thanks.
                                --ro
  




 > 
 > Signed-off-by: Steven Whitehouse <[EMAIL PROTECTED]>
 > 
 > diff --git a/Documentation/networking/pktgen.txt 
 > b/Documentation/networking/pktgen.txt
 > --- a/Documentation/networking/pktgen.txt
 > +++ b/Documentation/networking/pktgen.txt
 > @@ -109,6 +109,22 @@ Examples:
 >                           cycle through the port range.
 >   pgset "udp_dst_max 9"   set UDP destination port max.
 >  
 > + pgset "mpls 0001000a,0002000a,0000000a" set MPLS labels (in this example
 > +                                         outer label=16,middle label=32,
 > +                                     inner label=0 (IPv4 NULL)) Note that
 > +                                     there must be no spaces between the
 > +                                     arguments. Leading zeros are required.
 > +                                     Do not set the bottom of stack bit,
 > +                                     thats done automatically. If you do
 > +                                     set the bottom of stack bit, that
 > +                                     indicates that you want to randomly
 > +                                     generate that address and the flag
 > +                                     MPLS_RND will be turned on. You
 > +                                     can have any mix of random and fixed
 > +                                     labels in the label stack.
 > +
 > + pgset "mpls 0"               turn off mpls (or any invalid argument works 
 > too!)
 > +
 >   pgset stop                   aborts injection. Also, ^C aborts generator.
 >  
 >  
 > @@ -167,6 +183,8 @@ pkt_size 
 >  min_pkt_size
 >  max_pkt_size
 >  
 > +mpls
 > +
 >  udp_src_min
 >  udp_src_max
 >  
 > @@ -211,4 +229,4 @@ Grant Grundler for testing on IA-64 and 
 >  Stephen Hemminger, Andi Kleen, Dave Miller and many others.
 >  
 >  
 > -Good luck with the linux net-development.
 > \ No newline at end of file
 > +Good luck with the linux net-development.
 > diff --git a/net/core/pktgen.c b/net/core/pktgen.c
 > --- a/net/core/pktgen.c
 > +++ b/net/core/pktgen.c
 > @@ -106,6 +106,9 @@
 >   *
 >   * interruptible_sleep_on_timeout() replaced Nishanth Aravamudan <[EMAIL 
 > PROTECTED]> 
 >   * 050103
 > + *
 > + * MPLS support by Steven Whitehouse <[EMAIL PROTECTED]>
 > + *
 >   */
 >  #include <linux/sys.h>
 >  #include <linux/types.h>
 > @@ -154,7 +157,7 @@
 >  #include <asm/div64.h>              /* do_div */
 >  #include <asm/timex.h>
 >  
 > -#define VERSION  "pktgen v2.66: Packet Generator for packet performance 
 > testing.\n"
 > +#define VERSION  "pktgen v2.67: Packet Generator for packet performance 
 > testing.\n"
 >  
 >  /* #define PG_DEBUG(a) a */
 >  #define PG_DEBUG(a)
 > @@ -162,6 +165,8 @@
 >  /* The buckets are exponential in 'width' */
 >  #define LAT_BUCKETS_MAX 32
 >  #define IP_NAME_SZ 32
 > +#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
 > +#define MPLS_STACK_BOTTOM __constant_htonl(0x00000100)
 >  
 >  /* Device flag bits */
 >  #define F_IPSRC_RND   (1<<0)        /* IP-Src Random  */
 > @@ -172,6 +177,7 @@
 >  #define F_MACDST_RND  (1<<5)        /* MAC-Dst Random */
 >  #define F_TXSIZE_RND  (1<<6)        /* Transmit size is random */
 >  #define F_IPV6        (1<<7)        /* Interface in IPV6 Mode */
 > +#define F_MPLS_RND    (1<<8)        /* Random MPLS labels */
 >  
 >  /* Thread control flag bits */
 >  #define T_TERMINATE   (1<<0)
 > @@ -278,6 +284,10 @@ struct pktgen_dev {
 >      __u16 udp_dst_min;      /* inclusive, dest UDP port */
 >      __u16 udp_dst_max;      /* exclusive, dest UDP port */
 >  
 > +    /* MPLS */
 > +    unsigned nr_labels;     /* Depth of stack, 0 = no MPLS */
 > +    __be32 labels[MAX_MPLS_LABELS];
 > +
 >      __u32 src_mac_count;    /* How many MACs to iterate through */
 >      __u32 dst_mac_count;    /* How many MACs to iterate through */
 >  
 > @@ -623,9 +633,19 @@ static int pktgen_if_show(struct seq_fil
 >                 pkt_dev->udp_dst_min, pkt_dev->udp_dst_max);
 >  
 >      seq_printf(seq,
 > -               "     src_mac_count: %d  dst_mac_count: %d \n     Flags: ",
 > +               "     src_mac_count: %d  dst_mac_count: %d\n",
 >                 pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
 >  
 > +    if (pkt_dev->nr_labels) {
 > +            unsigned i;
 > +            seq_printf(seq, "     mpls: ");
 > +            for(i = 0; i < pkt_dev->nr_labels; i++)
 > +                    seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]),
 > +                               i == pkt_dev->nr_labels-1 ? "\n" : ", ");
 > +    }
 > +
 > +    seq_printf(seq, "     Flags: ");
 > +
 >      if (pkt_dev->flags & F_IPV6)
 >              seq_printf(seq, "IPV6  ");
 >  
 > @@ -644,6 +664,9 @@ static int pktgen_if_show(struct seq_fil
 >      if (pkt_dev->flags & F_UDPDST_RND)
 >              seq_printf(seq, "UDPDST_RND  ");
 >  
 > +    if (pkt_dev->flags & F_MPLS_RND)
 > +            seq_printf(seq,  "MPLS_RND  ");
 > +
 >      if (pkt_dev->flags & F_MACSRC_RND)
 >              seq_printf(seq, "MACSRC_RND  ");
 >  
 > @@ -691,6 +714,29 @@ static int pktgen_if_show(struct seq_fil
 >      return 0;
 >  }
 >  
 > +
 > +static int hex32_arg(const char __user *user_buffer, __u32 *num)
 > +{
 > +    int i = 0;
 > +    *num = 0;
 > +
 > +    for(; i < 8; i++) {
 > +            char c;
 > +            *num <<= 4;
 > +            if (get_user(c, &user_buffer[i]))
 > +                    return -EFAULT;
 > +            if ((c >= '0') && (c <= '9'))
 > +                    *num |= c - '0';
 > +            else if ((c >= 'a') && (c <= 'f'))
 > +                    *num |= c - 'a' + 10;
 > +            else if ((c >= 'A') && (c <= 'F'))
 > +                    *num |= c - 'A' + 10;
 > +            else
 > +                    break;
 > +    }
 > +    return i;
 > +}
 > +
 >  static int count_trail_chars(const char __user * user_buffer,
 >                           unsigned int maxlen)
 >  {
 > @@ -759,6 +805,35 @@ done_str:
 >      return i;
 >  }
 >  
 > +static ssize_t get_labels(const char __user *buffer, struct pktgen_dev 
 > *pkt_dev)
 > +{
 > +    unsigned n = 0;
 > +    char c;
 > +    ssize_t i = 0;
 > +    int len;
 > +
 > +    pkt_dev->nr_labels = 0;
 > +    do {
 > +            __u32 tmp;
 > +            len = hex32_arg(&buffer[i], &tmp);
 > +            if (len <= 0)
 > +                    return len;
 > +            pkt_dev->labels[n] = htonl(tmp);
 > +            if (pkt_dev->labels[n] & MPLS_STACK_BOTTOM)
 > +                    pkt_dev->flags |= F_MPLS_RND;
 > +            i += len;
 > +            if (get_user(c, &buffer[i]))
 > +                    return -EFAULT;
 > +            i++;
 > +            n++;
 > +            if (n >= MAX_MPLS_LABELS)
 > +                    return -E2BIG;
 > +    } while(c == ',');
 > +
 > +    pkt_dev->nr_labels = n;
 > +    return i;
 > +}
 > +
 >  static ssize_t pktgen_if_write(struct file *file,
 >                             const char __user * user_buffer, size_t count,
 >                             loff_t * offset)
 > @@ -1059,6 +1134,12 @@ static ssize_t pktgen_if_write(struct fi
 >              else if (strcmp(f, "!MACDST_RND") == 0)
 >                      pkt_dev->flags &= ~F_MACDST_RND;
 >  
 > +            else if (strcmp(f, "MPLS_RND") == 0)
 > +                    pkt_dev->flags |= F_MPLS_RND;
 > +
 > +            else if (strcmp(f, "!MPLS_RND") == 0)
 > +                    pkt_dev->flags &= ~F_MPLS_RND;
 > +
 >              else {
 >                      sprintf(pg_result,
 >                              "Flag -:%s:- unknown\nAvailable flags, (prepend 
 > ! to un-set flag):\n%s",
 > @@ -1354,6 +1435,19 @@ static ssize_t pktgen_if_write(struct fi
 >              return count;
 >      }
 >  
 > +    if (!strcmp(name, "mpls")) {
 > +            unsigned n, offset;
 > +            len = get_labels(&user_buffer[i], pkt_dev);
 > +            if (len < 0) { return len; }
 > +            i += len;
 > +            offset = sprintf(pg_result, "OK: mpls=");
 > +            for(n = 0; n < pkt_dev->nr_labels; n++)
 > +                    offset += sprintf(pg_result + offset,
 > +                                      "%08x%s", ntohl(pkt_dev->labels[n]),
 > +                                      n == pkt_dev->nr_labels-1 ? "" : ",");
 > +            return count;
 > +    }
 > +
 >      sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
 >      return -EINVAL;
 >  }
 > @@ -1846,6 +1940,15 @@ static void mod_cur_headers(struct pktge
 >              pkt_dev->hh[1] = tmp;
 >      }
 >  
 > +    if (pkt_dev->flags & F_MPLS_RND) {
 > +            unsigned i;
 > +            for(i = 0; i < pkt_dev->nr_labels; i++)
 > +                    if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM)
 > +                            pkt_dev->labels[i] = MPLS_STACK_BOTTOM |
 > +                                                 (pktgen_random() &
 > +                                                  htonl(0x000fffff));
 > +    }
 > +
 >      if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
 >              if (pkt_dev->flags & F_UDPSRC_RND)
 >                      pkt_dev->cur_udp_src =
 > @@ -1968,6 +2071,16 @@ static void mod_cur_headers(struct pktge
 >      pkt_dev->flows[flow].count++;
 >  }
 >  
 > +static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
 > +{
 > +    unsigned i;
 > +    for(i = 0; i < pkt_dev->nr_labels; i++) {
 > +            *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM;
 > +    }
 > +    mpls--;
 > +    *mpls |= MPLS_STACK_BOTTOM;
 > +}
 > +
 >  static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 >                                      struct pktgen_dev *pkt_dev)
 >  {
 > @@ -1977,6 +2090,11 @@ static struct sk_buff *fill_packet_ipv4(
 >      int datalen, iplen;
 >      struct iphdr *iph;
 >      struct pktgen_hdr *pgh = NULL;
 > +    __be16 protocol = __constant_htons(ETH_P_IP);
 > +    __be32 *mpls;
 > +
 > +    if (pkt_dev->nr_labels)
 > +            protocol = __constant_htons(ETH_P_MPLS_UC);
 >  
 >      /* Update any of the values, used when we're incrementing various
 >       * fields.
 > @@ -1984,7 +2102,8 @@ static struct sk_buff *fill_packet_ipv4(
 >      mod_cur_headers(pkt_dev);
 >  
 >      datalen = (odev->hard_header_len + 16) & ~0xf;
 > -    skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen, GFP_ATOMIC);
 > +    skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
 > +                    pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
 >      if (!skb) {
 >              sprintf(pkt_dev->result, "No memory");
 >              return NULL;
 > @@ -1994,13 +2113,18 @@ static struct sk_buff *fill_packet_ipv4(
 >  
 >      /*  Reserve for ethernet and IP header  */
 >      eth = (__u8 *) skb_push(skb, 14);
 > +    mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
 > +    if (pkt_dev->nr_labels)
 > +            mpls_push(mpls, pkt_dev);
 >      iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
 >      udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
 >  
 >      memcpy(eth, pkt_dev->hh, 12);
 > -    *(u16 *) & eth[12] = __constant_htons(ETH_P_IP);
 > +    *(u16 *) & eth[12] = protocol;
 >  
 > -    datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8;  /* Eth + IPh + UDPh */
 > +    /* Eth + IPh + UDPh + mpls */
 > +    datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
 > +              pkt_dev->nr_labels*sizeof(u32);
 >      if (datalen < sizeof(struct pktgen_hdr))
 >              datalen = sizeof(struct pktgen_hdr);
 >  
 > @@ -2021,8 +2145,8 @@ static struct sk_buff *fill_packet_ipv4(
 >      iph->tot_len = htons(iplen);
 >      iph->check = 0;
 >      iph->check = ip_fast_csum((void *)iph, iph->ihl);
 > -    skb->protocol = __constant_htons(ETH_P_IP);
 > -    skb->mac.raw = ((u8 *) iph) - 14;
 > +    skb->protocol = protocol;
 > +    skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
 >      skb->dev = odev;
 >      skb->pkt_type = PACKET_HOST;
 >  
 > @@ -2274,13 +2398,19 @@ static struct sk_buff *fill_packet_ipv6(
 >      int datalen;
 >      struct ipv6hdr *iph;
 >      struct pktgen_hdr *pgh = NULL;
 > +    __be16 protocol = __constant_htons(ETH_P_IPV6);
 > +    __be32 *mpls;
 > +
 > +    if (pkt_dev->nr_labels)
 > +            protocol = __constant_htons(ETH_P_MPLS_UC);
 >  
 >      /* Update any of the values, used when we're incrementing various
 >       * fields.
 >       */
 >      mod_cur_headers(pkt_dev);
 >  
 > -    skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
 > +    skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
 > +                    pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
 >      if (!skb) {
 >              sprintf(pkt_dev->result, "No memory");
 >              return NULL;
 > @@ -2290,13 +2420,19 @@ static struct sk_buff *fill_packet_ipv6(
 >  
 >      /*  Reserve for ethernet and IP header  */
 >      eth = (__u8 *) skb_push(skb, 14);
 > +    mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
 > +    if (pkt_dev->nr_labels)
 > +            mpls_push(mpls, pkt_dev);
 >      iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
 >      udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
 >  
 >      memcpy(eth, pkt_dev->hh, 12);
 >      *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6);
 >  
 > -    datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - 
 > sizeof(struct udphdr);  /* Eth + IPh + UDPh */
 > +    /* Eth + IPh + UDPh + mpls */
 > +    datalen = pkt_dev->cur_pkt_size - 14 -
 > +              sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
 > +              pkt_dev->nr_labels*sizeof(u32);
 >  
 >      if (datalen < sizeof(struct pktgen_hdr)) {
 >              datalen = sizeof(struct pktgen_hdr);
 > @@ -2320,8 +2456,8 @@ static struct sk_buff *fill_packet_ipv6(
 >      ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
 >      ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
 >  
 > -    skb->mac.raw = ((u8 *) iph) - 14;
 > -    skb->protocol = __constant_htons(ETH_P_IPV6);
 > +    skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
 > +    skb->protocol = protocol;
 >      skb->dev = odev;
 >      skb->pkt_type = PACKET_HOST;
 >  
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to