/**
 *  --Add and remove APIs in netif.c for adding/removing
 *    IPv6 addresses to an interface that also installs a route in the route
 *    table.
 *  --Add a hook for fetching the gateway in lwip/opt.h and use it in
 *    ethip6.c.
 */
diff --git a/src/core/ipv6/ethip6.c b/src/core/ipv6/ethip6.c
index 509fc1c..cf367c5 100644
--- a/src/core/ipv6/ethip6.c
+++ b/src/core/ipv6/ethip6.c
@@ -53,6 +53,9 @@
 #include "lwip/icmp6.h"
 #include "lwip/prot/ethernet.h"
 #include "netif/ethernet.h"
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+#include "lwip/ip6_route_table.h"
+#endif
 
 #include <string.h>
 
@@ -79,6 +82,9 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
 {
   struct eth_addr dest;
   s8_t i;
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+  ip6_addr_t *gateway = NULL;
+#endif
 
   /* multicast destination IP address? */
   if (ip6_addr_ismulticast(ip6addr)) {
@@ -96,6 +102,18 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
 
   /* We have a unicast destination IP address */
   /* @todo anycast? */
+
+  /* See if a gateway is present for the destination address in a routing table */
+#ifdef LWIP_HOOK_ETHIP6_GET_GW
+  gateway = LWIP_HOOK_ETHIP6_GET_GW(netif, ip6addr);
+#endif
+  if (gateway != NULL) {
+    /* Replace the destination with the gateway. The gateway is
+     * assumed to be on-link.
+     */
+    ip6addr = gateway;
+  }
+
   /* Get next hop record. */
   i = nd6_get_next_hop_entry(ip6addr, netif);
   if (i < 0) {
diff --git a/src/core/netif.c b/src/core/netif.c
index 69982b4..e48fadc 100644
--- a/src/core/netif.c
+++ b/src/core/netif.c
@@ -88,6 +88,9 @@
 #if LWIP_IPV6
 #include "lwip/nd6.h"
 #endif
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+#include "lwip/ip6_route_table.h"
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
 
 #if LWIP_NETIF_STATUS_CALLBACK
 #define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
@@ -1244,6 +1247,119 @@ netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chos
   return ERR_VAL;
 }
 
+/** This function allows for the easy removal of an IPv6 address from an interface.
+ *
+ * @param netif netif on which the address is assigned
+ * @param ip6addr address to remove
+ */
+err_t
+netif_remove_ip6_address(struct netif *netif, ip6_addr_t *ip6addr)
+{
+  s8_t i;
+
+  i = netif_matches_ip6_addr(netif, ip6addr);
+  if (i >= 0) {
+    ip6_addr_set_zero(netif_ip6_addr(netif, i));
+    netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID);
+    return ERR_OK;
+  }
+
+  return ERR_VAL;
+}
+
+/**
+ * This function allows for the addition of a new IPv6 address to an interface
+ * along with a prefix len to add a route to the routing table.
+ *
+ * @param netif netif to add the address on
+ * @param ip6addr address to add
+ * @prefix_len the prefix length for the route corresponding to the address
+ * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here
+ */
+err_t
+netif_add_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr,
+                                 u8_t prefix_len, s8_t *chosen_idx)
+{
+  s8_t retval = ERR_OK;
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+  struct ip6_prefix ip6_pref;
+
+  if (!ip6_prefix_valid(prefix_len)) {
+    retval = ERR_ARG;
+    goto fail;
+  }
+#else
+  if (prefix_len != 64 && prefix_len != 128) {
+    retval = ERR_ARG;
+    goto fail;
+  }
+#endif
+
+  if ((retval = netif_add_ip6_address(netif, ip6addr, chosen_idx)) !=
+                ERR_OK) {
+    goto fail;
+  }
+
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+  /* Add a route in routing table for the prefix len. Ignore adding route if
+   * prefix_len is zero(default route) or prefix_len is 128(host route)
+   */
+  if (prefix_len > 0 && prefix_len < IP6_MAX_PREFIX_LEN) {
+    ip6_addr_copy(ip6_pref.addr, *ip6addr);
+    ip6_pref.prefix_len = prefix_len;
+    if ((retval = ip6_add_route_entry(&ip6_pref, netif, NULL, NULL)) !=
+                  ERR_OK) {
+      goto fail;
+    }
+  }
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+fail:
+  return retval;
+}
+
+/**
+ * This function allows for the removal of an IPv6 address from an interface
+ * as well as any routes associated with it.
+ *
+ * @param netif netif on which the address is assigned
+ * @param ip6addr address to remove
+ * @prefix_len the prefix length for the route corresponding to the address
+ */
+err_t
+netif_remove_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr,
+                                    u8_t prefix_len)
+{
+  s8_t retval = ERR_OK;
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+  struct ip6_prefix ip6_pref;
+
+  if (!ip6_prefix_valid(prefix_len)) {
+    retval = ERR_ARG;
+    goto fail;
+  }
+#else
+  if (prefix_len != 64 && prefix_len != 128) {
+    retval = ERR_ARG;
+    goto fail;
+  }
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+  if ((retval = netif_remove_ip6_address(netif, ip6addr)) != ERR_OK) {
+      goto fail;
+  }
+
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+  /* Remove the route in routing table for the prefix len */
+  ip6_addr_copy(ip6_pref.addr, *ip6addr);
+  ip6_pref.prefix_len = prefix_len;
+  ip6_remove_route_entry(&ip6_pref);
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+fail:
+  return retval;
+}
+
 /** Dummy IPv6 output function for netifs not supporting IPv6
  */
 static err_t
diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h
index 67a2d24..e65deb5 100644
--- a/src/include/lwip/netif.h
+++ b/src/include/lwip/netif.h
@@ -458,6 +458,11 @@ void netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state);
 s8_t netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr);
 void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit);
 err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx);
+err_t netif_remove_ip6_address(struct netif *netif, ip6_addr_t *ip6addr);
+err_t netif_add_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr,
+                                       u8_t prefix_len, s8_t *chosen_idx);
+err_t netif_remove_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr,
+                                          u8_t prefix_len);
 #define netif_set_ip6_autoconfig_enabled(netif, action) do { if(netif) { (netif)->ip6_autoconfig_enabled = (action); }}while(0)
 #endif /* LWIP_IPV6 */
 
diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
index 304609b..434e580 100644
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -2379,6 +2379,20 @@
 #define LWIP_IPV6_DHCP6                 0
 #endif
 
+/**
+ * LWIP_IPV6_ROUTE_TABLE_SUPPORT==1: Enable support for adding static routes and referring to these during forwarding.
+ */
+#ifndef LWIP_IPV6_ROUTE_TABLE_SUPPORT
+#define LWIP_IPV6_ROUTE_TABLE_SUPPORT   0
+#endif
+
+/**
+ * LWIP_IPV6_NUM_ROUTES: Number of IPV6 routes that can be kept in the static route table.
+ */
+#ifndef LWIP_IPV6_NUM_ROUTE_ENTRIES
+#define LWIP_IPV6_NUM_ROUTE_ENTRIES     8
+#endif
+
 /*
    ---------------------------------------
    ---------- Hook options ---------------
@@ -2522,6 +2536,20 @@
 #ifdef __DOXYGEN__
 #define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif)
 #endif
+
+/**
+* LWIP_HOOK_ETHIP6_GET_GW(netif, dest):
+* - called from ethip6_output() (IPv6)
+* - netif: the netif used for sending
+* - dest: the destination IPv6 address
+* Returns the IPv6 address of the gateway to handle the specified destination
+* IPv6 address. If NULL is returned, the netif's default gateway is used.
+* The returned address MUST be reachable on the specified netif!
+*/
+#ifdef __DOXYGEN__
+#define LWIP_HOOK_ETHIP6_GET_GW(netif, dest)
+#endif
+
 /**
  * @}
  */
