diff --git a/system-dummy.c b/system-dummy.c
index b6b00508d70d34bea6764768f1972699ad1a1c86..40b0750a546a98efe67cbd32f173b34fe6fee823 100644
--- a/system-dummy.c
+++ b/system-dummy.c
@@ -321,12 +321,12 @@ time_t system_get_rtime(void)
 	return 0;
 }
 
-int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
+int system_del_ip_tunnel(const struct device *dev)
 {
 	return 0;
 }
 
-int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
+int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr)
 {
 	return 0;
 }
diff --git a/system-linux.c b/system-linux.c
index aaa626917d07ac41a920db06e0aed44b15879150..12755b5a46d95993386b5710ddd6f062c104f90b 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -90,7 +90,6 @@ static int cb_rtnl_event(struct nl_msg *msg, void *arg);
 static void handle_hotplug_event(struct uloop_fd *u, unsigned int events);
 static int system_add_proto_tunnel(const char *name, const uint8_t proto,
 					const unsigned int link, struct blob_attr **tb);
-static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb);
 
 static char dev_buf[256];
 
@@ -3703,7 +3702,7 @@ static int system_add_sit_tunnel(const char *name, const unsigned int link, stru
 	return ret;
 
 failure:
-	__system_del_ip_tunnel(name, tb);
+	system_link_del(name);
 	return ret;
 }
 
@@ -3765,33 +3764,9 @@ static int system_add_proto_tunnel(const char *name, const uint8_t proto, const
 	return -1;
 }
 
-static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
+int system_del_ip_tunnel(const struct device *dev)
 {
-	struct blob_attr *cur;
-	const char *str;
-
-	if (!(cur = tb[TUNNEL_ATTR_TYPE]))
-		return -EINVAL;
-	str = blobmsg_data(cur);
-
-	if (!strcmp(str, "greip") || !strcmp(str, "gretapip") ||
-	    !strcmp(str, "greip6") || !strcmp(str, "gretapip6") ||
-	    !strcmp(str, "vtiip") || !strcmp(str, "vtiip6") ||
-	    !strcmp(str, "vxlan") || !strcmp(str, "vxlan6") ||
-	    !strcmp(str, "xfrm"))
-		return system_link_del(name);
-	else
-		return tunnel_ioctl(name, SIOCDELTUNNEL, NULL);
-}
-
-int system_del_ip_tunnel(const char *name, struct blob_attr *attr)
-{
-	struct blob_attr *tb[__TUNNEL_ATTR_MAX];
-
-	blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
-		blob_data(attr), blob_len(attr));
-
-	return __system_del_ip_tunnel(name, tb);
+	return system_link_del(dev->ifname);
 }
 
 int system_update_ipv6_mtu(struct device *dev, int mtu)
@@ -3824,7 +3799,7 @@ out:
 	return ret;
 }
 
-int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
+int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr)
 {
 	struct blob_attr *tb[__TUNNEL_ATTR_MAX];
 	struct blob_attr *cur;
@@ -3833,7 +3808,7 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
 	blobmsg_parse(tunnel_attr_list.params, __TUNNEL_ATTR_MAX, tb,
 		blob_data(attr), blob_len(attr));
 
-	__system_del_ip_tunnel(name, tb);
+	system_link_del(dev->ifname);
 
 	if (!(cur = tb[TUNNEL_ATTR_TYPE]))
 		return -EINVAL;
@@ -3857,37 +3832,37 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
 	}
 
 	if (!strcmp(str, "sit"))
-		return system_add_sit_tunnel(name, link, tb);
+		return system_add_sit_tunnel(dev->ifname, link, tb);
 #ifdef IFLA_IPTUN_MAX
 	else if (!strcmp(str, "ipip6")) {
-		return system_add_ip6_tunnel(name, link, tb);
+		return system_add_ip6_tunnel(dev->ifname, link, tb);
 	} else if (!strcmp(str, "greip")) {
-		return system_add_gre_tunnel(name, "gre", link, tb, false);
+		return system_add_gre_tunnel(dev->ifname, "gre", link, tb, false);
 	} else if (!strcmp(str, "gretapip"))  {
-		return system_add_gre_tunnel(name, "gretap", link, tb, false);
+		return system_add_gre_tunnel(dev->ifname, "gretap", link, tb, false);
 	} else if (!strcmp(str, "greip6")) {
-		return system_add_gre_tunnel(name, "ip6gre", link, tb, true);
+		return system_add_gre_tunnel(dev->ifname, "ip6gre", link, tb, true);
 	} else if (!strcmp(str, "gretapip6")) {
-		return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
+		return system_add_gre_tunnel(dev->ifname, "ip6gretap", link, tb, true);
 #ifdef IFLA_VTI_MAX
 	} else if (!strcmp(str, "vtiip")) {
-		return system_add_vti_tunnel(name, "vti", link, tb, false);
+		return system_add_vti_tunnel(dev->ifname, "vti", link, tb, false);
 	} else if (!strcmp(str, "vtiip6")) {
-		return system_add_vti_tunnel(name, "vti6", link, tb, true);
+		return system_add_vti_tunnel(dev->ifname, "vti6", link, tb, true);
 #endif
 #ifdef IFLA_XFRM_MAX
 	} else if (!strcmp(str, "xfrm")) {
-		return system_add_xfrm_tunnel(name, "xfrm", link, tb);
+		return system_add_xfrm_tunnel(dev->ifname, "xfrm", link, tb);
 #endif
 #ifdef IFLA_VXLAN_MAX
 	} else if(!strcmp(str, "vxlan")) {
-		return system_add_vxlan(name, link, tb, false);
+		return system_add_vxlan(dev->ifname, link, tb, false);
 	} else if(!strcmp(str, "vxlan6")) {
-		return system_add_vxlan(name, link, tb, true);
+		return system_add_vxlan(dev->ifname, link, tb, true);
 #endif
 #endif
 	} else if (!strcmp(str, "ipip")) {
-		return system_add_proto_tunnel(name, IPPROTO_IPIP, link, tb);
+		return system_add_proto_tunnel(dev->ifname, IPPROTO_IPIP, link, tb);
 	}
 	else
 		return -EINVAL;
diff --git a/system.h b/system.h
index d4f2ca8c160af32461893228f740d1f132cb90a0..289eb959f0680ca683bbe4e27f121beb902f9eb5 100644
--- a/system.h
+++ b/system.h
@@ -264,8 +264,8 @@ bool system_resolve_rt_table(const char *name, unsigned int *id);
 bool system_is_default_rt_table(unsigned int id);
 bool system_resolve_rpfilter(const char *filter, unsigned int *id);
 
-int system_del_ip_tunnel(const char *name, struct blob_attr *attr);
-int system_add_ip_tunnel(const char *name, struct blob_attr *attr);
+int system_del_ip_tunnel(const struct device *dev);
+int system_add_ip_tunnel(const struct device *dev, struct blob_attr *attr);
 
 int system_add_iprule(struct iprule *rule);
 int system_del_iprule(struct iprule *rule);
diff --git a/tunnel.c b/tunnel.c
index 1383384075cf57e8e95b3edf31602e57eb159639..6d192ac8509423f4b4ac23a38295c0079880d154 100644
--- a/tunnel.c
+++ b/tunnel.c
@@ -28,14 +28,14 @@ tunnel_set_state(struct device *dev, bool up)
 	int ret;
 
 	if (up) {
-		ret = system_add_ip_tunnel(dev->ifname, dev->config);
+		ret = system_add_ip_tunnel(dev, dev->config);
 		if (ret != 0)
 			return ret;
 	}
 
 	ret = tun->set_state(dev, up);
 	if (ret || !up)
-		system_del_ip_tunnel(dev->ifname, dev->config);
+		system_del_ip_tunnel(dev);
 
 	return ret;
 }