diff --git a/src/firewall.c b/src/firewall.c
index 51f858277db26008ee4afd84dd863b10d4ce0647..99b84b6e015d15d11766dbf81504e6df38da4dcc 100644
--- a/src/firewall.c
+++ b/src/firewall.c
@@ -889,7 +889,6 @@ static int get_rule_source_interface(char *refparam, struct dmctx *ctx, void *da
 	if (rule_args->is_dynamic_rule) {
 		dmuci_get_option_value_string("upnpd", "config", "internal_iface", &src);
 	} else {
-		char *ifaceobj = NULL, src_iface[256] = {0};
 		struct uci_list *net_list = NULL;
 
 		dmuci_get_value_by_section_string(rule_args->config_section, "src", &src);
@@ -913,24 +912,18 @@ static int get_rule_source_interface(char *refparam, struct dmctx *ctx, void *da
 
 		if (net_list != NULL) {
 			struct uci_element *e = NULL;
-			unsigned pos = 0;
+			char src_iface[256] = {0};
 
-			src_iface[0] = 0;
 			uci_foreach_element(net_list, e) {
-				bbf_get_reference_param("Device.IP.Interface.", "Name", e->name, &ifaceobj);
-				if (DM_STRLEN(ifaceobj))
-					pos += snprintf(&src_iface[pos], sizeof(src_iface) - pos, "%s,", ifaceobj);
+				bbfdm_get_references(ctx, MATCH_FIRST, "Device.IP.Interface.", "Name", e->name, src_iface, sizeof(src_iface));
 			}
 
-			if (pos)
-				src_iface[pos - 1] = 0;
-
 			*value = dmstrdup(src_iface);
 			return 0;
 		}
 	}
 
-	bbf_get_reference_param("Device.IP.Interface.", "Name", src, value);
+	_bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", src, value);
 	return 0;
 }
 
@@ -958,7 +951,6 @@ static int get_rule_dest_interface(char *refparam, struct dmctx *ctx, void *data
 	if (rule_args->is_dynamic_rule) {
 		dmuci_get_option_value_string("upnpd", "config", "external_iface", &dest);
 	} else {
-		char *ifaceobj = NULL, dst_iface[256] = {0};
 		struct uci_list *net_list = NULL;
 
 		dmuci_get_value_by_section_string(rule_args->config_section, "dest", &dest);
@@ -982,24 +974,18 @@ static int get_rule_dest_interface(char *refparam, struct dmctx *ctx, void *data
 
 		if (net_list != NULL) {
 			struct uci_element *e = NULL;
-			unsigned pos = 0;
+			char dst_iface[256] = {0};
 
-			dst_iface[0] = 0;
 			uci_foreach_element(net_list, e) {
-				bbf_get_reference_param("Device.IP.Interface.", "Name", e->name, &ifaceobj);
-				if (DM_STRLEN(ifaceobj))
-					pos += snprintf(&dst_iface[pos], sizeof(dst_iface) - pos, "%s,", ifaceobj);
+				bbfdm_get_references(ctx, MATCH_FIRST, "Device.IP.Interface.", "Name", e->name, dst_iface, sizeof(dst_iface));
 			}
 
-			if (pos)
-				dst_iface[pos - 1] = 0;
-
 			*value = dmstrdup(dst_iface);
 			return 0;
 		}
 	}
 
-	bbf_get_reference_param("Device.IP.Interface.", "Name", dest, value);
+	_bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", dest, value);
 	return 0;
 }
 
@@ -1605,7 +1591,7 @@ static int set_rule_interface(struct dmctx *ctx, void *data, char *type, char *v
 	struct dm_reference reference = {0};
 	char *option = NULL;
 
-	bbf_get_reference_args(value, &reference);
+	bbfdm_get_reference_linker(ctx, value, &reference);
 
 	switch (action) {
 		case VALUECHECK:
@@ -2103,7 +2089,7 @@ static int get_FirewallDMZ_Interface(char *refparam, struct dmctx *ctx, void *da
 
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "interface", &interf);
 
-	bbf_get_reference_param("Device.IP.Interface.", "Name", interf, value);
+	_bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", interf, value);
 	return 0;
 }
 
@@ -2112,7 +2098,7 @@ static int set_FirewallDMZ_Interface(char *refparam, struct dmctx *ctx, void *da
 	char *allowed_objects[] = {"Device.IP.Interface.", NULL};
 	struct dm_reference reference = {0};
 
-	bbf_get_reference_args(value, &reference);
+	bbfdm_get_reference_linker(ctx, value, &reference);
 
 	switch (action) {
 		case VALUECHECK:
@@ -2215,7 +2201,7 @@ static int get_service_intf(char *refparam, struct dmctx *ctx, void *data, char
 	if (intf == NULL || *intf == '\0')
 		return 0;
 
-	bbf_get_reference_param("Device.IP.Interface.", "Name", intf, value);
+	_bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", intf, value);
 
 	return 0;
 }
@@ -2225,7 +2211,7 @@ static int set_service_intf(char *refparam, struct dmctx *ctx, void *data, char
 	char *allowed_objects[] = {"Device.IP.Interface.", NULL};
 	struct dm_reference reference = {0};
 
-	bbf_get_reference_args(value, &reference);
+	bbfdm_get_reference_linker(ctx, value, &reference);
 
 	switch (action) {
 		case VALUECHECK:
diff --git a/src/nat.c b/src/nat.c
index a3a171bc7a0ad1ec15b992eb3717f78e3159fe4f..d68e8fe5224275b94da59174a6b08ecc256eb7e8 100644
--- a/src/nat.c
+++ b/src/nat.c
@@ -229,26 +229,17 @@ static int set_nat_interface_setting_alias(char *refparam, struct dmctx *ctx, vo
 static int get_nat_interface_setting_interface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	struct uci_list *v = NULL;
-	char buf[256];
-	unsigned pos = 0;
+	char buf[256] = {0};
 
-	buf[0] = 0;
 	dmuci_get_value_by_section_list(((struct dm_data *)data)->config_section, "network", &v);
 	if (v) {
 		struct uci_element *e = NULL;
-		char *ifaceobj = NULL;
 
 		uci_foreach_element(v, e) {
-			bbf_get_reference_param("Device.IP.Interface.", "Name", e->name, &ifaceobj);
-			if (DM_STRLEN(ifaceobj))
-				pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s,", ifaceobj);
+			bbfdm_get_references(ctx, MATCH_FIRST, "Device.IP.Interface.", "Name", e->name, buf, sizeof(buf));
 		}
 	}
 
-	/* cut tailing ',' */
-	if (pos)
-		buf[pos - 1] = 0;
-
 	*value = dmstrdup(buf);
 	return 0;
 }
@@ -258,7 +249,7 @@ static int set_nat_interface_setting_interface(char *refparam, struct dmctx *ctx
 	char *allowed_objects[] = {"Device.IP.Interface.", NULL};
 	struct dm_reference reference = {0};
 
-	bbf_get_reference_args(value, &reference);
+	bbfdm_get_reference_linker(ctx, value, &reference);
 
 	switch (action) {
 		case VALUECHECK:
@@ -324,14 +315,12 @@ static int get_nat_port_mapping_interface(char *refparam, struct dmctx *ctx, voi
 {
 	struct uci_section *s = NULL;
 	struct uci_list *v = NULL;
-	char *zone_name = NULL, *name = NULL, *src_dip = NULL, buf[256];
-	unsigned pos = 0;
+	char *zone_name = NULL, *name = NULL, *src_dip = NULL, buf[256] = {0};
 
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "src_dip", &src_dip);
 	if (src_dip && DM_LSTRCMP(src_dip, "*") == 0)
 		return 0;
 
-	buf[0] = 0;
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "src", &zone_name);
 	uci_foreach_sections("firewall", "zone", s) {
 		dmuci_get_value_by_section_string(s, "name", &name);
@@ -343,19 +332,12 @@ static int get_nat_port_mapping_interface(char *refparam, struct dmctx *ctx, voi
 
 	if (v) {
 		struct uci_element *e = NULL;
-		char *ifaceobj = NULL;
 
 		uci_foreach_element(v, e) {
-			bbf_get_reference_param("Device.IP.Interface.", "Name", e->name, &ifaceobj);
-			if (DM_STRLEN(ifaceobj))
-				pos += snprintf(&buf[pos], sizeof(buf) - pos, "%s,", ifaceobj);
+			bbfdm_get_references(ctx, MATCH_FIRST, "Device.IP.Interface.", "Name", e->name, buf, sizeof(buf));
 		}
 	}
 
-	/* cut tailing ',' */
-	if (pos)
-		buf[pos - 1] = 0;
-
 	*value = dmstrdup(buf);
 	return 0;
 }
@@ -365,7 +347,7 @@ static int set_nat_port_mapping_interface(char *refparam, struct dmctx *ctx, voi
 	char *allowed_objects[] = {"Device.IP.Interface.", NULL};
 	struct dm_reference reference = {0};
 
-	bbf_get_reference_args(value, &reference);
+	bbfdm_get_reference_linker(ctx, value, &reference);
 
 	switch (action) {
 		case VALUECHECK:
diff --git a/src/nat_porttrigger.c b/src/nat_porttrigger.c
index d21fdc8758fc2ce699367b7e1d7b03f2d2b4c568..6d212f5dbab91327eff7514343c8f6c17215a67c 100644
--- a/src/nat_porttrigger.c
+++ b/src/nat_porttrigger.c
@@ -256,7 +256,7 @@ static int get_NATPortTrigger_Interface(char *refparam, struct dmctx *ctx, void
 
 	dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "src", &interf);
 
-	bbf_get_reference_param("Device.IP.Interface.", "Name", interf, value);
+	_bbfdm_get_references(ctx, "Device.IP.Interface.", "Name", interf, value);
 
 	return 0;
 }
@@ -266,7 +266,7 @@ static int set_NATPortTrigger_Interface(char *refparam, struct dmctx *ctx, void
 	char *allowed_objects[] = {"Device.IP.Interface.", NULL};
 	struct dm_reference reference = {0};
 
-	bbf_get_reference_args(value, &reference);
+	bbfdm_get_reference_linker(ctx, value, &reference);
 
 	switch (action) {
 		case VALUECHECK: