diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/pktgen.c | 146 | ||||
| -rw-r--r-- | net/core/utils.c | 24 |
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); | |||
| 449 | static void pktgen_stop(struct pktgen_thread *t); | 449 | static void pktgen_stop(struct pktgen_thread *t); |
| 450 | static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); | 450 | static void pktgen_clear_counters(struct pktgen_dev *pkt_dev); |
| 451 | 451 | ||
| 452 | static unsigned int scan_ip6(const char *s, char ip[16]); | ||
| 453 | |||
| 454 | /* Module parameters, defaults. */ | 452 | /* Module parameters, defaults. */ |
| 455 | static int pg_count_d __read_mostly = 1000; | 453 | static int pg_count_d __read_mostly = 1000; |
| 456 | static int pg_delay_d __read_mostly; | 454 | static 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 | |||
| 2770 | static 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 | |||
| 2852 | static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | 2766 | static 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 | */ | ||
| 110 | int in4_pton(const char *src, int srclen, | 122 | int 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 | } |
| 162 | EXPORT_SYMBOL(in4_pton); | 174 | EXPORT_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 | */ | ||
| 164 | int in6_pton(const char *src, int srclen, | 188 | int 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) |
