From 0a1828f74e977002de47adebd71147ac5504fa8f Mon Sep 17 00:00:00 2001
From: xiaqilin <xiaqilin@espressif.com>
Date: Fri, 7 Jul 2023 19:13:43 +0800
Subject: [PATCH] nd6: Add support to enable/disable ND6 protocol

2.1.3-esp: 7896c6ca lwip: add LWIP ND6 config
---
 doc/doxygen/lwip.Doxyfile          |  1 +
 doc/doxygen/lwip.Doxyfile.cmake.in |  1 +
 src/core/ipv6/icmp6.c              |  2 ++
 src/core/ipv6/ip6.c                |  6 ++++++
 src/core/ipv6/ip6_frag.c           |  4 ++++
 src/core/ipv6/nd6.c                |  4 ++--
 src/core/netif.c                   | 18 ++++++++++--------
 src/core/tcp.c                     |  5 +++++
 src/core/tcp_in.c                  |  8 ++++----
 src/core/timeouts.c                |  2 ++
 src/include/lwip/opt.h             | 12 ++++++++++++
 test/fuzz/lwipopts.h               |  1 +
 test/unit/lwipopts.h               |  1 +
 13 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/doc/doxygen/lwip.Doxyfile b/doc/doxygen/lwip.Doxyfile
index d13973e2e..f5b995026 100644
--- a/doc/doxygen/lwip.Doxyfile
+++ b/doc/doxygen/lwip.Doxyfile
@@ -2085,6 +2085,7 @@ PREDEFINED             = __DOXYGEN__=1 \
                          LWIP_TCPIP_CORE_LOCKING=1 \
                          LWIP_IPV4=1 \
                          LWIP_IPV6=1 \
+                         LWIP_ND6=1 \
                          LWIP_ICMP=1 \
                          LWIP_RAW=1 \
                          LWIP_DHCP=1 \
diff --git a/doc/doxygen/lwip.Doxyfile.cmake.in b/doc/doxygen/lwip.Doxyfile.cmake.in
index 7bc0ce039..3b4730983 100644
--- a/doc/doxygen/lwip.Doxyfile.cmake.in
+++ b/doc/doxygen/lwip.Doxyfile.cmake.in
@@ -2085,6 +2085,7 @@ PREDEFINED             = __DOXYGEN__=1 \
                          LWIP_TCPIP_CORE_LOCKING=1 \
                          LWIP_IPV4=1 \
                          LWIP_IPV6=1 \
+                         LWIP_ND6=1 \
                          LWIP_ICMP=1 \
                          LWIP_RAW=1 \
                          LWIP_DHCP=1 \
diff --git a/src/core/ipv6/icmp6.c b/src/core/ipv6/icmp6.c
index ed0bd7b74..57e41595c 100644
--- a/src/core/ipv6/icmp6.c
+++ b/src/core/ipv6/icmp6.c
@@ -118,7 +118,9 @@ icmp6_input(struct pbuf *p, struct netif *inp)
   case ICMP6_TYPE_RA: /* Router advertisement */
   case ICMP6_TYPE_RD: /* Redirect */
   case ICMP6_TYPE_PTB: /* Packet too big */
+#if LWIP_ND6
     nd6_input(p, inp);
+#endif /* LWIP_ND6 */
     return;
   case ICMP6_TYPE_RS:
 #if LWIP_IPV6_FORWARD
diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c
index 92d3a6793..b1df7cfc3 100644
--- a/src/core/ipv6/ip6.c
+++ b/src/core/ipv6/ip6.c
@@ -208,7 +208,9 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
   }
 
   /* Get the netif for a suitable router-announced route. */
+#if LWIP_ND6
   netif = nd6_find_route(dest);
+#endif /* LWIP_ND6 */
   if (netif != NULL) {
     return netif;
   }
@@ -1266,7 +1268,11 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
 #endif /* ENABLE_LOOPBACK */
 #if LWIP_IPV6_FRAG
   /* don't fragment if interface has mtu set to 0 [loopif] */
+#if LWIP_ND6
   if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
+#else
+  if (netif_mtu6(netif) && (p->tot_len > IP6_MIN_MTU_LENGTH)) {
+#endif /* LWIP_ND6 */
     return ip6_frag(p, netif, dest);
   }
 #else
diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c
index 24ad98e40..499acf7c3 100644
--- a/src/core/ipv6/ip6_frag.c
+++ b/src/core/ipv6/ip6_frag.c
@@ -765,7 +765,11 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
 #endif
   static u32_t identification;
   u16_t left, cop;
+#if LWIP_ND6
   const u16_t mtu = nd6_get_destination_mtu(dest, netif);
+#else 
+  const u16_t mtu = IP6_MIN_MTU_LENGTH;
+#endif /* LWIP_ND6 */
   const u16_t nfb = (u16_t)((mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK);
   u16_t fragment_offset = 0;
   u16_t last;
diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c
index 4bdb07200..9a059eee8 100644
--- a/src/core/ipv6/nd6.c
+++ b/src/core/ipv6/nd6.c
@@ -43,7 +43,7 @@
 
 #include "lwip/opt.h"
 
-#if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
+#if LWIP_IPV6 && LWIP_ND6 /* don't build if not configured for use in lwipopts.h */
 
 #include "lwip/nd6.h"
 #include "lwip/priv/nd6_priv.h"
@@ -2490,4 +2490,4 @@ nd6_restart_netif(struct netif *netif)
 #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
 }
 
-#endif /* LWIP_IPV6 */
+#endif /* LWIP_IPV6 && LWIP_ND6 */
diff --git a/src/core/netif.c b/src/core/netif.c
index a2c536472..53e317780 100644
--- a/src/core/netif.c
+++ b/src/core/netif.c
@@ -345,7 +345,9 @@ netif_add(struct netif *netif,
   /* IPv6 address autoconfiguration should be enabled by default */
   netif->ip6_autoconfig_enabled = 1;
 #endif /* LWIP_IPV6_AUTOCONFIG */
+#if LWIP_ND6
   nd6_restart_netif(netif);
+#endif /* LWIP_ND6*/
 #endif /* LWIP_IPV6 */
 #if LWIP_NETIF_STATUS_CALLBACK
   netif->status_callback = NULL;
@@ -896,9 +898,9 @@ netif_set_up(struct netif *netif)
 #endif
 
     netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6);
-#if LWIP_IPV6
+#if LWIP_IPV6 && LWIP_ND6
     nd6_restart_netif(netif);
-#endif /* LWIP_IPV6 */
+#endif /* LWIP_IPV6 && LWIP_ND6 */
   }
 }
 
@@ -976,9 +978,9 @@ netif_set_down(struct netif *netif)
     }
 #endif /* LWIP_IPV4 && LWIP_ARP */
 
-#if LWIP_IPV6
+#if LWIP_IPV6 && LWIP_ND6
     nd6_cleanup_netif(netif);
-#endif /* LWIP_IPV6 */
+#endif /* LWIP_IPV6 && LWIP_ND6 */
 
     NETIF_STATUS_CALLBACK(netif);
   }
@@ -1039,9 +1041,9 @@ netif_set_link_up(struct netif *netif)
 #endif /* LWIP_AUTOIP */
 
     netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6);
-#if LWIP_IPV6
+#if LWIP_IPV6 && LWIP_ND6
     nd6_restart_netif(netif);
-#endif /* LWIP_IPV6 */
+#endif /* LWIP_IPV6 && LWIP_ND6 */
 
     NETIF_LINK_CALLBACK(netif);
 #if LWIP_NETIF_EXT_STATUS_CALLBACK
@@ -1464,12 +1466,12 @@ netif_ip6_addr_set_state(struct netif *netif, s8_t addr_idx, u8_t state)
     u8_t new_valid = state & IP6_ADDR_VALID;
     LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set_state: netif address state being changed\n"));
 
-#if LWIP_IPV6_MLD
+#if LWIP_IPV6_MLD && LWIP_ND6
     /* Reevaluate solicited-node multicast group membership. */
     if (netif->flags & NETIF_FLAG_MLD6) {
       nd6_adjust_mld_membership(netif, addr_idx, state);
     }
-#endif /* LWIP_IPV6_MLD */
+#endif /* LWIP_IPV6_MLD && LWIP_ND6 */
 
     if (old_valid && !new_valid) {
       /* address about to be removed by setting invalid */
diff --git a/src/core/tcp.c b/src/core/tcp.c
index 5c9d20f79..f5b796d26 100644
--- a/src/core/tcp.c
+++ b/src/core/tcp.c
@@ -2265,8 +2265,13 @@ tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif, const ip_addr_t *dest
   if (IP_IS_V6(dest))
 #endif /* LWIP_IPV4 */
   {
+#if LWIP_ND6
     /* First look in destination cache, to see if there is a Path MTU. */
     mtu = nd6_get_destination_mtu(ip_2_ip6(dest), outif);
+#else
+    LWIP_UNUSED_ARG(outif); /* in case LWIP_ND6 is disabled */
+    mtu = TCP_MSS;
+#endif /* LWIP_ND6 */
   }
 #if LWIP_IPV4
   else
diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c
index 8045085be..f4d34af82 100644
--- a/src/core/tcp_in.c
+++ b/src/core/tcp_in.c
@@ -1328,12 +1328,12 @@ tcp_receive(struct tcp_pcb *pcb)
       }
 #endif /* TCP_OVERSIZE */
 
-#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
+#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS && LWIP_ND6
       if (ip_current_is_v6()) {
         /* Inform neighbor reachability of forward progress. */
         nd6_reachability_hint(ip6_current_src_addr());
       }
-#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
+#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS && LWIP_ND6 */
 
       pcb->snd_buf = (tcpwnd_size_t)(pcb->snd_buf + recv_acked);
       /* check if this ACK ends our retransmission of in-flight data */
@@ -1675,12 +1675,12 @@ tcp_receive(struct tcp_pcb *pcb)
         }
 #endif /* LWIP_TCP_SACK_OUT */
 
-#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
+#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS && LWIP_ND6
         if (ip_current_is_v6()) {
           /* Inform neighbor reachability of forward progress. */
           nd6_reachability_hint(ip6_current_src_addr());
         }
-#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
+#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS && LWIP_ND6*/
 
       } else {
         /* We get here if the incoming segment is out-of-sequence. */
diff --git a/src/core/timeouts.c b/src/core/timeouts.c
index 5f669a3bd..9ab967413 100644
--- a/src/core/timeouts.c
+++ b/src/core/timeouts.c
@@ -104,7 +104,9 @@ const struct lwip_cyclic_timer lwip_cyclic_timers[] = {
   {DNS_TMR_INTERVAL, HANDLER(dns_tmr)},
 #endif /* LWIP_DNS */
 #if LWIP_IPV6
+#if LWIP_ND6
   {ND6_TMR_INTERVAL, HANDLER(nd6_tmr)},
+#endif /* LWIP_ND6 */
 #if LWIP_IPV6_REASS && !ESP_LWIP_IP6_REASSEMBLY_TIMERS_ONDEMAND
   {IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)},
 #endif /* LWIP_IPV6_REASS */
diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h
index 32fd8e8c5..31d9e994c 100644
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -2448,6 +2448,18 @@
 #define LWIP_IPV6                       0
 #endif
 
+/**
+ * LWIP_ND6==1: Enable NDP
+ * when LWIP_IPV6 is enabled in lwIP, NDP timer is enabled by default with a timeout of 1 second.
+ * However, in the case of sleepy end-device, NDP is not required.
+ * This leads to CPU waking up every 1 second, resulting in increased power consumption.
+ * Therefore, add a option to control nd6, using LWIP_ND6 enable/disable ND6 protocol.
+ * Unless you are very clear that you do not need to use ND6, please do not disable it!
+ */
+#if !defined LWIP_ND6 || defined __DOXYGEN__
+#define LWIP_ND6                       1
+#endif
+
 /**
  * IPV6_REASS_MAXAGE: Maximum time (in multiples of IP6_REASS_TMR_INTERVAL - so seconds, normally)
  * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
diff --git a/test/fuzz/lwipopts.h b/test/fuzz/lwipopts.h
index 1492fd929..0734442e4 100644
--- a/test/fuzz/lwipopts.h
+++ b/test/fuzz/lwipopts.h
@@ -43,6 +43,7 @@
 #define SYS_LIGHTWEIGHT_PROT            0
 
 #define LWIP_IPV6                       1
+#define LWIP_ND6                        1
 #define IPV6_FRAG_COPYHEADER            1
 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS   0
 
diff --git a/test/unit/lwipopts.h b/test/unit/lwipopts.h
index 4ecaed94a..35b122c8d 100644
--- a/test/unit/lwipopts.h
+++ b/test/unit/lwipopts.h
@@ -35,6 +35,7 @@
 #define LWIP_TESTMODE                   1
 
 #define LWIP_IPV6                       1
+#define LWIP_ND6                        1
 
 #define LWIP_CHECKSUM_ON_COPY           1
 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 1