diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..1d881fe
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement. You (or your employer) retain the copyright to your contribution;
+this simply gives us permission to use and redistribute your contributions as
+part of the project. Head over to to see
+your current agreements on file or to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code reviews
+
+All submissions, including submissions by project members, require review. We
+use GitHub pull requests for this purpose. Consult
+[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
+information on using pull requests.
+
diff --git a/COPYING b/COPYING
deleted file mode 100755
index e23898b..0000000
--- a/COPYING
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
- * 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.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels
- *
- */
-
-
diff --git a/Kconfig b/Kconfig
index a0b9478..2d0807a 100644
--- a/Kconfig
+++ b/Kconfig
@@ -1,21 +1,5 @@
menu "LWIP"
-config L2_TO_L3_COPY
- bool "Enable copy between Layer2 and Layer3 packets"
- default n
- help
- If this feature is enabled, all traffic from layer2(WIFI Driver) will be
- copied to a new buffer before sending it to layer3(LWIP stack), freeing
- the layer2 buffer.
- Please be notified that the total layer2 receiving buffer is fixed and
- ESP32 currently supports 25 layer2 receiving buffer, when layer2 buffer
- runs out of memory, then the incoming packets will be dropped in hardware.
- The layer3 buffer is allocated from the heap, so the total layer3 receiving
- buffer depends on the available heap size, when heap runs out of memory,
- no copy will be sent to layer3 and packet will be dropped in layer2.
- Please make sure you fully understand the impact of this feature before
- enabling it.
-
config LWIP_MAX_SOCKETS
int "Max number of open sockets"
range 1 32
diff --git a/LICENSE b/LICENSE
new file mode 100755
index 0000000..97b1536
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,268 @@
+
+The openweave-esp32-lwip project is a derivative work of the LwIP project
+(https://savannah.nongnu.org/projects/lwip/).
+
+LwIP is Copyright (c) 2001, 2002 Swedish Institute of Computer Science, and is published
+under a modified BSD license:
+
+ 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.
+
+The openweave-esp32-lwip project also contains software contributed by Espressif Systems
+as part of their ESP-IDF project (https://github.com/espressif/esp-idf).
+
+The ESP-IDF LwIP software is Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD,
+and is published under the Apache 2.0 license (attached below).
+
+Finally, the following files contain work that is contributed by Google as part of the
+OpenWeave project (https://openweave.io/). These contributions are Copyright 2018 Google LLC,
+and published under the Apache 2.0 license.
+
+ Kconfig
+ core/ipv6/ethip6.c
+ core/ipv6/ip6.c
+ core/ipv6/ip6_route_table.c
+ core/ipv6/nd6.c
+ core/netif.c
+ core/udp.c
+ include/lwip/lwip/ip6_addr.h
+ include/lwip/lwip/ip6_route_table.h
+ include/lwip/lwip/netif.h
+ include/lwip/lwip/opt.h
+ include/lwip/lwip/priv/tcpip_priv.h
+ include/lwip/lwip/tcpip.h
+ include/lwip/lwip/udp.h
+ include/lwip/port/lwipopts.h
+ patches/openweave-esp32-lwip-patch-0001-Add-custom-core-locking.patch
+ patches/openweave-esp32-lwip-patch-0002-Enforce-wlan-buffer-copy.patch
+ patches/openweave-esp32-lwip-patch-0003-Removed-include-lwipopts.h.patch
+ patches/openweave-esp32-lwip-patch-0004-Fix-source-IPv6-addr.patch
+ patches/openweave-esp32-lwip-patch-0005-Fix-ip6_get_subnet_id.patch
+ patches/openweave-esp32-lwip-patch-0006-Send-neighbor-solicitation.patch
+ patches/openweave-esp32-lwip-patch-0007-UDP-interface-binding-support.patch
+ patches/openweave-esp32-lwip-patch-0008-Static-route-table-management.patch
+ patches/openweave-esp32-lwip-patch-0009-Enable-custom-pbufs.patch
+ port/netif/wlanif.c
+
+-----
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
\ No newline at end of file
diff --git a/README b/README
index 495556e..ac42ff4 100755
--- a/README
+++ b/README
@@ -1,3 +1,25 @@
+openweave-esp32-lwip
+
+openweave-esp32-lwip is version of the LwIP Lightweight TCP/IP stack enhanced
+to support Nest’s OpenWeave IoT application layer framework running on the
+Espressif ESP32.
+
+openweave-esp32-lwip is a combination of three open-source code bases:
+
+ * the baseline LwIP stack published, by the LwIP project;
+ * patches to LwIP for the ESP32, published by Espressif Systems; and
+ * patches to LwIP to support OpenWeave, published by Nest/Google.
+
+The Nest team has published this code in a combined form to make it easier for
+developers to build and test OpenWeave applications on the ESP32. Despite
+this, openweave-esp32-lwip does not constitute an officially supported Google
+Product.
+
+
+-------------------------------------------------------------------------
+Original LwIP README documentation follows
+-------------------------------------------------------------------------
+
INTRODUCTION
lwIP is a small independent implementation of the TCP/IP protocol
diff --git a/core/ipv6/ethip6.c b/core/ipv6/ethip6.c
index 36aa952..c68a54c 100755
--- a/core/ipv6/ethip6.c
+++ b/core/ipv6/ethip6.c
@@ -38,6 +38,21 @@
* Please coordinate changes and requests with Ivan Delamer
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#include "lwip/opt.h"
@@ -51,6 +66,9 @@
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/icmp6.h"
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+#include "lwip/ip6_route_table.h"
+#endif
#include "netif/ethernet.h"
#include
@@ -103,6 +121,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
/* make room for Ethernet header - should not fail */
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
@@ -128,6 +149,20 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
/* We have a unicast destination IP address */
/* TODO anycast? */
+
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+ /* See if a gateway is present for the destination address in the static route 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;
+ }
+#endif
+
/* Get next hop record. */
i = nd6_get_next_hop_entry(ip6addr, netif);
if (i < 0) {
diff --git a/core/ipv6/ip6.c b/core/ipv6/ip6.c
index acd28fb..61dd5c5 100755
--- a/core/ipv6/ip6.c
+++ b/core/ipv6/ip6.c
@@ -38,6 +38,21 @@
* Please coordinate changes and requests with Ivan Delamer
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#include "lwip/opt.h"
@@ -59,6 +74,10 @@
#include "lwip/debug.h"
#include "lwip/stats.h"
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+#include "lwip/ip6_route_table.h"
+#endif
+
/**
* Finds the appropriate network interface for a given IPv6 address. It tries to select
* a netif following a sequence of heuristics:
@@ -66,9 +85,16 @@
* 2) if the destination is a link-local address, try to match the src address to a netif.
* this is a tricky case because with multiple netifs, link-local addresses only have
* meaning within a particular subnet/link.
+ * #if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+ * 3) tries to find a netif with a configured address matching the destination or look up
+ * a route table for potential matching routes.
+ * #else
* 3) tries to match the destination subnet to a configured address
+ * #endif
* 4) tries to find a router
+ * #if !LWIP_IPV6_ROUTE_TABLE_SUPPORT
* 5) tries to match the source address to the netif
+ * #endif
* 6) returns the default netif, if configured
*
* @param src the source IPv6 address, if known
@@ -78,7 +104,7 @@
struct netif *
ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
{
- struct netif *netif;
+ struct netif *netif = NULL;
s8_t i;
/* If single netif configuration, fast return. */
@@ -127,6 +153,25 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
}
#endif
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+ /* Loop through the netif list to find a matching address */
+ for (netif = netif_list; netif != NULL; netif = netif->next) {
+ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+ if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+ ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
+ /* Configured address on netif matches destination address */
+ return netif;
+ }
+ }
+ }
+
+ /* Lookup route table */
+ if ((netif = ip6_static_route(src, dest)) != NULL)
+ {
+ return netif;
+ }
+
+#else /* else LWIP_IPV6_ROUTE_TABLE_SUPPORT */
/* See if the destination subnet matches a configured address. */
for (netif = netif_list; netif != NULL; netif = netif->next) {
if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
@@ -139,6 +184,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
}
}
}
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
/* Get the netif for a suitable router. */
i = nd6_select_router(dest, NULL);
@@ -152,6 +198,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
}
}
+#if !LWIP_IPV6_ROUTE_TABLE_SUPPORT
/* try with the netif that matches the source address. */
if (!ip6_addr_isany(src)) {
for (netif = netif_list; netif != NULL; netif = netif->next) {
@@ -166,6 +213,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
}
}
}
+#endif /* !LWIP_IPV6_ROUTE_TABLE_SUPPORT */
#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
/* loopif is disabled, loopback traffic is passed through any netif */
@@ -233,7 +281,7 @@ ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest)
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) &&
- ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
+ ip6_addr_net48cmp(dest, netif_ip6_addr(netif, i))) {
return netif_ip_addr6(netif, i);
}
}
diff --git a/core/ipv6/ip6_route_table.c b/core/ipv6/ip6_route_table.c
new file mode 100644
index 0000000..960b43d
--- /dev/null
+++ b/core/ipv6/ip6_route_table.c
@@ -0,0 +1,267 @@
+/**
+ * @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
+ *
+ *
+ * Please coordinate changes and requests with Pradip De
+ *
+ */
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/netif.h"
+#include "lwip/ip6.h"
+#include "lwip/ip6_route_table.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/nd6.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+
+#include "string.h"
+
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+
+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 index 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(struct ip6_prefix *ip6_prefix, struct netif *netif, ip6_addr_t *gateway, s8_t *index)
+{
+ int 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 (index != NULL) {
+ *index = 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(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;
+ }
+ }
+
+ return;
+}
+
+/**
+ * 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 index of the found route entry; -1 if not found.
+ */
+s8_t
+ip6_find_route_entry(ip6_addr_t *ip6_dest_addr)
+{
+ int i, index = -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) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+}
+
+/**
+ * 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(ip6_addr_t *src, ip6_addr_t *dest)
+{
+
+ int i;
+ /* 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
+ */
+ip6_addr_t *
+ip6_get_gateway(struct netif *netif, ip6_addr_t *dest)
+{
+ ip6_addr_t *ret_gw = NULL;
+ const int i = ip6_find_route_entry(dest);
+
+ 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.
+ */
+struct ip6_route_entry *
+ip6_get_route_table(void)
+{
+ return static_route_table;
+}
+
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+#endif /* LWIP_IPV6 */
diff --git a/core/ipv6/nd6.c b/core/ipv6/nd6.c
index 1cec55d..25ce6c3 100755
--- a/core/ipv6/nd6.c
+++ b/core/ipv6/nd6.c
@@ -40,6 +40,21 @@
* Please coordinate changes and requests with Ivan Delamer
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#include "lwip/opt.h"
@@ -672,7 +687,12 @@ nd6_tmr(void)
(!neighbor_cache[i].isrouter)) {
/* Retries exceeded. */
nd6_free_neighbor_cache_entry(i);
- } else {
+ }
+ else if (neighbor_cache[i].counter.probes_sent == 0) {
+ /* the first NS has already been sent when the 'INCOMPLETE' neighbor entry is created */
+ neighbor_cache[i].counter.probes_sent++;
+ }
+ else {
/* Send a NS for this entry. */
neighbor_cache[i].counter.probes_sent++;
nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST);
@@ -1408,6 +1428,7 @@ nd6_new_router(const ip6_addr_t * router_addr, struct netif * netif)
neighbor_cache[neighbor_index].q = NULL;
neighbor_cache[neighbor_index].state = ND6_INCOMPLETE;
neighbor_cache[neighbor_index].counter.probes_sent = 0;
+ nd6_send_ns(neighbor_cache[neighbor_index].netif, &(neighbor_cache[neighbor_index].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST);
}
/* Mark neighbor as router. */
@@ -1592,6 +1613,7 @@ nd6_get_next_hop_entry(const ip6_addr_t * ip6addr, struct netif * netif)
neighbor_cache[i].netif = netif;
neighbor_cache[i].state = ND6_INCOMPLETE;
neighbor_cache[i].counter.probes_sent = 0;
+ nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST);
}
}
diff --git a/core/netif.c b/core/netif.c
index 2b25143..5feb8ac 100755
--- a/core/netif.c
+++ b/core/netif.c
@@ -35,6 +35,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#include "lwip/opt.h"
@@ -69,6 +84,10 @@
#include "lwip/mld6.h"
#endif /* LWIP_IPV6_MLD */
+#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)
#else
@@ -997,6 +1016,99 @@ netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
#endif /* LWIP_IPV6_AUTOCONFIG */
}
+/**
+ * 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;
+}
+
/** This function allows for the easy addition of a new IPv6 address to an interface.
* It takes care of finding an empty slot and then sets the address tentative
* (to make sure that all the subsequent processing happens).
@@ -1037,6 +1149,28 @@ 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_get_ip6_addr_match(netif, ip6addr);
+ if (i >= 0) {
+ ip6_addr_t zero;
+ ip6_addr_set_zero(&zero);
+ netif_ip6_addr_set(netif, i, &zero);
+ netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID);
+ return ERR_OK;
+ }
+
+ return ERR_VAL;
+}
+
/** Dummy IPv6 output function for netifs not supporting IPv6
*/
static err_t
diff --git a/core/udp.c b/core/udp.c
index 779dd9a..c379031 100755
--- a/core/udp.c
+++ b/core/udp.c
@@ -35,6 +35,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
/* udp.c
@@ -273,6 +288,9 @@ udp_input(struct pbuf *p, struct netif *inp)
ip_addr_debug_print(UDP_DEBUG, &pcb->remote_ip);
LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port));
+ if ( ! (pcb->intf_filter == NULL || pcb->intf_filter == inp) )
+ continue;
+
/* compare PCB local addr+port to UDP destination addr+port */
if ((pcb->local_port == dest) &&
(udp_input_local_match(pcb, inp, broadcast) != 0)) {
@@ -578,8 +596,12 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
}
#endif /* LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) */
- /* find the outgoing network interface for this packet */
- netif = ip_route(&pcb->local_ip, dst_ip_route);
+ if (pcb->intf_filter == NULL) {
+ /* find the outgoing network interface for this packet */
+ netif = ip_route(&pcb->local_ip, dst_ip_route);
+ } else {
+ netif = pcb->intf_filter;
+ }
/* no outgoing network interface could be found? */
if (netif == NULL) {
diff --git a/include/lwip/lwip/ip6_addr.h b/include/lwip/lwip/ip6_addr.h
index a75d894..93f8980 100755
--- a/include/lwip/lwip/ip6_addr.h
+++ b/include/lwip/lwip/ip6_addr.h
@@ -39,6 +39,21 @@
* Please coordinate changes and requests with Ivan Delamer
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef LWIP_HDR_IP6_ADDR_H
#define LWIP_HDR_IP6_ADDR_H
@@ -153,12 +168,16 @@ Little-endian version, stored in network order (no htonl). */
#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]))
+#define ip6_addr_net48cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+ (((addr1)->addr[1] & PP_HTONL(0xffff0000UL)) == \
+ ((addr2)->addr[1] & PP_HTONL(0xffff0000UL))))
+
#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]) && \
((addr1)->addr[2] == (addr2)->addr[2]) && \
((addr1)->addr[3] == (addr2)->addr[3]))
-#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[2]) & 0x0000ffffUL)
+#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[1]) & 0x0000ffffUL)
#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
((ip6addr).addr[1] == 0) && \
diff --git a/include/lwip/lwip/ip6_route_table.h b/include/lwip/lwip/ip6_route_table.h
new file mode 100644
index 0000000..be4655d
--- /dev/null
+++ b/include/lwip/lwip/ip6_route_table.h
@@ -0,0 +1,105 @@
+/**
+ * @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
+ *
+ *
+ * Please coordinate changes and requests with Pradip De
+ *
+ */
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
+
+#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/ip.h"
+#include "lwip/ip6_addr.h"
+#include "lwip/def.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
+
+#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;
+ ip6_addr_t *gateway;
+};
+
+err_t ip6_add_route_entry(struct ip6_prefix *ip6_prefix, struct netif *netif,
+ ip6_addr_t *gateway, s8_t *index);
+void ip6_remove_route_entry(struct ip6_prefix *ip6_prefix);
+s8_t ip6_find_route_entry(ip6_addr_t *ip6_dest_addr);
+struct netif *ip6_static_route(ip6_addr_t *src, ip6_addr_t *dest);
+ip6_addr_t *ip6_get_gateway(struct netif *netif, ip6_addr_t *dest);
+struct ip6_route_entry *ip6_get_route_table(void);
+#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_IPV6 */
+
+#endif /* __LWIP_IP6_ROUTE_TABLE_H__ */
diff --git a/include/lwip/lwip/netif.h b/include/lwip/lwip/netif.h
index bd25b82..48b003a 100755
--- a/include/lwip/lwip/netif.h
+++ b/include/lwip/lwip/netif.h
@@ -29,6 +29,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef LWIP_HDR_NETIF_H
#define LWIP_HDR_NETIF_H
@@ -436,6 +451,11 @@ void netif_poll_all(void);
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);
#endif /* LWIP_IPV6 */
#if LWIP_NETIF_HWADDRHINT
diff --git a/include/lwip/lwip/opt.h b/include/lwip/lwip/opt.h
index 6ea556a..5d6a157 100755
--- a/include/lwip/lwip/opt.h
+++ b/include/lwip/lwip/opt.h
@@ -35,6 +35,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef LWIP_HDR_OPT_H
#define LWIP_HDR_OPT_H
@@ -2662,6 +2677,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 ---------------
diff --git a/include/lwip/lwip/priv/tcpip_priv.h b/include/lwip/lwip/priv/tcpip_priv.h
index cc1c54e..7af487b 100755
--- a/include/lwip/lwip/priv/tcpip_priv.h
+++ b/include/lwip/lwip/priv/tcpip_priv.h
@@ -29,6 +29,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef LWIP_HDR_TCPIP_PRIV_H
#define LWIP_HDR_TCPIP_PRIV_H
@@ -53,6 +68,7 @@ struct netif;
#define LWIP_TCPIP_THREAD_ALIVE()
#endif
+#if !LWIP_CUSTOM_CORE_LOCKING
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
extern sys_mutex_t lock_tcpip_core;
@@ -62,6 +78,7 @@ extern sys_mutex_t lock_tcpip_core;
#define LOCK_TCPIP_CORE()
#define UNLOCK_TCPIP_CORE()
#endif /* LWIP_TCPIP_CORE_LOCKING */
+#endif /* LWIP_CUSTOME_CORE_LOCKING */
#if LWIP_MPU_COMPATIBLE
#define API_VAR_REF(name) (*(name))
diff --git a/include/lwip/lwip/tcpip.h b/include/lwip/lwip/tcpip.h
index c123586..93b1f2a 100755
--- a/include/lwip/lwip/tcpip.h
+++ b/include/lwip/lwip/tcpip.h
@@ -29,6 +29,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef LWIP_HDR_TCPIP_H
#define LWIP_HDR_TCPIP_H
@@ -76,6 +91,13 @@ err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
err_t tcpip_untimeout(sys_timeout_handler h, void *arg);
#endif /* LWIP_TCPIP_TIMEOUT */
+#if LWIP_CUSTOM_CORE_LOCKING
+extern void lock_lwip_core();
+extern void unlock_lwip_core();
+#define LOCK_TCPIP_CORE() lock_lwip_core()
+#define UNLOCK_TCPIP_CORE() unlock_lwip_core()
+#endif /* LWIP_CUSTOME_CORE_LOCKING */
+
#ifdef __cplusplus
}
#endif
diff --git a/include/lwip/lwip/udp.h b/include/lwip/lwip/udp.h
index c2f6ed9..4701099 100644
--- a/include/lwip/lwip/udp.h
+++ b/include/lwip/lwip/udp.h
@@ -29,6 +29,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef LWIP_HDR_UDP_H
#define LWIP_HDR_UDP_H
@@ -95,6 +110,7 @@ struct udp_pcb {
/* Protocol specific PCB members */
struct udp_pcb *next;
+ struct netif *intf_filter;
u8_t flags;
/** ports are in host byte order */
diff --git a/include/lwip/port/lwipopts.h b/include/lwip/port/lwipopts.h
index 4652c6d..94b0802 100644
--- a/include/lwip/port/lwipopts.h
+++ b/include/lwip/port/lwipopts.h
@@ -29,6 +29,21 @@
* Author: Simon Goldschmidt
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
@@ -37,7 +52,6 @@
#include
#include
#include
-#include
#include "esp_task.h"
#include "esp_system.h"
#include "sdkconfig.h"
@@ -346,6 +360,12 @@
----------------------------------
*/
+/**
+ * Enable support for custom PBUFs.
+ */
+#define LWIP_SUPPORT_CUSTOM_PBUF 1
+
+
/*
------------------------------------------------
---------- Network Interfaces options ----------
@@ -478,6 +498,12 @@
*/
#define LWIP_TCPIP_CORE_LOCKING 0
+/**
+ * Enable custom core locking functions necessary for correct operation of Weave
+ * Inet Layer.
+ */
+#define LWIP_CUSTOM_CORE_LOCKING 1
+
/*
------------------------------------
---------- Socket options ----------
@@ -612,6 +638,11 @@
*/
#define LWIP_IPV6 1
+/**
+ * Enable IPv6 routing table support
+ */
+#define LWIP_IPV6_ROUTE_TABLE_SUPPORT 1
+
/*
---------------------------------------
---------- Hook options ---------------
@@ -719,7 +750,9 @@
#define ESP_RANDOM_TCP_PORT 1
#define ESP_IP4_ATON 1
#define ESP_LIGHT_SLEEP 1
-#define ESP_L2_TO_L3_COPY CONFIG_L2_TO_L3_COPY
+#define ESP_L2_TO_L3_COPY 1
+#define ESP_L2_TO_L3_COPY 1
+#define ESP_L2_TO_L3_COPY_BUF_TYPE PBUF_POOL
#define ESP_STATS_MEM CONFIG_LWIP_STATS
#define ESP_STATS_DROP CONFIG_LWIP_STATS
#define ESP_STATS_TCP 0
diff --git a/netif/ppp/eap.c b/netif/ppp/eap.c
index 39cd21e..20a640b 100755
--- a/netif/ppp/eap.c
+++ b/netif/ppp/eap.c
@@ -1424,7 +1424,7 @@ static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) {
}
/* Not so likely to happen. */
- if (vallen >= len + sizeof (rhostname)) {
+ if (len - vallen >= sizeof (rhostname)) {
ppp_dbglog("EAP: trimming really long peer name down");
MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1);
rhostname[sizeof (rhostname) - 1] = '\0';
@@ -1850,7 +1850,7 @@ static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) {
}
/* Not so likely to happen. */
- if (vallen >= len + sizeof (rhostname)) {
+ if (len - vallen >= sizeof (rhostname)) {
ppp_dbglog("EAP: trimming really long peer name down");
MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1);
rhostname[sizeof (rhostname) - 1] = '\0';
diff --git a/patches/openweave-esp32-lwip-patch-0001-Add-custom-core-locking.patch b/patches/openweave-esp32-lwip-patch-0001-Add-custom-core-locking.patch
new file mode 100644
index 0000000..76634b1
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0001-Add-custom-core-locking.patch
@@ -0,0 +1,169 @@
+From 1754d83f149b0e17fb5e740dc0ba55e3bbe1080e Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 18 May 2018 10:48:05 -0700
+Subject: [PATCH 1/9] openweave-esp32-lwip-patch-0001 : Add custom core locking
+
+Added ability for the host environment to define locking functions that
+protect entry to the LwIP stack by the LwIP tcpip thread. This enables
+coordinated use of the LwIP "raw" APIs from multiple threads.
+
+This feature differs from LwIP's experimental TCPIP_CORE_LOCKING feature
+in that it does not alter the behavior of other LwIP APIs such as the
+netconn API. Note that the two features cannot be used together.
+---
+ COPYING | 16 ++++++++++++++++
+ include/lwip/lwip/priv/tcpip_priv.h | 17 +++++++++++++++++
+ include/lwip/lwip/tcpip.h | 22 ++++++++++++++++++++++
+ include/lwip/port/lwipopts.h | 21 +++++++++++++++++++++
+ 4 files changed, 76 insertions(+)
+
+diff --git a/COPYING b/COPYING
+index e23898b..c80bbaa 100755
+--- a/COPYING
++++ b/COPYING
+@@ -29,5 +29,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+
+diff --git a/include/lwip/lwip/priv/tcpip_priv.h b/include/lwip/lwip/priv/tcpip_priv.h
+index cc1c54e..7af487b 100755
+--- a/include/lwip/lwip/priv/tcpip_priv.h
++++ b/include/lwip/lwip/priv/tcpip_priv.h
+@@ -29,6 +29,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef LWIP_HDR_TCPIP_PRIV_H
+ #define LWIP_HDR_TCPIP_PRIV_H
+
+@@ -53,6 +68,7 @@ struct netif;
+ #define LWIP_TCPIP_THREAD_ALIVE()
+ #endif
+
++#if !LWIP_CUSTOM_CORE_LOCKING
+ #if LWIP_TCPIP_CORE_LOCKING
+ /** The global semaphore to lock the stack. */
+ extern sys_mutex_t lock_tcpip_core;
+@@ -62,6 +78,7 @@ extern sys_mutex_t lock_tcpip_core;
+ #define LOCK_TCPIP_CORE()
+ #define UNLOCK_TCPIP_CORE()
+ #endif /* LWIP_TCPIP_CORE_LOCKING */
++#endif /* LWIP_CUSTOME_CORE_LOCKING */
+
+ #if LWIP_MPU_COMPATIBLE
+ #define API_VAR_REF(name) (*(name))
+diff --git a/include/lwip/lwip/tcpip.h b/include/lwip/lwip/tcpip.h
+index c123586..93b1f2a 100755
+--- a/include/lwip/lwip/tcpip.h
++++ b/include/lwip/lwip/tcpip.h
+@@ -29,6 +29,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef LWIP_HDR_TCPIP_H
+ #define LWIP_HDR_TCPIP_H
+
+@@ -76,6 +91,13 @@ err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
+ err_t tcpip_untimeout(sys_timeout_handler h, void *arg);
+ #endif /* LWIP_TCPIP_TIMEOUT */
+
++#if LWIP_CUSTOM_CORE_LOCKING
++extern void lock_lwip_core();
++extern void unlock_lwip_core();
++#define LOCK_TCPIP_CORE() lock_lwip_core()
++#define UNLOCK_TCPIP_CORE() unlock_lwip_core()
++#endif /* LWIP_CUSTOME_CORE_LOCKING */
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/include/lwip/port/lwipopts.h b/include/lwip/port/lwipopts.h
+index 4652c6d..b588a94 100644
+--- a/include/lwip/port/lwipopts.h
++++ b/include/lwip/port/lwipopts.h
+@@ -29,6 +29,21 @@
+ * Author: Simon Goldschmidt
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef __LWIPOPTS_H__
+ #define __LWIPOPTS_H__
+
+@@ -478,6 +493,12 @@
+ */
+ #define LWIP_TCPIP_CORE_LOCKING 0
+
++/**
++ * Enable custom core locking functions necessary for correct operation of Weave
++ * Inet Layer.
++ */
++#define LWIP_CUSTOM_CORE_LOCKING 1
++
+ /*
+ ------------------------------------
+ ---------- Socket options ----------
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0002-Enforce-wlan-buffer-copy.patch b/patches/openweave-esp32-lwip-patch-0002-Enforce-wlan-buffer-copy.patch
new file mode 100644
index 0000000..5168003
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0002-Enforce-wlan-buffer-copy.patch
@@ -0,0 +1,93 @@
+From 74f1ee538f7f83bc398d321326b518a1a2300b6f Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 18 May 2018 11:11:40 -0700
+Subject: [PATCH 2/9] openweave-esp32-lwip-patch-0002 : Enforce wlan buffer
+ copy
+
+Enforce a copy of inbound buffers received from the wlan (WiFi) interface
+into a PBUF_POOL buffer.
+---
+ Kconfig | 16 ----------------
+ include/lwip/port/lwipopts.h | 4 +++-
+ port/netif/wlanif.c | 17 ++++++++++++++++-
+ 3 files changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/Kconfig b/Kconfig
+index a0b9478..2d0807a 100644
+--- a/Kconfig
++++ b/Kconfig
+@@ -1,21 +1,5 @@
+ menu "LWIP"
+
+-config L2_TO_L3_COPY
+- bool "Enable copy between Layer2 and Layer3 packets"
+- default n
+- help
+- If this feature is enabled, all traffic from layer2(WIFI Driver) will be
+- copied to a new buffer before sending it to layer3(LWIP stack), freeing
+- the layer2 buffer.
+- Please be notified that the total layer2 receiving buffer is fixed and
+- ESP32 currently supports 25 layer2 receiving buffer, when layer2 buffer
+- runs out of memory, then the incoming packets will be dropped in hardware.
+- The layer3 buffer is allocated from the heap, so the total layer3 receiving
+- buffer depends on the available heap size, when heap runs out of memory,
+- no copy will be sent to layer3 and packet will be dropped in layer2.
+- Please make sure you fully understand the impact of this feature before
+- enabling it.
+-
+ config LWIP_MAX_SOCKETS
+ int "Max number of open sockets"
+ range 1 32
+diff --git a/include/lwip/port/lwipopts.h b/include/lwip/port/lwipopts.h
+index b588a94..70940f4 100644
+--- a/include/lwip/port/lwipopts.h
++++ b/include/lwip/port/lwipopts.h
+@@ -740,7 +740,9 @@
+ #define ESP_RANDOM_TCP_PORT 1
+ #define ESP_IP4_ATON 1
+ #define ESP_LIGHT_SLEEP 1
+-#define ESP_L2_TO_L3_COPY CONFIG_L2_TO_L3_COPY
++#define ESP_L2_TO_L3_COPY 1
++#define ESP_L2_TO_L3_COPY 1
++#define ESP_L2_TO_L3_COPY_BUF_TYPE PBUF_POOL
+ #define ESP_STATS_MEM CONFIG_LWIP_STATS
+ #define ESP_STATS_DROP CONFIG_LWIP_STATS
+ #define ESP_STATS_TCP 0
+diff --git a/port/netif/wlanif.c b/port/netif/wlanif.c
+index 7f14562..50ab8ba 100644
+--- a/port/netif/wlanif.c
++++ b/port/netif/wlanif.c
+@@ -35,6 +35,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+ #include "lwip/opt.h"
+
+@@ -152,7 +167,7 @@ wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
+ }
+
+ #if (ESP_L2_TO_L3_COPY == 1)
+- p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
++ p = pbuf_alloc(PBUF_RAW, len, ESP_L2_TO_L3_COPY_BUF_TYPE);
+ if (p == NULL) {
+ ESP_STATS_DROP_INC(esp.wlanif_input_pbuf_fail);
+ esp_wifi_internal_free_rx_buffer(eb);
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0003-Removed-include-lwipopts.h.patch b/patches/openweave-esp32-lwip-patch-0003-Removed-include-lwipopts.h.patch
new file mode 100644
index 0000000..6e05662
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0003-Removed-include-lwipopts.h.patch
@@ -0,0 +1,27 @@
+From 53656ebfa3a8799c8641c2ff5493921f778da0a6 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 18 May 2018 11:14:30 -0700
+Subject: [PATCH 3/9] openweave-esp32-lwip-patch-0003 : Removed include in
+ lwipopts.h
+
+Removed unnecessary inclusion of sys/ioctl.h in lwipopts.h that results in
+compilation errors in certain contexts where LwIP headers are included.
+---
+ include/lwip/port/lwipopts.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/include/lwip/port/lwipopts.h b/include/lwip/port/lwipopts.h
+index 70940f4..40df825 100644
+--- a/include/lwip/port/lwipopts.h
++++ b/include/lwip/port/lwipopts.h
+@@ -52,7 +52,6 @@
+ #include
+ #include
+ #include
+-#include
+ #include "esp_task.h"
+ #include "esp_system.h"
+ #include "sdkconfig.h"
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0004-Fix-source-IPv6-addr.patch b/patches/openweave-esp32-lwip-patch-0004-Fix-source-IPv6-addr.patch
new file mode 100644
index 0000000..4fae9a1
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0004-Fix-source-IPv6-addr.patch
@@ -0,0 +1,95 @@
+From 0f92fd2931f9c53fd10ed61ca8bd8669a7ad46a4 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 23 Mar 2018 20:31:25 -0700
+Subject: [PATCH 4/9] openweave-esp32-lwip-patch-0004 : Fix source IPv6 address
+ selection logic
+
+Fixed a bug in LwIP source address selection logic for IPv6 packets.
+
+This change corresponds to commit e2cb69d8d5782b35c95120860e56c08430ea238c
+from tps/lwip:nest/stable
+
+ Author: james woodyatt
+ Date: Mon Mar 9 12:49:01 2015 -0700
+
+ Jira COM-483: LWIP bad source IPv6 address selection logic.
+---
+ core/ipv6/ip6.c | 17 ++++++++++++++++-
+ include/lwip/lwip/ip6_addr.h | 19 +++++++++++++++++++
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/core/ipv6/ip6.c b/core/ipv6/ip6.c
+index acd28fb..6bb5408 100755
+--- a/core/ipv6/ip6.c
++++ b/core/ipv6/ip6.c
+@@ -38,6 +38,21 @@
+ * Please coordinate changes and requests with Ivan Delamer
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+ #include "lwip/opt.h"
+
+@@ -233,7 +248,7 @@ ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest)
+ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+ if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+ ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) &&
+- ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) {
++ ip6_addr_net48cmp(dest, netif_ip6_addr(netif, i))) {
+ return netif_ip_addr6(netif, i);
+ }
+ }
+diff --git a/include/lwip/lwip/ip6_addr.h b/include/lwip/lwip/ip6_addr.h
+index a75d894..9982f8a 100755
+--- a/include/lwip/lwip/ip6_addr.h
++++ b/include/lwip/lwip/ip6_addr.h
+@@ -39,6 +39,21 @@
+ * Please coordinate changes and requests with Ivan Delamer
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef LWIP_HDR_IP6_ADDR_H
+ #define LWIP_HDR_IP6_ADDR_H
+
+@@ -153,6 +168,10 @@ Little-endian version, stored in network order (no htonl). */
+ #define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+ ((addr1)->addr[1] == (addr2)->addr[1]))
+
++#define ip6_addr_net48cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
++ (((addr1)->addr[1] & PP_HTONL(0xffff0000UL)) == \
++ ((addr2)->addr[1] & PP_HTONL(0xffff0000UL))))
++
+ #define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+ ((addr1)->addr[1] == (addr2)->addr[1]) && \
+ ((addr1)->addr[2] == (addr2)->addr[2]) && \
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0005-Fix-ip6_get_subnet_id.patch b/patches/openweave-esp32-lwip-patch-0005-Fix-ip6_get_subnet_id.patch
new file mode 100644
index 0000000..41733c6
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0005-Fix-ip6_get_subnet_id.patch
@@ -0,0 +1,36 @@
+From 7ea0f5ffd7d2e5c861ef43d91fa846652e0f0322 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 23 Mar 2018 20:34:11 -0700
+Subject: [PATCH 5/9] openweave-esp32-lwip-patch-0005 : Fix ip6_get_subnet_id()
+
+This change corresponds to commit 192ac1284fa1b24d8cb9cd770eb8b4ece234fdc1 from tps/lwip:nest/stable
+
+ Author: Abtin Keshavarzian
+ Date: Fri Apr 8 09:35:44 2016 -0700
+
+ ip6_addr.h: Fix the ip6_get_subnet_id() marco to return correct
+ subnet id
+
+ This commit changes the macro definition of ip6_get_subnet_id() in
+ ip6_addr.h header file, so it returns the correct subnet id for a
+ given ipv6 address.
+---
+ include/lwip/lwip/ip6_addr.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/lwip/lwip/ip6_addr.h b/include/lwip/lwip/ip6_addr.h
+index 9982f8a..93f8980 100755
+--- a/include/lwip/lwip/ip6_addr.h
++++ b/include/lwip/lwip/ip6_addr.h
+@@ -177,7 +177,7 @@ Little-endian version, stored in network order (no htonl). */
+ ((addr1)->addr[2] == (addr2)->addr[2]) && \
+ ((addr1)->addr[3] == (addr2)->addr[3]))
+
+-#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[2]) & 0x0000ffffUL)
++#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[1]) & 0x0000ffffUL)
+
+ #define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
+ ((ip6addr).addr[1] == 0) && \
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0006-Send-neighbor-solicitation.patch b/patches/openweave-esp32-lwip-patch-0006-Send-neighbor-solicitation.patch
new file mode 100644
index 0000000..1de10a1
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0006-Send-neighbor-solicitation.patch
@@ -0,0 +1,77 @@
+From 5b319c1534b574db25f0859b439dc133360ae9c1 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 23 Mar 2018 20:41:43 -0700
+Subject: [PATCH 6/9] openweave-esp32-lwip-patch-0006 : Send neighbor
+ solicitation immediately
+
+This change corresponds to commit e8214e9a9d39832f5cd2268cc4eb7a3049e0cdb4
+from tps/lwip:nest/stable
+
+ Author: chenshu
+ Date: Fri Apr 8 16:22:08 2016 +0800
+
+ WEAV-1175: Send neighbor solicitation immediately for the new add
+ 'INCOMPLETE' neighbor entry
+---
+ core/ipv6/nd6.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/core/ipv6/nd6.c b/core/ipv6/nd6.c
+index 1cec55d..25ce6c3 100755
+--- a/core/ipv6/nd6.c
++++ b/core/ipv6/nd6.c
+@@ -40,6 +40,21 @@
+ * Please coordinate changes and requests with Ivan Delamer
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+ #include "lwip/opt.h"
+
+@@ -672,7 +687,12 @@ nd6_tmr(void)
+ (!neighbor_cache[i].isrouter)) {
+ /* Retries exceeded. */
+ nd6_free_neighbor_cache_entry(i);
+- } else {
++ }
++ else if (neighbor_cache[i].counter.probes_sent == 0) {
++ /* the first NS has already been sent when the 'INCOMPLETE' neighbor entry is created */
++ neighbor_cache[i].counter.probes_sent++;
++ }
++ else {
+ /* Send a NS for this entry. */
+ neighbor_cache[i].counter.probes_sent++;
+ nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST);
+@@ -1408,6 +1428,7 @@ nd6_new_router(const ip6_addr_t * router_addr, struct netif * netif)
+ neighbor_cache[neighbor_index].q = NULL;
+ neighbor_cache[neighbor_index].state = ND6_INCOMPLETE;
+ neighbor_cache[neighbor_index].counter.probes_sent = 0;
++ nd6_send_ns(neighbor_cache[neighbor_index].netif, &(neighbor_cache[neighbor_index].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST);
+ }
+
+ /* Mark neighbor as router. */
+@@ -1592,6 +1613,7 @@ nd6_get_next_hop_entry(const ip6_addr_t * ip6addr, struct netif * netif)
+ neighbor_cache[i].netif = netif;
+ neighbor_cache[i].state = ND6_INCOMPLETE;
+ neighbor_cache[i].counter.probes_sent = 0;
++ nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST);
+ }
+ }
+
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0007-UDP-interface-binding-support.patch b/patches/openweave-esp32-lwip-patch-0007-UDP-interface-binding-support.patch
new file mode 100644
index 0000000..4e9c162
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0007-UDP-interface-binding-support.patch
@@ -0,0 +1,103 @@
+From f19fe6a259577b8cdb222a0dbbbcc9bab40e90e8 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 23 Mar 2018 21:11:21 -0700
+Subject: [PATCH 7/9] openweave-esp32-lwip-patch-0007 : UDP interface binding
+ support
+
+Add support to LwIP UDP PCBs for binding to a specific interface.
+
+This change is adapted from commit 1720798ad6454de2d97ef2f0871614c29db7d970
+in tps/lwip:nest/stable.
+---
+ core/udp.c | 26 ++++++++++++++++++++++++--
+ include/lwip/lwip/udp.h | 16 ++++++++++++++++
+ 2 files changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/core/udp.c b/core/udp.c
+index 779dd9a..c379031 100755
+--- a/core/udp.c
++++ b/core/udp.c
+@@ -35,6 +35,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+
+ /* udp.c
+@@ -273,6 +288,9 @@ udp_input(struct pbuf *p, struct netif *inp)
+ ip_addr_debug_print(UDP_DEBUG, &pcb->remote_ip);
+ LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port));
+
++ if ( ! (pcb->intf_filter == NULL || pcb->intf_filter == inp) )
++ continue;
++
+ /* compare PCB local addr+port to UDP destination addr+port */
+ if ((pcb->local_port == dest) &&
+ (udp_input_local_match(pcb, inp, broadcast) != 0)) {
+@@ -578,8 +596,12 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
+ }
+ #endif /* LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) */
+
+- /* find the outgoing network interface for this packet */
+- netif = ip_route(&pcb->local_ip, dst_ip_route);
++ if (pcb->intf_filter == NULL) {
++ /* find the outgoing network interface for this packet */
++ netif = ip_route(&pcb->local_ip, dst_ip_route);
++ } else {
++ netif = pcb->intf_filter;
++ }
+
+ /* no outgoing network interface could be found? */
+ if (netif == NULL) {
+diff --git a/include/lwip/lwip/udp.h b/include/lwip/lwip/udp.h
+index c2f6ed9..4701099 100644
+--- a/include/lwip/lwip/udp.h
++++ b/include/lwip/lwip/udp.h
+@@ -29,6 +29,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef LWIP_HDR_UDP_H
+ #define LWIP_HDR_UDP_H
+
+@@ -95,6 +110,7 @@ struct udp_pcb {
+ /* Protocol specific PCB members */
+
+ struct udp_pcb *next;
++ struct netif *intf_filter;
+
+ u8_t flags;
+ /** ports are in host byte order */
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0008-Static-route-table-management.patch b/patches/openweave-esp32-lwip-patch-0008-Static-route-table-management.patch
new file mode 100644
index 0000000..662a883
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0008-Static-route-table-management.patch
@@ -0,0 +1,844 @@
+From bcdc59798e85d82c893b9bb457a5addb8bebe0b1 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Wed, 23 Sep 2015 15:00:54 -0700
+Subject: [PATCH 8/9] openweave-esp32-lwip-patch-0008 : Static route table
+ management in LwIP.
+
+Added support for creating and managing IPv6 static routes in LwIP. This gives applications the
+ability to configure additional IPv6 routes (and corresponding gateways) beyond those discovered
+via IPv6 router advertisements. The change also introduces the ability to assign an IPv6 address
+to an interface with a prefix length that is less than or greater than /64 (e.g. /48 or /128).
+
+This change squashes the following commits from tps/lwip:nest/stable:
+
+ 1bcf5288ce15cd9f9ba66212dca6082f558f5744 Static route table management in LwIP
+ 0d81f966acd45499a55f50df37add7980fa150dc Fix for build breakage
+ 050faa22689a53b874a73a5d2420d9a95034dc79 Replace entry if a prefix match is found
+ 8a30aa1b561bc1ef3cfb69547bda39aa6a6804e6 Added function to return the head of the route table
+ c193a852cd7dfcc60a852e60448dcd2d1901c2eb Compare prefix length and address(upto prefix length) separately for adding to route table
+ 6c75b0a1dbb8cfef73fbdf8fc9732867e96b5962 fix issues resulting in failures when trying to remove an IPv6 route from the route table.
+---
+ core/ipv6/ethip6.c | 35 +++++
+ core/ipv6/ip6.c | 35 ++++-
+ core/ipv6/ip6_route_table.c | 267 ++++++++++++++++++++++++++++++++++++
+ core/netif.c | 134 ++++++++++++++++++
+ include/lwip/lwip/ip6_route_table.h | 105 ++++++++++++++
+ include/lwip/lwip/netif.h | 20 +++
+ include/lwip/lwip/opt.h | 29 ++++
+ include/lwip/port/lwipopts.h | 5 +
+ 8 files changed, 629 insertions(+), 1 deletion(-)
+ create mode 100644 core/ipv6/ip6_route_table.c
+ create mode 100644 include/lwip/lwip/ip6_route_table.h
+
+diff --git a/core/ipv6/ethip6.c b/core/ipv6/ethip6.c
+index 36aa952..c68a54c 100755
+--- a/core/ipv6/ethip6.c
++++ b/core/ipv6/ethip6.c
+@@ -38,6 +38,21 @@
+ * Please coordinate changes and requests with Ivan Delamer
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+ #include "lwip/opt.h"
+
+@@ -51,6 +66,9 @@
+ #include "lwip/inet_chksum.h"
+ #include "lwip/netif.h"
+ #include "lwip/icmp6.h"
++#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++#include "lwip/ip6_route_table.h"
++#endif
+ #include "netif/ethernet.h"
+
+ #include
+@@ -103,6 +121,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
+
+ /* make room for Ethernet header - should not fail */
+ if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
+@@ -128,6 +149,20 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
+
+ /* We have a unicast destination IP address */
+ /* TODO anycast? */
++
++#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++ /* See if a gateway is present for the destination address in the static route 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;
++ }
++#endif
++
+ /* Get next hop record. */
+ i = nd6_get_next_hop_entry(ip6addr, netif);
+ if (i < 0) {
+diff --git a/core/ipv6/ip6.c b/core/ipv6/ip6.c
+index 6bb5408..61dd5c5 100755
+--- a/core/ipv6/ip6.c
++++ b/core/ipv6/ip6.c
+@@ -74,6 +74,10 @@
+ #include "lwip/debug.h"
+ #include "lwip/stats.h"
+
++#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++#include "lwip/ip6_route_table.h"
++#endif
++
+ /**
+ * Finds the appropriate network interface for a given IPv6 address. It tries to select
+ * a netif following a sequence of heuristics:
+@@ -81,9 +85,16 @@
+ * 2) if the destination is a link-local address, try to match the src address to a netif.
+ * this is a tricky case because with multiple netifs, link-local addresses only have
+ * meaning within a particular subnet/link.
++ * #if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++ * 3) tries to find a netif with a configured address matching the destination or look up
++ * a route table for potential matching routes.
++ * #else
+ * 3) tries to match the destination subnet to a configured address
++ * #endif
+ * 4) tries to find a router
++ * #if !LWIP_IPV6_ROUTE_TABLE_SUPPORT
+ * 5) tries to match the source address to the netif
++ * #endif
+ * 6) returns the default netif, if configured
+ *
+ * @param src the source IPv6 address, if known
+@@ -93,7 +104,7 @@
+ struct netif *
+ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+ {
+- struct netif *netif;
++ struct netif *netif = NULL;
+ s8_t i;
+
+ /* If single netif configuration, fast return. */
+@@ -142,6 +153,25 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+ }
+ #endif
+
++#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++ /* Loop through the netif list to find a matching address */
++ for (netif = netif_list; netif != NULL; netif = netif->next) {
++ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
++ if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
++ ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
++ /* Configured address on netif matches destination address */
++ return netif;
++ }
++ }
++ }
++
++ /* Lookup route table */
++ if ((netif = ip6_static_route(src, dest)) != NULL)
++ {
++ return netif;
++ }
++
++#else /* else LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+ /* See if the destination subnet matches a configured address. */
+ for (netif = netif_list; netif != NULL; netif = netif->next) {
+ if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
+@@ -154,6 +184,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+ }
+ }
+ }
++#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+ /* Get the netif for a suitable router. */
+ i = nd6_select_router(dest, NULL);
+@@ -167,6 +198,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+ }
+ }
+
++#if !LWIP_IPV6_ROUTE_TABLE_SUPPORT
+ /* try with the netif that matches the source address. */
+ if (!ip6_addr_isany(src)) {
+ for (netif = netif_list; netif != NULL; netif = netif->next) {
+@@ -181,6 +213,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
+ }
+ }
+ }
++#endif /* !LWIP_IPV6_ROUTE_TABLE_SUPPORT */
+
+ #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
+ /* loopif is disabled, loopback traffic is passed through any netif */
+diff --git a/core/ipv6/ip6_route_table.c b/core/ipv6/ip6_route_table.c
+new file mode 100644
+index 0000000..960b43d
+--- /dev/null
++++ b/core/ipv6/ip6_route_table.c
+@@ -0,0 +1,267 @@
++/**
++ * @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
++ *
++ *
++ * Please coordinate changes and requests with Pradip De
++ *
++ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
++
++#include "lwip/opt.h"
++
++#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
++
++#include "lwip/def.h"
++#include "lwip/mem.h"
++#include "lwip/netif.h"
++#include "lwip/ip6.h"
++#include "lwip/ip6_route_table.h"
++#include "lwip/ip6_addr.h"
++#include "lwip/nd6.h"
++#include "lwip/debug.h"
++#include "lwip/stats.h"
++
++#include "string.h"
++
++#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++
++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 index 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(struct ip6_prefix *ip6_prefix, struct netif *netif, ip6_addr_t *gateway, s8_t *index)
++{
++ int 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 (index != NULL) {
++ *index = 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(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;
++ }
++ }
++
++ return;
++}
++
++/**
++ * 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 index of the found route entry; -1 if not found.
++ */
++s8_t
++ip6_find_route_entry(ip6_addr_t *ip6_dest_addr)
++{
++ int i, index = -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) {
++ index = i;
++ break;
++ }
++ }
++
++ return index;
++}
++
++/**
++ * 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(ip6_addr_t *src, ip6_addr_t *dest)
++{
++
++ int i;
++ /* 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
++ */
++ip6_addr_t *
++ip6_get_gateway(struct netif *netif, ip6_addr_t *dest)
++{
++ ip6_addr_t *ret_gw = NULL;
++ const int i = ip6_find_route_entry(dest);
++
++ 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.
++ */
++struct ip6_route_entry *
++ip6_get_route_table(void)
++{
++ return static_route_table;
++}
++
++#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
++
++#endif /* LWIP_IPV6 */
+diff --git a/core/netif.c b/core/netif.c
+index 2b25143..5feb8ac 100755
+--- a/core/netif.c
++++ b/core/netif.c
+@@ -35,6 +35,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+
+ #include "lwip/opt.h"
+
+@@ -69,6 +84,10 @@
+ #include "lwip/mld6.h"
+ #endif /* LWIP_IPV6_MLD */
+
++#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)
+ #else
+@@ -997,6 +1016,99 @@ netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
+ #endif /* LWIP_IPV6_AUTOCONFIG */
+ }
+
++/**
++ * 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;
++}
++
+ /** This function allows for the easy addition of a new IPv6 address to an interface.
+ * It takes care of finding an empty slot and then sets the address tentative
+ * (to make sure that all the subsequent processing happens).
+@@ -1037,6 +1149,28 @@ 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_get_ip6_addr_match(netif, ip6addr);
++ if (i >= 0) {
++ ip6_addr_t zero;
++ ip6_addr_set_zero(&zero);
++ netif_ip6_addr_set(netif, i, &zero);
++ netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID);
++ return ERR_OK;
++ }
++
++ return ERR_VAL;
++}
++
+ /** Dummy IPv6 output function for netifs not supporting IPv6
+ */
+ static err_t
+diff --git a/include/lwip/lwip/ip6_route_table.h b/include/lwip/lwip/ip6_route_table.h
+new file mode 100644
+index 0000000..be4655d
+--- /dev/null
++++ b/include/lwip/lwip/ip6_route_table.h
+@@ -0,0 +1,105 @@
++/**
++ * @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
++ *
++ *
++ * Please coordinate changes and requests with Pradip De
++ *
++ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
++
++#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/ip.h"
++#include "lwip/ip6_addr.h"
++#include "lwip/def.h"
++#include "lwip/netif.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#if LWIP_IPV6_ROUTE_TABLE_SUPPORT
++
++#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;
++ ip6_addr_t *gateway;
++};
++
++err_t ip6_add_route_entry(struct ip6_prefix *ip6_prefix, struct netif *netif,
++ ip6_addr_t *gateway, s8_t *index);
++void ip6_remove_route_entry(struct ip6_prefix *ip6_prefix);
++s8_t ip6_find_route_entry(ip6_addr_t *ip6_dest_addr);
++struct netif *ip6_static_route(ip6_addr_t *src, ip6_addr_t *dest);
++ip6_addr_t *ip6_get_gateway(struct netif *netif, ip6_addr_t *dest);
++struct ip6_route_entry *ip6_get_route_table(void);
++#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* LWIP_IPV6 */
++
++#endif /* __LWIP_IP6_ROUTE_TABLE_H__ */
+diff --git a/include/lwip/lwip/netif.h b/include/lwip/lwip/netif.h
+index bd25b82..48b003a 100755
+--- a/include/lwip/lwip/netif.h
++++ b/include/lwip/lwip/netif.h
+@@ -29,6 +29,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef LWIP_HDR_NETIF_H
+ #define LWIP_HDR_NETIF_H
+
+@@ -436,6 +451,11 @@ void netif_poll_all(void);
+ 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);
+ #endif /* LWIP_IPV6 */
+
+ #if LWIP_NETIF_HWADDRHINT
+diff --git a/include/lwip/lwip/opt.h b/include/lwip/lwip/opt.h
+index 6ea556a..5d6a157 100755
+--- a/include/lwip/lwip/opt.h
++++ b/include/lwip/lwip/opt.h
+@@ -35,6 +35,21 @@
+ * Author: Adam Dunkels
+ *
+ */
++/*
++ * Copyright 2018 Google LLC
++ *
++ * Licensed 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
++ *
++ * https://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.
++ */
+ #ifndef LWIP_HDR_OPT_H
+ #define LWIP_HDR_OPT_H
+
+@@ -2662,6 +2677,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 ---------------
+diff --git a/include/lwip/port/lwipopts.h b/include/lwip/port/lwipopts.h
+index 40df825..efaa46d 100644
+--- a/include/lwip/port/lwipopts.h
++++ b/include/lwip/port/lwipopts.h
+@@ -632,6 +632,11 @@
+ */
+ #define LWIP_IPV6 1
+
++/**
++ * Enable IPv6 routing table support
++ */
++#define LWIP_IPV6_ROUTE_TABLE_SUPPORT 1
++
+ /*
+ ---------------------------------------
+ ---------- Hook options ---------------
+--
+1.9.1
+
diff --git a/patches/openweave-esp32-lwip-patch-0009-Enable-custom-pbufs.patch b/patches/openweave-esp32-lwip-patch-0009-Enable-custom-pbufs.patch
new file mode 100644
index 0000000..d2297a7
--- /dev/null
+++ b/patches/openweave-esp32-lwip-patch-0009-Enable-custom-pbufs.patch
@@ -0,0 +1,31 @@
+From 9c3d3dfe41eeeec2332c6d299f4b14c1b528d1d7 Mon Sep 17 00:00:00 2001
+From: Jay Logue
+Date: Fri, 18 May 2018 16:12:55 -0700
+Subject: [PATCH 9/9] openweave-esp32-lwip-patch-0009 : Enable custom pbufs
+
+Enabled support for LwIP's custom pbufs, which are required for certain Weave
+functionality.
+---
+ include/lwip/port/lwipopts.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/include/lwip/port/lwipopts.h b/include/lwip/port/lwipopts.h
+index efaa46d..94b0802 100644
+--- a/include/lwip/port/lwipopts.h
++++ b/include/lwip/port/lwipopts.h
+@@ -360,6 +360,12 @@
+ ----------------------------------
+ */
+
++/**
++ * Enable support for custom PBUFs.
++ */
++#define LWIP_SUPPORT_CUSTOM_PBUF 1
++
++
+ /*
+ ------------------------------------------------
+ ---------- Network Interfaces options ----------
+--
+1.9.1
+
diff --git a/port/netif/wlanif.c b/port/netif/wlanif.c
index 7f14562..50ab8ba 100644
--- a/port/netif/wlanif.c
+++ b/port/netif/wlanif.c
@@ -35,6 +35,21 @@
* Author: Adam Dunkels
*
*/
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed 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
+ *
+ * https://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.
+ */
#include "lwip/opt.h"
@@ -152,7 +167,7 @@ wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
}
#if (ESP_L2_TO_L3_COPY == 1)
- p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
+ p = pbuf_alloc(PBUF_RAW, len, ESP_L2_TO_L3_COPY_BUF_TYPE);
if (p == NULL) {
ESP_STATS_DROP_INC(esp.wlanif_input_pbuf_fail);
esp_wifi_internal_free_rx_buffer(eb);