diff --git a/Knot.files b/Knot.files
index 01457e00ce720c3aadff295b06e7f88253fb6c56..26db34392affa84386145c9c2c491d4803c7e9ca 100644
--- a/Knot.files
+++ b/Knot.files
@@ -153,6 +153,7 @@ src/libknot/packet/query.c
 src/libknot/packet/query.h
 src/libknot/packet/response.c
 src/libknot/packet/response.h
+src/libknot/rdata.h
 src/libknot/rrset-dump.c
 src/libknot/rrset-dump.h
 src/libknot/rrset.c
diff --git a/src/knot/ctl/remote.c b/src/knot/ctl/remote.c
index 831899616d1b49498c18786ad00468400f7a00bd..5296a7b754ca1166388c585a2900b50c358172fd 100644
--- a/src/knot/ctl/remote.c
+++ b/src/knot/ctl/remote.c
@@ -30,6 +30,7 @@
 #include "libknot/packet/response.h"
 #include "libknot/nameserver/name-server.h"
 #include "libknot/tsig-op.h"
+#include "libknot/rdata.h"
 
 #define KNOT_CTL_REALM "knot."
 #define KNOT_CTL_REALM_EXT ("." KNOT_CTL_REALM)
@@ -100,7 +101,7 @@ static int remote_rdata_apply(server_t *s, remote_cmdargs_t* a, remote_zonef_t *
 		for (uint16_t i = 0; i < knot_rrset_rdata_rr_count(rr); i++) {
 			/* Refresh zones. */
 			const knot_dname_t *dn =
-				knot_rrset_rdata_ns_name(rr, i);
+				knot_rdata_ns_name(rr, i);
 			rcu_read_lock();
 			zone = knot_zonedb_find_zone(ns->zone_db, dn);
 			if (cb(s, zone) != KNOT_EOK) {
@@ -228,7 +229,7 @@ static int remote_c_zonestatus(server_t *s, remote_cmdargs_t* a)
 			soa_rrs = knot_node_rrset(knot_zone_contents_apex(contents),
 			                          KNOT_RRTYPE_SOA);
 			assert(soa_rrs != NULL);
-			serial = knot_rrset_rdata_soa_serial(soa_rrs);
+			serial = knot_rdata_soa_serial(soa_rrs);
 		}
 
 		/* Evalute zone type. */
diff --git a/src/knot/server/notify.c b/src/knot/server/notify.c
index 244aa6b91c103149984144ca882a674094c74c43..2f361b9f3c91951f4b70bf81b3e2b76a83086785 100644
--- a/src/knot/server/notify.c
+++ b/src/knot/server/notify.c
@@ -34,6 +34,7 @@
 #include "common/evsched.h"
 #include "knot/other/debug.h"
 #include "knot/server/server.h"
+#include "libknot/rdata.h"
 
 
 /* Messages. */
@@ -266,7 +267,7 @@ int notify_process_request(knot_nameserver_t *ns,
 		const knot_rrset_t *soa_rr = NULL;
 		soa_rr = knot_packet_answer_rrset(notify, 0);
 		if (soa_rr && knot_rrset_type(soa_rr) == KNOT_RRTYPE_SOA) {
-			serial = knot_rrset_rdata_soa_serial(soa_rr);
+			serial = knot_rdata_soa_serial(soa_rr);
 		}
 	}
 	rcu_read_unlock();
diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c
index 612cd520302214b0ba0243c21e44feef7696f9dd..0d9591a1aa9ba2d84ee3f1fbf5561783dbb31c0a 100644
--- a/src/knot/server/zones.c
+++ b/src/knot/server/zones.c
@@ -42,6 +42,7 @@
 #include "libknot/packet/response.h"
 #include "libknot/zone/zone-diff.h"
 #include "libknot/updates/ddns.h"
+#include "libknot/rdata.h"
 
 static const size_t XFRIN_CHANGESET_BINARY_SIZE = 100;
 static const size_t XFRIN_CHANGESET_BINARY_STEP = 100;
@@ -168,7 +169,7 @@ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone)
 		soa_rrs = knot_node_rrset(knot_zone_contents_apex(contents),
 					  KNOT_RRTYPE_SOA);
 		assert(soa_rrs != NULL);
-		int64_t serial = knot_rrset_rdata_soa_serial(soa_rrs);
+		int64_t serial = knot_rdata_soa_serial(soa_rrs);
 		zd->zonefile_serial = (uint32_t)serial;
 		if (serial < 0) {
 			return KNOT_EINVAL;
@@ -238,7 +239,7 @@ static uint32_t zones_soa_timer(knot_zone_t *zone,
  */
 static uint32_t zones_soa_refresh(knot_zone_t *zone)
 {
-	return zones_soa_timer(zone, knot_rrset_rdata_soa_refresh);
+	return zones_soa_timer(zone, knot_rdata_soa_refresh);
 }
 
 /*!
@@ -249,7 +250,7 @@ static uint32_t zones_soa_refresh(knot_zone_t *zone)
  */
 static uint32_t zones_soa_retry(knot_zone_t *zone)
 {
-	return zones_soa_timer(zone, knot_rrset_rdata_soa_retry);
+	return zones_soa_timer(zone, knot_rdata_soa_retry);
 }
 
 /*!
@@ -260,7 +261,7 @@ static uint32_t zones_soa_retry(knot_zone_t *zone)
  */
 static uint32_t zones_soa_expire(knot_zone_t *zone)
 {
-	return zones_soa_timer(zone, knot_rrset_rdata_soa_expire);
+	return zones_soa_timer(zone, knot_rdata_soa_expire);
 }
 
 /*!
@@ -710,7 +711,7 @@ int zones_changesets_from_binary(knot_changesets_t *chgsets)
 		             knot_rrset_type(rrset));
 		assert(knot_rrset_type(rrset) == KNOT_RRTYPE_SOA);
 		assert(chs->serial_from ==
-		       knot_rrset_rdata_soa_serial(rrset));
+		       knot_rdata_soa_serial(rrset));
 		knot_changeset_store_soa(&chs->soa_from, &chs->serial_from,
 					 rrset);
 
@@ -945,7 +946,7 @@ static int zones_journal_apply(knot_zone_t *zone)
 	soa_rrs = knot_node_rrset(knot_zone_contents_apex(contents),
 	                            KNOT_RRTYPE_SOA);
 	assert(soa_rrs != NULL);
-	int64_t serial_ret = knot_rrset_rdata_soa_serial(soa_rrs);
+	int64_t serial_ret = knot_rdata_soa_serial(soa_rrs);
 	if (serial_ret < 0) {
 		rcu_read_unlock();
 		return KNOT_EINVAL;
@@ -1095,7 +1096,7 @@ static int zones_insert_zone(conf_zone_t *z, knot_zone_t **dst,
 					KNOT_RRTYPE_SOA);
 				int64_t sn = 0;
 				if (apex && soa) {
-					sn = knot_rrset_rdata_soa_serial(soa);
+					sn = knot_rdata_soa_serial(soa);
 					if (sn < 0) sn = 0;
 				}
 				log_server_info("Loaded zone '%s' serial %u\n",
@@ -1909,7 +1910,7 @@ int zones_zonefile_sync(knot_zone_t *zone, journal_t *journal)
 	                            KNOT_RRTYPE_SOA);
 	assert(soa_rrs != NULL);
 
-	int64_t serial_ret = knot_rrset_rdata_soa_serial(soa_rrs);
+	int64_t serial_ret = knot_rdata_soa_serial(soa_rrs);
 	if (serial_ret < 0) {
 		rcu_read_unlock();
 		pthread_mutex_unlock(&zd->lock);
diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c
index 79ae711c60b8c6e4724566e4f5e8db28d7670d8c..59478e2eb618be623c25d8a4ab0ce4f321f049ba 100644
--- a/src/knot/zone/semantic-check.c
+++ b/src/knot/zone/semantic-check.c
@@ -30,6 +30,7 @@
 #include "common/crc.h"
 #include "common/descriptor.h"
 #include "common/mempattern.h"
+#include "libknot/rdata.h"
 
 #include "semantic-check.h"
 
@@ -295,7 +296,7 @@ static int check_rrsig_rdata(err_handler_t *handler,
 		return KNOT_EOK;
 	}
 
-	if (knot_rrset_rdata_rrsig_type_covered(rrsig) !=
+	if (knot_rdata_rrsig_type_covered(rrsig, 1) !=
 	    knot_rrset_type(rrset)) {
 		/* zoneparser would not let this happen
 		 * but to be on the safe side
@@ -306,7 +307,7 @@ static int check_rrsig_rdata(err_handler_t *handler,
 	}
 
 	/* label number at the 2nd index should be same as owner's */
-	uint8_t labels_rdata = knot_rrset_rdata_rrsig_labels(rrsig, rr_pos);
+	uint8_t labels_rdata = knot_rdata_rrsig_labels(rrsig, rr_pos);
 
 	int tmp = knot_dname_labels(knot_rrset_owner(rrset), NULL) - labels_rdata;
 
@@ -327,7 +328,7 @@ static int check_rrsig_rdata(err_handler_t *handler,
 
 	/* check original TTL */
 	uint32_t original_ttl =
-		knot_rrset_rdata_rrsig_original_ttl(rrsig, rr_pos);
+		knot_rdata_rrsig_original_ttl(rrsig, rr_pos);
 
 	if (original_ttl != knot_rrset_ttl(rrset)) {
 		err_handler_handle_error(handler, node, ZC_ERR_RRSIG_RDATA_TTL,
@@ -336,7 +337,7 @@ static int check_rrsig_rdata(err_handler_t *handler,
 
 	/* signer's name is same as in the zone apex */
 	const knot_dname_t *signer_name =
-		knot_rrset_rdata_rrsig_signer_name(rrsig, rr_pos);
+		knot_rdata_rrsig_signer_name(rrsig, rr_pos);
 
 	/* dnskey is in the apex node */
 	if (knot_dname_cmp(signer_name,
@@ -351,12 +352,12 @@ static int check_rrsig_rdata(err_handler_t *handler,
 	 * before */
 	
 	int match = 0;
-	uint8_t rrsig_alg = knot_rrset_rdata_rrsig_algorithm(rrsig, rr_pos);
-	uint16_t key_tag_rrsig = knot_rrset_rdata_rrsig_key_tag(rrsig, rr_pos);
+	uint8_t rrsig_alg = knot_rdata_rrsig_algorithm(rrsig, rr_pos);
+	uint16_t key_tag_rrsig = knot_rdata_rrsig_key_tag(rrsig, rr_pos);
 	for (uint16_t i = 0; i < knot_rrset_rdata_rr_count(dnskey_rrset) &&
 	     !match; ++i) {
 		uint8_t dnskey_alg =
-			knot_rrset_rdata_dnskey_alg(dnskey_rrset, i);
+			knot_rdata_dnskey_alg(dnskey_rrset, i);
 		if (rrsig_alg != dnskey_alg) {
 			continue;
 		}
@@ -526,9 +527,9 @@ static int rdata_nsec_to_type_array(const knot_rrset_t *rrset, size_t pos,
 	uint8_t *data = NULL;
 	uint16_t rr_bitmap_size = 0;
 	if (rrset->type == KNOT_RRTYPE_NSEC) {
-		knot_rrset_rdata_nsec_bitmap(rrset, pos, &data, &rr_bitmap_size);
+		knot_rdata_nsec_bitmap(rrset, pos, &data, &rr_bitmap_size);
 	} else {
-		knot_rrset_rdata_nsec3_bitmap(rrset, pos, &data, &rr_bitmap_size);
+		knot_rdata_nsec3_bitmap(rrset, pos, &data, &rr_bitmap_size);
 	}
 	if (data == NULL) {
 		return KNOT_EMALF;
@@ -636,7 +637,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
 
 			/* check for Opt-Out flag */
 			uint8_t flags =
-				knot_rrset_rdata_nsec3_flags(previous_rrset, 0);
+				knot_rdata_nsec3_flags(previous_rrset, 0);
 			uint8_t opt_out_mask = 1;
 
 			if (!(flags & opt_out_mask)) {
@@ -658,7 +659,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
 		knot_node_rrset(knot_zone_contents_apex(zone),
 	                        KNOT_RRTYPE_SOA);
 	assert(soa_rrset);
-	uint32_t minimum_ttl = knot_rrset_rdata_soa_minimum(soa_rrset);
+	uint32_t minimum_ttl = knot_rdata_soa_minimum(soa_rrset);
 
 	if (knot_rrset_ttl(nsec3_rrset) != minimum_ttl) {
 			err_handler_handle_error(handler, node,
@@ -669,7 +670,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
 	uint8_t *next_dname_str = NULL;
 	uint8_t next_dname_size = 0;
 	uint8_t *next_dname_decoded = NULL;
-	knot_rrset_rdata_nsec3_next_hashed(nsec3_rrset, 0, &next_dname_str,
+	knot_rdata_nsec3_next_hashed(nsec3_rrset, 0, &next_dname_str,
 	                                   &next_dname_size);
 	size_t real_size =
 		base32hex_encode_alloc(next_dname_str,
@@ -880,7 +881,7 @@ static int sem_check_node_optional(knot_zone_contents_t *zone,
 
 		/* TODO How about multiple RRs? */
 		knot_dname_t *ns_dname =
-			knot_dname_copy(knot_rrset_rdata_ns_name(ns_rrset,
+			knot_dname_copy(knot_rdata_ns_name(ns_rrset,
 		                             0));
 		if (ns_dname == NULL) {
 			return KNOT_ENOMEM;
@@ -1076,7 +1077,7 @@ static int semantic_checks_dnssec(knot_zone_contents_t *zone,
 
 			if (nsec_rrset != NULL) {
 				const knot_dname_t *next_domain =
-					knot_rrset_rdata_nsec_next(nsec_rrset, 0);
+					knot_rdata_nsec_next(nsec_rrset, 0);
 				assert(next_domain);
 
 				if (knot_zone_contents_find_node(zone,
@@ -1219,7 +1220,7 @@ void log_cyclic_errors_in_zone(err_handler_t *handler,
 		uint8_t *next_dname_str = NULL;
 		uint8_t next_dname_size = 0;
 		uint8_t *next_dname_decoded = NULL;
-		knot_rrset_rdata_nsec3_next_hashed(nsec3_rrset, 0, &next_dname_str,
+		knot_rdata_nsec3_next_hashed(nsec3_rrset, 0, &next_dname_str,
 		                                   &next_dname_size);
 		size_t real_size =
 			base32hex_encode_alloc(next_dname_str,
@@ -1287,7 +1288,7 @@ void log_cyclic_errors_in_zone(err_handler_t *handler,
 			}
 
 			const knot_dname_t *next_dname =
-				knot_rrset_rdata_nsec_next(nsec_rrset, 0);
+				knot_rdata_nsec_next(nsec_rrset, 0);
 			assert(next_dname);
 
 			const knot_dname_t *apex_dname =
diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c
index 045e820c6afbd11861952120ba276a2ec73633b8..86ccf058f8d7cfd1e0547aa67a01d3372fcc4e5e 100644
--- a/src/knot/zone/zone-load.c
+++ b/src/knot/zone/zone-load.c
@@ -34,6 +34,7 @@
 #include "knot/other/debug.h"
 #include "knot/zone/zone-load.h"
 #include "zscanner/file_loader.h"
+#include "libknot/rdata.h"
 
 /* ZONE LOADING FROM FILE USING RAGEL PARSER */
 
@@ -94,16 +95,16 @@ static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone,
 
 	knot_rrset_t *tmp_rrset =
 		knot_node_get_rrset(node,
-	                            knot_rrset_rdata_rrsig_type_covered(rrsig));
+	                            knot_rdata_rrsig_type_covered(rrsig, 1));
 
 	int ret;
 
 	if (tmp_rrset == NULL) {
 		dbg_zp("zp: find_rr_for_sig_in_node: Node does not contain "
 		       "RRSet of type %d.\n",
-		       knot_rrset_rdata_rrsig_type_covered(rrsig));
+		       knot_rdata_rrsig_type_covered(rrsig, 1));
 		tmp_rrset = knot_rrset_new(knot_dname_copy(rrsig->owner),
-		                           knot_rrset_rdata_rrsig_type_covered(rrsig),
+		                           knot_rdata_rrsig_type_covered(rrsig, 1),
 		                           rrsig->rclass,
 		                           rrsig->ttl);
 		if (tmp_rrset == NULL) {
@@ -130,7 +131,7 @@ static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone,
 		log_zone_warning("RRSIG owned by: %s (covering type %d) cannot be added to "
 		                 "its RRSet, because their TTLs differ. "
 		                 "Changing TTL=%d to value=%d.\n",
-		                 name, knot_rrset_rdata_rrsig_type_covered(rrsig),
+		                 name, knot_rdata_rrsig_type_covered(rrsig, 1),
 		                 rrsig->ttl, tmp_rrset->ttl);
 		free(name);
 	}
@@ -349,7 +350,7 @@ static void process_rr(const scanner_t *scanner)
 	uint16_t type_covered = 0;
 	if (current_rrset->type == KNOT_RRTYPE_RRSIG) {
 		type_covered =
-			knot_rrset_rdata_rrsig_type_covered(current_rrset);
+			knot_rdata_rrsig_type_covered(current_rrset, 1);
 	}
 
 	if (current_rrset->type != KNOT_RRTYPE_NSEC3 &&
diff --git a/src/libknot/libknot.h b/src/libknot/libknot.h
index c6a8c152f5eb1736baa7313008dbffe058546e11..89045975cae6ba22274bd8fd1ab8ff15acb2e422 100644
--- a/src/libknot/libknot.h
+++ b/src/libknot/libknot.h
@@ -46,6 +46,7 @@
 #include "zone/node.h"
 #include "zone/zone.h"
 #include "zone/zonedb.h"
+#include "rdata.h"
 
 #endif
 
diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index ee8dffc66e04237b8c7ce47feaa09db800e6668b..c01a0664393cce67710cfd96721a618263b73128 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -37,6 +37,7 @@
 #include "updates/changesets.h"
 #include "updates/ddns.h"
 #include "tsig-op.h"
+#include "libknot/rdata.h"
 
 /*----------------------------------------------------------------------------*/
 
@@ -425,7 +426,7 @@ dbg_ns_exec_verb(
 
 		// get the name from the CNAME RDATA
 		const knot_dname_t *cname =
-			knot_rrset_rdata_cname_name(cname_rrset);
+			knot_rdata_cname_name(cname_rrset);
 		dbg_ns_detail("CNAME name from RDATA: %p\n", cname);
 
 		/* Attempt to find mentioned name in zone. */
@@ -651,7 +652,7 @@ static int ns_put_additional_for_rrset(knot_packet_t *resp,
 	for (uint16_t i = 0; i < knot_rrset_rdata_rr_count(rrset); i++) {
 		dbg_ns_verb("Getting name from RDATA, type %u..\n",
 		            knot_rrset_type(rrset));
-		const knot_dname_t *dname = knot_rrset_rdata_name(rrset, i);
+		const knot_dname_t *dname = knot_rdata_name(rrset, i);
 		assert(dname);
 dbg_ns_exec_detail(
 		char *name = knot_dname_to_str(dname);
@@ -886,7 +887,7 @@ static int ns_put_authority_soa(const knot_zone_contents_t *zone,
 
 	// if SOA's TTL is larger than MINIMUM, copy the RRSet and set
 	// MINIMUM as TTL
-	uint32_t min = knot_rrset_rdata_soa_minimum(soa_rrset);
+	uint32_t min = knot_rdata_soa_minimum(soa_rrset);
 	if (min < knot_rrset_ttl(soa_rrset)) {
 		knot_rrset_t *soa_copy = NULL;
 		ret = knot_rrset_deep_copy(soa_rrset, &soa_copy);
@@ -1963,7 +1964,7 @@ static knot_rrset_t *ns_cname_from_dname(const knot_rrset_t *dname_rrset,
 	/* Replace last labels of qname with DNAME. */
 	const knot_dname_t *dname_wire = knot_rrset_owner(dname_rrset);
 	size_t labels = knot_dname_labels(dname_wire, NULL);
-	const knot_dname_t *dname_tgt = knot_rrset_rdata_dname_target(dname_rrset);
+	const knot_dname_t *dname_tgt = knot_rdata_dname_target(dname_rrset);
 	knot_dname_t *cname = knot_dname_replace_suffix(qname, labels, dname_tgt);
 	if (cname == NULL) {
 		knot_rrset_free(&cname_rrset);
@@ -2005,7 +2006,7 @@ static int ns_dname_is_too_long(const knot_rrset_t *rrset,
 	// TODO: add function for getting DNAME target
 	if (knot_dname_labels(qname, NULL)
 	        - knot_dname_labels(knot_rrset_owner(rrset), NULL)
-	        + knot_dname_labels(knot_rrset_rdata_dname_target(rrset), NULL)
+	        + knot_dname_labels(knot_rdata_dname_target(rrset), NULL)
 	        > KNOT_DNAME_MAXLEN) {
 		return 1;
 	} else {
@@ -2071,7 +2072,7 @@ dbg_ns_exec_verb(
 	}
 
 	// get the next SNAME from the CNAME RDATA
-	const knot_dname_t *cname = knot_rrset_rdata_cname_name(synth_cname);
+	const knot_dname_t *cname = knot_rdata_cname_name(synth_cname);
 	dbg_ns_verb("CNAME name from RDATA: %p\n", cname);
 
 	// save the new name which should be used for replacing wildcard
@@ -2932,8 +2933,8 @@ static int ns_ixfr_from_zone(knot_ns_xfr_t *xfr)
 		} else {
 			log_zone_info("%s Serial %u -> %u.\n",
 			              xfr->msg,
-			              knot_rrset_rdata_soa_serial(chs->soa_from),
-			              knot_rrset_rdata_soa_serial(chs->soa_to));
+			              knot_rdata_soa_serial(chs->soa_from),
+			              knot_rdata_soa_serial(chs->soa_to));
 		}
 	}
 
@@ -3904,9 +3905,9 @@ int ns_ixfr_load_serials(const knot_ns_xfr_t *xfr, uint32_t *serial_from,
 	}
 
 	// retrieve origin (xfr) serial and target (zone) serial
-	*serial_to = knot_rrset_rdata_soa_serial(zone_soa);
+	*serial_to = knot_rdata_soa_serial(zone_soa);
 	*serial_from =
-		knot_rrset_rdata_soa_serial(knot_packet_authority_rrset(xfr->query, 0));
+		knot_rdata_soa_serial(knot_packet_authority_rrset(xfr->query, 0));
 
 	return KNOT_EOK;
 }
@@ -4212,8 +4213,8 @@ int knot_ns_process_ixfrin(knot_nameserver_t *nameserver,
 			}
 
 			if (ns_serial_compare(
-			      knot_rrset_rdata_soa_serial(chgsets->first_soa),
-			      knot_rrset_rdata_soa_serial(zone_soa))
+			      knot_rdata_soa_serial(chgsets->first_soa),
+			      knot_rdata_soa_serial(zone_soa))
 			    > 0) {
 				if ((xfr->flags & XFR_FLAG_UDP) != 0) {
 					// IXFR over UDP
diff --git a/src/libknot/nsec3.c b/src/libknot/nsec3.c
index 4fe332a1719fb40122537db8660a024b9330fc90..f359a46f81cb5238f136ec03d9ddc917d22ba77e 100644
--- a/src/libknot/nsec3.c
+++ b/src/libknot/nsec3.c
@@ -29,6 +29,7 @@
 #include "util/utils.h"
 #include "util/tolower.h"
 #include "util/debug.h"
+#include "rdata.h"
 
 /*----------------------------------------------------------------------------*/
 
@@ -42,11 +43,11 @@ int knot_nsec3_params_from_wire(knot_nsec3_params_t *params,
 
 	assert(knot_rrset_type(nsec3param) == KNOT_RRTYPE_NSEC3PARAM);
 
-	params->algorithm = knot_rrset_rdata_nsec3param_algorithm(nsec3param);
-	params->iterations = knot_rrset_rdata_nsec3param_iterations(nsec3param);
-	params->flags = knot_rrset_rdata_nsec3param_flags(nsec3param);
+	params->algorithm = knot_rdata_nsec3param_algorithm(nsec3param, 1);
+	params->iterations = knot_rdata_nsec3param_iterations(nsec3param, 1);
+	params->flags = knot_rdata_nsec3param_flags(nsec3param, 1);
 	params->salt_length =
-		knot_rrset_rdata_nsec3param_salt_length(nsec3param);
+		knot_rdata_nsec3param_salt_length(nsec3param, 1);
 
 	if (params->salt_length > 0) {
 		/* It is called also on reload, so we need to free if exists. */
@@ -57,7 +58,7 @@ int knot_nsec3_params_from_wire(knot_nsec3_params_t *params,
 		params->salt = (uint8_t *)malloc(params->salt_length);
 		CHECK_ALLOC_LOG(params->salt, KNOT_ENOMEM);
 		memcpy(params->salt,
-		       knot_rrset_rdata_nsec3param_salt(nsec3param),
+		       knot_rdata_nsec3param_salt(nsec3param, 1),
 		       params->salt_length);
 	} else {
 		params->salt = NULL;
diff --git a/src/libknot/rdata.h b/src/libknot/rdata.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6546b00a5c1cbdae8dbe874e58dad089c8d5513
--- /dev/null
+++ b/src/libknot/rdata.h
@@ -0,0 +1,480 @@
+/*!
+ * \file rrset.h
+ *
+ * \author Lubos Slovak <lubos.slovak@nic.cz>
+ *
+ * \brief API for manipulating RDATA contents.
+ *
+ * \addtogroup libknot
+ * @{
+ */
+/*  Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _KNOT_RDATA_H_
+#define _KNOT_RDATA_H_
+
+#include "util/utils.h"
+#include "rrset.h"
+#include "dname.h"
+
+static inline const knot_dname_t *knot_rdata_cname_name(
+                const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return NULL;
+	}
+
+	return rrset->rdata;
+}
+
+static inline const knot_dname_t *knot_rdata_dname_target(
+                const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return NULL;
+	}
+
+	return rrset->rdata;
+}
+
+static inline const knot_dname_t *knot_rdata_soa_primary_ns(
+                const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return NULL;
+	}
+
+	return rrset->rdata;
+}
+
+static inline const knot_dname_t *knot_rdata_soa_mailbox(
+                const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return NULL;
+	}
+
+	return rrset->rdata + knot_dname_size(rrset->rdata);
+}
+
+static inline size_t knot_rrset_rdata_soa_names_len(const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return 0;
+	}
+
+	return knot_dname_size(knot_rdata_soa_primary_ns(rrset))
+	       + knot_dname_size(knot_rdata_soa_mailbox(rrset));
+}
+
+static inline uint32_t knot_rdata_soa_serial(const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(rrset->rdata
+	                          + knot_rrset_rdata_soa_names_len(rrset));
+}
+
+static inline void knot_rdata_soa_serial_set(knot_rrset_t *rrset,
+                                             uint32_t serial)
+{
+	if (rrset == NULL) {
+		return;
+	}
+
+	// the number is in network byte order, transform it
+	knot_wire_write_u32(rrset->rdata
+	                    + knot_rrset_rdata_soa_names_len(rrset), serial);
+}
+
+static inline uint32_t knot_rdata_soa_refresh(const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(rrset->rdata
+	                          + knot_rrset_rdata_soa_names_len(rrset) + 4);
+}
+
+static inline uint32_t knot_rdata_soa_retry(const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(rrset->rdata
+	                          + knot_rrset_rdata_soa_names_len(rrset) + 8);
+}
+
+static inline uint32_t knot_rdata_soa_expire(const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(rrset->rdata
+	                          + knot_rrset_rdata_soa_names_len(rrset) + 12);
+}
+
+static inline uint32_t knot_rdata_soa_minimum(const knot_rrset_t *rrset)
+{
+	if (rrset == NULL) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(rrset->rdata
+	                          + knot_rrset_rdata_soa_names_len(rrset) + 16);
+}
+
+static inline uint16_t knot_rdata_rrsig_type_covered(const knot_rrset_t *rrset,
+                                                     size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return 0;
+	}
+
+	return knot_wire_read_u16(knot_rrset_get_rdata(rrset, pos));
+}
+
+static inline uint8_t knot_rdata_rrsig_algorithm(const knot_rrset_t *rrset,
+                                                 size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(knot_rrset_get_rdata(rrset, pos) + 2);
+}
+
+static inline uint8_t knot_rdata_rrsig_labels(const knot_rrset_t *rrset,
+                                              size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(knot_rrset_get_rdata(rrset, pos) + 3);
+}
+
+static inline uint32_t knot_rdata_rrsig_original_ttl(const knot_rrset_t *rrset,
+                                                     size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(knot_rrset_get_rdata(rrset, pos) + 4);
+}
+
+static inline uint32_t knot_rdata_rrsig_sig_expiration(const knot_rrset_t *rrset,
+                                                       size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(knot_rrset_get_rdata(rrset, pos) + 8);
+}
+
+static inline uint32_t knot_rdata_rrsig_sig_inception(const knot_rrset_t *rrset,
+                                                      size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return knot_wire_read_u32(knot_rrset_get_rdata(rrset, pos) + 12);
+}
+
+static inline uint16_t knot_rdata_rrsig_key_tag(const knot_rrset_t *rrset,
+                                                size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return knot_wire_read_u16(knot_rrset_get_rdata(rrset, pos) + 16);
+}
+
+static inline const knot_dname_t *knot_rdata_rrsig_signer_name(
+                const knot_rrset_t *rrset, size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return NULL;
+	}
+
+	return knot_rrset_get_rdata(rrset, pos) + 18;
+}
+
+static inline uint16_t knot_rdata_dnskey_flags(const knot_rrset_t *rrset,
+                                               size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return knot_wire_read_u16(knot_rrset_get_rdata(rrset, pos));
+}
+
+static inline uint8_t knot_rdata_dnskey_proto(const knot_rrset_t *rrset,
+                                              size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(knot_rrset_get_rdata(rrset, pos) + 2);
+}
+
+static inline uint8_t knot_rdata_dnskey_alg(const knot_rrset_t *rrset,
+                                            size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(knot_rrset_get_rdata(rrset, pos) + 3);
+}
+
+static inline void knot_rdata_dnskey_key(const knot_rrset_t *rrset,
+                                         size_t pos, uint8_t **key,
+                                         uint16_t *key_size)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return;
+	}
+
+	*key = knot_rrset_get_rdata(rrset, pos) + 4;
+	*key_size = rrset_rdata_item_size(rrset, pos) - 4;
+}
+
+static inline const knot_dname_t *knot_rdata_nsec_next(const knot_rrset_t *rrset,
+                                                       size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return NULL;
+	}
+
+	return rrset_rdata_pointer(rrset, pos);
+}
+
+static inline void knot_rdata_nsec_bitmap(const knot_rrset_t *rrset,
+                                          size_t rr_pos, uint8_t **bitmap,
+                                          uint16_t *size)
+{
+	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
+		return;
+	}
+
+	uint8_t *rdata = knot_rrset_get_rdata(rrset, rr_pos);
+	int next_size = knot_dname_size(rdata);
+
+	*bitmap = rdata + next_size;
+	*size = rrset_rdata_item_size(rrset, rr_pos) - next_size;
+}
+
+static inline uint8_t knot_rdata_nsec3_algorithm(const knot_rrset_t *rrset,
+                                                 size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(rrset_rdata_pointer(rrset, pos));
+}
+
+static inline uint8_t knot_rdata_nsec3_flags(const knot_rrset_t *rrset,
+                                             size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(rrset_rdata_pointer(rrset, pos) + 1);
+}
+
+static inline uint16_t knot_rdata_nsec3_iterations(const knot_rrset_t *rrset,
+                                                   size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return knot_wire_read_u16(rrset_rdata_pointer(rrset, pos) + 2);
+}
+
+static inline uint8_t knot_rdata_nsec3_salt_length(const knot_rrset_t *rrset,
+                                                   size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return 0;
+	}
+
+	return *(rrset_rdata_pointer(rrset, pos) + 4);
+}
+
+static inline const uint8_t *knot_rdata_nsec3_salt(const knot_rrset_t *rrset,
+                                                   size_t pos)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return NULL;
+	}
+
+	return rrset_rdata_pointer(rrset, pos) + 5;
+}
+
+static inline void knot_rdata_nsec3_next_hashed(const knot_rrset_t *rrset,
+                                                size_t pos, uint8_t **name,
+                                                uint8_t *name_size)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return;
+	}
+
+	uint8_t salt_size = knot_rdata_nsec3_salt_length(rrset, pos);
+	*name_size = *(knot_rrset_get_rdata(rrset, pos) + 4 + salt_size + 1);
+	*name = knot_rrset_get_rdata(rrset, pos) + 4 + salt_size + 2;
+}
+
+static inline void knot_rdata_nsec3_bitmap(const knot_rrset_t *rrset,
+                                           size_t pos, uint8_t **bitmap,
+                                           uint16_t *size)
+{
+	if (rrset == NULL || pos >= rrset->rdata_count) {
+		return;
+	}
+
+	/* Bitmap is last, skip all the items. */
+	size_t offset = 6; //hash alg., flags, iterations, salt len., hash len.
+	offset += knot_rdata_nsec3_salt_length(rrset, pos); //salt
+
+	uint8_t *next_hashed = NULL;
+	uint8_t next_hashed_size = 0;
+	knot_rdata_nsec3_next_hashed(rrset, pos, &next_hashed,
+	                             &next_hashed_size);
+	offset += next_hashed_size; //hash
+
+	*bitmap = knot_rrset_get_rdata(rrset, pos) + offset;
+	*size = rrset_rdata_item_size(rrset, pos) - offset;
+}
+
+static inline uint8_t knot_rdata_nsec3param_algorithm(const knot_rrset_t *rrset,
+                                                      size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return 0;
+	}
+
+	return *(rrset_rdata_pointer(rrset, pos));
+}
+
+static inline uint8_t knot_rdata_nsec3param_flags(const knot_rrset_t *rrset,
+                                                  size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return 0;
+	}
+
+	return *(rrset_rdata_pointer(rrset, pos) + 1);
+}
+
+static inline uint16_t knot_rdata_nsec3param_iterations(
+                const knot_rrset_t *rrset, size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return 0;
+	}
+
+	return knot_wire_read_u16(rrset_rdata_pointer(rrset, pos) + 2);
+}
+
+static inline uint8_t knot_rdata_nsec3param_salt_length(
+                const knot_rrset_t *rrset, size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return 0;
+	}
+
+	return *(rrset_rdata_pointer(rrset, pos) + 4);
+}
+
+static inline const uint8_t *knot_rdata_nsec3param_salt(
+                const knot_rrset_t *rrset, size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return NULL;
+	}
+
+	return rrset_rdata_pointer(rrset, pos) + 5;
+}
+
+static inline const knot_dname_t *knot_rdata_ns_name(const knot_rrset_t *rrset,
+                                              size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return NULL;
+	}
+
+	return rrset_rdata_pointer(rrset, pos);
+}
+
+static inline const knot_dname_t *knot_rdata_mx_name(const knot_rrset_t *rrset,
+                                                     size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return NULL;
+	}
+
+	return rrset_rdata_pointer(rrset, pos) + 2;
+}
+
+static inline const knot_dname_t *knot_rdata_srv_name(const knot_rrset_t *rrset,
+                                                      size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return NULL;
+	}
+
+	return rrset_rdata_pointer(rrset, pos) + 6;
+}
+
+static inline const knot_dname_t *knot_rdata_name(const knot_rrset_t *rrset,
+                                                  size_t pos)
+{
+	if (rrset == NULL || rrset->rdata_count <= pos) {
+		return NULL;
+	}
+
+	switch (rrset->type) {
+		case KNOT_RRTYPE_NS:
+			return knot_rdata_ns_name(rrset, pos);
+		case KNOT_RRTYPE_MX:
+			return knot_rdata_mx_name(rrset, pos);
+		case KNOT_RRTYPE_SRV:
+			return knot_rdata_srv_name(rrset, pos);
+		case KNOT_RRTYPE_CNAME:
+			return knot_rdata_cname_name(rrset);
+	}
+
+	return NULL;
+}
+
+#endif /* _KNOT_RDATA_H_ */
+/*! @} */
diff --git a/src/libknot/rrset.c b/src/libknot/rrset.c
index cb3423dc978bafabbb720365199c6fd5a2358e20..c7d5d701119a71b6ab9d18a083ffe0231bf99211 100644
--- a/src/libknot/rrset.c
+++ b/src/libknot/rrset.c
@@ -57,8 +57,7 @@ static int rrset_release_dnames_in_rr(knot_dname_t **dname, void *data)
 	return KNOT_EOK;
 }
 
-static uint32_t rrset_rdata_offset(const knot_rrset_t *rrset,
-                                   size_t pos)
+static uint32_t rrset_rdata_offset(const knot_rrset_t *rrset, size_t pos)
 {
 	if (rrset == NULL || rrset->rdata_indices == NULL ||
 	    pos >= rrset->rdata_count || pos == 0) {
@@ -69,8 +68,7 @@ static uint32_t rrset_rdata_offset(const knot_rrset_t *rrset,
 	return rrset->rdata_indices[pos - 1];
 }
 
-static uint8_t *rrset_rdata_pointer(const knot_rrset_t *rrset,
-                                    size_t pos)
+uint8_t *rrset_rdata_pointer(const knot_rrset_t *rrset, size_t pos)
 {
 	if (rrset == NULL || rrset->rdata == NULL
 	    || pos >= rrset->rdata_count) {
@@ -1581,455 +1579,6 @@ int knot_rrset_merge_sort(knot_rrset_t *rrset1, const knot_rrset_t *rrset2,
 	return KNOT_EOK;
 }
 
-const knot_dname_t *knot_rrset_rdata_cname_name(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = rrset->rdata;
-//	memcpy(&dname, rrset->rdata, sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_dname_target(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-	const knot_dname_t *dname = rrset->rdata;
-//	memcpy(&dname, rrset->rdata, sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_soa_primary_ns(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-	const knot_dname_t *dname = rrset->rdata;
-//	memcpy(&dname, rrset->rdata, sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_soa_mailbox(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-	const knot_dname_t *dname = rrset->rdata
-	                            + knot_dname_size(rrset->rdata);
-//	memcpy(&dname, rrset->rdata + sizeof(knot_dname_t *),
-//	       sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_rp_first_dname(const knot_rrset_t *rrset,
-                                                    size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = knot_rrset_get_rdata(rrset, pos);
-//	memcpy(&dname, knot_rrset_get_rdata(rrset, pos), sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_rp_second_dname(const knot_rrset_t *rrset,
-                                                     size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = knot_rrset_get_rdata(rrset, pos)
-	                            + knot_dname_size(rrset->rdata);
-//	memcpy(&dname, knot_rrset_get_rdata(rrset, pos) + sizeof(knot_dname_t *),
-//	       sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_minfo_first_dname(const knot_rrset_t *rrset,
-                                                       size_t pos)
-{
-	return knot_rrset_rdata_rp_first_dname(rrset, pos);
-}
-
-const knot_dname_t *knot_rrset_rdata_minfo_second_dname(const knot_rrset_t *rrset,
-                                                        size_t pos)
-{
-	return knot_rrset_rdata_rp_second_dname(rrset, pos);
-}
-
-uint32_t knot_rrset_rdata_soa_serial(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(rrset->rdata + sizeof(knot_dname_t *) * 2);
-}
-
-/*---------------------------------------------------------------------------*/
-
-void knot_rrset_rdata_soa_serial_set(knot_rrset_t *rrset, uint32_t serial)
-{
-	if (rrset == NULL) {
-		return;
-	}
-
-	// the number is in network byte order, transform it
-	knot_wire_write_u32(rrset->rdata + sizeof(knot_dname_t *) * 2,
-	                    serial);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint32_t knot_rrset_rdata_soa_refresh(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(rrset->rdata +
-	                          sizeof(knot_dname_t *) * 2 + 4);
-}
-
-/*---------------------------------------------------------------------------*/
-
-
-uint32_t knot_rrset_rdata_soa_retry(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(rrset->rdata +
-	                          sizeof(knot_dname_t *) * 2 + 8);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint32_t knot_rrset_rdata_soa_expire(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(rrset->rdata +
-	                          sizeof(knot_dname_t *) * 2 + 12);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint32_t knot_rrset_rdata_soa_minimum(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(rrset->rdata +
-	                          sizeof(knot_dname_t *) * 2 + 16);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint16_t knot_rrset_rdata_rrsig_type_covered(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u16(rrset->rdata);
-}
-
-uint8_t knot_rrset_rdata_rrsig_algorithm(const knot_rrset_t *rrset,
-                                         size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(knot_rrset_get_rdata(rrset, rr_pos) + 2);
-}
-
-uint8_t knot_rrset_rdata_rrsig_labels(const knot_rrset_t *rrset,
-                                      size_t rr_pos)
-
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(knot_rrset_get_rdata(rrset, rr_pos) + 3);
-}
-
-uint32_t knot_rrset_rdata_rrsig_original_ttl(const knot_rrset_t *rrset,
-                                             size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(knot_rrset_get_rdata(rrset, rr_pos) + 4);
-}
-
-uint32_t knot_rrset_rdata_rrsig_sig_expiration(const knot_rrset_t *rrset,
-                                               size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(knot_rrset_get_rdata(rrset, rr_pos) + 8);
-}
-
-uint32_t knot_rrset_rdata_rrsig_sig_inception(const knot_rrset_t *rrset,
-                                              size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return knot_wire_read_u32(knot_rrset_get_rdata(rrset, rr_pos) + 12);
-}
-
-uint16_t knot_rrset_rdata_rrsig_key_tag(const knot_rrset_t *rrset,
-                                        size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return knot_wire_read_u16(knot_rrset_get_rdata(rrset, rr_pos) + 16);
-}
-
-const knot_dname_t *knot_rrset_rdata_rrsig_signer_name(const knot_rrset_t *rrset,
-                                                       size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = NULL;
-	memcpy(&dname, knot_rrset_get_rdata(rrset, rr_pos) + 18,
-	       sizeof(knot_dname_t *));
-
-	return dname;
-}
-
-uint16_t knot_rrset_rdata_dnskey_flags(const knot_rrset_t *rrset, size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return knot_wire_read_u16(knot_rrset_get_rdata(rrset, rr_pos));
-}
-
-uint8_t knot_rrset_rdata_dnskey_proto(const knot_rrset_t *rrset, size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(knot_rrset_get_rdata(rrset, rr_pos) + 2);
-}
-
-uint8_t knot_rrset_rdata_dnskey_alg(const knot_rrset_t *rrset, size_t rr_pos)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(knot_rrset_get_rdata(rrset, rr_pos) + 3);
-}
-
-void knot_rrset_rdata_dnskey_key(const knot_rrset_t *rrset, size_t rr_pos,
-                                 uint8_t **key, uint16_t *key_size)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return;
-	}
-
-	*key = knot_rrset_get_rdata(rrset, rr_pos) + 4;
-	*key_size = rrset_rdata_item_size(rrset, rr_pos) - 4;
-}
-
-const knot_dname_t *knot_rrset_rdata_nsec_next(const knot_rrset_t *rrset,
-                                               size_t rr_pos)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname;
-	memcpy(&dname, rrset_rdata_pointer(rrset, rr_pos),
-	       sizeof(knot_dname_t *));
-	return dname;
-}
-
-void knot_rrset_rdata_nsec_bitmap(const knot_rrset_t *rrset, size_t rr_pos,
-                                  uint8_t **bitmap, uint16_t *size)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return;
-	}
-
-	*bitmap = knot_rrset_get_rdata(rrset, rr_pos) + sizeof(knot_dname_t *);
-	*size = rrset_rdata_item_size(rrset, rr_pos) - sizeof(knot_dname_t *);
-}
-
-void knot_rrset_rdata_nsec3_bitmap(const knot_rrset_t *rrset, size_t rr_pos,
-                                   uint8_t **bitmap, uint16_t *size)
-{
-	if (rrset == NULL || rr_pos >= rrset->rdata_count) {
-		return;
-	}
-
-	/* Bitmap is last, skip all the items. */
-	size_t offset = 1; //hash alg.
-	offset += 1; //flags
-	offset += 2; //iterations
-	offset += 1; //salt lenght
-	offset += knot_rrset_rdata_nsec3_salt_length(rrset, rr_pos); //sal
-	uint8_t *next_hashed = NULL;
-	uint8_t next_hashed_size = 0;
-	knot_rrset_rdata_nsec3_next_hashed(rrset, rr_pos, &next_hashed,
-	                                   &next_hashed_size);
-	offset += 1; //hash length
-	offset += next_hashed_size; //hash
-	*bitmap = knot_rrset_get_rdata(rrset, rr_pos) + offset;
-	*size = rrset_rdata_item_size(rrset, rr_pos) - offset;
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint8_t knot_rrset_rdata_nsec3_algorithm(const knot_rrset_t *rrset,
-                                         size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(rrset_rdata_pointer(rrset, pos));
-}
-
-uint8_t knot_rrset_rdata_nsec3_flags(const knot_rrset_t *rrset,
-                                     size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(rrset_rdata_pointer(rrset, pos) + 1);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint16_t knot_rrset_rdata_nsec3_iterations(const knot_rrset_t *rrset,
-                                           size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return knot_wire_read_u16(rrset_rdata_pointer(rrset, pos) + 2);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint8_t knot_rrset_rdata_nsec3param_flags(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return *(rrset_rdata_pointer(rrset, 0) + 1);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint8_t knot_rrset_rdata_nsec3param_algorithm(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return *(rrset_rdata_pointer(rrset, 0));
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint16_t knot_rrset_rdata_nsec3param_iterations(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return knot_wire_read_u16(rrset_rdata_pointer(rrset, 0) + 2);
-}
-
-/*---------------------------------------------------------------------------*/
-
-uint8_t knot_rrset_rdata_nsec3param_salt_length(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return 0;
-	}
-
-	return *(rrset_rdata_pointer(rrset, 0) + 4);
-}
-
-/*---------------------------------------------------------------------------*/
-
-const uint8_t *knot_rrset_rdata_nsec3param_salt(const knot_rrset_t *rrset)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-
-	return rrset_rdata_pointer(rrset, 0) + 5;
-}
-
-/*---------------------------------------------------------------------------*/
-
-
-uint8_t knot_rrset_rdata_nsec3_salt_length(const knot_rrset_t *rrset,
-                                           size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return 0;
-	}
-
-	return *(rrset_rdata_pointer(rrset, pos) + 4);
-}
-
-void knot_rrset_rdata_nsec3_next_hashed(const knot_rrset_t *rrset, size_t pos,
-                                        uint8_t **name, uint8_t *name_size)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return;
-	}
-
-	uint8_t salt_size = knot_rrset_rdata_nsec3_salt_length(rrset, pos);
-	*name_size = *(knot_rrset_get_rdata(rrset, pos) + 4 + salt_size + 1);
-	*name = knot_rrset_get_rdata(rrset, pos) + 4 + salt_size + 2;
-}
-
-/*---------------------------------------------------------------------------*/
-
-const uint8_t *knot_rrset_rdata_nsec3_salt(const knot_rrset_t *rrset,
-                                           size_t pos)
-{
-	if (rrset == NULL || pos >= rrset->rdata_count) {
-		return NULL;
-	}
-
-	return rrset_rdata_pointer(rrset, pos) + 5;
-}
-
 void knot_rrset_dump(const knot_rrset_t *rrset)
 {
 dbg_rrset_exec_detail(
@@ -2249,66 +1798,6 @@ dbg_rrset_exec_detail(
 	return KNOT_EOK;
 }
 
-const knot_dname_t *knot_rrset_rdata_ns_name(const knot_rrset_t *rrset,
-                                             size_t rdata_pos)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = rrset_rdata_pointer(rrset, rdata_pos);
-//	memcpy(&dname, rrset_rdata_pointer(rrset, rdata_pos),
-//	       sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_mx_name(const knot_rrset_t *rrset,
-                                             size_t rdata_pos)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = rrset_rdata_pointer(rrset, rdata_pos) + 2;
-//	memcpy(&dname, rrset_rdata_pointer(rrset, rdata_pos) + 2,
-//	       sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_srv_name(const knot_rrset_t *rrset,
-                                              size_t rdata_pos)
-{
-	if (rrset == NULL) {
-		return NULL;
-	}
-
-	const knot_dname_t *dname = rrset_rdata_pointer(rrset, rdata_pos) + 6;
-//	memcpy(&dname, rrset_rdata_pointer(rrset, rdata_pos) + 6,
-//	       sizeof(knot_dname_t *));
-	return dname;
-}
-
-const knot_dname_t *knot_rrset_rdata_name(const knot_rrset_t *rrset,
-                                          size_t rdata_pos)
-{
-	if (rrset == NULL || rrset->rdata_count <= rdata_pos) {
-		return NULL;
-	}
-
-	switch (rrset->type) {
-		case KNOT_RRTYPE_NS:
-			return knot_rrset_rdata_ns_name(rrset, rdata_pos);
-		case KNOT_RRTYPE_MX:
-			return knot_rrset_rdata_mx_name(rrset, rdata_pos);
-		case KNOT_RRTYPE_SRV:
-			return knot_rrset_rdata_srv_name(rrset, rdata_pos);
-		case KNOT_RRTYPE_CNAME:
-			return knot_rrset_rdata_cname_name(rrset);
-	}
-
-	return NULL;
-}
-
 int knot_rrset_find_rr_pos(const knot_rrset_t *rr_search_in,
                            const knot_rrset_t *rr_reference, size_t pos,
                            size_t *pos_out)
diff --git a/src/libknot/rrset.h b/src/libknot/rrset.h
index cd6f253db20bc41fe1757a4a0a79bf0e86c86577..b669a60ac3267c380e058a7481f9435aa889dfd4 100644
--- a/src/libknot/rrset.h
+++ b/src/libknot/rrset.h
@@ -330,82 +330,6 @@ int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2);
 int knot_rrset_merge_sort(knot_rrset_t *rrset1, const knot_rrset_t *rrset2,
                           int *merged, int *deleted_rrs);
 
-const knot_dname_t *knot_rrset_rdata_cname_name(const knot_rrset_t *rrset);
-const knot_dname_t *knot_rrset_rdata_dname_target(const knot_rrset_t *rrset);
-void knot_rrset_rdata_set_cname_name(knot_rrset_t *rrset,
-                                     const knot_dname_t *name);
-void knot_rrset_rdata_set_dname_target(knot_rrset_t *rrset,
-                                       const knot_dname_t *target);
-const knot_dname_t *knot_rrset_rdata_soa_primary_ns(const knot_rrset_t *rrset);
-const knot_dname_t *knot_rrset_rdata_soa_mailbox(const knot_rrset_t *rrset);
-uint32_t knot_rrset_rdata_soa_serial(const knot_rrset_t *rrset);
-void knot_rrset_rdata_soa_serial_set(knot_rrset_t *rrset, uint32_t serial);
-uint32_t knot_rrset_rdata_soa_refresh(const knot_rrset_t *rrset);
-uint32_t knot_rrset_rdata_soa_retry(const knot_rrset_t *rrset);
-uint32_t knot_rrset_rdata_soa_expire(const knot_rrset_t *rrset);
-uint32_t knot_rrset_rdata_soa_minimum(const knot_rrset_t *rrset);
-uint16_t knot_rrset_rdata_rrsig_type_covered(const knot_rrset_t *rrset);
-uint8_t knot_rrset_rdata_rrsig_algorithm(const knot_rrset_t *rrset,
-                                         size_t rr_pos);
-uint8_t knot_rrset_rdata_rrsig_labels(const knot_rrset_t *rrset, size_t rr_pos);
-uint32_t knot_rrset_rdata_rrsig_original_ttl(const knot_rrset_t *rrset,
-                                             size_t rr_pos);
-uint32_t knot_rrset_rdata_rrsig_sig_expiration(const knot_rrset_t *rrset,
-                                               size_t rr_pos);
-uint32_t knot_rrset_rdata_rrsig_sig_inception(const knot_rrset_t *rrset,
-                                              size_t rr_pos);
-uint16_t knot_rrset_rdata_rrsig_key_tag(const knot_rrset_t *rrset,
-                                        size_t rr_pos);
-const knot_dname_t *knot_rrset_rdata_rrsig_signer_name(const knot_rrset_t *rrset,
-                                                       size_t rr_pos);
-
-uint16_t knot_rrset_rdata_dnskey_flags(const knot_rrset_t *rrset, size_t rr_pos);
-uint8_t knot_rrset_rdata_dnskey_proto(const knot_rrset_t *rrset, size_t rr_pos);
-uint8_t knot_rrset_rdata_dnskey_alg(const knot_rrset_t *rrset, size_t rr_pos);
-void knot_rrset_rdata_dnskey_key(const knot_rrset_t *rrset, size_t rr_pos,
-                                 uint8_t **key, uint16_t *key_size);
-const knot_dname_t *knot_rrset_rdata_nsec_next(const knot_rrset_t *rrset,
-                                               size_t rr_pos);
-void knot_rrset_rdata_nsec_bitmap(const knot_rrset_t *rrset, size_t rr_pos,
-                                  uint8_t **bitmap, uint16_t *size);
-
-void knot_rrset_rdata_nsec3_bitmap(const knot_rrset_t *rrset, size_t rr_pos,
-                                   uint8_t **bitmap, uint16_t *size);
-uint8_t knot_rrset_rdata_nsec3_algorithm(const knot_rrset_t *rrset,
-                                         size_t pos);
-uint8_t knot_rrset_rdata_nsec3_flags(const knot_rrset_t *rrset,
-                                     size_t pos);
-uint16_t knot_rrset_rdata_nsec3_iterations(const knot_rrset_t *rrset,
-                                           size_t pos);
-uint8_t knot_rrset_rdata_nsec3_salt_length(const knot_rrset_t *rrset,
-                                           size_t pos);
-void knot_rrset_rdata_nsec3_next_hashed(const knot_rrset_t *rrset, size_t pos,
-                                        uint8_t **name, uint8_t *name_size);
-const uint8_t *knot_rrset_rdata_nsec3_salt(const knot_rrset_t *rrset,
-                                           size_t pos);
-uint8_t knot_rrset_rdata_nsec3param_algorithm(const knot_rrset_t *rrset);
-uint8_t knot_rrset_rdata_nsec3param_flags(const knot_rrset_t *rrset);
-uint16_t knot_rrset_rdata_nsec3param_iterations(const knot_rrset_t *rrset);
-uint8_t knot_rrset_rdata_nsec3param_salt_length(const knot_rrset_t *rrset);
-const uint8_t *knot_rrset_rdata_nsec3param_salt(const knot_rrset_t *rrset);
-
-const knot_dname_t *knot_rrset_rdata_rp_first_dname(const knot_rrset_t *rrset,
-                                                    size_t pos);
-const knot_dname_t *knot_rrset_rdata_rp_second_dname(const knot_rrset_t *rrset,
-                                                     size_t pos);
-const knot_dname_t *knot_rrset_rdata_minfo_first_dname(const knot_rrset_t *rrset,
-                                                       size_t pos);
-const knot_dname_t *knot_rrset_rdata_minfo_second_dname(const knot_rrset_t *rrset,
-                                                        size_t pos);
-const knot_dname_t *knot_rrset_rdata_ns_name(const knot_rrset_t *rrset,
-                                             size_t rdata_pos);
-const knot_dname_t *knot_rrset_rdata_mx_name(const knot_rrset_t *rrset,
-                                             size_t rdata_pos);
-const knot_dname_t *knot_rrset_rdata_srv_name(const knot_rrset_t *rrset,
-                                              size_t rdata_pos);
-const knot_dname_t *knot_rrset_rdata_name(const knot_rrset_t *rrset,
-                                          size_t rdata_pos);
-
 void knot_rrset_dump(const knot_rrset_t *rrset);
 
 //TODO test
@@ -442,6 +366,9 @@ int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset,
                                    size_t total_size, size_t rdlength);
 
 int knot_rrset_ds_check(const knot_rrset_t *rrset);
+
+uint8_t *rrset_rdata_pointer(const knot_rrset_t *rrset, size_t pos);
+
 #endif /* _KNOT_RRSET_H_ */
 
 /*! @} */
diff --git a/src/libknot/updates/changesets.c b/src/libknot/updates/changesets.c
index 1f7997cf6be80875dce38a2998acf00c0af4fa7c..1bf823b828cfb0853bbb22be2fe08487b914ba1d 100644
--- a/src/libknot/updates/changesets.c
+++ b/src/libknot/updates/changesets.c
@@ -24,6 +24,7 @@
 #include "common/descriptor.h"
 #include "rrset.h"
 #include "util/debug.h"
+#include "rdata.h"
 
 static const size_t KNOT_CHANGESET_COUNT = 5;
 static const size_t KNOT_CHANGESET_STEP = 5;
@@ -66,8 +67,8 @@ static int knot_changeset_rrsets_match(const knot_rrset_t *rrset1,
 {
 	return knot_rrset_equal(rrset1, rrset2, KNOT_RRSET_COMPARE_HEADER)
 	       && (knot_rrset_type(rrset1) != KNOT_RRTYPE_RRSIG
-	           || knot_rrset_rdata_rrsig_type_covered(rrset1)
-	              == knot_rrset_rdata_rrsig_type_covered(rrset2));
+	           || knot_rdata_rrsig_type_covered(rrset1, 1)
+	              == knot_rdata_rrsig_type_covered(rrset2, 1));
 }
 
 /*----------------------------------------------------------------------------*/
@@ -204,7 +205,7 @@ void knot_changeset_store_soa(knot_rrset_t **chg_soa,
                                uint32_t *chg_serial, knot_rrset_t *soa)
 {
 	*chg_soa = soa;
-	*chg_serial = knot_rrset_rdata_soa_serial(soa);
+	*chg_serial = knot_rdata_soa_serial(soa);
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/src/libknot/updates/ddns.c b/src/libknot/updates/ddns.c
index cd0803db929427f519384a00750b0fb0376c3f8f..f7a825a637703014d6885f097a454467d1c0f814 100644
--- a/src/libknot/updates/ddns.c
+++ b/src/libknot/updates/ddns.c
@@ -29,6 +29,7 @@
 #include "nameserver/name-server.h"  // ns_serial_compare() - TODO: extract
 #include "updates/xfr-in.h"
 #include "common/descriptor.h"
+#include "rdata.h"
 
 /*----------------------------------------------------------------------------*/
 // Copied from XFR - maybe extract somewhere else
@@ -677,7 +678,7 @@ int knot_ddns_process_update(const knot_zone_contents_t *zone,
 	}
 
 	/* Current SERIAL */
-	int64_t sn = knot_rrset_rdata_soa_serial(soa_begin);
+	int64_t sn = knot_rdata_soa_serial(soa_begin);
 	int64_t sn_new;
 	/* Incremented SERIAL
 	 * We must set it now to be able to compare SERIAL from SOAs in the
@@ -730,9 +731,9 @@ int knot_ddns_process_update(const knot_zone_contents_t *zone,
 		 *       RRSet. This should be handled somehow.
 		 */
 		if (knot_rrset_type(rrset) == KNOT_RRTYPE_SOA
-		    && ns_serial_compare(knot_rrset_rdata_soa_serial(rrset),
+		    && ns_serial_compare(knot_rdata_soa_serial(rrset),
 		                         sn_new) > 0) {
-			sn_new = knot_rrset_rdata_soa_serial(rrset);
+			sn_new = knot_rdata_soa_serial(rrset);
 			soa_end = (knot_rrset_t *)rrset_copy;
 		}
 	}
@@ -747,7 +748,7 @@ int knot_ddns_process_update(const knot_zone_contents_t *zone,
 			         knot_strerror(ret));
 			return ret;
 		}
-		knot_rrset_rdata_soa_serial_set(soa_end, sn_new);
+		knot_rdata_soa_serial_set(soa_end, sn_new);
 	}
 
 	knot_changeset_store_soa(&changeset->soa_to,
@@ -903,7 +904,7 @@ static int knot_ddns_rr_is_nsec3(const knot_rrset_t *rr)
 	if ((knot_rrset_type(rr) == KNOT_RRTYPE_NSEC3)
 	    || (knot_rrset_type(rr) == KNOT_RRTYPE_RRSIG
 	        && knot_rrset_rdata_rr_count(rr)
-	        && knot_rrset_rdata_rrsig_type_covered(rr)
+	        && knot_rdata_rrsig_type_covered(rr, 1)
 	            == KNOT_RRTYPE_NSEC3))
 	{
 		dbg_ddns_detail("This is NSEC3-related RRSet.\n");
@@ -1117,8 +1118,8 @@ static int knot_ddns_process_add_soa(knot_node_t *node,
 		}
 
 		/* Check that the serial is indeed larger than the current one*/
-		assert(ns_serial_compare(knot_rrset_rdata_soa_serial(removed),
-		                         knot_rrset_rdata_soa_serial(rr)) < 0);
+		assert(ns_serial_compare(knot_rdata_soa_serial(removed),
+		                         knot_rdata_soa_serial(rr)) < 0);
 
 		/* 1) Store it to 'changes', together with its RRSIGs. */
 		ret = knot_changes_add_old_rrsets(
@@ -1397,7 +1398,7 @@ static int knot_ddns_add_rr(knot_node_t *node, const knot_rrset_t *rr,
 
 	uint16_t type = knot_rrset_type(rr);
 	uint16_t type_covered = (type == KNOT_RRTYPE_RRSIG)
-	                ? knot_rrset_rdata_rrsig_type_covered(rr)
+	                ? knot_rdata_rrsig_type_covered(rr, 1)
 	                : type;
 
 	/* If the RR belongs to a RRSet already present in the node, we must
@@ -1686,7 +1687,7 @@ static int knot_ddns_process_rem_rr(const knot_rrset_t *rr,
 	 * 1) Copy the RRSet.
 	 */
 	uint16_t type_to_copy = (type != KNOT_RRTYPE_RRSIG) ? type
-	                : knot_rrset_rdata_rrsig_type_covered(rr);
+	                : knot_rdata_rrsig_type_covered(rr, 1);
 	knot_rrset_t *rrset_copy = NULL;
 	int ret = xfrin_copy_rrset(node, type_to_copy, &rrset_copy, changes, 1);
 	if (ret < 0) {
@@ -2317,7 +2318,7 @@ int knot_ddns_process_update2(knot_zone_contents_t *zone,
 	}
 
 	/* Current SERIAL */
-	int64_t sn = knot_rrset_rdata_soa_serial(soa_begin);
+	int64_t sn = knot_rdata_soa_serial(soa_begin);
 	int64_t sn_new;
 
 	/* Incremented SERIAL
@@ -2369,7 +2370,7 @@ int knot_ddns_process_update2(knot_zone_contents_t *zone,
 		if (knot_rrset_type(rr) == KNOT_RRTYPE_SOA
 		    && (knot_rrset_class(rr) == KNOT_CLASS_NONE
 		        || knot_rrset_class(rr) == KNOT_CLASS_ANY
-		        || ns_serial_compare(knot_rrset_rdata_soa_serial(rr),
+		        || ns_serial_compare(knot_rdata_soa_serial(rr),
 		                             sn_new) < 0)) {
 			// This ignores also SOA removals
 			dbg_ddns_verb("Ignoring SOA...\n");
@@ -2391,7 +2392,7 @@ int knot_ddns_process_update2(knot_zone_contents_t *zone,
 
 		// we need the RR copy, that's why this code is here
 		if (knot_rrset_type(rr) == KNOT_RRTYPE_SOA) {
-			int64_t sn_rr = knot_rrset_rdata_soa_serial(rr);
+			int64_t sn_rr = knot_rdata_soa_serial(rr);
 			dbg_ddns_verb("Replacing SOA. Old serial: %"PRId64", "
 			              "new serial: %"PRId64"\n", sn_new, sn_rr);
 			assert(ns_serial_compare(sn_rr, sn_new) >= 0);
@@ -2420,7 +2421,7 @@ int knot_ddns_process_update2(knot_zone_contents_t *zone,
 			*rcode = KNOT_RCODE_SERVFAIL;
 			return ret;
 		}
-		knot_rrset_rdata_soa_serial_set(soa_end, sn_new);
+		knot_rdata_soa_serial_set(soa_end, sn_new);
 
 		/* And replace it in the zone. */
 		ret = xfrin_replace_rrset_in_node(
diff --git a/src/libknot/updates/xfr-in.c b/src/libknot/updates/xfr-in.c
index 371888675634e7ed9deba1ca99fea80b5278efa3..648b50f8b95f00cc156f256e1254739aa22cbfed 100644
--- a/src/libknot/updates/xfr-in.c
+++ b/src/libknot/updates/xfr-in.c
@@ -34,6 +34,7 @@
 #include "tsig.h"
 #include "tsig-op.h"
 #include "common/descriptor.h"
+#include "rdata.h"
 
 /*----------------------------------------------------------------------------*/
 /* Non-API functions                                                          */
@@ -176,7 +177,7 @@ int xfrin_transfer_needed(const knot_zone_contents_t *zone,
 		return KNOT_ERROR;
 	}
 
-	int64_t local_serial = knot_rrset_rdata_soa_serial(soa_rrset);
+	int64_t local_serial = knot_rdata_soa_serial(soa_rrset);
 	if (local_serial < 0) {
 dbg_xfrin_exec(
 		char *name = knot_dname_to_str(knot_rrset_owner(soa_rrset));
@@ -196,7 +197,7 @@ dbg_xfrin_exec(
 		return KNOT_EMALF;
 	}
 
-	int64_t remote_serial = knot_rrset_rdata_soa_serial(soa_rrset);
+	int64_t remote_serial = knot_rdata_soa_serial(soa_rrset);
 	if (remote_serial < 0) {
 		return KNOT_EMALF;	// maybe some other error
 	}
@@ -265,7 +266,7 @@ static int xfrin_process_orphan_rrsigs(knot_zone_contents_t *zone,
 			char *name = knot_dname_to_str((*last)->rrsig->owner);
 			char type[16];
 			knot_rrtype_to_string(
-			    knot_rrset_rdata_rrsig_type_covered((*last)->rrsig),
+			    knot_rdata_rrsig_type_covered((*last)->rrsig, 1),
 			    type, 16);
 
 			log_zone_warning("No RRSet for RRSIG: "
@@ -1077,8 +1078,8 @@ dbg_xfrin_exec_verb(
 				goto cleanup;
 			}
 
-			if (knot_rrset_rdata_soa_serial(rr)
-			    == knot_rrset_rdata_soa_serial((*chs)->first_soa)) {
+			if (knot_rdata_soa_serial(rr)
+			    == knot_rdata_soa_serial((*chs)->first_soa)) {
 
 				/*! \note [TSIG] Check TSIG, we're at the end of
 				 *               transfer.
@@ -1155,8 +1156,8 @@ dbg_xfrin_exec_verb(
 			if (knot_rrset_type(rr) == KNOT_RRTYPE_SOA) {
 				log_zone_info("%s Serial %u -> %u.\n",
 					      xfr->msg,
-					      knot_rrset_rdata_soa_serial(cur->soa_from),
-					      knot_rrset_rdata_soa_serial(cur->soa_to));
+					      knot_rdata_soa_serial(cur->soa_from),
+					      knot_rdata_soa_serial(cur->soa_to));
 				state = -1;
 				continue;
 			} else {
@@ -1395,15 +1396,14 @@ static int xfrin_apply_remove_rrsigs(knot_changes_t *changes,
 
 	if (*rrset
 	    && knot_dname_is_equal(knot_rrset_owner(*rrset), knot_node_owner(node))
-	    && knot_rrset_type(*rrset) == knot_rrset_rdata_rrsig_type_covered(remove)) {
+	    && knot_rrset_type(*rrset) == knot_rdata_rrsig_type_covered(remove, 1)) {
 		// this RRSet should be the already copied RRSet so we may
 		// update it right away
 		/*! \todo Does this case even occur? */
 		dbg_xfrin_verb("Using RRSet from previous iteration.\n");
 	} else {
 		// find RRSet based on the Type Covered
-		uint16_t type =
-			knot_rrset_rdata_rrsig_type_covered(remove);
+		uint16_t type = knot_rdata_rrsig_type_covered(remove, 1);
 
 		// copy the rrset
 		dbg_xfrin_detail("Copying RRSet that carries the RRSIGs.\n");
@@ -1931,18 +1931,18 @@ static int xfrin_apply_add_normal_ddns(knot_changes_t *changes,
 		 *    serial is less than the current serial, ignore.
 		 */
 		if (knot_node_rrset(node, KNOT_RRTYPE_SOA) == NULL
-		    || ns_serial_compare(knot_rrset_rdata_soa_serial(
+		    || ns_serial_compare(knot_rdata_soa_serial(
 		       knot_node_rrset(node, KNOT_RRTYPE_SOA)),
-			   knot_rrset_rdata_soa_serial(add) > 0
+			   knot_rdata_soa_serial(add) > 0
 		    )) {
 			dbg_ddns_verb("DDNS: Ignoring SOA.\n");
 			return KNOT_EOK;
 		} else {
 			dbg_ddns_verb("DDNS: replacing SOA (old serial: %u,"
 				      " new serial: %u.\n",
-				      knot_rrset_rdata_soa_serial(knot_node_rrset(node,
+				      knot_rdata_soa_serial(knot_node_rrset(node,
 							  KNOT_RRTYPE_SOA)),
-				      knot_rrset_rdata_soa_serial(add));
+				      knot_rdata_soa_serial(add));
 			/* b) Otherwise, replace the current SOA. */
 			ret = xfrin_replace_rrset_in_node(node, add,
 							      changes,
@@ -2162,7 +2162,7 @@ static int xfrin_apply_add_rrsig(knot_changes_t *changes,
 
 	int ret;
 
-	uint16_t type = knot_rrset_rdata_rrsig_type_covered(add);
+	uint16_t type = knot_rdata_rrsig_type_covered(add, 1);
 
 dbg_xfrin_exec_verb(
 	char *name = knot_dname_to_str(knot_rrset_owner(add));
@@ -2521,7 +2521,7 @@ dbg_xfrin_exec_detail(
 		// check if the RRSet belongs to the NSEC3 tree
 		if ((knot_rrset_type(chset->remove[i]) == KNOT_RRTYPE_NSEC3)
 		    || (knot_rrset_type(chset->remove[i]) == KNOT_RRTYPE_RRSIG
-			&& knot_rrset_rdata_rrsig_type_covered(chset->remove[i])
+			&& knot_rdata_rrsig_type_covered(chset->remove[i], 1)
 			    == KNOT_RRTYPE_NSEC3))
 		{
 			dbg_xfrin_verb("Removed RRSet belongs to NSEC3 tree.\n");
@@ -2614,7 +2614,7 @@ dbg_xfrin_exec_detail(
 		// check if the RRSet belongs to the NSEC3 tree
 		if ((knot_rrset_type(chset->add[i]) == KNOT_RRTYPE_NSEC3)
 		    || (knot_rrset_type(chset->add[i]) == KNOT_RRTYPE_RRSIG
-			&& knot_rrset_rdata_rrsig_type_covered(chset->add[i])
+			&& knot_rdata_rrsig_type_covered(chset->add[i], 1)
 			    == KNOT_RRTYPE_NSEC3))
 		{
 			dbg_xfrin_detail("This is NSEC3-related RRSet.\n");
@@ -2776,7 +2776,7 @@ static int xfrin_apply_changeset(knot_zone_contents_t *contents,
 	/*! \todo Only if SOA is present? */
 	const knot_rrset_t *soa = knot_node_rrset(contents->apex,
 						  KNOT_RRTYPE_SOA);
-	if (soa == NULL || knot_rrset_rdata_soa_serial(soa)
+	if (soa == NULL || knot_rdata_soa_serial(soa)
 			   != chset->serial_from) {
 		dbg_xfrin("SOA serials do not match!!\n");
 		return KNOT_ERROR;
diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c
index 03a1661cf53975d6f548e5ec8367e13669c56c6e..72f570db3bc21c3017e771de76c4549065120a42 100644
--- a/src/libknot/zone/zone-contents.c
+++ b/src/libknot/zone/zone-contents.c
@@ -26,6 +26,7 @@
 #include "libknot/zone/zone-tree.h"
 #include "libknot/util/wire.h"
 #include "consts.h"
+#include "libknot/rdata.h"
 
 /*----------------------------------------------------------------------------*/
 /* Non-API functions                                                          */
@@ -606,19 +607,19 @@ static int knot_zc_nsec3_parameters_match(const knot_rrset_t *rrset,
 
 	dbg_zone_detail("RDATA algo: %u, iterations: %u, salt length: %u, salt:"
 			" %.*s\n",
-			knot_rrset_rdata_nsec3_algorithm(rrset, rdata_pos),
-			knot_rrset_rdata_nsec3_iterations(rrset, rdata_pos),
-			knot_rrset_rdata_nsec3_salt_length(rrset, rdata_pos),
-			knot_rrset_rdata_nsec3_salt_length(rrset, rdata_pos),
-			knot_rrset_rdata_nsec3_salt(rrset, rdata_pos));
+			knot_rdata_nsec3_algorithm(rrset, rdata_pos),
+			knot_rdata_nsec3_iterations(rrset, rdata_pos),
+			knot_rdata_nsec3_salt_length(rrset, rdata_pos),
+			knot_rdata_nsec3_salt_length(rrset, rdata_pos),
+			knot_rdata_nsec3_salt(rrset, rdata_pos));
 	dbg_zone_detail("NSEC3PARAM algo: %u, iterations: %u, salt length: %u, "
 			"salt: %.*s\n",  params->algorithm, params->iterations,
 			params->salt_length, params->salt_length, params->salt);
 
-	return (knot_rrset_rdata_nsec3_algorithm(rrset, rdata_pos) == params->algorithm
-		&& knot_rrset_rdata_nsec3_iterations(rrset, rdata_pos) == params->iterations
-		&& knot_rrset_rdata_nsec3_salt_length(rrset, rdata_pos) == params->salt_length
-		&& strncmp((const char *)knot_rrset_rdata_nsec3_salt(rrset, rdata_pos),
+	return (knot_rdata_nsec3_algorithm(rrset, rdata_pos) == params->algorithm
+		&& knot_rdata_nsec3_iterations(rrset, rdata_pos) == params->iterations
+		&& knot_rdata_nsec3_salt_length(rrset, rdata_pos) == params->salt_length
+		&& strncmp((const char *)knot_rdata_nsec3_salt(rrset, rdata_pos),
 			   (const char *)params->salt, params->salt_length)
 		   == 0);
 }
@@ -963,7 +964,8 @@ dbg_zone_exec(
 		// find proper node
 		knot_node_t *(*get_node)(const knot_zone_contents_t *,
 					   const knot_dname_t *)
-		    = (knot_rrset_rdata_rrsig_type_covered(rrsigs) == KNOT_RRTYPE_NSEC3)
+		    = (knot_rdata_rrsig_type_covered(rrsigs, 1)
+		       == KNOT_RRTYPE_NSEC3)
 		       ? knot_zone_contents_get_nsec3_node
 		       : knot_zone_contents_get_node;
 
@@ -979,9 +981,9 @@ dbg_zone_exec(
 		// find the RRSet in the node
 		// take only the first RDATA from the RRSIGs
 		dbg_zone_detail("Finding RRSet for type %d\n",
-				knot_rrset_rdata_rrsig_type_covered(rrsigs));
+				knot_rdata_rrsig_type_covered(rrsigs, 1));
 		*rrset = knot_node_get_rrset(
-			     *node, knot_rrset_rdata_rrsig_type_covered(rrsigs));
+			     *node, knot_rdata_rrsig_type_covered(rrsigs, 1));
 		if (*rrset == NULL) {
 			dbg_zone("Failed to find RRSet for RRSIGs.\n");
 			return KNOT_ENORRSET;
@@ -2345,5 +2347,5 @@ unsigned knot_zone_serial(const knot_zone_contents_t *zone)
 	if (!zone) return 0;
 	const knot_rrset_t *soa = NULL;
 	soa = knot_node_rrset(knot_zone_contents_apex(zone), KNOT_RRTYPE_SOA);
-	return knot_rrset_rdata_soa_serial(soa);
+	return knot_rdata_soa_serial(soa);
 }
diff --git a/src/libknot/zone/zone-diff.c b/src/libknot/zone/zone-diff.c
index d8e7ad6c079482993331c7062db794a658a9e46f..4d4ac9058c1bd6e49aadc36ca12f509a99aeb519 100644
--- a/src/libknot/zone/zone-diff.c
+++ b/src/libknot/zone/zone-diff.c
@@ -24,6 +24,7 @@
 #include "zone-diff.h"
 #include "libknot/nameserver/name-server.h"
 #include "common/descriptor.h"
+#include "libknot/rdata.h"
 
 struct zone_diff_param {
 	const knot_zone_contents_t *contents;
@@ -70,13 +71,13 @@ static int knot_zone_diff_load_soas(const knot_zone_contents_t *zone1,
 	}
 
 	int64_t soa_serial1 =
-		knot_rrset_rdata_soa_serial(soa_rrset1);
+		knot_rdata_soa_serial(soa_rrset1);
 	if (soa_serial1 == -1) {
 		dbg_zonediff("zone_diff: load_soas: Got bad SOA.\n");
 	}
 
 	int64_t soa_serial2 =
-		knot_rrset_rdata_soa_serial(soa_rrset2);
+		knot_rdata_soa_serial(soa_rrset2);
 
 	if (soa_serial2 == -1) {
 		dbg_zonediff("zone_diff: load_soas: Got bad SOA.\n");
diff --git a/src/utils/dig/dig_exec.c b/src/utils/dig/dig_exec.c
index e4572909e4857783fc0f694933009a090a5cdfd0..dee0bd2a396e3613f049152ba91038eb3a7a99a5 100644
--- a/src/utils/dig/dig_exec.c
+++ b/src/utils/dig/dig_exec.c
@@ -122,7 +122,7 @@ static knot_packet_t* create_query_packet(const query_t *query,
 		}
 
 		// Set SOA serial.
-		knot_rrset_rdata_soa_serial_set(soa, query->xfr_serial);
+		knot_rdata_soa_serial_set(soa, query->xfr_serial);
 
 		// Add authority section.
 		ret = knot_query_add_rrset_authority(packet, soa);
@@ -241,7 +241,7 @@ static int64_t first_serial_check(const knot_packet_t *reply)
 	if (first->type != KNOT_RRTYPE_SOA) {
 		return -1;
 	} else {
-		return knot_rrset_rdata_soa_serial(first);
+		return knot_rdata_soa_serial(first);
 	}
 }
 
@@ -256,7 +256,7 @@ static bool last_serial_check(const uint32_t serial, const knot_packet_t *reply)
 	if (last->type != KNOT_RRTYPE_SOA) {
 		return false;
 	} else {
-		int64_t last_serial = knot_rrset_rdata_soa_serial(last);
+		int64_t last_serial = knot_rdata_soa_serial(last);
 
 		if (last_serial == serial) {
 			return true;