[DTrace-devel] [PATCH] Do not use :: in IPv6 addresses without zero-collapsing

Kris Van Hees kris.van.hees at oracle.com
Mon Sep 4 19:52:25 UTC 2023


Addresses that do not contain a sequence of two or more zero-words should
not contain the zero-collapse marker (::).  Rather than adding a special
case in the output generation code for this, this patch adds a branch to
a code block that simply outputs 8 words, separated by ':'.

The testcase has been expanded to contain at least one of each possible
case: leading collapsible zero-words, collapsible zero-words in the middle,
trailing collapsible zero-words, addresses without zero-words.

Reported-by: Eugene Loh <eugene.loh at oracle.com>
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 bpf/inet_ntoa6.S                              | 28 +++++++-
 .../funcs/inet_ntoa6/tst.inet_ntoa6.d         | 68 +++++++++++++++++++
 .../funcs/inet_ntoa6/tst.inet_ntoa6.r         |  4 ++
 3 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/bpf/inet_ntoa6.S b/bpf/inet_ntoa6.S
index a4f56da8..3995b92a 100644
--- a/bpf/inet_ntoa6.S
+++ b/bpf/inet_ntoa6.S
@@ -235,11 +235,13 @@ dt_inet_ntoa6:
 	/*
 	 * Determine the number of words to output at the start of the address.
 	 * It is found in the upper 4 bits in %r7 (result of the table lookup
-	 * above).  We place an upper bound to make the BPF verifier happy.
+	 * above).  If the number of leading non-zero words is 7, the address
+	 * does not allow for zero-word collapsing and we jump to code that
+	 * simply outputs all 8 words.
 	 */
 	mov	%r6, %r7
 	rsh	%r6, 4
-	jgt	%r6, 7, .Ldone
+	jge	%r6, 7, .Lfull
 
 	/*
 	 * Loop to output the first %r6 words of the address.  Each value is
@@ -342,4 +344,26 @@ dt_inet_ntoa6:
 	call	dt_inet_ntoa
 	mov	%r0, 0
 	exit
+
+.Lfull:
+	/* Output an IPv6 address without zero-cord collapsing. */
+	mov	%r6, 7
+.Lfull_loop:
+	jle	%r6, 0, .Lfull_end
+	ldxh	%r1, [%r8 + 0]
+	mov	%r2, %r9
+	call	write_hex16
+	add	%r9, %r0
+	stb	[%r9 + 0], ':'
+	add	%r9, 1
+	add	%r8, 2
+	sub	%r6, 1
+	ja	.Lfull_loop
+
+.Lfull_end:
+	ldxh	%r1, [%r8 + 0]
+	mov	%r2, %r9
+	call	write_hex16
+	add	%r9, %r0
+	ja	.Ldone
 	.size	dt_inet_ntoa6, .-dt_inet_ntoa6
diff --git a/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.d b/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.d
index 1f316afb..feae1d64 100644
--- a/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.d
+++ b/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.d
@@ -14,6 +14,10 @@ struct in6_addr *ip6d;
 struct in6_addr *ip6e;
 struct in6_addr *ip6f;
 struct in6_addr *ip6g;
+struct in6_addr *ip6h;
+struct in6_addr *ip6i;
+struct in6_addr *ip6j;
+struct in6_addr *ip6k;
 
 BEGIN
 {
@@ -24,6 +28,10 @@ BEGIN
 	this->buf6e = alloca(sizeof(struct in6_addr));
 	this->buf6f = alloca(sizeof(struct in6_addr));
 	this->buf6g = alloca(sizeof(struct in6_addr));
+	this->buf6h = alloca(sizeof(struct in6_addr));
+	this->buf6i = alloca(sizeof(struct in6_addr));
+	this->buf6j = alloca(sizeof(struct in6_addr));
+	this->buf6k = alloca(sizeof(struct in6_addr));
 	ip6a = this->buf6a;
 	ip6b = this->buf6b;
 	ip6c = this->buf6c;
@@ -31,6 +39,10 @@ BEGIN
 	ip6e = this->buf6e;
 	ip6f = this->buf6f;
 	ip6g = this->buf6g;
+	ip6h = this->buf6h;
+	ip6i = this->buf6i;
+	ip6j = this->buf6j;
+	ip6k = this->buf6k;
 
 	ip6a->in6_u.u6_addr8[0] = 0xfe;
 	ip6a->in6_u.u6_addr8[1] = 0x80;
@@ -61,6 +73,58 @@ BEGIN
 	ip6g->in6_u.u6_addr8[11] = 0xfe;
 	ip6g->in6_u.u6_addr8[12] = 0x7f;
 	ip6g->in6_u.u6_addr8[15] = 0x01;
+	ip6h->in6_u.u6_addr8[0] = 0xfe;
+	ip6h->in6_u.u6_addr8[1] = 0x12;
+	ip6h->in6_u.u6_addr8[2] = 0x34;
+	ip6h->in6_u.u6_addr8[3] = 0x56;
+	ip6h->in6_u.u6_addr8[4] = 0x78;
+	ip6h->in6_u.u6_addr8[5] = 0x9a;
+	ip6h->in6_u.u6_addr8[6] = 0xbc;
+	ip6h->in6_u.u6_addr8[7] = 0xde;
+	ip6h->in6_u.u6_addr8[8] = 0x02;
+	ip6h->in6_u.u6_addr8[9] = 0x14;
+	ip6i->in6_u.u6_addr8[0] = 0xfe;
+	ip6i->in6_u.u6_addr8[1] = 0x12;
+	ip6i->in6_u.u6_addr8[2] = 0x34;
+	ip6i->in6_u.u6_addr8[3] = 0x56;
+	ip6i->in6_u.u6_addr8[4] = 0x78;
+	ip6i->in6_u.u6_addr8[5] = 0x9a;
+	ip6i->in6_u.u6_addr8[6] = 0xbc;
+	ip6i->in6_u.u6_addr8[7] = 0xde;
+	ip6i->in6_u.u6_addr8[8] = 0x02;
+	ip6i->in6_u.u6_addr8[9] = 0x14;
+	ip6i->in6_u.u6_addr8[10] = 0x4f;
+	ip6i->in6_u.u6_addr8[11] = 0xff;
+	ip6j->in6_u.u6_addr8[0] = 0xfe;
+	ip6j->in6_u.u6_addr8[1] = 0x12;
+	ip6j->in6_u.u6_addr8[2] = 0x34;
+	ip6j->in6_u.u6_addr8[3] = 0x56;
+	ip6j->in6_u.u6_addr8[4] = 0x78;
+	ip6j->in6_u.u6_addr8[5] = 0x9a;
+	ip6j->in6_u.u6_addr8[6] = 0xbc;
+	ip6j->in6_u.u6_addr8[7] = 0xde;
+	ip6j->in6_u.u6_addr8[8] = 0x02;
+	ip6j->in6_u.u6_addr8[9] = 0x14;
+	ip6j->in6_u.u6_addr8[10] = 0x4f;
+	ip6j->in6_u.u6_addr8[11] = 0xff;
+	ip6j->in6_u.u6_addr8[12] = 0xfe;
+	ip6j->in6_u.u6_addr8[13] = 0x0b;
+	ip6k->in6_u.u6_addr8[0] = 0xfe;
+	ip6k->in6_u.u6_addr8[1] = 0x12;
+	ip6k->in6_u.u6_addr8[2] = 0x34;
+	ip6k->in6_u.u6_addr8[3] = 0x56;
+	ip6k->in6_u.u6_addr8[4] = 0x78;
+	ip6k->in6_u.u6_addr8[5] = 0x9a;
+	ip6k->in6_u.u6_addr8[6] = 0xbc;
+	ip6k->in6_u.u6_addr8[7] = 0xde;
+	ip6k->in6_u.u6_addr8[8] = 0x02;
+	ip6k->in6_u.u6_addr8[9] = 0x14;
+	ip6k->in6_u.u6_addr8[10] = 0x4f;
+	ip6k->in6_u.u6_addr8[11] = 0xff;
+	ip6k->in6_u.u6_addr8[12] = 0xfe;
+	ip6k->in6_u.u6_addr8[13] = 0x0b;
+	ip6k->in6_u.u6_addr8[14] = 0x76;
+	ip6k->in6_u.u6_addr8[15] = 0xc8;
 
 	printf("%s\n", inet_ntoa6(ip6a));
 	printf("%s\n", inet_ntoa6(ip6b));
@@ -69,6 +133,10 @@ BEGIN
 	printf("%s\n", inet_ntoa6(ip6e));
 	printf("%s\n", inet_ntoa6(ip6f));
 	printf("%s\n", inet_ntoa6(ip6g));
+	printf("%s\n", inet_ntoa6(ip6h));
+	printf("%s\n", inet_ntoa6(ip6i));
+	printf("%s\n", inet_ntoa6(ip6j));
+	printf("%s\n", inet_ntoa6(ip6k));
 
 	exit(0);
 }
diff --git a/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.r b/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.r
index d87c1f61..81479e09 100644
--- a/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.r
+++ b/test/unittest/funcs/inet_ntoa6/tst.inet_ntoa6.r
@@ -5,4 +5,8 @@ fe80::214:4fff:fe0b:76c8
 127.0.0.1
 127.0.0.1
 ::fffe:7f00:1
+fe12:3456:789a:bcde:214::
+fe12:3456:789a:bcde:214:4fff::
+fe12:3456:789a:bcde:214:4fff:fe0b:0
+fe12:3456:789a:bcde:214:4fff:fe0b:76c8
 
-- 
2.40.1




More information about the DTrace-devel mailing list