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);