aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/pktgen.c146
-rw-r--r--net/core/utils.c24
2 files changed, 53 insertions, 117 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 148e73d2c451..d1dc14c2aac4 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -248,8 +248,8 @@ struct pktgen_dev {
248 int removal_mark; /* non-zero => the device is marked for 248 int removal_mark; /* non-zero => the device is marked for
249 * removal by worker thread */ 249 * removal by worker thread */
250 250
251 int min_pkt_size; /* = ETH_ZLEN; */ 251 int min_pkt_size;
252 int max_pkt_size; /* = ETH_ZLEN; */ 252 int max_pkt_size;
253 int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */ 253 int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */
254 int nfrags; 254 int nfrags;
255 struct page *page; 255 struct page *page;
@@ -449,8 +449,6 @@ static void pktgen_stop_all_threads_ifs(void);
449static void pktgen_stop(struct pktgen_thread *t); 449static void pktgen_stop(struct pktgen_thread *t);
450static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); 450static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
451 451
452static unsigned int scan_ip6(const char *s, char ip[16]);
453
454/* Module parameters, defaults. */ 452/* Module parameters, defaults. */
455static int pg_count_d __read_mostly = 1000; 453static int pg_count_d __read_mostly = 1000;
456static int pg_delay_d __read_mostly; 454static int pg_delay_d __read_mostly;
@@ -702,8 +700,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
702 &pkt_dev->cur_in6_saddr, 700 &pkt_dev->cur_in6_saddr,
703 &pkt_dev->cur_in6_daddr); 701 &pkt_dev->cur_in6_daddr);
704 } else 702 } else
705 seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n", 703 seq_printf(seq, " cur_saddr: %pI4 cur_daddr: %pI4\n",
706 pkt_dev->cur_saddr, pkt_dev->cur_daddr); 704 &pkt_dev->cur_saddr, &pkt_dev->cur_daddr);
707 705
708 seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n", 706 seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
709 pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); 707 pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
@@ -1299,7 +1297,7 @@ static ssize_t pktgen_if_write(struct file *file,
1299 return -EFAULT; 1297 return -EFAULT;
1300 buf[len] = 0; 1298 buf[len] = 0;
1301 1299
1302 scan_ip6(buf, pkt_dev->in6_daddr.s6_addr); 1300 in6_pton(buf, -1, pkt_dev->in6_daddr.s6_addr, -1, NULL);
1303 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr); 1301 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr);
1304 1302
1305 pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr; 1303 pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr;
@@ -1322,7 +1320,7 @@ static ssize_t pktgen_if_write(struct file *file,
1322 return -EFAULT; 1320 return -EFAULT;
1323 buf[len] = 0; 1321 buf[len] = 0;
1324 1322
1325 scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr); 1323 in6_pton(buf, -1, pkt_dev->min_in6_daddr.s6_addr, -1, NULL);
1326 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr); 1324 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr);
1327 1325
1328 pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr; 1326 pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr;
@@ -1344,7 +1342,7 @@ static ssize_t pktgen_if_write(struct file *file,
1344 return -EFAULT; 1342 return -EFAULT;
1345 buf[len] = 0; 1343 buf[len] = 0;
1346 1344
1347 scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr); 1345 in6_pton(buf, -1, pkt_dev->max_in6_daddr.s6_addr, -1, NULL);
1348 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr); 1346 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr);
1349 1347
1350 if (debug) 1348 if (debug)
@@ -1365,7 +1363,7 @@ static ssize_t pktgen_if_write(struct file *file,
1365 return -EFAULT; 1363 return -EFAULT;
1366 buf[len] = 0; 1364 buf[len] = 0;
1367 1365
1368 scan_ip6(buf, pkt_dev->in6_saddr.s6_addr); 1366 in6_pton(buf, -1, pkt_dev->in6_saddr.s6_addr, -1, NULL);
1369 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr); 1367 snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr);
1370 1368
1371 pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr; 1369 pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr;
@@ -2036,19 +2034,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2036 /* Set up Dest MAC */ 2034 /* Set up Dest MAC */
2037 memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN); 2035 memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
2038 2036
2039 /* Set up pkt size */
2040 pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
2041
2042 if (pkt_dev->flags & F_IPV6) { 2037 if (pkt_dev->flags & F_IPV6) {
2043 /*
2044 * Skip this automatic address setting until locks or functions
2045 * gets exported
2046 */
2047
2048#ifdef NOTNOW
2049 int i, set = 0, err = 1; 2038 int i, set = 0, err = 1;
2050 struct inet6_dev *idev; 2039 struct inet6_dev *idev;
2051 2040
2041 if (pkt_dev->min_pkt_size == 0) {
2042 pkt_dev->min_pkt_size = 14 + sizeof(struct ipv6hdr)
2043 + sizeof(struct udphdr)
2044 + sizeof(struct pktgen_hdr)
2045 + pkt_dev->pkt_overhead;
2046 }
2047
2052 for (i = 0; i < IN6_ADDR_HSIZE; i++) 2048 for (i = 0; i < IN6_ADDR_HSIZE; i++)
2053 if (pkt_dev->cur_in6_saddr.s6_addr[i]) { 2049 if (pkt_dev->cur_in6_saddr.s6_addr[i]) {
2054 set = 1; 2050 set = 1;
@@ -2069,9 +2065,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2069 struct inet6_ifaddr *ifp; 2065 struct inet6_ifaddr *ifp;
2070 2066
2071 read_lock_bh(&idev->lock); 2067 read_lock_bh(&idev->lock);
2072 for (ifp = idev->addr_list; ifp; 2068 list_for_each_entry(ifp, &idev->addr_list, if_list) {
2073 ifp = ifp->if_next) { 2069 if ((ifp->scope & IFA_LINK) &&
2074 if (ifp->scope == IFA_LINK &&
2075 !(ifp->flags & IFA_F_TENTATIVE)) { 2070 !(ifp->flags & IFA_F_TENTATIVE)) {
2076 pkt_dev->cur_in6_saddr = ifp->addr; 2071 pkt_dev->cur_in6_saddr = ifp->addr;
2077 err = 0; 2072 err = 0;
@@ -2084,8 +2079,14 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2084 if (err) 2079 if (err)
2085 pr_err("ERROR: IPv6 link address not available\n"); 2080 pr_err("ERROR: IPv6 link address not available\n");
2086 } 2081 }
2087#endif
2088 } else { 2082 } else {
2083 if (pkt_dev->min_pkt_size == 0) {
2084 pkt_dev->min_pkt_size = 14 + sizeof(struct iphdr)
2085 + sizeof(struct udphdr)
2086 + sizeof(struct pktgen_hdr)
2087 + pkt_dev->pkt_overhead;
2088 }
2089
2089 pkt_dev->saddr_min = 0; 2090 pkt_dev->saddr_min = 0;
2090 pkt_dev->saddr_max = 0; 2091 pkt_dev->saddr_max = 0;
2091 if (strlen(pkt_dev->src_min) == 0) { 2092 if (strlen(pkt_dev->src_min) == 0) {
@@ -2111,6 +2112,10 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2111 pkt_dev->daddr_max = in_aton(pkt_dev->dst_max); 2112 pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
2112 } 2113 }
2113 /* Initialize current values. */ 2114 /* Initialize current values. */
2115 pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
2116 if (pkt_dev->min_pkt_size > pkt_dev->max_pkt_size)
2117 pkt_dev->max_pkt_size = pkt_dev->min_pkt_size;
2118
2114 pkt_dev->cur_dst_mac_offset = 0; 2119 pkt_dev->cur_dst_mac_offset = 0;
2115 pkt_dev->cur_src_mac_offset = 0; 2120 pkt_dev->cur_src_mac_offset = 0;
2116 pkt_dev->cur_saddr = pkt_dev->saddr_min; 2121 pkt_dev->cur_saddr = pkt_dev->saddr_min;
@@ -2758,97 +2763,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2758 return skb; 2763 return skb;
2759} 2764}
2760 2765
2761/*
2762 * scan_ip6, fmt_ip taken from dietlibc-0.21
2763 * Author Felix von Leitner <felix-dietlibc@fefe.de>
2764 *
2765 * Slightly modified for kernel.
2766 * Should be candidate for net/ipv4/utils.c
2767 * --ro
2768 */
2769
2770static unsigned int scan_ip6(const char *s, char ip[16])
2771{
2772 unsigned int i;
2773 unsigned int len = 0;
2774 unsigned long u;
2775 char suffix[16];
2776 unsigned int prefixlen = 0;
2777 unsigned int suffixlen = 0;
2778 __be32 tmp;
2779 char *pos;
2780
2781 for (i = 0; i < 16; i++)
2782 ip[i] = 0;
2783
2784 for (;;) {
2785 if (*s == ':') {
2786 len++;
2787 if (s[1] == ':') { /* Found "::", skip to part 2 */
2788 s += 2;
2789 len++;
2790 break;
2791 }
2792 s++;
2793 }
2794
2795 u = simple_strtoul(s, &pos, 16);
2796 i = pos - s;
2797 if (!i)
2798 return 0;
2799 if (prefixlen == 12 && s[i] == '.') {
2800
2801 /* the last 4 bytes may be written as IPv4 address */
2802
2803 tmp = in_aton(s);
2804 memcpy((struct in_addr *)(ip + 12), &tmp, sizeof(tmp));
2805 return i + len;
2806 }
2807 ip[prefixlen++] = (u >> 8);
2808 ip[prefixlen++] = (u & 255);
2809 s += i;
2810 len += i;
2811 if (prefixlen == 16)
2812 return len;
2813 }
2814
2815/* part 2, after "::" */
2816 for (;;) {
2817 if (*s == ':') {
2818 if (suffixlen == 0)
2819 break;
2820 s++;
2821 len++;
2822 } else if (suffixlen != 0)
2823 break;
2824
2825 u = simple_strtol(s, &pos, 16);
2826 i = pos - s;
2827 if (!i) {
2828 if (*s)
2829 len--;
2830 break;
2831 }
2832 if (suffixlen + prefixlen <= 12 && s[i] == '.') {
2833 tmp = in_aton(s);
2834 memcpy((struct in_addr *)(suffix + suffixlen), &tmp,
2835 sizeof(tmp));
2836 suffixlen += 4;
2837 len += strlen(s);
2838 break;
2839 }
2840 suffix[suffixlen++] = (u >> 8);
2841 suffix[suffixlen++] = (u & 255);
2842 s += i;
2843 len += i;
2844 if (prefixlen + suffixlen == 16)
2845 break;
2846 }
2847 for (i = 0; i < suffixlen; i++)
2848 ip[16 - suffixlen + i] = suffix[i];
2849 return len;
2850}
2851
2852static struct sk_buff *fill_packet_ipv6(struct net_device *odev, 2766static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2853 struct pktgen_dev *pkt_dev) 2767 struct pktgen_dev *pkt_dev)
2854{ 2768{
@@ -2927,7 +2841,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2927 sizeof(struct ipv6hdr) - sizeof(struct udphdr) - 2841 sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
2928 pkt_dev->pkt_overhead; 2842 pkt_dev->pkt_overhead;
2929 2843
2930 if (datalen < sizeof(struct pktgen_hdr)) { 2844 if (datalen < 0 || datalen < sizeof(struct pktgen_hdr)) {
2931 datalen = sizeof(struct pktgen_hdr); 2845 datalen = sizeof(struct pktgen_hdr);
2932 net_info_ratelimited("increased datalen to %d\n", datalen); 2846 net_info_ratelimited("increased datalen to %d\n", datalen);
2933 } 2847 }
@@ -3548,8 +3462,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3548 } 3462 }
3549 3463
3550 pkt_dev->removal_mark = 0; 3464 pkt_dev->removal_mark = 0;
3551 pkt_dev->min_pkt_size = ETH_ZLEN;
3552 pkt_dev->max_pkt_size = ETH_ZLEN;
3553 pkt_dev->nfrags = 0; 3465 pkt_dev->nfrags = 0;
3554 pkt_dev->delay = pg_delay_d; 3466 pkt_dev->delay = pg_delay_d;
3555 pkt_dev->count = pg_count_d; 3467 pkt_dev->count = pg_count_d;
diff --git a/net/core/utils.c b/net/core/utils.c
index f5613d569c23..e3487e461939 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -107,6 +107,18 @@ static inline int xdigit2bin(char c, int delim)
107 return IN6PTON_UNKNOWN; 107 return IN6PTON_UNKNOWN;
108} 108}
109 109
110/**
111 * in4_pton - convert an IPv4 address from literal to binary representation
112 * @src: the start of the IPv4 address string
113 * @srclen: the length of the string, -1 means strlen(src)
114 * @dst: the binary (u8[4] array) representation of the IPv4 address
115 * @delim: the delimiter of the IPv4 address in @src, -1 means no delimiter
116 * @end: A pointer to the end of the parsed string will be placed here
117 *
118 * Return one on success, return zero when any error occurs
119 * and @end will point to the end of the parsed string.
120 *
121 */
110int in4_pton(const char *src, int srclen, 122int in4_pton(const char *src, int srclen,
111 u8 *dst, 123 u8 *dst,
112 int delim, const char **end) 124 int delim, const char **end)
@@ -161,6 +173,18 @@ out:
161} 173}
162EXPORT_SYMBOL(in4_pton); 174EXPORT_SYMBOL(in4_pton);
163 175
176/**
177 * in6_pton - convert an IPv6 address from literal to binary representation
178 * @src: the start of the IPv6 address string
179 * @srclen: the length of the string, -1 means strlen(src)
180 * @dst: the binary (u8[16] array) representation of the IPv6 address
181 * @delim: the delimiter of the IPv6 address in @src, -1 means no delimiter
182 * @end: A pointer to the end of the parsed string will be placed here
183 *
184 * Return one on success, return zero when any error occurs
185 * and @end will point to the end of the parsed string.
186 *
187 */
164int in6_pton(const char *src, int srclen, 188int in6_pton(const char *src, int srclen,
165 u8 *dst, 189 u8 *dst,
166 int delim, const char **end) 190 int delim, const char **end)