You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/06/06 18:05:06 UTC

[GitHub] ccollins476ad closed pull request #1128: lwIP static routing for IPv6

ccollins476ad closed pull request #1128: lwIP static routing for IPv6
URL: https://github.com/apache/mynewt-core/pull/1128
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/net/ip/include/lwipopts.h b/net/ip/include/lwipopts.h
index 2110570475..5ca8f1cf5e 100644
--- a/net/ip/include/lwipopts.h
+++ b/net/ip/include/lwipopts.h
@@ -19,6 +19,8 @@
 #ifndef __LWIP_LWIPOPTS_H__
 #define __LWIP_LWIPOPTS_H__
 
+#include "syscfg/syscfg.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -181,7 +183,7 @@ extern "C" {
 
 /* ---------- Statistics options ---------- */
 /* XXX hook into sys/stats */
-#define LWIP_STATS                           0
+#define LWIP_STATS                      0
 
 #if LWIP_STATS
 #define LINK_STATS                      1
@@ -199,6 +201,21 @@ extern "C" {
 #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
 #define ERRNO                     0
 
+
+/* -------------- Hooks -------------- */
+
+#if MYNEWT_VAL(LWIP_IPV6_STATIC_ROUTING)
+
+#define LWIP_HOOK_IP6_ROUTE             ip6_static_route
+
+struct netif;
+struct ip6_addr;
+
+struct netif *ip6_static_route(const struct ip6_addr *src,
+                               const struct ip6_addr *dest);
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/net/ip/lwip_base/pkg.yml b/net/ip/lwip_base/pkg.yml
index bf24446be6..dfb0a91336 100644
--- a/net/ip/lwip_base/pkg.yml
+++ b/net/ip/lwip_base/pkg.yml
@@ -30,6 +30,9 @@ pkg.keywords:
 pkg.deps:
     - net/ip
 
+pkg.deps.LWIP_IPV6_STATIC_ROUTING:
+    - '@apache-mynewt-core/net/ip/lwip_contrib/addons/ipv6_static_routing'
+
 pkg.cflags:
     - -Wno-unused
     - -Wno-error=address
diff --git a/net/ip/lwip_base/syscfg.yml b/net/ip/lwip_base/syscfg.yml
new file mode 100644
index 0000000000..041171c45f
--- /dev/null
+++ b/net/ip/lwip_base/syscfg.yml
@@ -0,0 +1,4 @@
+syscfg.defs:
+    LWIP_IPV6_STATIC_ROUTING:
+        decription: Enables static IPv6 routing tables.
+        value: 0
diff --git a/net/ip/lwip_contrib/addons/ipv6_static_routing/README b/net/ip/lwip_contrib/addons/ipv6_static_routing/README
new file mode 100644
index 0000000000..0c3b06cc08
--- /dev/null
+++ b/net/ip/lwip_contrib/addons/ipv6_static_routing/README
@@ -0,0 +1,43 @@
+A simple routing table implementation for addition, deletion and lookup of IPv6 routes. 
+
+APIs are:
+1) s8_t ip6_add_route_entry(struct ip6_prefix *ip6_prefix,
+                            struct netif *netif,
+                            ip6_addr_t *gateway,
+                            s8_t *index);
+
+2) err_t ip6_remove_route_entry(struct ip6_prefix *ip6_prefix);
+
+3) s8_t ip6_find_route_entry(ip6_addr_t *ip6_dest_addr);
+
+4) struct netif *ip6_static_route(ip6_addr_t *src, ip6_addr_t *dest);
+
+5) ip6_addr_t *ip6_get_gateway(struct netif *netif, ip6_addr_t *dest);
+
+6) struct ip6_route_entry *ip6_get_route_table(void);
+
+For route lookup from the table, The LWIP_HOOK_IP6_ROUTE hook in ip6_route(..) of ip6.c
+could be assigned to the ip6_static_route() API of this implementation to return the 
+appropriate netif.
+
+-- The application can add routes using the API ip6_add_route_entry(..). 
+   This API adds the ip6 prefix route into the static route table while
+   keeping all entries sorted in decreasing order of prefix length.
+   Subsequently, a linear search down the list can be performed to retrieve a
+   matching route entry for a Longest Prefix Match.
+   The prefix length is expected to be at an 8-bit boundary. While this is 
+   a limitation, it would serve most practical purposes.
+
+-- The application can remove routes using the API ip6_remove_route_entry(..).
+
+-- The application can find a route entry for a specific address using the 
+   ip6_find_route_entry() function which returns the index of the found entry. 
+   This is used internally by the route lookup function ip6_static_route() API.
+
+-- To fetch the gateway IPv6 address for a specific destination IPv6 
+   address and target netif, the application can call ip6_get_gateway(..).
+   This API could be assigned to the LWIP_HOOK_ND6_GET_GW() if a gateway has
+   been added as part of the ip6_add_route_entry().
+
+-- To fetch a pointer to the head of the table, the application can call 
+   ip6_get_route_table().
diff --git a/net/ip/lwip_contrib/addons/ipv6_static_routing/include/ipv6_static_routing/ip6_route_table.h b/net/ip/lwip_contrib/addons/ipv6_static_routing/include/ipv6_static_routing/ip6_route_table.h
new file mode 100644
index 0000000000..1cab880e8a
--- /dev/null
+++ b/net/ip/lwip_contrib/addons/ipv6_static_routing/include/ipv6_static_routing/ip6_route_table.h
@@ -0,0 +1,94 @@
+/**
+ * @file
+ *
+ * IPv6 static route table.
+ */
+
+/*
+ * Copyright (c) 2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Pradip De <pr...@google.com>
+ *
+ *
+ * Please coordinate changes and requests with Pradip De
+ * <pr...@google.com>
+ */
+
+#ifndef __LWIP_IP6_ROUTE_TABLE_H__
+#define __LWIP_IP6_ROUTE_TABLE_H__
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/ip6_addr.h"
+#include "lwip/err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct netif;
+  
+/**
+ * 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
+
+#define IP6_MAX_PREFIX_LEN                  (128)
+#define IP6_PREFIX_ALLOWED_GRANULARITY      (8)
+/* Prefix length cannot be greater than 128 bits and needs to be at a byte boundary */
+#define ip6_prefix_valid(prefix_len)        (((prefix_len) <= IP6_MAX_PREFIX_LEN) &&                 \
+                                             (((prefix_len) % IP6_PREFIX_ALLOWED_GRANULARITY) == 0))
+
+struct ip6_prefix {
+  ip6_addr_t addr;
+  u8_t prefix_len; /* prefix length in bits at byte boundaries */
+};
+
+struct ip6_route_entry {
+  struct ip6_prefix prefix;
+  struct netif *netif;
+  const ip6_addr_t *gateway;
+};
+
+err_t ip6_add_route_entry(const struct ip6_prefix *ip6_prefix, struct netif *netif,
+                          const ip6_addr_t *gateway, s8_t *idx);
+void ip6_remove_route_entry(const struct ip6_prefix *ip6_prefix);
+s8_t ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr);
+struct netif *ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest);
+const ip6_addr_t *ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest);
+const struct ip6_route_entry *ip6_get_route_table(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* __LWIP_IP6_ROUTE_TABLE_H__ */
diff --git a/net/ip/lwip_contrib/addons/ipv6_static_routing/pkg.yml b/net/ip/lwip_contrib/addons/ipv6_static_routing/pkg.yml
new file mode 100644
index 0000000000..f221f54321
--- /dev/null
+++ b/net/ip/lwip_contrib/addons/ipv6_static_routing/pkg.yml
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: net/ip/lwip_contrib/addons/ipv6_static_routing
+pkg.description: LwIP 
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://savannah.nongnu.org/git/?group=lwip"
+pkg.keywords:
+    - ipv6
+    - static route
+
+pkg.deps:
+    - '@apache-mynewt-core/net/ip/lwip_base'
diff --git a/net/ip/lwip_contrib/addons/ipv6_static_routing/src/ip6_route_table.c b/net/ip/lwip_contrib/addons/ipv6_static_routing/src/ip6_route_table.c
new file mode 100644
index 0000000000..beb20bfab3
--- /dev/null
+++ b/net/ip/lwip_contrib/addons/ipv6_static_routing/src/ip6_route_table.c
@@ -0,0 +1,248 @@
+/**
+ * @file
+ * IPv6 static route table.
+ */
+
+/*
+ * Copyright (c) 2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Pradip De <pr...@google.com>
+ *
+ *
+ * Please coordinate changes and requests with Pradip De
+ * <pr...@google.com>
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+
+#include "ipv6_static_routing/ip6_route_table.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/nd6.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+
+#include "string.h"
+
+static struct ip6_route_entry static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES];
+
+/**
+ * Add the ip6 prefix route and target netif into the static route table while
+ * keeping all entries sorted in decreasing order of prefix length.
+ * 1. Search from the last entry up to find the correct slot to insert while
+ *    moving entries one position down to create room.
+ * 2. Insert into empty slot created.
+ *
+ * Subsequently, a linear search down the list can be performed to retrieve a
+ * matching route entry for a Longest Prefix Match.
+ *
+ * @param ip6_prefix the route prefix entry to add.
+ * @param netif pointer to target netif.
+ * @param gateway the gateway address to use to send through. Has to be link local.
+ * @param idx return value argument of index where route entry was added in table.
+ * @return ERR_OK  if addition was successful.
+ *         ERR_MEM if table is already full.
+ *         ERR_ARG if passed argument is bad or route already exists in table.
+ */
+err_t
+ip6_add_route_entry(const struct ip6_prefix *ip6_prefix, struct netif *netif, const ip6_addr_t *gateway, s8_t *idx)
+{
+  s8_t i = -1;
+  err_t retval = ERR_OK;
+
+  if (!ip6_prefix_valid(ip6_prefix->prefix_len) || (netif == NULL)) {
+    retval = ERR_ARG;
+    goto exit;
+  }
+
+  /* Check if an entry already exists with matching prefix; If so, replace it. */
+  for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+    if ((ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len) &&
+        memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr,
+               ip6_prefix->prefix_len / 8) == 0) {
+      /* Prefix matches; replace the netif with the one being added. */
+      goto insert;
+    }
+  }
+
+  /* Check if the table is full */
+  if (static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES - 1].netif != NULL) {
+    retval = ERR_MEM;
+    goto exit;
+  }
+
+  /* Shift all entries down the table until slot is found */
+  for (i = LWIP_IPV6_NUM_ROUTE_ENTRIES - 1;
+       i > 0 && (ip6_prefix->prefix_len > static_route_table[i - 1].prefix.prefix_len); i--) {
+    SMEMCPY(&static_route_table[i], &static_route_table[i - 1], sizeof(struct ip6_route_entry));
+  }
+
+insert:
+  /* Insert into the slot selected */
+  SMEMCPY(&static_route_table[i].prefix, ip6_prefix, sizeof(struct ip6_prefix));
+  static_route_table[i].netif = netif;
+
+  /* Add gateway to route table */
+  static_route_table[i].gateway = gateway;
+
+  if (idx != NULL) {
+    *idx = i;
+  }
+
+exit:
+  return retval;
+}
+
+/**
+ * Removes the route entry from the static route table.
+ *
+ * @param ip6_prefix the route prefix entry to delete.
+ */
+void
+ip6_remove_route_entry(const struct ip6_prefix *ip6_prefix)
+{
+  int i, pos = -1;
+
+  for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+    /* compare prefix to find position to delete */
+    if (ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len &&
+        memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr,
+               ip6_prefix->prefix_len / 8) == 0) {
+      pos = i;
+      break;
+    }
+  }
+
+  if (pos >= 0) {
+    /* Shift everything beyond pos one slot up */
+    for (i = pos; i < LWIP_IPV6_NUM_ROUTE_ENTRIES - 1; i++) {
+      SMEMCPY(&static_route_table[i], &static_route_table[i+1], sizeof(struct ip6_route_entry));
+      if (static_route_table[i].netif == NULL) {
+        break;
+      }
+    }
+    /* Zero the remaining entries */
+    for (; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+      ip6_addr_set_zero((&static_route_table[i].prefix.addr));
+      static_route_table[i].netif = NULL;
+    }
+  }
+}
+
+/**
+ * Finds the appropriate route entry in the static route table corresponding to the given
+ * destination IPv6 address. Since the entries in the route table are kept sorted in decreasing
+ * order of prefix length, a linear search down the list is performed to retrieve a matching
+ * index.
+ *
+ * @param ip6_dest_addr the destination address to match
+ * @return the idx of the found route entry; -1 if not found.
+ */
+s8_t
+ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr)
+{
+  s8_t i, idx = -1;
+
+  /* Search prefix in the sorted(decreasing order of prefix length) list */
+  for(i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) {
+    if (memcmp(ip6_dest_addr, &static_route_table[i].prefix.addr,
+        static_route_table[i].prefix.prefix_len / 8) == 0) {
+      idx = i;
+      break;
+    }
+  }
+
+  return idx;
+}
+
+/**
+ * Finds the appropriate network interface for a given IPv6 address from a routing table with
+ * static IPv6 routes.
+ *
+ * @param src the source IPv6 address, if known
+ * @param dest the destination IPv6 address for which to find the route
+ * @return the netif on which to send to reach dest
+ */
+struct netif *
+ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+{
+  int i;
+
+  LWIP_UNUSED_ARG(src);
+
+  /* Perform table lookup */
+  i = ip6_find_route_entry(dest);
+
+  if (i >= 0) {
+    return static_route_table[i].netif;
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * Finds the gateway IP6 address for a given destination IPv6 address and target netif
+ * from a routing table with static IPv6 routes.
+ *
+ * @param netif the netif used for sending
+ * @param dest the destination IPv6 address
+ * @return the ip6 address of the gateway to forward packet to
+ */
+const ip6_addr_t *
+ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest)
+{
+  const ip6_addr_t *ret_gw = NULL;
+  const int i = ip6_find_route_entry(dest);
+
+  LWIP_UNUSED_ARG(netif);
+  
+  if (i >= 0) {
+    if (static_route_table[i].gateway != NULL) {
+      ret_gw = static_route_table[i].gateway;
+    }
+  }
+
+  return ret_gw;
+}
+
+/**
+ * Returns the top of the route table.
+ * This should be used for debug printing only.
+ *
+ * @return the top of the route table.
+ */
+const struct ip6_route_entry *
+ip6_get_route_table(void)
+{
+    return static_route_table;
+}
+
+#endif /* LWIP_IPV6 */


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services