 src/core/ipv6/ip6.c | 37 +++++++++++++++++++++++++++++++++----
 src/core/ipv6/nd6.c | 28 +++++++++++++++++++++++++---
 2 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c
index 7478d67..b7c5a8f 100644
--- a/src/core/ipv6/ip6.c
+++ b/src/core/ipv6/ip6.c
@@ -60,6 +60,18 @@
 #include "lwip/debug.h"
 #include "lwip/stats.h"
 
+/** small helper function that returns 1 if a netif is usable for transmission
+ * (i.e. is up, has link and has a link-local address set
+ */
+static int
+ip6_netif_usable(struct netif* netif)
+{
+  if ((netif != NULL) && netif_is_up(netif) && netif_is_link_up(netif) &&
+    ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) {
+    return 1;
+  }
+  return 0;
+}
 
 /**
  * Finds the appropriate network interface for a given IPv6 address. It tries to select
@@ -85,6 +97,9 @@ ip6_route(const struct ip6_addr *src, const struct ip6_addr *dest)
 
   /* If single netif configuration, fast return. */
   if ((netif_list != NULL) && (netif_list->next == NULL)) {
+    if (!ip6_netif_usable(netif_list)) {
+      return NULL;
+    }
     return netif_list;
   }
 
@@ -92,7 +107,9 @@ ip6_route(const struct ip6_addr *src, const struct ip6_addr *dest)
   if (ip6_addr_islinklocal(dest)) {
     if (ip6_addr_isany(src)) {
       /* Use default netif. */
-      return netif_default;
+      if (ip6_netif_usable(netif_default)) {
+        return netif_default;
+      }
     }
 
     /* Try to find the netif for the source address. */
@@ -100,12 +117,17 @@ ip6_route(const struct ip6_addr *src, const struct ip6_addr *dest)
       for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
         if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
             ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
-          return netif;
+          if (ip6_netif_usable(netif)) {
+            return netif;
+          }
         }
       }
     }
 
     /* netif not found, use default netif */
+    if (!ip6_netif_usable(netif_default)) {
+      return NULL;
+    }
     return netif_default;
   }
 
@@ -114,7 +136,9 @@ ip6_route(const struct ip6_addr *src, const struct ip6_addr *dest)
     for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
       if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
           ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
-        return netif;
+        if (ip6_netif_usable(netif)) {
+          return netif;
+        }
       }
     }
   }
@@ -135,13 +159,18 @@ ip6_route(const struct ip6_addr *src, const struct ip6_addr *dest)
       for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
         if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
             ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
-          return netif;
+          if (ip6_netif_usable(netif)) {
+            return netif;
+          }
         }
       }
     }
   }
 
   /* no matching netif found, use default netif */
+  if (!ip6_netif_usable(netif_default)) {
+    return NULL;
+  }
   return netif_default;
 }
 
diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c
index bf938a1..3f391df 100644
--- a/src/core/ipv6/nd6.c
+++ b/src/core/ipv6/nd6.c
@@ -1238,6 +1238,28 @@ nd6_is_prefix_in_netif(const ip6_addr_t * ip6addr, struct netif * netif)
   return 0;
 }
 
+/** small helper function that returns 1 if a netif is usable for transmission
+ * (i.e. is up, has link and has a link-local address set
+ */
+static int
+nd6_check_router_netif(struct netif* netif_a, struct netif* netif_b)
+{
+  if (netif_a != NULL) {
+    /* a router on a specific netif is requested */
+    if(netif_a == netif_b) {
+      return 1;
+    }
+  } else {
+    /* ip6_route requests a router, so the netif should be up, have a link and
+       a valid link-local address */
+    if(netif_is_up(netif_b) && netif_is_link_up(netif_b) &&
+            ip6_addr_isvalid(netif_ip6_addr_state(netif_b, 0))) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
 /**
  * Select a default router for a destination.
  *
@@ -1264,7 +1286,7 @@ nd6_select_router(const ip6_addr_t * ip6addr, struct netif * netif)
       last_router = 0;
     }
     if ((default_router_list[i].neighbor_entry != NULL) &&
-        (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1) &&
+        nd6_check_router_netif(netif, default_router_list[i].neighbor_entry->netif) &&
         (default_router_list[i].invalidation_timer > 0) &&
         (default_router_list[i].neighbor_entry->state == ND6_REACHABLE)) {
       return i;
@@ -1277,7 +1299,7 @@ nd6_select_router(const ip6_addr_t * ip6addr, struct netif * netif)
       last_router = 0;
     }
     if ((default_router_list[i].neighbor_entry != NULL) &&
-        (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1) &&
+        nd6_check_router_netif(netif, default_router_list[i].neighbor_entry->netif) &&
         (default_router_list[i].invalidation_timer > 0)) {
       return i;
     }
@@ -1289,7 +1311,7 @@ nd6_select_router(const ip6_addr_t * ip6addr, struct netif * netif)
       last_router = 0;
     }
     if (default_router_list[i].neighbor_entry != NULL &&
-        (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1)) {
+        nd6_check_router_netif(netif, default_router_list[i].neighbor_entry->netif)) {
       return i;
     }
   }
