netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [v3] pktgen: Allow configuration of IPv6 source address range
@ 2020-01-14  1:01 Niu Xilei
  2020-01-14  1:59 ` Jakub Kicinski
  0 siblings, 1 reply; 2+ messages in thread
From: Niu Xilei @ 2020-01-14  1:01 UTC (permalink / raw)
  To: davem
  Cc: tglx, fw, peterz, steffen.klassert, bigeasy, jonathan.lemon,
	pabeni, anshuman.khandual, netdev, linux-kernel, Niu Xilei

Pktgen can use only one IPv6 source address from output device or src6
command setting. In pressure test we need create lots of sessions more than
65535. So add src6_min and src6_max command to set the range.

Signed-off-by: Niu Xilei <niu_xilei@163.com>

Changes since v2:
 - reword subject line
Changes since v1:
 - only create IPv6 source address over least significant 64 bit range
---
 net/core/pktgen.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 294bfcf0ce0e..33435ae0ba68 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -1355,6 +1355,49 @@ static ssize_t pktgen_if_write(struct file *file,
 		sprintf(pg_result, "OK: dst6_max=%s", buf);
 		return count;
 	}
+	if (!strcmp(name, "src6_min")) {
+		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
+		if (len < 0)
+			return len;
+
+		pkt_dev->flags |= F_IPV6;
+
+		if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+		buf[len] = 0;
+
+		in6_pton(buf, -1, pkt_dev->min_in6_saddr.s6_addr, -1, NULL);
+		snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_saddr);
+
+		pkt_dev->cur_in6_saddr = pkt_dev->min_in6_saddr;
+		if (debug)
+			pr_debug("src6_min set to: %s\n", buf);
+
+		i += len;
+		sprintf(pg_result, "OK: src6_min=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "src6_max")) {
+		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
+		if (len < 0)
+			return len;
+
+		pkt_dev->flags |= F_IPV6;
+
+		if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+		buf[len] = 0;
+
+		in6_pton(buf, -1, pkt_dev->max_in6_saddr.s6_addr, -1, NULL);
+		snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_saddr);
+
+		if (debug)
+			pr_debug("dst6_max set to: %s\n", buf);
+
+		i += len;
+		sprintf(pg_result, "OK: dst6_max=%s", buf);
+		return count;
+	}
 	if (!strcmp(name, "src6")) {
 		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
 		if (len < 0)
@@ -2286,6 +2329,51 @@ static void set_cur_queue_map(struct pktgen_dev *pkt_dev)
 	pkt_dev->cur_queue_map  = pkt_dev->cur_queue_map % pkt_dev->odev->real_num_tx_queues;
 }
 
+/* generate ipv6 source addr */
+static inline void set_src_in6_addr(struct pktgen_dev *pkt_dev)
+{
+	__be64 min6_h, min6_l, max6_h, max6_l, addr_l, *t;
+	u64 min6, max6, rand, i;
+	struct in6_addr addr6;
+
+	memcpy(&min6_h, pkt_dev->min_in6_saddr.s6_addr, 8);
+	memcpy(&min6_l, pkt_dev->min_in6_saddr.s6_addr + 8, 8);
+	memcpy(&max6_h, pkt_dev->max_in6_saddr.s6_addr, 8);
+	memcpy(&max6_l, pkt_dev->max_in6_saddr.s6_addr + 8, 8);
+
+	/* only generate source address in least significant 64 bits range
+	 * most significant 64 bits must be equal
+	 */
+	if (max6_h != min6_h)
+		return;
+
+	addr6 = pkt_dev->min_in6_saddr;
+	t = (__be64 *)addr6.s6_addr + 1;
+	min6 = be64_to_cpu(min6_l);
+	max6 = be64_to_cpu(max6_l);
+
+	if (min6 < max6) {
+		if (pkt_dev->flags & F_IPSRC_RND) {
+			do {
+				prandom_bytes(&rand, sizeof(rand));
+				rand = rand % (max6 - min6) + min6;
+				addr_l = cpu_to_be64(rand);
+				memcpy(t, &addr_l, 8);
+			} while (ipv6_addr_loopback(&addr6) ||
+				 ipv6_addr_v4mapped(&addr6) ||
+				 ipv6_addr_is_multicast(&addr6));
+		} else {
+			addr6 = pkt_dev->cur_in6_saddr;
+			i = be64_to_cpu(*t);
+			if (++i > max6)
+				i = min6;
+			addr_l = cpu_to_be64(i);
+			memcpy(t, &addr_l, 8);
+		}
+	}
+	pkt_dev->cur_in6_saddr = addr6;
+}
+
 /* Increment/randomize headers according to flags and current values
  * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
  */
@@ -2454,6 +2542,8 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
 		}
 	} else {		/* IPV6 * */
 
+		set_src_in6_addr(pkt_dev);
+
 		if (!ipv6_addr_any(&pkt_dev->min_in6_daddr)) {
 			int i;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [v3] pktgen: Allow configuration of IPv6 source address range
  2020-01-14  1:01 [v3] pktgen: Allow configuration of IPv6 source address range Niu Xilei
@ 2020-01-14  1:59 ` Jakub Kicinski
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Kicinski @ 2020-01-14  1:59 UTC (permalink / raw)
  To: Niu Xilei
  Cc: davem, tglx, fw, peterz, steffen.klassert, bigeasy,
	jonathan.lemon, pabeni, anshuman.khandual, netdev, linux-kernel

On Tue, 14 Jan 2020 09:01:22 +0800, Niu Xilei wrote:
> Pktgen can use only one IPv6 source address from output device or src6
> command setting. In pressure test we need create lots of sessions more than
> 65535. So add src6_min and src6_max command to set the range.
> 
> Signed-off-by: Niu Xilei <niu_xilei@163.com>
> 
> Changes since v2:
>  - reword subject line

Seems you have missed the inline feedback on v2. There were two other
issues I raised within the quoted patch. Please take a look again.

> Changes since v1:
>  - only create IPv6 source address over least significant 64 bit range

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-01-14  1:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-14  1:01 [v3] pktgen: Allow configuration of IPv6 source address range Niu Xilei
2020-01-14  1:59 ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).