lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240308171656.9034-2-stephen@networkplumber.org>
Date: Fri,  8 Mar 2024 09:16:00 -0800
From: Stephen Hemminger <stephen@...workplumber.org>
To: netdev@...r.kernel.org
Cc: Stephen Hemminger <stephen@...workplumber.org>,
	Marc Blanchet <marc.blanchet@...genie.ca>
Subject: [PATCH iproute2-next 2/3] netem: use 64 bit value for latency and jitter

The current version of netem in iproute2 has a maximum of 4.3
seconds because of scaled 32 bit clock values. Some users would
like to be able to use larger delays to emulate things
like storage delays.

Since kernel version 4.15, netem qdisc had netlink parameters
to express wider range of delays in nanoseconds. But the iproute2
side was never updated to use them.

This does break compatibility with older kernels (4.14 and earlier).
With these out of support kernels, the latency/delay parameter
will end up being ignored.

Reported-by: Marc Blanchet <marc.blanchet@...genie.ca>
Signed-off-by: Stephen Hemminger <stephen@...workplumber.org>
---
 tc/q_netem.c | 83 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 46 insertions(+), 37 deletions(-)

diff --git a/tc/q_netem.c b/tc/q_netem.c
index 4ce9ab6e529b..86cabbfe7b3a 100644
--- a/tc/q_netem.c
+++ b/tc/q_netem.c
@@ -170,26 +170,6 @@ static int get_distribution(const char *type, __s16 *data, int maxdata)
 #define NEXT_IS_SIGNED_NUMBER() \
 	(NEXT_ARG_OK() && (isdigit(argv[1][0]) || argv[1][0] == '-'))
 
-/*
- * Adjust for the fact that psched_ticks aren't always usecs
- *  (based on kernel PSCHED_CLOCK configuration
- */
-static int get_ticks(__u32 *ticks, const char *str)
-{
-	unsigned int t;
-
-	if (get_time(&t, str))
-		return -1;
-
-	if (tc_core_time2big(t)) {
-		fprintf(stderr, "Illegal %u time (too large)\n", t);
-		return -1;
-	}
-
-	*ticks = tc_core_time2tick(t);
-	return 0;
-}
-
 static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
 			   struct nlmsghdr *n, const char *dev)
 {
@@ -208,6 +188,8 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
 	__s16 *slot_dist_data = NULL;
 	__u16 loss_type = NETEM_LOSS_UNSPEC;
 	int present[__TCA_NETEM_MAX] = {};
+	__s64 latency64 = 0;
+	__s64 jitter64 = 0;
 	__u64 rate64 = 0;
 	__u64 seed = 0;
 
@@ -221,14 +203,20 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
 		} else if (matches(*argv, "latency") == 0 ||
 			   matches(*argv, "delay") == 0) {
 			NEXT_ARG();
-			if (get_ticks(&opt.latency, *argv)) {
+
+			/* Old latency value in opt is no longer used. */
+			present[TCA_NETEM_LATENCY64] = 1;
+
+			if (get_time64(&latency64, *argv)) {
 				explain1("latency");
 				return -1;
 			}
 
 			if (NEXT_IS_NUMBER()) {
 				NEXT_ARG();
-				if (get_ticks(&opt.jitter, *argv)) {
+
+				present[TCA_NETEM_JITTER64] = 1;
+				if (get_time64(&jitter64, *argv)) {
 					explain1("latency");
 					return -1;
 				}
@@ -552,7 +540,7 @@ random_loss_model:
 	tail = NLMSG_TAIL(n);
 
 	if (reorder.probability) {
-		if (opt.latency == 0) {
+		if (latency64 == 0) {
 			fprintf(stderr, "reordering not possible without specifying some delay\n");
 			explain();
 			return -1;
@@ -573,7 +561,7 @@ random_loss_model:
 		}
 	}
 
-	if (dist_data && (opt.latency == 0 || opt.jitter == 0)) {
+	if (dist_data && (latency64 == 0 || jitter64 == 0)) {
 		fprintf(stderr, "distribution specified but no latency and jitter values\n");
 		explain();
 		return -1;
@@ -582,6 +570,14 @@ random_loss_model:
 	if (addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)) < 0)
 		return -1;
 
+	if (present[TCA_NETEM_LATENCY64] &&
+	    addattr_l(n, 1024, TCA_NETEM_LATENCY64, &latency64, sizeof(latency64)) < 0)
+		return -1;
+
+	if (present[TCA_NETEM_JITTER64] &&
+	    addattr_l(n, 1024, TCA_NETEM_JITTER64, &jitter64, sizeof(jitter64)) < 0)
+		return -1;
+
 	if (present[TCA_NETEM_CORR] &&
 	    addattr_l(n, 1024, TCA_NETEM_CORR, &cor, sizeof(cor)) < 0)
 		return -1;
@@ -676,6 +672,8 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 	__u64 seed = 0;
 	int len;
 	__u64 rate64 = 0;
+	__u64 latency64 = 0;
+	__u64 jitter64 = 0;
 
 	SPRINT_BUF(b1);
 
@@ -734,6 +732,18 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 				return -1;
 			rate64 = rta_getattr_u64(tb[TCA_NETEM_RATE64]);
 		}
+		if (tb[TCA_NETEM_LATENCY64]) {
+			if (RTA_PAYLOAD(tb[TCA_NETEM_LATENCY64]) < sizeof(latency64))
+				return -1;
+			latency64 = rta_getattr_u64(tb[TCA_NETEM_LATENCY64]);
+
+		}
+		if (tb[TCA_NETEM_JITTER64]) {
+			if (RTA_PAYLOAD(tb[TCA_NETEM_JITTER64]) < sizeof(jitter64))
+				return -1;
+			jitter64 = rta_getattr_u64(tb[TCA_NETEM_JITTER64]);
+
+		}
 		if (tb[TCA_NETEM_SLOT]) {
 			if (RTA_PAYLOAD(tb[TCA_NETEM_SLOT]) < sizeof(*slot))
 				return -1;
@@ -749,24 +759,23 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
 
 	print_uint(PRINT_ANY, "limit", "limit %d", qopt.limit);
 
-	if (qopt.latency) {
+
+	if (latency64 != 0) {
 		open_json_object("delay");
-		if (!is_json_context()) {
-			print_string(PRINT_FP, NULL, " delay %s",
-				     sprint_ticks(qopt.latency, b1));
 
-			if (qopt.jitter)
-				print_string(PRINT_FP, NULL, "  %s",
-					     sprint_ticks(qopt.jitter, b1));
-		} else {
+		if (is_json_context()) {
 			print_float(PRINT_JSON, "delay", NULL,
-				    tc_core_tick2time(qopt.latency) /
-				    1000000.);
+				    (double)latency64 / 1000000000.);
 			print_float(PRINT_JSON, "jitter", NULL,
-				    tc_core_tick2time(qopt.jitter) /
-				    1000000.);
+				    (double)jitter64 / 1000000000.);
+		} else {
+			print_string(PRINT_FP, NULL, " delay %s",
+				     sprint_time64(latency64, b1));
+			if (jitter64 != 0)
+				print_string(PRINT_FP, NULL, "  %s",
+					     sprint_time64(jitter64, b1));
 		}
-		print_corr(qopt.jitter && cor && cor->delay_corr,
+		print_corr(jitter64 && cor && cor->delay_corr,
 			   cor ? cor->delay_corr : 0);
 		close_json_object();
 	}
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ