Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[firefly-linux-kernel-4.4.55.git] / net / core / pktgen.c
index 6ed9e27d8202c9d4bf2ec43537a83a444c7d8822..67870e9fd097f2ff04edf8d360596ec9e45c9604 100644 (file)
@@ -450,7 +450,6 @@ static void pktgen_stop(struct pktgen_thread *t);
 static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
 
 static unsigned int scan_ip6(const char *s, char ip[16]);
-static unsigned int fmt_ip6(char *s, const char ip[16]);
 
 /* Module parameters, defaults. */
 static int pg_count_d __read_mostly = 1000;
@@ -557,21 +556,13 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
                           pkt_dev->skb_priority);
 
        if (pkt_dev->flags & F_IPV6) {
-               char b1[128], b2[128], b3[128];
-               fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
-               fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
-               fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
                seq_printf(seq,
-                          "     saddr: %s  min_saddr: %s  max_saddr: %s\n", b1,
-                          b2, b3);
-
-               fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
-               fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
-               fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
-               seq_printf(seq,
-                          "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1,
-                          b2, b3);
-
+                          "     saddr: %pI6c  min_saddr: %pI6c  max_saddr: %pI6c\n"
+                          "     daddr: %pI6c  min_daddr: %pI6c  max_daddr: %pI6c\n",
+                          &pkt_dev->in6_saddr,
+                          &pkt_dev->min_in6_saddr, &pkt_dev->max_in6_saddr,
+                          &pkt_dev->in6_daddr,
+                          &pkt_dev->min_in6_daddr, &pkt_dev->max_in6_daddr);
        } else {
                seq_printf(seq,
                           "     dst_min: %s  dst_max: %s\n",
@@ -707,10 +698,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
                   pkt_dev->cur_src_mac_offset);
 
        if (pkt_dev->flags & F_IPV6) {
-               char b1[128], b2[128];
-               fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
-               fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
-               seq_printf(seq, "     cur_saddr: %s  cur_daddr: %s\n", b2, b1);
+               seq_printf(seq, "     cur_saddr: %pI6c  cur_daddr: %pI6c\n",
+                               &pkt_dev->cur_in6_saddr,
+                               &pkt_dev->cur_in6_daddr);
        } else
                seq_printf(seq, "     cur_saddr: 0x%x  cur_daddr: 0x%x\n",
                           pkt_dev->cur_saddr, pkt_dev->cur_daddr);
@@ -1310,7 +1300,7 @@ static ssize_t pktgen_if_write(struct file *file,
                buf[len] = 0;
 
                scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
-               fmt_ip6(buf, pkt_dev->in6_daddr.s6_addr);
+               snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr);
 
                ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr);
 
@@ -1333,7 +1323,7 @@ static ssize_t pktgen_if_write(struct file *file,
                buf[len] = 0;
 
                scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
-               fmt_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
+               snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr);
 
                ipv6_addr_copy(&pkt_dev->cur_in6_daddr,
                               &pkt_dev->min_in6_daddr);
@@ -1356,7 +1346,7 @@ static ssize_t pktgen_if_write(struct file *file,
                buf[len] = 0;
 
                scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
-               fmt_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
+               snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr);
 
                if (debug)
                        printk(KERN_DEBUG "pktgen: dst6_max set to: %s\n", buf);
@@ -1377,7 +1367,7 @@ static ssize_t pktgen_if_write(struct file *file,
                buf[len] = 0;
 
                scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
-               fmt_ip6(buf, pkt_dev->in6_saddr.s6_addr);
+               snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr);
 
                ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr);
 
@@ -1431,11 +1421,6 @@ static ssize_t pktgen_if_write(struct file *file,
                return count;
        }
        if (!strcmp(name, "dst_mac")) {
-               char *v = valstr;
-               unsigned char old_dmac[ETH_ALEN];
-               unsigned char *m = pkt_dev->dst_mac;
-               memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
-
                len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
                if (len < 0)
                        return len;
@@ -1443,35 +1428,16 @@ static ssize_t pktgen_if_write(struct file *file,
                memset(valstr, 0, sizeof(valstr));
                if (copy_from_user(valstr, &user_buffer[i], len))
                        return -EFAULT;
-               i += len;
-
-               for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) {
-                       int value;
-
-                       value = hex_to_bin(*v);
-                       if (value >= 0)
-                               *m = *m * 16 + value;
-
-                       if (*v == ':') {
-                               m++;
-                               *m = 0;
-                       }
-               }
 
+               if (!mac_pton(valstr, pkt_dev->dst_mac))
+                       return -EINVAL;
                /* Set up Dest MAC */
-               if (compare_ether_addr(old_dmac, pkt_dev->dst_mac))
-                       memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
+               memcpy(&pkt_dev->hh[0], pkt_dev->dst_mac, ETH_ALEN);
 
-               sprintf(pg_result, "OK: dstmac");
+               sprintf(pg_result, "OK: dstmac %pM", pkt_dev->dst_mac);
                return count;
        }
        if (!strcmp(name, "src_mac")) {
-               char *v = valstr;
-               unsigned char old_smac[ETH_ALEN];
-               unsigned char *m = pkt_dev->src_mac;
-
-               memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN);
-
                len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
                if (len < 0)
                        return len;
@@ -1479,26 +1445,13 @@ static ssize_t pktgen_if_write(struct file *file,
                memset(valstr, 0, sizeof(valstr));
                if (copy_from_user(valstr, &user_buffer[i], len))
                        return -EFAULT;
-               i += len;
-
-               for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) {
-                       int value;
-
-                       value = hex_to_bin(*v);
-                       if (value >= 0)
-                               *m = *m * 16 + value;
-
-                       if (*v == ':') {
-                               m++;
-                               *m = 0;
-                       }
-               }
 
+               if (!mac_pton(valstr, pkt_dev->src_mac))
+                       return -EINVAL;
                /* Set up Src MAC */
-               if (compare_ether_addr(old_smac, pkt_dev->src_mac))
-                       memcpy(&(pkt_dev->hh[6]), pkt_dev->src_mac, ETH_ALEN);
+               memcpy(&pkt_dev->hh[6], pkt_dev->src_mac, ETH_ALEN);
 
-               sprintf(pg_result, "OK: srcmac");
+               sprintf(pg_result, "OK: srcmac %pM", pkt_dev->src_mac);
                return count;
        }
 
@@ -2515,7 +2468,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
 {
        struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
        int err = 0;
-       struct iphdr *iph;
 
        if (!x)
                return 0;
@@ -2525,7 +2477,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
                return 0;
 
        spin_lock(&x->lock);
-       iph = ip_hdr(skb);
 
        err = x->outer_mode->output(x, skb);
        if (err)
@@ -2625,6 +2576,7 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
        } else {
                int frags = pkt_dev->nfrags;
                int i, len;
+               int frag_len;
 
 
                if (frags > MAX_SKB_FRAGS)
@@ -2636,6 +2588,8 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
                }
 
                i = 0;
+               frag_len = (datalen/frags) < PAGE_SIZE ?
+                          (datalen/frags) : PAGE_SIZE;
                while (datalen > 0) {
                        if (unlikely(!pkt_dev->page)) {
                                int node = numa_node_id();
@@ -2649,38 +2603,18 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
                        skb_shinfo(skb)->frags[i].page = pkt_dev->page;
                        get_page(pkt_dev->page);
                        skb_shinfo(skb)->frags[i].page_offset = 0;
-                       skb_shinfo(skb)->frags[i].size =
-                           (datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+                       /*last fragment, fill rest of data*/
+                       if (i == (frags - 1))
+                               skb_shinfo(skb)->frags[i].size =
+                                   (datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+                       else
+                               skb_shinfo(skb)->frags[i].size = frag_len;
                        datalen -= skb_shinfo(skb)->frags[i].size;
                        skb->len += skb_shinfo(skb)->frags[i].size;
                        skb->data_len += skb_shinfo(skb)->frags[i].size;
                        i++;
                        skb_shinfo(skb)->nr_frags = i;
                }
-
-               while (i < frags) {
-                       int rem;
-
-                       if (i == 0)
-                               break;
-
-                       rem = skb_shinfo(skb)->frags[i - 1].size / 2;
-                       if (rem == 0)
-                               break;
-
-                       skb_shinfo(skb)->frags[i - 1].size -= rem;
-
-                       skb_shinfo(skb)->frags[i] =
-                           skb_shinfo(skb)->frags[i - 1];
-                       get_page(skb_shinfo(skb)->frags[i].page);
-                       skb_shinfo(skb)->frags[i].page =
-                           skb_shinfo(skb)->frags[i - 1].page;
-                       skb_shinfo(skb)->frags[i].page_offset +=
-                           skb_shinfo(skb)->frags[i - 1].size;
-                       skb_shinfo(skb)->frags[i].size = rem;
-                       i++;
-                       skb_shinfo(skb)->nr_frags = i;
-               }
        }
 
        /* Stamp the time, and sequence number,
@@ -2918,79 +2852,6 @@ static unsigned int scan_ip6(const char *s, char ip[16])
        return len;
 }
 
-static char tohex(char hexdigit)
-{
-       return hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
-}
-
-static int fmt_xlong(char *s, unsigned int i)
-{
-       char *bak = s;
-       *s = tohex((i >> 12) & 0xf);
-       if (s != bak || *s != '0')
-               ++s;
-       *s = tohex((i >> 8) & 0xf);
-       if (s != bak || *s != '0')
-               ++s;
-       *s = tohex((i >> 4) & 0xf);
-       if (s != bak || *s != '0')
-               ++s;
-       *s = tohex(i & 0xf);
-       return s - bak + 1;
-}
-
-static unsigned int fmt_ip6(char *s, const char ip[16])
-{
-       unsigned int len;
-       unsigned int i;
-       unsigned int temp;
-       unsigned int compressing;
-       int j;
-
-       len = 0;
-       compressing = 0;
-       for (j = 0; j < 16; j += 2) {
-
-#ifdef V4MAPPEDPREFIX
-               if (j == 12 && !memcmp(ip, V4mappedprefix, 12)) {
-                       inet_ntoa_r(*(struct in_addr *)(ip + 12), s);
-                       temp = strlen(s);
-                       return len + temp;
-               }
-#endif
-               temp = ((unsigned long)(unsigned char)ip[j] << 8) +
-                   (unsigned long)(unsigned char)ip[j + 1];
-               if (temp == 0) {
-                       if (!compressing) {
-                               compressing = 1;
-                               if (j == 0) {
-                                       *s++ = ':';
-                                       ++len;
-                               }
-                       }
-               } else {
-                       if (compressing) {
-                               compressing = 0;
-                               *s++ = ':';
-                               ++len;
-                       }
-                       i = fmt_xlong(s, temp);
-                       len += i;
-                       s += i;
-                       if (j < 14) {
-                               *s++ = ':';
-                               ++len;
-                       }
-               }
-       }
-       if (compressing) {
-               *s++ = ':';
-               ++len;
-       }
-       *s = 0;
-       return len;
-}
-
 static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
                                        struct pktgen_dev *pkt_dev)
 {