Commit ebf8786964 for bind

commit ebf8786964404b38738804560c46d97929550bfd
Author: Alessio Podda <alessio@isc.org>
Date:   Fri Apr 10 19:09:58 2026 +0200

    Add _Generic dns_name wrappers for linkedname

    This commit adds wrappers that use _Generic to automatically cast
    dns_linkedname_t to dns_name_t in order to improve readability.

diff --git a/bin/dig/dig.c b/bin/dig/dig.c
index 440fe8a86b..e8d83c5288 100644
--- a/bin/dig/dig.c
+++ b/bin/dig/dig.c
@@ -625,7 +625,7 @@ isdotlocal(dns_message_t *msg) {
 	static dns_name_t local = DNS_NAME_INITABSOLUTE(local_ndata);

 	MSG_SECTION_FOREACH(msg, DNS_SECTION_QUESTION, name) {
-		if (dns_name_issubdomain(dns_linkedname_name(name), &local)) {
+		if (dns_name_issubdomain(name, &local)) {
 			return true;
 		}
 	}
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 89ff9ba235..a26a2b58c0 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -1817,9 +1817,8 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) {
 			int order;

 			domain = dns_fixedname_name(&query->lookup->fdomain);
-			namereln =
-				dns_name_fullcompare(dns_linkedname_name(name),
-						     domain, &order, &nlabels);
+			namereln = dns_name_fullcompare(name, domain, &order,
+							&nlabels);
 			if (namereln == dns_namereln_equal) {
 				if (!horizontal) {
 					dighost_warning("BAD (HORIZONTAL) "
@@ -1875,8 +1874,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) {
 					lookup->recurse = false;
 				}
 				domain = dns_fixedname_name(&lookup->fdomain);
-				dns_name_copy(dns_linkedname_name(name),
-					      domain);
+				dns_name_copy(name, domain);
 				lookup->edns = lookup->original_edns;
 			}
 			debug("adding server %s", namestr);
@@ -2044,8 +2042,7 @@ insert_soa(dig_lookup_t *lookup) {
 	dns_rdatalist_tordataset(rdatalist, rdataset);

 	dns_message_gettempname(lookup->sendmsg, &soaname);
-	dns_name_clone(dns_linkedname_name(lookup->name),
-		       dns_linkedname_name(soaname));
+	dns_name_clone(lookup->name, dns_linkedname_name(soaname));
 	ISC_LIST_INIT(soaname->list);
 	ISC_LIST_APPEND(soaname->list, rdataset, link);
 	dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY);
@@ -2265,10 +2262,9 @@ setup_lookup(dig_lookup_t *lookup) {
 			}
 		}
 	}
-	dns_name_format(dns_linkedname_name(lookup->name), store,
-			sizeof(store));
+	dns_name_format(lookup->name, store, sizeof(store));
 	dighost_trying(store, lookup);
-	INSIST(dns_name_isabsolute(dns_linkedname_name(lookup->name)));
+	INSIST(dns_name_isabsolute(lookup->name));

 	lookup->sendmsg->id = (dns_messageid_t)isc_random16();
 	lookup->sendmsg->opcode = lookup->opcode;
@@ -4201,16 +4197,13 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
 			ISC_LIST_FOREACH(name->list, rdataset, link) {
 				if (l->rdtype != rdataset->type ||
 				    l->rdclass != rdataset->rdclass ||
-				    !dns_name_equal(
-					    dns_linkedname_name(l->name),
-					    dns_linkedname_name(name)))
+				    !dns_name_equal(l->name, name))
 				{
 					char namestr[DNS_NAME_FORMATSIZE];
 					char typebuf[DNS_RDATATYPE_FORMATSIZE];
 					char classbuf[DNS_RDATACLASS_FORMATSIZE];
-					dns_name_format(
-						dns_linkedname_name(name),
-						namestr, sizeof(namestr));
+					dns_name_format(name, namestr,
+							sizeof(namestr));
 					dns_rdatatype_format(rdataset->type,
 							     typebuf,
 							     sizeof(typebuf));
diff --git a/bin/dig/host.c b/bin/dig/host.c
index 2e95938a87..5a414ae1f2 100644
--- a/bin/dig/host.c
+++ b/bin/dig/host.c
@@ -375,8 +375,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,

 	if (msg->rcode != 0) {
 		char namestr[DNS_NAME_FORMATSIZE];
-		dns_name_format(dns_linkedname_name(query->lookup->name),
-				namestr, sizeof(namestr));
+		dns_name_format(query->lookup->name, namestr, sizeof(namestr));

 		if (query->lookup->identify_previous_line) {
 			printf("Nameserver %s:\n\t%s not found: %d(%s)\n",
@@ -403,7 +402,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,

 		/* Add AAAA and MX lookups. */
 		name = dns_fixedname_initname(&fixed);
-		dns_name_copy(dns_linkedname_name(query->lookup->name), name);
+		dns_name_copy(query->lookup->name, name);
 		chase_cnamechain(msg, name);
 		dns_name_format(name, namestr, sizeof(namestr));
 		lookup = clone_lookup(query->lookup, false);
@@ -532,8 +531,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
 	{
 		char namestr[DNS_NAME_FORMATSIZE];
 		char typestr[DNS_RDATATYPE_FORMATSIZE];
-		dns_name_format(dns_linkedname_name(query->lookup->name),
-				namestr, sizeof(namestr));
+		dns_name_format(query->lookup->name, namestr, sizeof(namestr));
 		dns_rdatatype_format(query->lookup->rdtype, typestr,
 				     sizeof(typestr));
 		printf("%s has no %s record\n", namestr, typestr);
diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c
index 992a99cdd5..3281ec6f63 100644
--- a/bin/dig/nslookup.c
+++ b/bin/dig/nslookup.c
@@ -215,24 +215,21 @@ printsection(dig_query_t *query, dns_message_t *msg, bool headers,
 					if (section != DNS_SECTION_ANSWER) {
 						goto def_short_section;
 					}
-					dns_name_format(
-						dns_linkedname_name(name),
-						namebuf, sizeof(namebuf));
+					dns_name_format(name, namebuf,
+							sizeof(namebuf));
 					printf("Name:\t%s\n", namebuf);
 					printaddr(&rdata);
 					break;
 				case dns_rdatatype_soa:
-					dns_name_format(
-						dns_linkedname_name(name),
-						namebuf, sizeof(namebuf));
+					dns_name_format(name, namebuf,
+							sizeof(namebuf));
 					printf("%s\n", namebuf);
 					printsoa(&rdata);
 					break;
 				default:
 				def_short_section:
-					dns_name_format(
-						dns_linkedname_name(name),
-						namebuf, sizeof(namebuf));
+					dns_name_format(name, namebuf,
+							sizeof(namebuf));
 					printf("%s\t", namebuf);
 					printrdata(&rdata);
 					break;
@@ -274,8 +271,7 @@ detailsection(dig_query_t *query, dns_message_t *msg, bool headers,
 	MSG_SECTION_FOREACH(msg, section, name) {
 		ISC_LIST_FOREACH(name->list, rdataset, link) {
 			if (section == DNS_SECTION_QUESTION) {
-				dns_name_format(dns_linkedname_name(name),
-						namebuf, sizeof(namebuf));
+				dns_name_format(name, namebuf, sizeof(namebuf));
 				printf("\t%s, ", namebuf);
 				dns_rdatatype_format(rdataset->type, namebuf,
 						     sizeof(namebuf));
@@ -288,8 +284,7 @@ detailsection(dig_query_t *query, dns_message_t *msg, bool headers,
 				dns_rdata_t rdata = DNS_RDATA_INIT;
 				dns_rdataset_current(rdataset, &rdata);

-				dns_name_format(dns_linkedname_name(name),
-						namebuf, sizeof(namebuf));
+				dns_name_format(name, namebuf, sizeof(namebuf));
 				printf("    ->  %s\n", namebuf);

 				switch (rdata.type) {
@@ -378,8 +373,8 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,

 	if (msg->rcode != 0) {
 		char nametext[DNS_NAME_FORMATSIZE];
-		dns_name_format(dns_linkedname_name(query->lookup->name),
-				nametext, sizeof(nametext));
+		dns_name_format(query->lookup->name, nametext,
+				sizeof(nametext));
 		printf("** server can't find %s: %s\n", nametext,
 		       rcode_totext(msg->rcode));
 		debug("returning with rcode == 0");
@@ -397,7 +392,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,

 		/* Add AAAA lookup. */
 		name = dns_fixedname_initname(&fixed);
-		dns_name_copy(dns_linkedname_name(query->lookup->name), name);
+		dns_name_copy(query->lookup->name, name);
 		chase_cnamechain(msg, name);
 		dns_name_format(name, namestr, sizeof(namestr));
 		lookup = clone_lookup(query->lookup, false);
diff --git a/bin/dnssec/dnssec-cds.c b/bin/dnssec/dnssec-cds.c
index 8f0cddb5fb..d994dd42eb 100644
--- a/bin/dnssec/dnssec-cds.c
+++ b/bin/dnssec/dnssec-cds.c
@@ -622,8 +622,7 @@ matching_sigs(keyinfo_t *keytbl, dns_rdataset_t *rdataset,
 		for (i = 0; i < nkey; i++) {
 			keyinfo_t *ki = &keytbl[i];
 			if (sig.keyid != ki->tag || sig.algorithm != ki->algo ||
-			    !dns_name_equal(dns_linkedname_name(&sig.signer),
-					    name))
+			    !dns_name_equal(&sig.signer, name))
 			{
 				continue;
 			}
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
index 6aa0eba274..40259f6e88 100644
--- a/bin/dnssec/dnssec-signzone.c
+++ b/bin/dnssec/dnssec-signzone.c
@@ -350,8 +350,7 @@ keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
 	ISC_LIST_FOREACH(keylist, key, link) {
 		if (rrsig->keyid == dst_key_id(key->key) &&
 		    algorithm == dst_key_alg(key->key) &&
-		    dns_name_equal(dns_linkedname_name(&rrsig->signer),
-				   dst_key_name(key->key)))
+		    dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
 		{
 			return key;
 		}
diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c
index 08557186c3..bb8d12d5e3 100644
--- a/bin/dnssec/dnssectool.c
+++ b/bin/dnssec/dnssectool.c
@@ -126,8 +126,7 @@ sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) {
 	dst_algorithm_t algorithm = dst_algorithm_fromdata(
 		sig->algorithm, sig->signature, sig->siglen);

-	dns_name_format(dns_linkedname_name(&sig->signer), namestr,
-			sizeof(namestr));
+	dns_name_format(&sig->signer, namestr, sizeof(namestr));
 	dst_algorithm_format(algorithm, algstr, sizeof(algstr));
 	snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid);
 }
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
index 79f2fb8979..5a915a73ed 100644
--- a/bin/nsupdate/nsupdate.c
+++ b/bin/nsupdate/nsupdate.c
@@ -2028,8 +2028,7 @@ parseclass:
 		{
 			char namebuf[DNS_NAME_FORMATSIZE];

-			dns_name_format(dns_linkedname_name(name), namebuf,
-					sizeof(namebuf));
+			dns_name_format(name, namebuf, sizeof(namebuf));
 			fprintf(stderr, "check-names failed: bad owner '%s'\n",
 				namebuf);
 			goto failure;
@@ -2862,8 +2861,7 @@ lookforsoa:

 	if (debugging) {
 		char namestr[DNS_NAME_FORMATSIZE];
-		dns_name_format(dns_linkedname_name(name), namestr,
-				sizeof(namestr));
+		dns_name_format(name, namestr, sizeof(namestr));
 		fprintf(stderr, "Found zone name: %s\n", namestr);
 	}

@@ -2886,7 +2884,7 @@ lookforsoa:
 		 * address.
 		 */
 		zname = dns_fixedname_initname(&fzname);
-		dns_name_copy(dns_linkedname_name(name), zname);
+		dns_name_copy(name, zname);
 	}

 	if (debugging) {
@@ -2954,7 +2952,7 @@ out:
 droplabel:
 	INSIST(!ISC_LIST_EMPTY(soaquery->sections[DNS_SECTION_QUESTION]));
 	name = ISC_LIST_HEAD(soaquery->sections[DNS_SECTION_QUESTION]);
-	nlabels = dns_name_countlabels(dns_linkedname_name(name));
+	nlabels = dns_name_countlabels(name);
 	if (nlabels == 1) {
 		fatal("could not find enclosing zone");
 	}
@@ -3409,8 +3407,7 @@ start_update(void) {

 		dns_linkedname_t *firstname =
 			ISC_LIST_HEAD(updatemsg->sections[section]);
-		dns_name_clone(dns_linkedname_name(firstname),
-			       dns_linkedname_name(name));
+		dns_name_clone(firstname, dns_linkedname_name(name));

 		/*
 		 * Looks to see if the first name references a DS record
@@ -3423,8 +3420,7 @@ start_update(void) {
 		    !dns_name_isroot(dns_linkedname_name(firstname)) &&
 		    tmprdataset->type == dns_rdatatype_ds)
 		{
-			unsigned int labels =
-				dns_name_countlabels(dns_linkedname_name(name));
+			unsigned int labels = dns_name_countlabels(name);
 			dns_name_getlabelsequence(dns_linkedname_name(name), 1,
 						  labels - 1,
 						  dns_linkedname_name(name));
diff --git a/bin/plugins/filter-a.c b/bin/plugins/filter-a.c
index 65dd2f9e63..c309687458 100644
--- a/bin/plugins/filter-a.c
+++ b/bin/plugins/filter-a.c
@@ -570,9 +570,7 @@ process_section(const section_filter_t *filter) {
 	dns_message_t *message = qctx->client->message;

 	MSG_SECTION_FOREACH(message, section, cur) {
-		if (name != NULL &&
-		    !dns_name_equal(name, dns_linkedname_name(cur)))
-		{
+		if (name != NULL && !dns_name_equal(name, cur)) {
 			/*
 			 * We only want to process 'name' and this is not it.
 			 */
diff --git a/bin/plugins/filter-aaaa.c b/bin/plugins/filter-aaaa.c
index f238a9447f..8bf91aed17 100644
--- a/bin/plugins/filter-aaaa.c
+++ b/bin/plugins/filter-aaaa.c
@@ -575,9 +575,7 @@ process_section(const section_filter_t *filter) {
 	dns_message_t *message = qctx->client->message;

 	MSG_SECTION_FOREACH(message, section, cur) {
-		if (name != NULL &&
-		    !dns_name_equal(name, dns_linkedname_name(cur)))
-		{
+		if (name != NULL && !dns_name_equal(name, cur)) {
 			/*
 			 * We only want to process 'name' and this is not it.
 			 */
diff --git a/bin/plugins/synthrecord.c b/bin/plugins/synthrecord.c
index 0acacd5f52..ba2818ef17 100644
--- a/bin/plugins/synthrecord.c
+++ b/bin/plugins/synthrecord.c
@@ -159,8 +159,7 @@ synthrecord_respond(synthrecord_t *inst, query_ctx_t *qctx, void *rdata,
 	 * rdataset to it.
 	 */
 	dns_message_gettempname(msg, &aname);
-	dns_name_copy(dns_linkedname_name(qctx->client->query.qname),
-		      dns_linkedname_name(aname));
+	dns_name_copy(qctx->client->query.qname, aname);
 	dns_message_addname(msg, aname, DNS_SECTION_ANSWER);
 	dns_rdataset_setownercase(synthset, dns_linkedname_name(aname));
 	ISC_LIST_APPEND(aname->list, synthset, link);
diff --git a/lib/dns/deleg.c b/lib/dns/deleg.c
index 8362465d90..e12a8aab92 100644
--- a/lib/dns/deleg.c
+++ b/lib/dns/deleg.c
@@ -541,8 +541,7 @@ delegset_size(dns_delegset_t *delegset) {
 			sz += sizeof(*address);
 		}
 		ISC_LIST_FOREACH(deleg->names, name, link) {
-			sz += sizeof(*name) +
-			      dns_name_size(dns_linkedname_name(name));
+			sz += sizeof(*name) + dns_name_size(name);
 		}
 	}

@@ -775,7 +774,7 @@ tostring_namelist(dns_namelist_t *namelist, const char *id, FILE *fp) {
 			char bdata[DNS_NAME_FORMATSIZE] = { 0 };

 			isc_buffer_init(&nameb, bdata, sizeof(bdata));
-			dns_name_totext(dns_linkedname_name(name), 0, &nameb);
+			dns_name_totext(name, 0, &nameb);
 			fprintf(fp, "%s", bdata);

 			if (name != ISC_LIST_TAIL(*namelist)) {
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index 7acf861af8..75bbb50f9b 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -196,7 +196,7 @@ digest_sig(dst_context_t *ctx, bool downcase, dns_rdata_t *sigrdata,
 			ISC_R_SUCCESS);
 		dns_name_toregion(dns_fixedname_name(&fname), &r);
 	} else {
-		dns_name_toregion(dns_linkedname_name(&rrsig->signer), &r);
+		dns_name_toregion(&rrsig->signer, &r);
 	}

 	return dst_context_adddata(ctx, &r);
@@ -471,21 +471,19 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
 	case dns_rdatatype_ns:
 	case dns_rdatatype_soa:
 	case dns_rdatatype_dnskey:
-		if (!dns_name_equal(name, dns_linkedname_name(&sig.signer))) {
+		if (!dns_name_equal(name, &sig.signer)) {
 			inc_stat(dns_dnssecstats_fail);
 			return DNS_R_SIGINVALID;
 		}
 		break;
 	case dns_rdatatype_ds:
-		if (dns_name_equal(name, dns_linkedname_name(&sig.signer))) {
+		if (dns_name_equal(name, &sig.signer)) {
 			inc_stat(dns_dnssecstats_fail);
 			return DNS_R_SIGINVALID;
 		}
 		FALLTHROUGH;
 	default:
-		if (!dns_name_issubdomain(name,
-					  dns_linkedname_name(&sig.signer)))
-		{
+		if (!dns_name_issubdomain(name, &sig.signer)) {
 			inc_stat(dns_dnssecstats_fail);
 			return DNS_R_SIGINVALID;
 		}
@@ -599,8 +597,7 @@ again:
 	result = dst_context_verify(ctx, &r);
 	if (result == ISC_R_SUCCESS && downcase) {
 		char namebuf[DNS_NAME_FORMATSIZE];
-		dns_name_format(dns_linkedname_name(&sig.signer), namebuf,
-				sizeof(namebuf));
+		dns_name_format(&sig.signer, namebuf, sizeof(namebuf));
 		isc_log_write(DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC,
 			      ISC_LOG_DEBUG(1),
 			      "successfully validated after lower casing "
diff --git a/lib/dns/dnstap.c b/lib/dns/dnstap.c
index 62008fe839..c05d66492f 100644
--- a/lib/dns/dnstap.c
+++ b/lib/dns/dnstap.c
@@ -1192,8 +1192,7 @@ dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) {
 		dns_message_currentname(d->msg, DNS_SECTION_QUESTION, &name);
 		rdataset = ISC_LIST_HEAD(name->list);

-		dns_name_format(dns_linkedname_name(name), d->namebuf,
-				sizeof(d->namebuf));
+		dns_name_format(name, d->namebuf, sizeof(d->namebuf));
 		dns_rdatatype_format(rdataset->type, d->typebuf,
 				     sizeof(d->typebuf));
 		dns_rdataclass_format(rdataset->rdclass, d->classbuf,
diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h
index d3d313291e..15cdd0dbed 100644
--- a/lib/dns/include/dns/name.h
+++ b/lib/dns/include/dns/name.h
@@ -134,6 +134,11 @@ dns_linkedname_name_const(const dns_linkedname_t *nwl) {
 	return nwl != NULL ? &nwl->name : NULL;
 }

+static inline const dns_name_t *
+dns_name__readonly_arg(const dns_name_t *name) {
+	return name;
+}
+
 #define DNS_NAME_MAGIC	  ISC_MAGIC('D', 'N', 'S', 'n')
 #define DNS_NAME_VALID(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)

@@ -371,7 +376,7 @@ dns_name_hasbuffer(const dns_name_t *name);
  ***/

 bool
-dns_name_isabsolute(const dns_name_t *name);
+dns_name__isabsolute(const dns_name_t *name);
 /*%<
  * Does 'name' end in the root label?
  *
@@ -384,7 +389,7 @@ dns_name_isabsolute(const dns_name_t *name);
  */

 bool
-dns_name_iswildcard(const dns_name_t *name);
+dns_name__iswildcard(const dns_name_t *name);
 /*%<
  * Is 'name' a wildcard name?
  *
@@ -399,7 +404,7 @@ dns_name_iswildcard(const dns_name_t *name);
  */

 uint32_t
-dns_name_hash(const dns_name_t *name);
+dns_name__hash(const dns_name_t *name);
 /*%<
  * Provide a hash value for 'name'.
  *
@@ -431,8 +436,8 @@ dns_name_hash_ex(isc_hash32_t *hash, const dns_name_t *name);
  ***/

 dns_namereln_t
-dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
-		     int *orderp, unsigned int *nlabelsp);
+dns_name__fullcompare(const dns_name_t *name1, const dns_name_t *name2,
+		      int *orderp, unsigned int *nlabelsp);
 /*%<
  * Determine the relative ordering under the DNSSEC order relation of
  * 'name1' and 'name2', and also determine the hierarchical
@@ -475,7 +480,7 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
  */

 int
-dns_name_compare(const dns_name_t *name1, const dns_name_t *name2);
+dns_name__compare(const dns_name_t *name1, const dns_name_t *name2);
 /*%<
  * Determine the relative ordering under the DNSSEC order relation of
  * 'name1' and 'name2'.
@@ -499,7 +504,7 @@ dns_name_compare(const dns_name_t *name1, const dns_name_t *name2);
  */

 bool
-dns_name_equal(const dns_name_t *name1, const dns_name_t *name2);
+dns_name__equal(const dns_name_t *name1, const dns_name_t *name2);
 /*%<
  * Are 'name1' and 'name2' equal?
  *
@@ -552,7 +557,7 @@ dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2);
  */

 bool
-dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2);
+dns_name__issubdomain(const dns_name_t *name1, const dns_name_t *name2);
 /*%<
  * Is 'name1' a subdomain of 'name2'?
  *
@@ -646,7 +651,7 @@ dns_name_empty(const dns_name_t *name) {
  */

 static inline uint8_t
-dns_name_countlabels(const dns_name_t *name) {
+dns_name__countlabels(const dns_name_t *name) {
 	REQUIRE(DNS_NAME_VALID(name));

 	return dns_name_offsets(name, NULL);
@@ -710,7 +715,7 @@ dns_name_getlabelsequence(const dns_name_t *source, unsigned int first,
  */

 void
-dns_name_clone(const dns_name_t *source, dns_name_t *target);
+dns_name__clone(const dns_name_t *source, dns_name_t *target);
 /*%<
  * Make 'target' refer to the same name as 'source'.
  *
@@ -756,7 +761,7 @@ dns_name_fromregion(dns_name_t *name, const isc_region_t *r);
  */

 static inline void
-dns_name_toregion(const dns_name_t *name, isc_region_t *r) {
+dns_name__toregion(const dns_name_t *name, isc_region_t *r) {
 	REQUIRE(DNS_NAME_VALID(name));
 	REQUIRE(r != NULL);

@@ -939,8 +944,8 @@ dns_name_wirefromtext(isc_buffer_t *source, const dns_name_t *origin,
 #define DNS_NAME_QUOTED	      0x04U /* minimal escaping within double quotes */

 isc_result_t
-dns_name_totext(const dns_name_t *name, unsigned int options,
-		isc_buffer_t *target);
+dns_name__totext(const dns_name_t *name, unsigned int options,
+		 isc_buffer_t *target);
 /*%<
  * Convert 'name' into text format, storing the result in 'target'.
  *
@@ -1085,7 +1090,7 @@ dns_name_split(const dns_name_t *name, unsigned int suffixlabels,
 	REQUIRE(suffix == NULL ||
 		(DNS_NAME_VALID(suffix) && DNS_NAME_BINDABLE(suffix)));

-	uint8_t labels = dns_name_countlabels(name);
+	uint8_t labels = dns_name__countlabels(name);
 	INSIST(suffixlabels <= labels);

 	if (prefix != NULL) {
@@ -1142,7 +1147,7 @@ dns_name_split(const dns_name_t *name, unsigned int suffixlabels,
  */

 void
-dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target);
+dns_name__dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target);
 /*%<
  * Make 'target' a dynamically allocated copy of 'source'.
  *
@@ -1211,7 +1216,7 @@ dns_name_digest(const dns_name_t *name, dns_digestfunc_t digest, void *arg);
  */

 bool
-dns_name_dynamic(const dns_name_t *name);
+dns_name__dynamic(const dns_name_t *name);
 /*%<
  * Returns whether there is dynamic memory associated with this name.
  *
@@ -1243,7 +1248,7 @@ dns_name_print(const dns_name_t *name, FILE *stream);
  */

 void
-dns_name_format(const dns_name_t *name, char *cp, unsigned int size);
+dns_name__format(const dns_name_t *name, char *cp, unsigned int size);
 /*%<
  * Format 'name' as text appropriate for use in log messages.
  *
@@ -1334,7 +1339,7 @@ dns_name_settotextfilter(dns_name_totextfilter_t *proc);
  */

 void
-dns_name_copy(const dns_name_t *source, dns_name_t *dest);
+dns_name__copy(const dns_name_t *source, dns_name_t *dest);
 /*%<
  * Copies the name in 'source' into 'dest'.  The name data is copied to
  * the dedicated buffer for 'dest'. (If copying to a name that doesn't
@@ -1368,7 +1373,7 @@ dns_name_ismailbox(const dns_name_t *name);
  */

 bool
-dns_name_internalwildcard(const dns_name_t *name);
+dns_name__internalwildcard(const dns_name_t *name);
 /*%<
  * Return true if 'name' contains a internal wildcard name.
  *
@@ -1395,7 +1400,7 @@ dns_name_isula(const dns_name_t *owner);
  */

 bool
-dns_name_istat(const dns_name_t *name);
+dns_name__istat(const dns_name_t *name);
 /*%<
  * Determine if 'name' is a potential 'trust-anchor-telemetry' name.
  */
@@ -1408,14 +1413,14 @@ dns_name_isdnssvcb(const dns_name_t *name);
  */

 size_t
-dns_name_size(const dns_name_t *name);
+dns_name__size(const dns_name_t *name);
 /*%<
  * Return the amount of dynamically allocated memory associated with
  * 'name' (which is 0 if 'name' is not dynamic).
  */

 bool
-dns_name_israd(const dns_name_t *name, const dns_name_t *rad);
+dns_name__israd(const dns_name_t *name, const dns_name_t *rad);
 /*%<
  * Determine whether 'name' matches the prescribed format of a
  * DNS error-reporting name:
@@ -1456,3 +1461,60 @@ dns_name_belowroot(const dns_name_t *name) {
  * Requires:
  * \li	'name' to be valid.
  */
+
+#define DNS_NAME__RO_ARG(arg)                               \
+	_Generic((arg),                                     \
+		dns_name_t *: dns_name__readonly_arg,       \
+		const dns_name_t *: dns_name__readonly_arg, \
+		dns_linkedname_t *: dns_linkedname_name,    \
+		const dns_linkedname_t *: dns_linkedname_name_const)(arg)
+
+#define dns_name_clone(source, target) \
+	dns_name__clone(DNS_NAME__RO_ARG(source), target)
+
+#define dns_name_dup(source, mctx, target) \
+	dns_name__dup(DNS_NAME__RO_ARG(source), mctx, target)
+
+#define dns_name_copy(source, dest) \
+	dns_name__copy(DNS_NAME__RO_ARG(source), dest)
+
+#define dns_name_isabsolute(name) dns_name__isabsolute(DNS_NAME__RO_ARG(name))
+
+#define dns_name_iswildcard(name) dns_name__iswildcard(DNS_NAME__RO_ARG(name))
+
+#define dns_name_hash(name) dns_name__hash(DNS_NAME__RO_ARG(name))
+
+#define dns_name_fullcompare(name1, name2, orderp, nlabelsp) \
+	dns_name__fullcompare(DNS_NAME__RO_ARG(name1),       \
+			      DNS_NAME__RO_ARG(name2), orderp, nlabelsp)
+
+#define dns_name_compare(name1, name2) \
+	dns_name__compare(DNS_NAME__RO_ARG(name1), DNS_NAME__RO_ARG(name2))
+
+#define dns_name_equal(name1, name2) \
+	dns_name__equal(DNS_NAME__RO_ARG(name1), DNS_NAME__RO_ARG(name2))
+
+#define dns_name_issubdomain(name1, name2) \
+	dns_name__issubdomain(DNS_NAME__RO_ARG(name1), DNS_NAME__RO_ARG(name2))
+
+#define dns_name_countlabels(name) dns_name__countlabels(DNS_NAME__RO_ARG(name))
+
+#define dns_name_toregion(name, r) dns_name__toregion(DNS_NAME__RO_ARG(name), r)
+
+#define dns_name_totext(name, options, target) \
+	dns_name__totext(DNS_NAME__RO_ARG(name), options, target)
+
+#define dns_name_dynamic(name) dns_name__dynamic(DNS_NAME__RO_ARG(name))
+
+#define dns_name_format(name, cp, size) \
+	dns_name__format(DNS_NAME__RO_ARG(name), cp, size)
+
+#define dns_name_internalwildcard(name) \
+	dns_name__internalwildcard(DNS_NAME__RO_ARG(name))
+
+#define dns_name_istat(name) dns_name__istat(DNS_NAME__RO_ARG(name))
+
+#define dns_name_size(name) dns_name__size(DNS_NAME__RO_ARG(name))
+
+#define dns_name_israd(name, rad) \
+	dns_name__israd(DNS_NAME__RO_ARG(name), DNS_NAME__RO_ARG(rad))
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 2c0286dc5d..1fae66c878 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -771,14 +771,15 @@ ISC_REFCOUNT_IMPL(dns_message, dns__message_destroy);

 static bool
 name_match(void *node, const void *key) {
-	return dns_name_equal(node, key);
+	return dns_name_equal((dns_linkedname_t *)node,
+			      (const dns_linkedname_t *)key);
 }

 static isc_result_t
 findname(dns_linkedname_t **foundname, const dns_name_t *target,
 	 dns_namelist_t *section) {
 	ISC_LIST_FOREACH_REV(*section, name, link) {
-		if (dns_name_equal(dns_linkedname_name(name), target)) {
+		if (dns_name_equal(name, target)) {
 			SET_IF_NOT_NULL(foundname, name);
 			return ISC_R_SUCCESS;
 		}
@@ -1301,10 +1302,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_section_t sectionid,
 			 * allocated name since we no longer need it, and set
 			 * our name pointer to point to the name we found.
 			 */
-			result = isc_hashmap_add(
-				name_map,
-				dns_name_hash(dns_linkedname_name(name)),
-				name_match, name, name, (void **)&found_name);
+			result = isc_hashmap_add(name_map, dns_name_hash(name),
+						 name_match, name, name,
+						 (void **)&found_name);

 			/*
 			 * If it is a new name, append to the section.
@@ -2361,7 +2361,7 @@ dns_message_addname(dns_message_t *msg, dns_linkedname_t *name,
 		    dns_section_t section) {
 	REQUIRE(msg != NULL);
 	REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
-	REQUIRE(dns_name_isabsolute(dns_linkedname_name(name)));
+	REQUIRE(dns_name_isabsolute(name));
 	REQUIRE(VALID_NAMED_SECTION(section));

 	ISC_LIST_APPEND(msg->sections[section], name, link);
@@ -2372,7 +2372,7 @@ dns_message_removename(dns_message_t *msg, dns_linkedname_t *name,
 		       dns_section_t section) {
 	REQUIRE(msg != NULL);
 	REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
-	REQUIRE(dns_name_isabsolute(dns_linkedname_name(name)));
+	REQUIRE(dns_name_isabsolute(name));
 	REQUIRE(VALID_NAMED_SECTION(section));

 	ISC_LIST_UNLINK(msg->sections[section], name, link);
@@ -2436,7 +2436,7 @@ dns_message_puttempname(dns_message_t *msg, dns_linkedname_t **itemp) {
 	/*
 	 * we need to check this in case dns_name_dup() was used.
 	 */
-	if (dns_name_dynamic(dns_linkedname_name(item))) {
+	if (dns_name_dynamic(item)) {
 		dns_name_free(dns_linkedname_name(item), msg->mctx);
 	}

diff --git a/lib/dns/name.c b/lib/dns/name.c
index 8fe3710e79..96901985be 100644
--- a/lib/dns/name.c
+++ b/lib/dns/name.c
@@ -131,7 +131,7 @@ dns_name_hasbuffer(const dns_name_t *name) {
 }

 bool
-dns_name_isabsolute(const dns_name_t *name) {
+dns_name__isabsolute(const dns_name_t *name) {
 	/*
 	 * Does 'name' end in the root label?
 	 */
@@ -255,7 +255,7 @@ dns_name_ishostname(const dns_name_t *name, bool wildcard) {
 }

 bool
-dns_name_iswildcard(const dns_name_t *name) {
+dns_name__iswildcard(const dns_name_t *name) {
 	unsigned char *ndata;

 	/*
@@ -276,7 +276,7 @@ dns_name_iswildcard(const dns_name_t *name) {
 }

 bool
-dns_name_internalwildcard(const dns_name_t *name) {
+dns_name__internalwildcard(const dns_name_t *name) {
 	unsigned char *ndata;
 	unsigned int count;
 	unsigned int label;
@@ -318,7 +318,7 @@ dns_name_hash_ex(isc_hash32_t *hash, const dns_name_t *name) {
 }

 uint32_t
-dns_name_hash(const dns_name_t *name) {
+dns_name__hash(const dns_name_t *name) {
 	isc_hash32_t hash;

 	isc_hash32_init(&hash);
@@ -329,8 +329,8 @@ dns_name_hash(const dns_name_t *name) {
 }

 dns_namereln_t
-dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
-		     int *orderp, unsigned int *nlabelsp) {
+dns_name__fullcompare(const dns_name_t *name1, const dns_name_t *name2,
+		      int *orderp, unsigned int *nlabelsp) {
 	unsigned int l1, l2, l, count1, count2, count, nlabels;
 	int cdiff, ldiff, diff;
 	unsigned char *label1, *label2;
@@ -425,7 +425,7 @@ done:
 }

 int
-dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
+dns_name__compare(const dns_name_t *name1, const dns_name_t *name2) {
 	int order;
 	unsigned int nlabels;

@@ -445,7 +445,7 @@ dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
 }

 bool
-dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
+dns_name__equal(const dns_name_t *name1, const dns_name_t *name2) {
 	unsigned int length;

 	/*
@@ -525,7 +525,7 @@ dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
 }

 bool
-dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
+dns_name__issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
 	int order;
 	unsigned int nlabels;
 	dns_namereln_t namereln;
@@ -647,7 +647,7 @@ dns_name_getlabelsequence(const dns_name_t *source, unsigned int first,
 }

 void
-dns_name_clone(const dns_name_t *source, dns_name_t *target) {
+dns_name__clone(const dns_name_t *source, dns_name_t *target) {
 	/*
 	 * Make 'target' refer to the same name as 'source'.
 	 */
@@ -983,8 +983,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
 }

 isc_result_t
-dns_name_totext(const dns_name_t *name, unsigned int options,
-		isc_buffer_t *target) {
+dns_name__totext(const dns_name_t *name, unsigned int options,
+		 isc_buffer_t *target) {
 	isc_result_t result;
 	unsigned char *ndata = NULL;
 	unsigned int nlen;
@@ -1615,7 +1615,7 @@ dns_name_concatenate(const dns_name_t *prefix, const dns_name_t *suffix,
 }

 void
-dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
+dns_name__dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
 	/*
 	 * Make 'target' a dynamically allocated copy of 'source'.
 	 */
@@ -1651,7 +1651,7 @@ dns_name_free(dns_name_t *name, isc_mem_t *mctx) {
 }

 size_t
-dns_name_size(const dns_name_t *name) {
+dns_name__size(const dns_name_t *name) {
 	size_t size;

 	REQUIRE(DNS_NAME_VALID(name));
@@ -1685,7 +1685,7 @@ dns_name_digest(const dns_name_t *name, dns_digestfunc_t digest, void *arg) {
 }

 bool
-dns_name_dynamic(const dns_name_t *name) {
+dns_name__dynamic(const dns_name_t *name) {
 	REQUIRE(DNS_NAME_VALID(name));

 	/*
@@ -1736,7 +1736,7 @@ dns_name_settotextfilter(dns_name_totextfilter_t *proc) {
 }

 void
-dns_name_format(const dns_name_t *name, char *cp, unsigned int size) {
+dns_name__format(const dns_name_t *name, char *cp, unsigned int size) {
 	isc_result_t result;
 	isc_buffer_t buf;

@@ -1807,7 +1807,7 @@ dns_name_fromstring(dns_name_t *target, const char *src,
 }

 void
-dns_name_copy(const dns_name_t *source, dns_name_t *dest) {
+dns_name__copy(const dns_name_t *source, dns_name_t *dest) {
 	isc_buffer_t *target = NULL;
 	unsigned char *ndata = NULL;

@@ -1946,7 +1946,7 @@ dns_name_isula(const dns_name_t *name) {
 }

 bool
-dns_name_istat(const dns_name_t *name) {
+dns_name__istat(const dns_name_t *name) {
 	unsigned char len;
 	const unsigned char *ndata;

@@ -2047,7 +2047,7 @@ dns_name_isdnssvcb(const dns_name_t *name) {
 }

 bool
-dns_name_israd(const dns_name_t *name, const dns_name_t *rad) {
+dns_name__israd(const dns_name_t *name, const dns_name_t *rad) {
 	dns_name_t suffix;
 	char labelbuf[64];
 	unsigned long v, last = ULONG_MAX;
diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c
index f57d4bd94f..3834abedc1 100644
--- a/lib/dns/ncache.c
+++ b/lib/dns/ncache.c
@@ -194,8 +194,7 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
 					/*
 					 * Copy the owner name to the buffer.
 					 */
-					dns_name_toregion(
-						dns_linkedname_name(name), &r);
+					dns_name_toregion(name, &r);
 					RETERR(isc_buffer_copyregion(&buffer,
 								     &r));
 					/*
diff --git a/lib/dns/rdatalist.c b/lib/dns/rdatalist.c
index 86e0a7edc4..328fd32914 100644
--- a/lib/dns/rdatalist.c
+++ b/lib/dns/rdatalist.c
@@ -250,7 +250,7 @@ dns__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
 		return ISC_R_NOTFOUND;
 	}

-	dns_name_clone(dns_linkedname_name(noqname), name);
+	dns_name_clone(noqname, name);
 	dns_rdataset_clone(tneg, neg);
 	dns_rdataset_clone(tnegsig, negsig);
 	return ISC_R_SUCCESS;
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 542fa748bc..f7bd1d00dd 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -5281,9 +5281,8 @@ is_lame(fetchctx_t *fctx, dns_message_t *message) {
 			if (rdataset->type != dns_rdatatype_ns) {
 				continue;
 			}
-			namereln = dns_name_fullcompare(
-				dns_linkedname_name(name), fctx->domain, &order,
-				&labels);
+			namereln = dns_name_fullcompare(name, fctx->domain,
+							&order, &labels);
 			if (namereln == dns_namereln_equal &&
 			    (message->flags & DNS_MESSAGEFLAG_AA) != 0)
 			{
@@ -5382,14 +5381,13 @@ same_question(fetchctx_t *fctx, dns_message_t *message) {

 	if (fctx->type != rdataset->type ||
 	    fctx->res->rdclass != rdataset->rdclass ||
-	    !dns_name_equal(fctx->name, dns_linkedname_name(name)))
+	    !dns_name_equal(fctx->name, name))
 	{
 		char namebuf[DNS_NAME_FORMATSIZE];
 		char classbuf[DNS_RDATACLASS_FORMATSIZE];
 		char typebuf[DNS_RDATATYPE_FORMATSIZE];

-		dns_name_format(dns_linkedname_name(name), namebuf,
-				sizeof(namebuf));
+		dns_name_format(name, namebuf, sizeof(namebuf));
 		dns_rdataclass_format(rdataset->rdclass, classbuf,
 				      sizeof(classbuf));
 		dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
@@ -5747,8 +5745,7 @@ fctx_cacheauthority(fetchctx_t *fctx, dns_message_t *message,
 			 * "black lies".
 			 */
 			if (rdataset->type == dns_rdatatype_nsec &&
-			    !dns_name_equal(fctx->name,
-					    dns_linkedname_name(name)) &&
+			    !dns_name_equal(fctx->name, name) &&
 			    is_minimal_nsec(rdataset))
 			{
 				continue;
@@ -5979,7 +5976,7 @@ answer_response:
 	FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);

 	fctx_setresult(fctx);
-	dns_name_copy(dns_linkedname_name(val->name), fctx->resp.foundname);
+	dns_name_copy(val->name, fctx->resp.foundname);
 	dns_db_transfernode(fctx->cache, &node, &fctx->resp_node);

 	done = true;
@@ -6431,7 +6428,7 @@ rctx_cachename(respctx_t *rctx, dns_message_t *message,
 		if (dns_rdataset_isassociated(&fctx->resp.rdataset)) {
 			fctx_setresult(fctx);
 		}
-		dns_name_copy(dns_linkedname_name(name), fctx->resp.foundname);
+		dns_name_copy(name, fctx->resp.foundname);
 		dns_db_transfernode(fctx->cache, &node, &fctx->resp_node);
 		FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER);
 	}
@@ -8750,9 +8747,8 @@ rctx_answer_scan(respctx_t *rctx) {
 		unsigned int nlabels;
 		dns_namereln_t namereln;

-		namereln = dns_name_fullcompare(fctx->name,
-						dns_linkedname_name(name),
-						&order, &nlabels);
+		namereln = dns_name_fullcompare(fctx->name, name, &order,
+						&nlabels);
 		switch (namereln) {
 		case dns_namereln_equal:
 			ISC_LIST_FOREACH(name->list, rdataset, link) {
@@ -9082,7 +9078,7 @@ rctx_authority_positive(respctx_t *rctx) {
 	MSG_SECTION_FOREACH(msg, DNS_SECTION_AUTHORITY, name) {
 		if (!name_external(dns_linkedname_name(name), dns_rdatatype_ns,
 				   rctx) &&
-		    dns_name_issubdomain(fctx->name, dns_linkedname_name(name)))
+		    dns_name_issubdomain(fctx->name, name))
 		{
 			/*
 			 * We expect to find NS or SIG NS rdatasets, and
@@ -9282,9 +9278,7 @@ rctx_authority_negative(respctx_t *rctx) {

 	dns_message_t *msg = rctx->query->rmessage;
 	MSG_SECTION_FOREACH(msg, section, name) {
-		if (!dns_name_issubdomain(dns_linkedname_name(name),
-					  fctx->domain))
-		{
+		if (!dns_name_issubdomain(name, fctx->domain)) {
 			continue;
 		}

@@ -9295,15 +9289,13 @@ rctx_authority_negative(respctx_t *rctx) {
 			}
 			if ((type == dns_rdatatype_ns ||
 			     type == dns_rdatatype_soa) &&
-			    !dns_name_issubdomain(fctx->name,
-						  dns_linkedname_name(name)))
+			    !dns_name_issubdomain(fctx->name, name))
 			{
 				char qbuf[DNS_NAME_FORMATSIZE];
 				char nbuf[DNS_NAME_FORMATSIZE];
 				char tbuf[DNS_RDATATYPE_FORMATSIZE];
 				dns_rdatatype_format(type, tbuf, sizeof(tbuf));
-				dns_name_format(dns_linkedname_name(name), nbuf,
-						sizeof(nbuf));
+				dns_name_format(name, nbuf, sizeof(nbuf));
 				dns_name_format(fctx->name, qbuf, sizeof(qbuf));
 				log_formerr(fctx,
 					    "unrelated %s %s in "
@@ -9395,9 +9387,7 @@ rctx_authority_dnssec(respctx_t *rctx) {

 	dns_message_t *msg = rctx->query->rmessage;
 	MSG_SECTION_FOREACH(msg, DNS_SECTION_AUTHORITY, name) {
-		if (!dns_name_issubdomain(dns_linkedname_name(name),
-					  fctx->domain))
-		{
+		if (!dns_name_issubdomain(name, fctx->domain)) {
 			/*
 			 * Invalid name found; preserve it for logging
 			 * later.
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
index d50168ae3b..be6098a3bc 100644
--- a/lib/dns/tkey.c
+++ b/lib/dns/tkey.c
@@ -410,9 +410,8 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
 		keyname = dns_fixedname_initname(&fkeyname);

 		if (!dns_name_isroot(dns_linkedname_name(qname))) {
-			unsigned int n = dns_name_countlabels(
-				dns_linkedname_name(qname));
-			dns_name_copy(dns_linkedname_name(qname), keyname);
+			unsigned int n = dns_name_countlabels(qname);
+			dns_name_copy(qname, keyname);
 			dns_name_getlabelsequence(keyname, 0, n - 1, keyname);
 		} else {
 			unsigned char randomdata[16];
diff --git a/lib/dns/transport.c b/lib/dns/transport.c
index a6acbf15dd..398e0506f3 100644
--- a/lib/dns/transport.c
+++ b/lib/dns/transport.c
@@ -72,7 +72,7 @@ static bool
 transport_match(void *node, const void *key) {
 	dns_transport_t *transport = node;

-	return dns_name_equal(transport->name, key);
+	return dns_name_equal(transport->name, (const dns_name_t *)key);
 }

 static isc_result_t
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c
index b13bd723f8..f999e7d311 100644
--- a/lib/dns/tsig.c
+++ b/lib/dns/tsig.c
@@ -143,7 +143,7 @@ static bool
 tkey_match(void *node, const void *key) {
 	dns_tsigkey_t *tkey = node;

-	return dns_name_equal(tkey->name, key);
+	return dns_name_equal(tkey->name, (const dns_name_t *)key);
 }

 static bool
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 9bd64bac92..3d21614fd1 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -1149,10 +1149,8 @@ validator_callback_nsec(void *arg) {
 		    rdataset->trust == dns_trust_secure &&
 		    (NEEDNODATA(val) || NEEDNOQNAME(val)) &&
 		    !FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
-		    dns_name_issubdomain(
-			    dns_linkedname_name(val->name),
-			    dns_linkedname_name(
-				    &subvalidator->siginfo->signer)) &&
+		    dns_name_issubdomain(val->name,
+					 &subvalidator->siginfo->signer) &&
 		    dns_nsec_noexistnodata(
 			    val->type, dns_linkedname_name(val->name),
 			    dns_linkedname_name(subvalidator->name), rdataset,
@@ -1286,7 +1284,7 @@ static bool
 check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
 	       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
 	for (dns_validator_t *cur = val; cur != NULL; cur = cur->parent) {
-		if (!dns_name_equal(dns_linkedname_name(cur->name), name)) {
+		if (!dns_name_equal(cur->name, name)) {
 			continue;
 		}

@@ -1519,9 +1517,8 @@ seek_dnskey(dns_validator_t *val) {
 	 * The signer name must be at the same level as the owner name
 	 * or closer to the DNS root.
 	 */
-	namereln = dns_name_fullcompare(dns_linkedname_name(val->name),
-					dns_linkedname_name(&siginfo->signer),
-					&order, &nlabels);
+	namereln = dns_name_fullcompare(val->name, &siginfo->signer, &order,
+					&nlabels);
 	if (namereln != dns_namereln_subdomain &&
 	    namereln != dns_namereln_equal)
 	{
@@ -1745,8 +1742,7 @@ selfsigned_dnskey(dns_validator_t *val) {

 			if (sig.algorithm != key.algorithm ||
 			    sig.keyid != keytag ||
-			    !dns_name_equal(name,
-					    dns_linkedname_name(&sig.signer)))
+			    !dns_name_equal(name, &sig.signer))
 			{
 				continue;
 			}
@@ -1897,7 +1893,7 @@ again:
 			      isc_result_totext(result));
 	}
 	if (result == DNS_R_FROMWILDCARD) {
-		if (!dns_name_equal(dns_linkedname_name(val->name), wild)) {
+		if (!dns_name_equal(val->name, wild)) {
 			dns_name_t *closest = dns_fixedname_name(&val->closest);

 			/*
@@ -3290,8 +3286,7 @@ validate_neg_rrset(dns_validator_t *val, dns_linkedname_t *name,
 	 */
 	if (val->type == dns_rdatatype_dnskey &&
 	    rdataset->type == dns_rdatatype_nsec &&
-	    dns_name_equal(dns_linkedname_name(name),
-			   dns_linkedname_name(val->name)))
+	    dns_name_equal(name, val->name))
 	{
 		dns_rdata_t nsec = DNS_RDATA_INIT;

@@ -3687,16 +3682,14 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) {
 	dns_name_t *found = dns_fixedname_initname(&fixedfound);
 	dns_linkedname_t *tname = dns_fixedname_initlinkedname(&val->fname);

-	if (val->labels == dns_name_countlabels(dns_linkedname_name(val->name)))
-	{
-		dns_name_copy(dns_linkedname_name(val->name),
-			      dns_linkedname_name(tname));
+	if (val->labels == dns_name_countlabels(val->name)) {
+		dns_name_copy(val->name, dns_linkedname_name(tname));
 	} else {
 		dns_name_split(dns_linkedname_name(val->name), val->labels,
 			       NULL, dns_linkedname_name(tname));
 	}

-	dns_name_format(dns_linkedname_name(tname), namebuf, sizeof(namebuf));
+	dns_name_format(tname, namebuf, sizeof(namebuf));
 	validator_log(val, ISC_LOG_DEBUG(3), "checking existence of DS at '%s'",
 		      namebuf);

@@ -3819,7 +3812,7 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) {
 		    dns_view_bestzonecut(val->view, dns_linkedname_name(tname),
 					 found, NULL, 0, 0, false, false,
 					 NULL) == ISC_R_SUCCESS &&
-		    dns_name_equal(dns_linkedname_name(tname), found))
+		    dns_name_equal(tname, found))
 		{
 			*resp = markanswer(val, "seek_ds (2)");
 			return ISC_R_COMPLETE;
@@ -3970,7 +3963,7 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool have_dnskey,
 	 */
 	val->attributes |= VALATTR_INSECURITY;

-	dns_name_copy(dns_linkedname_name(val->name), secroot);
+	dns_name_copy(val->name, secroot);

 	/*
 	 * If this is a response to a DS query, we need to look in
@@ -4067,9 +4060,7 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool have_dnskey,
 	 * Walk down through each of the remaining labels in the name,
 	 * looking for DS records.
 	 */
-	while (val->labels <=
-	       dns_name_countlabels(dns_linkedname_name(val->name)))
-	{
+	while (val->labels <= dns_name_countlabels(val->name)) {
 		isc_result_t tresult;

 		result = seek_ds(val, &tresult);
@@ -4444,8 +4435,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t category,
 		char namebuf[DNS_NAME_FORMATSIZE];
 		char typebuf[DNS_RDATATYPE_FORMATSIZE];

-		dns_name_format(dns_linkedname_name(val->name), namebuf,
-				sizeof(namebuf));
+		dns_name_format(val->name, namebuf, sizeof(namebuf));
 		dns_rdatatype_format(val->type, typebuf, sizeof(typebuf));
 		isc_log_write(category, module, level,
 			      "%s%s%s%.*svalidating %s/%s: %s", sep1, viewname,
@@ -4503,8 +4493,7 @@ validator_addede(dns_validator_t *val, uint16_t code, const char *extra) {
 		if (extra != NULL) {
 			isc_buffer_putuint8(&b, ' ');
 		}
-		dns_name_totext(dns_linkedname_name(val->name),
-				DNS_NAME_OMITFINALDOT, &b);
+		dns_name_totext(val->name, DNS_NAME_OMITFINALDOT, &b);
 		isc_buffer_putuint8(&b, '/');
 		dns_rdatatype_totext(val->type, &b);
 	}
diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
index 01e90cb98a..b918727962 100644
--- a/lib/dns/xfrin.c
+++ b/lib/dns/xfrin.c
@@ -1938,7 +1938,7 @@ xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) {

 		LIBDNS_XFRIN_RECV_QUESTION(xfr, xfr->info, msg);

-		if (!dns_name_equal(dns_linkedname_name(name), &xfr->name)) {
+		if (!dns_name_equal(name, &xfr->name)) {
 			xfrin_log(xfr, ISC_LOG_NOTICE,
 				  "question name mismatch");
 			CLEANUP(DNS_R_FORMERR);
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 6b1b55b081..7d374235bd 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -17127,9 +17127,7 @@ checkds_done(void *arg) {
 	/* Lookup DS RRset. */

 	MSG_SECTION_FOREACH(message, DNS_SECTION_ANSWER, name) {
-		if (dns_name_compare(&zone->origin,
-				     dns_linkedname_name(name)) != 0)
-		{
+		if (dns_name_compare(&zone->origin, name) != 0) {
 			continue;
 		}

diff --git a/lib/dns/zoneverify.c b/lib/dns/zoneverify.c
index b8efb180ab..6969cd2b3e 100644
--- a/lib/dns/zoneverify.c
+++ b/lib/dns/zoneverify.c
@@ -183,8 +183,7 @@ goodsig(const vctx_t *vctx, dns_rdata_t *sigrdata, const dns_name_t *name,
 	for (size_t key = 0; key < nkeys; key++) {
 		if (algorithm != dst_key_alg(dstkeys[key]) ||
 		    sig.keyid != dst_key_id(dstkeys[key]) ||
-		    !dns_name_equal(dns_linkedname_name(&sig.signer),
-				    vctx->origin))
+		    !dns_name_equal(&sig.signer, vctx->origin))
 		{
 			continue;
 		}
diff --git a/lib/ns/client.c b/lib/ns/client.c
index 996d4a4234..1d41aec766 100644
--- a/lib/ns/client.c
+++ b/lib/ns/client.c
@@ -2946,15 +2946,13 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {

 		LOCK(&client->query.fetchlock);
 		INSIST(client->query.qname != NULL);
-		dns_name_format(dns_linkedname_name(client->query.qname),
-				namebuf, sizeof(namebuf));
+		dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
 		if (client->query.qname != client->query.origqname &&
 		    client->query.origqname != NULL)
 		{
 			origfor = " for ";
-			dns_name_format(
-				dns_linkedname_name(client->query.origqname),
-				original, sizeof(original));
+			dns_name_format(client->query.origqname, original,
+					sizeof(original));
 		} else {
 			origfor = "";
 			original[0] = '\0';
@@ -3111,7 +3109,7 @@ ns_client_keepname(ns_client_t *client, dns_linkedname_t *name,
 	 */
 	REQUIRE(client->query.namebufused);

-	dns_name_toregion(dns_linkedname_name(name), &r);
+	dns_name_toregion(name, &r);
 	isc_buffer_add(dbuf, r.length);
 	dns_name_setbuffer(dns_linkedname_name(name), NULL);
 	client->query.namebufused = false;
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 55cd910a43..26e9a2b326 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -107,9 +107,8 @@ client_trace(ns_client_t *client, int level, const char *message) {
 		if (isc_log_wouldlog(level)) {
 			char qbuf[DNS_NAME_FORMATSIZE];
 			char tbuf[DNS_RDATATYPE_FORMATSIZE];
-			dns_name_format(
-				dns_linkedname_name(client->query.qname), qbuf,
-				sizeof(qbuf));
+			dns_name_format(client->query.qname, qbuf,
+					sizeof(qbuf));
 			dns_rdatatype_format(client->query.qtype, tbuf,
 					     sizeof(tbuf));
 			isc_log_write(NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY,
@@ -592,8 +591,7 @@ log_response(ns_client_t *client, dns_rcode_t rcode) {
 		return;
 	}

-	dns_name_format(dns_linkedname_name(client->query.origqname), namebuf,
-			sizeof(namebuf));
+	dns_name_format(client->query.origqname, namebuf, sizeof(namebuf));
 	dns_rdataclass_format(client->message->rdclass, classbuf,
 			      sizeof(classbuf));
 	dns_rdatatype_format(client->query.qtype, typebuf, sizeof(typebuf));
@@ -1268,8 +1266,7 @@ rpz_log_rewrite(ns_client_t *client, bool disabled, dns_rpz_policy_t policy,
 		return;
 	}

-	dns_name_format(dns_linkedname_name(client->query.qname), qname_buf,
-			sizeof(qname_buf));
+	dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf));
 	dns_name_format(p_name, p_name_buf, sizeof(p_name_buf));
 	if (cname != NULL) {
 		s1 = " (CNAME to: ";
@@ -1332,8 +1329,7 @@ rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name,

 	str_blank = (*str != ' ' && *str != '\0') ? " " : "";

-	dns_name_format(dns_linkedname_name(client->query.qname), qnamebuf,
-			sizeof(qnamebuf));
+	dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf));

 	if (p_name != NULL) {
 		via = " via ";
@@ -1382,9 +1378,8 @@ rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type,
 		if (st->popt.no_log == 0 &&
 		    isc_log_wouldlog(DNS_RPZ_DEBUG_LEVEL2))
 		{
-			dns_name_format(
-				dns_linkedname_name(client->query.qname),
-				qnamebuf, sizeof(qnamebuf));
+			dns_name_format(client->query.qname, qnamebuf,
+					sizeof(qnamebuf));
 			dns_name_format(p_name, p_namebuf, sizeof(p_namebuf));
 			ns_client_log(client, DNS_LOGCATEGORY_RPZ,
 				      NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
@@ -2469,8 +2464,7 @@ stale_refresh_aftermath(ns_client_t *client, isc_result_t result) {
 	case DNS_R_DNAME:
 		break;
 	default:
-		dns_name_format(dns_linkedname_name(client->query.qname),
-				namebuf, sizeof(namebuf));
+		dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
 		dns_rdatatype_format(client->query.qtype, typebuf,
 				     sizeof(typebuf));
 		ns_client_log(client, NS_LOGCATEGORY_SERVE_STALE,
@@ -3930,8 +3924,7 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
 			 * Check IPv4 addresses in A RRs next.
 			 * Reset to the start of the NS names.
 			 */
-			st->r.label = dns_name_countlabels(
-				dns_linkedname_name(client->query.qname));
+			st->r.label = dns_name_countlabels(client->query.qname);
 			st->state &= ~(DNS_RPZ_DONE_QNAME_IP |
 				       DNS_RPZ_DONE_IPv4);
 		}
@@ -3994,17 +3987,14 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
 	}

 	dns_fixedname_init(&nsnamef);
-	dns_name_clone(dns_linkedname_name(client->query.qname),
-		       dns_fixedname_name(&nsnamef));
+	dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
 	options = client->query.dboptions | DNS_DBFIND_GLUEOK;
 	while (st->r.label > st->popt.min_ns_labels) {
 		bool was_glue = false;
 		/*
 		 * Get NS rrset for each domain in the current qname.
 		 */
-		if (st->r.label == dns_name_countlabels(dns_linkedname_name(
-					   client->query.qname)))
-		{
+		if (st->r.label == dns_name_countlabels(client->query.qname)) {
 			nsname = dns_linkedname_name(client->query.qname);
 		} else {
 			nsname = dns_fixedname_name(&nsnamef);
@@ -4622,7 +4612,7 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
 	}

 	redirectname = dns_fixedname_initname(&fixedredirect);
-	labels = dns_name_countlabels(dns_linkedname_name(client->query.qname));
+	labels = dns_name_countlabels(client->query.qname);
 	if (labels > 1U) {
 		dns_name_t prefix;

@@ -4937,9 +4927,8 @@ query_trace(query_ctx_t *qctx) {
 	char qabuf[sizeof(qctx->client->query.attrs) * 2 + 1] = { 0 };

 	if (qctx->client->query.origqname != NULL) {
-		dns_name_format(
-			dns_linkedname_name(qctx->client->query.origqname),
-			qbuf, sizeof(qbuf));
+		dns_name_format(qctx->client->query.origqname, qbuf,
+				sizeof(qbuf));
 	} else {
 		snprintf(qbuf, sizeof(qbuf), "<unset>");
 	}
@@ -5088,7 +5077,7 @@ qctx_reportquery(query_ctx_t *qctx) {

 	/* If this isn't an error-report query, there's nothing more to do */
 	if (client->query.qtype != dns_rdatatype_txt ||
-	    !dns_name_israd(dns_linkedname_name(client->query.qname),
+	    !dns_name_israd(client->query.qname,
 			    dns_zone_getorigin(qctx->zone)))
 	{
 		return;
@@ -5110,8 +5099,7 @@ qctx_reportquery(query_ctx_t *qctx) {
 		char classbuf[DNS_RDATACLASS_FORMATSIZE];
 		char namebuf[DNS_NAME_FORMATSIZE];

-		dns_name_format(dns_linkedname_name(client->query.qname),
-				namebuf, sizeof(namebuf));
+		dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
 		dns_rdataclass_format(client->inner.view->rdclass, classbuf,
 				      sizeof(classbuf));

@@ -5203,8 +5191,8 @@ ns__query_start(query_ctx_t *qctx) {
 		char typebuf[DNS_RDATATYPE_FORMATSIZE];
 		char classbuf[DNS_RDATACLASS_FORMATSIZE];

-		dns_name_format(dns_linkedname_name(qctx->client->query.qname),
-				namebuf, sizeof(namebuf));
+		dns_name_format(qctx->client->query.qname, namebuf,
+				sizeof(namebuf));
 		dns_rdatatype_format(qctx->qtype, typebuf, sizeof(typebuf));
 		dns_rdataclass_format(qctx->client->message->rdclass, classbuf,
 				      sizeof(classbuf));
@@ -5644,7 +5632,7 @@ query_lookup(query_ctx_t *qctx) {
 	 * node resolution, such as ANY/RRSIG iteration.
 	 */
 	if (qctx->dns64 && qctx->rpz) {
-		dns_name_copy(dns_linkedname_name(qctx->client->query.qname),
+		dns_name_copy(qctx->client->query.qname,
 			      dns_linkedname_name(qctx->fname));
 		dns_linkedname_name(qctx->fname)->attributes.wildcard = false;
 		dns_rdataset_cleanup(qctx->sigrdataset);
@@ -5697,8 +5685,8 @@ query_lookup(query_ctx_t *qctx) {
 	}

 	if (dbfind_stale || stale_refresh_window || stale_timeout) {
-		dns_name_format(dns_linkedname_name(qctx->client->query.qname),
-				namebuf, sizeof(namebuf));
+		dns_name_format(qctx->client->query.qname, namebuf,
+				sizeof(namebuf));
 		dns_rdatatype_format(qctx->qtype, typebuf, sizeof(typebuf));

 		inc_stats(qctx->client, ns_statscounter_trystale);
@@ -6498,9 +6486,8 @@ ns__query_sfcache(query_ctx_t *qctx) {
 			char namebuf[DNS_NAME_FORMATSIZE];
 			char typebuf[DNS_RDATATYPE_FORMATSIZE];

-			dns_name_format(
-				dns_linkedname_name(qctx->client->query.qname),
-				namebuf, sizeof(namebuf));
+			dns_name_format(qctx->client->query.qname, namebuf,
+					sizeof(namebuf));
 			dns_rdatatype_format(qctx->qtype, typebuf,
 					     sizeof(typebuf));
 			ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
@@ -6535,10 +6522,8 @@ query_trace_rrldrop(query_ctx_t *qctx,

 	char qnamebuf[DNS_NAME_FORMATSIZE];
 	char fnamebuf[DNS_NAME_FORMATSIZE];
-	dns_name_format(dns_linkedname_name(qctx->client->query.qname),
-			qnamebuf, sizeof(qnamebuf));
-	dns_name_format(dns_linkedname_name(qctx->fname), fnamebuf,
-			sizeof(fnamebuf));
+	dns_name_format(qctx->client->query.qname, qnamebuf, sizeof(qnamebuf));
+	dns_name_format(qctx->fname, fnamebuf, sizeof(fnamebuf));
 	LIBNS_RRL_DROP(peerbuf, qnamebuf, fnamebuf, rrl_result);
 }

@@ -6571,9 +6556,7 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
 		"query.rpz_st=%p(%u), RRL_CHECKED=%u",
 		qctx->client->inner.view->rrl, qctx->client->inner.havecookie,
 		isc_result_toid(result), qctx->fname,
-		qctx->fname != NULL
-			? dns_name_isabsolute(dns_linkedname_name(qctx->fname))
-			: 0,
+		qctx->fname != NULL ? dns_name_isabsolute(qctx->fname) : 0,
 		qctx->is_zone, qctx->client->query.recursionok,
 		qctx->client->query.rpz_st,
 		qctx->client->query.rpz_st != NULL
@@ -6583,8 +6566,7 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
 		qctx->client->query.rrl_checked);

 	if (qctx->view->rrl != NULL && !qctx->client->inner.havecookie &&
-	    ((qctx->fname != NULL &&
-	      dns_name_isabsolute(dns_linkedname_name(qctx->fname))) ||
+	    ((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) ||
 	     (result == ISC_R_NOTFOUND && !qctx->client->query.recursionok)) &&
 	    !(result == ISC_R_NOTFOUND && !qctx->is_zone &&
 	      qctx->client->query.recursionok) &&
@@ -6766,8 +6748,7 @@ query_checkrpz(query_ctx_t *qctx, isc_result_t result) {
 		qctx->rpz_st->q.db = MOVE_OWNERSHIP(qctx->db);
 		qctx->rpz_st->q.rdataset = MOVE_OWNERSHIP(qctx->rdataset);
 		qctx->rpz_st->q.sigrdataset = MOVE_OWNERSHIP(qctx->sigrdataset);
-		dns_name_copy(dns_linkedname_name(qctx->fname),
-			      qctx->rpz_st->fname);
+		dns_name_copy(qctx->fname, qctx->rpz_st->fname);
 		qctx->rpz_st->q.result = result;
 		fixedname_move(&qctx->foundname, &qctx->rpz_st->q.foundname);
 		qctx->client->query.recursing = true;
@@ -6793,7 +6774,7 @@ query_checkrpz(query_ctx_t *qctx, isc_result_t result) {
 		 * we looked up even if we were stopped short
 		 * in recursion or for a deferral.
 		 */
-		dns_name_copy(dns_linkedname_name(qctx->client->query.qname),
+		dns_name_copy(qctx->client->query.qname,
 			      dns_linkedname_name(qctx->fname));
 		rpz_clean(&qctx->zone, &qctx->db, NULL);
 		dns_fixedname_init(&qctx->foundname);
@@ -7565,9 +7546,8 @@ query_respond_any(query_ctx_t *qctx) {
 		    dns_db_issecure(qctx->db))
 		{
 			char namebuf[DNS_NAME_FORMATSIZE];
-			dns_name_format(
-				dns_linkedname_name(qctx->client->query.qname),
-				namebuf, sizeof(namebuf));
+			dns_name_format(qctx->client->query.qname, namebuf,
+					sizeof(namebuf));
 			ns_client_log(qctx->client, DNS_LOGCATEGORY_DNSSEC,
 				      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
 				      "missing signature for %s", namebuf);
@@ -7828,9 +7808,8 @@ query_respond(query_ctx_t *qctx) {
 		 * We've already got an NS, no need to add one in
 		 * the authority section
 		 */
-		if (dns_name_equal(
-			    dns_linkedname_name(qctx->client->query.qname),
-			    dns_db_origin(qctx->db)))
+		if (dns_name_equal(qctx->client->query.qname,
+				   dns_db_origin(qctx->db)))
 		{
 			qctx->answer_has_ns = true;
 		}
@@ -8178,8 +8157,7 @@ query_prepare_delegation_response(query_ctx_t *qctx) {
 	 * it here in case we need it.
 	 */
 	dns_fixedname_init(&qctx->dsname);
-	dns_name_copy(dns_linkedname_name(qctx->fname),
-		      dns_fixedname_name(&qctx->dsname));
+	dns_name_copy(qctx->fname, dns_fixedname_name(&qctx->dsname));

 	/*
 	 * This is the best answer.
@@ -8382,7 +8360,7 @@ use_zone_delegation(query_ctx_t *qctx) {
 	 * Nothing found in the cache, `qctx->fname` remains in
 	 * its initial state.
 	 */
-	if (!dns_name_isabsolute(dns_linkedname_name(qctx->fname))) {
+	if (!dns_name_isabsolute(qctx->fname)) {
 		return true;
 	}

@@ -8390,9 +8368,7 @@ use_zone_delegation(query_ctx_t *qctx) {
 	 * We've already got a delegation from authoritative data, and it is
 	 *    better than what we found in the cache.
 	 */
-	if (dns_name_issubdomain(dns_linkedname_name(qctx->fname),
-				 dns_linkedname_name(qctx->zfname)))
-	{
+	if (dns_name_issubdomain(qctx->fname, qctx->zfname)) {
 		return true;
 	}

@@ -8403,8 +8379,7 @@ use_zone_delegation(query_ctx_t *qctx) {
 	 * nameservers configured in the static-stub zone.
 	 */
 	return qctx->is_staticstub_zone &&
-	       dns_name_equal(dns_linkedname_name(qctx->fname),
-			      dns_linkedname_name(qctx->zfname));
+	       dns_name_equal(qctx->fname, qctx->zfname);
 }

 /*%
@@ -8653,7 +8628,7 @@ query_nodata(query_ctx_t *qctx, isc_result_t res) {
 			qctx->fname = ns_client_newname(qctx->client,
 							qctx->dbuf, &b);
 		}
-		dns_name_copy(dns_linkedname_name(qctx->client->query.qname),
+		dns_name_copy(qctx->client->query.qname,
 			      dns_linkedname_name(qctx->fname));
 		qctx->dns64 = false;
 #ifdef dns64_bis_return_excluded_addresses
@@ -8892,7 +8867,7 @@ query_addnxrrsetnsec(query_ctx_t *qctx) {
 	result = dns_rdata_tostruct(&sigrdata, &sig);
 	RUNTIME_CHECK(result == ISC_R_SUCCESS);

-	labels = dns_name_countlabels(dns_linkedname_name(qctx->fname));
+	labels = dns_name_countlabels(qctx->fname);
 	if ((unsigned int)sig.labels + 1 >= labels) {
 		return;
 	}
@@ -9071,8 +9046,7 @@ query_redirect(query_ctx_t *qctx, isc_result_t saved_result) {
 		qctx->client->query.redirect.sigrdataset =
 			MOVE_OWNERSHIP(qctx->sigrdataset);
 		qctx->client->query.redirect.result = saved_result;
-		dns_name_copy(dns_linkedname_name(qctx->fname),
-			      qctx->client->query.redirect.fname);
+		dns_name_copy(qctx->fname, qctx->client->query.redirect.fname);
 		fixedname_move(&qctx->foundname,
 			       &qctx->client->query.redirect.foundname);
 		qctx->client->query.redirect.authoritative =
@@ -9225,8 +9199,7 @@ query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,

 	dbuf = ns_client_getnamebuf(qctx->client);
 	name = ns_client_newname(qctx->client, dbuf, &b);
-	dns_name_copy(dns_linkedname_name(qctx->client->query.qname),
-		      dns_linkedname_name(name));
+	dns_name_copy(qctx->client->query.qname, dns_linkedname_name(name));

 	cloneset = ns_client_newrdataset(qctx->client);
 	dns_rdataset_clone(rdataset, cloneset);
@@ -9301,9 +9274,7 @@ query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
 	dns_rdata_reset(&rdata);

-	if (dns_name_equal(dns_linkedname_name(qctx->client->query.qname),
-			   &cname.cname))
-	{
+	if (dns_name_equal(qctx->client->query.qname, &cname.cname)) {
 		dns_message_puttempname(qctx->client->message, &tname);
 		return ISC_R_SUCCESS;
 	}
@@ -9428,11 +9399,8 @@ checksignames(dns_name_t *signer, dns_rdataset_t *sigrdataset) {
 		RUNTIME_CHECK(result == ISC_R_SUCCESS);

 		if (dns_name_empty(signer)) {
-			dns_name_copy(dns_linkedname_name(&rrsig.signer),
-				      signer);
-		} else if (!dns_name_equal(signer,
-					   dns_linkedname_name(&rrsig.signer)))
-		{
+			dns_name_copy(&rrsig.signer, signer);
+		} else if (!dns_name_equal(signer, &rrsig.signer)) {
 			return ISC_R_FAILURE;
 		}
 	}
@@ -9494,14 +9462,13 @@ query_coveringnsec(query_ctx_t *qctx) {
 	 * For records that belong to the parent zone (i.e. DS),
 	 * remove a label to find the correct namespace.
 	 */
-	dns_name_clone(dns_linkedname_name(qctx->client->query.qname), &qname);
+	dns_name_clone(qctx->client->query.qname, &qname);
 	labels = dns_name_countlabels(&qname);
 	if (dns_rdatatype_atparent(qctx->qtype) && labels > 1) {
 		dns_name_getlabelsequence(&qname, 1, labels - 1, &qname);
 	}
 	dns_view_sfd_find(qctx->view, &qname, namespace);
-	if (!dns_name_issubdomain(dns_linkedname_name(qctx->fname), namespace))
-	{
+	if (!dns_name_issubdomain(qctx->fname, namespace)) {
 		goto cleanup;
 	}

@@ -9971,9 +9938,8 @@ query_dname(query_ctx_t *qctx) {
 	 * to know how many labels and bits are in common because
 	 * we're going to have to split qname later on.
 	 */
-	namereln = dns_name_fullcompare(
-		dns_linkedname_name(qctx->client->query.qname),
-		dns_linkedname_name(qctx->fname), &order, &nlabels);
+	namereln = dns_name_fullcompare(qctx->client->query.qname, qctx->fname,
+					&order, &nlabels);

 	/*
 	 * Handling DNAME response is valid as soon as the qname is a subname of
@@ -10153,8 +10119,7 @@ query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) {

 	dns_message_gettempname(client->message, &aname);

-	dns_name_copy(dns_linkedname_name(client->query.qname),
-		      dns_linkedname_name(aname));
+	dns_name_copy(client->query.qname, dns_linkedname_name(aname));

 	dns_message_gettemprdatalist(client->message, &rdatalist);

@@ -10166,7 +10131,7 @@ query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) {
 	rdatalist->rdclass = client->message->rdclass;
 	rdatalist->ttl = ttl;

-	dns_name_toregion(dns_linkedname_name(qctx->fname), &r);
+	dns_name_toregion(qctx->fname, &r);
 	rdata->data = r.base;
 	rdata->length = r.length;
 	rdata->rdclass = client->message->rdclass;
@@ -10199,7 +10164,6 @@ query_prepresponse(query_ctx_t *qctx) {
 	CCTRACE(ISC_LOG_DEBUG(3), "query_prepresponse");

 	CALL_HOOK(NS_QUERY_PREP_RESPONSE_BEGIN, qctx);
-
 	if (qctx->type == dns_rdatatype_any) {
 		return query_respond_any(qctx);
 	}
@@ -10462,7 +10426,7 @@ query_addbestns(query_ctx_t *qctx) {
 	dns_clientinfo_init(&ci, client, NULL);

 	dns_name_init(&qname);
-	dns_name_clone(dns_linkedname_name(client->query.qname), &qname);
+	dns_name_clone(client->query.qname, &qname);

 	/*
 	 * Find the right database.
@@ -10718,8 +10682,7 @@ again:
 		 * minlabels: suffix length of non NXDOMAIN result
 		 */
 		unsigned int maxlabels = dns_name_countlabels(name);
-		unsigned int minlabels =
-			dns_name_countlabels(dns_linkedname_name(fname));
+		unsigned int minlabels = dns_name_countlabels(fname);
 		unsigned int namelabels = maxlabels;
 		bool search = result == DNS_R_NXDOMAIN;
 		dns_name_copy(name, cname);
@@ -10848,9 +10811,8 @@ again:
 			dns_rdataset_current(rdataset, &rdata);
 			result = dns_rdata_tostruct(&rdata, &nsec);
 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
-			(void)dns_name_fullcompare(name,
-						   dns_linkedname_name(fname),
-						   &order, &olabels);
+			(void)dns_name_fullcompare(name, fname, &order,
+						   &olabels);
 			(void)dns_name_fullcompare(name, &nsec.next, &order,
 						   &nlabels);
 			/*
@@ -10962,10 +10924,7 @@ query_glueanswer(query_ctx_t *qctx) {

 	msg = qctx->client->message;
 	MSG_SECTION_FOREACH(msg, section, name) {
-		if (dns_name_equal(
-			    dns_linkedname_name(name),
-			    dns_linkedname_name(qctx->client->query.qname)))
-		{
+		if (dns_name_equal(name, qctx->client->query.qname)) {
 			ISC_LIST_FOREACH(name->list, rdataset, link) {
 				if (rdataset->type == qctx->qtype) {
 					ISC_LIST_UNLINK(msg->sections[section],
@@ -11154,7 +11113,7 @@ log_tat(ns_client_t *client) {
 	}

 	if ((client->query.qtype != dns_rdatatype_null ||
-	     !dns_name_istat(dns_linkedname_name(client->query.qname))) &&
+	     !dns_name_istat(client->query.qname)) &&
 	    (client->inner.keytag == NULL ||
 	     client->query.qtype != dns_rdatatype_dnskey))
 	{
@@ -11162,8 +11121,7 @@ log_tat(ns_client_t *client) {
 	}

 	isc_netaddr_fromsockaddr(&netaddr, &client->inner.peeraddr);
-	dns_name_format(dns_linkedname_name(client->query.qname), namebuf,
-			sizeof(namebuf));
+	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
 	isc_netaddr_format(&netaddr, clientbuf, sizeof(clientbuf));
 	dns_rdataclass_format(client->inner.view->rdclass, classbuf,
 			      sizeof(classbuf));
@@ -11218,8 +11176,7 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {

 	rdataset = ISC_LIST_HEAD(client->query.qname->list);
 	INSIST(rdataset != NULL);
-	dns_name_format(dns_linkedname_name(client->query.qname), namebuf,
-			sizeof(namebuf));
+	dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
 	dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf));
 	dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf));
 	isc_sockaddr_format(&client->inner.destsockaddr, sabuf, sizeof(sabuf));
@@ -11255,8 +11212,8 @@ log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
 	 * expect exceptional cases.
 	 */
 	if (client->query.origqname != NULL) {
-		dns_name_format(dns_linkedname_name(client->query.origqname),
-				namebuf, sizeof(namebuf));
+		dns_name_format(client->query.origqname, namebuf,
+				sizeof(namebuf));
 		namep = namebuf;
 		sep1 = " for ";

diff --git a/lib/ns/xfrout.c b/lib/ns/xfrout.c
index b7373fe5f0..5afd3de47c 100644
--- a/lib/ns/xfrout.c
+++ b/lib/ns/xfrout.c
@@ -90,8 +90,7 @@
 		char _buf1[DNS_NAME_FORMATSIZE];                             \
 		char _buf2[DNS_RDATACLASS_FORMATSIZE];                       \
 		result = (code);                                             \
-		dns_name_format(dns_linkedname_name(question), _buf1,        \
-				sizeof(_buf1));                              \
+		dns_name_format(question, _buf1, sizeof(_buf1));             \
 		dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2));        \
 		ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,              \
 			      NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO,           \
@@ -802,9 +801,8 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
 				char _buf2[DNS_RDATACLASS_FORMATSIZE];

 				result = DNS_R_REFUSED;
-				dns_name_format(
-					dns_linkedname_name(question_name),
-					_buf1, sizeof(_buf1));
+				dns_name_format(question_name, _buf1,
+						sizeof(_buf1));
 				dns_rdataclass_format(question_class, _buf2,
 						      sizeof(_buf2));
 				ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
@@ -857,9 +855,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
 		/*
 		 * Ignore data whose owner name is not the zone apex.
 		 */
-		if (!dns_name_equal(dns_linkedname_name(soa_name),
-				    dns_linkedname_name(question_name)))
-		{
+		if (!dns_name_equal(soa_name, question_name)) {
 			continue;
 		}

diff --git a/tests/bench/load-names.c b/tests/bench/load-names.c
index 79296cfeaf..a6b6594150 100644
--- a/tests/bench/load-names.c
+++ b/tests/bench/load-names.c
@@ -120,14 +120,12 @@ lfht_match(struct cds_lfht_node *ht_node, const void *_key) {
 						  ht_node);
 	const dns_name_t *key = _key;

-	return dns_name_equal(key,
-			      dns_linkedname_name_const(&i->fixed.name_wl));
+	return dns_name_equal(key, &i->fixed.name_wl);
 }

 static isc_result_t
 add_lfht(void *lfht, size_t count) {
-	unsigned long hash =
-		dns_name_hash(dns_linkedname_name(&item[count].fixed.name_wl));
+	unsigned long hash = dns_name_hash(&item[count].fixed.name_wl);

 	struct cds_lfht_node *ht_node = cds_lfht_add_unique(
 		lfht, hash, lfht_match,
@@ -143,8 +141,7 @@ add_lfht(void *lfht, size_t count) {

 static isc_result_t
 get_lfht(void *lfht, size_t count, void **pval) {
-	unsigned long hash =
-		dns_name_hash(dns_linkedname_name(&item[count].fixed.name_wl));
+	unsigned long hash = dns_name_hash(&item[count].fixed.name_wl);

 	struct cds_lfht_iter iter;
 	cds_lfht_lookup(lfht, hash, lfht_match,
@@ -202,27 +199,23 @@ new_hashmap(isc_mem_t *mem) {
 static bool
 name_match(void *node, const void *key) {
 	const struct item_s *i = node;
-	return dns_name_equal(dns_linkedname_name_const(&i->fixed.name_wl),
-			      key);
+	return dns_name_equal(&i->fixed.name_wl, (const dns_name_t *)key);
 }

 static isc_result_t
 add_hashmap(void *hashmap, size_t count) {
 	isc_result_t result = isc_hashmap_add(
-		hashmap,
-		dns_name_hash(dns_linkedname_name(&item[count].fixed.name_wl)),
-		name_match, dns_linkedname_name(&item[count].fixed.name_wl),
-		&item[count], NULL);
+		hashmap, dns_name_hash(&item[count].fixed.name_wl), name_match,
+		dns_linkedname_name(&item[count].fixed.name_wl), &item[count],
+		NULL);
 	return result;
 }

 static isc_result_t
 get_hashmap(void *hashmap, size_t count, void **pval) {
 	isc_result_t result = isc_hashmap_find(
-		hashmap,
-		dns_name_hash(dns_linkedname_name(&item[count].fixed.name_wl)),
-		name_match, dns_linkedname_name(&item[count].fixed.name_wl),
-		pval);
+		hashmap, dns_name_hash(&item[count].fixed.name_wl), name_match,
+		dns_linkedname_name(&item[count].fixed.name_wl), pval);
 	return result;
 }