You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2017/04/19 18:18:13 UTC

[17/30] incubator-mynewt-core git commit: net/ip/lwip_base; update to LwIP to tag STABLE-2_0_2_RELEASE

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/icmp.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/icmp.c b/net/ip/lwip_base/src/core/ipv4/icmp.c
index e60e448..5ee24ee 100644
--- a/net/ip/lwip_base/src/core/ipv4/icmp.c
+++ b/net/ip/lwip_base/src/core/ipv4/icmp.c
@@ -51,6 +51,10 @@
 
 #include <string.h>
 
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
 /** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
  * used to modify and send a response packet (and to 1 if this is not the case,
  * e.g. when link header is stripped of when receiving) */
@@ -81,7 +85,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
 #endif /* LWIP_DEBUG */
   struct icmp_echo_hdr *iecho;
   const struct ip_hdr *iphdr_in;
-  s16_t hlen;
+  u16_t hlen;
   const ip4_addr_t* src;
 
   ICMP_STATS_INC(icmp.recv);
@@ -148,7 +152,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
     }
 #endif
 #if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
-    if (pbuf_header(p, (hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
+    if (pbuf_header(p, (s16_t)(hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
       /* p is not big enough to contain link headers
        * allocate a new one and copy p into it
        */
@@ -167,7 +171,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
       /* copy the ip header */
       MEMCPY(r->payload, iphdr_in, hlen);
       /* switch r->payload back to icmp header (cannot fail) */
-      if (pbuf_header(r, -hlen)) {
+      if (pbuf_header(r, (s16_t)-hlen)) {
         LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0);
         pbuf_free(r);
         goto icmperr;
@@ -194,7 +198,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
     /* We generate an answer by switching the dest and src ip addresses,
      * setting the icmp type to ECHO_RESPONSE and updating the checksum. */
     iecho = (struct icmp_echo_hdr *)p->payload;
-    if (pbuf_header(p, hlen)) {
+    if (pbuf_header(p, (s16_t)hlen)) {
       LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet"));
     } else {
       err_t ret;
@@ -247,7 +251,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
     if (type == ICMP_DUR) {
       MIB2_STATS_INC(mib2.icmpindestunreachs);
     } else if (type == ICMP_TE) {
-      MIB2_STATS_INC(mib2.icmpindestunreachs);
+      MIB2_STATS_INC(mib2.icmpintimeexcds);
     } else if (type == ICMP_PP) {
       MIB2_STATS_INC(mib2.icmpinparmprobs);
     } else if (type == ICMP_SQ) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/igmp.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/igmp.c b/net/ip/lwip_base/src/core/ipv4/igmp.c
index f3db591..74a6c37 100644
--- a/net/ip/lwip_base/src/core/ipv4/igmp.c
+++ b/net/ip/lwip_base/src/core/ipv4/igmp.c
@@ -195,10 +195,13 @@ igmp_report_groups(struct netif *netif)
 
   LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void*)netif));
 
+  /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+  if(group != NULL) {
+    group = group->next;
+  }
+  
   while (group != NULL) {
-    if (!(ip4_addr_cmp(&(group->group_address), &allsystems))) {
-      igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
-    }
+    igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
     group = group->next;
   }
 }
@@ -237,10 +240,11 @@ igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr)
  * @return a struct igmp_group*,
  *         NULL on memory error.
  */
-struct igmp_group *
+static struct igmp_group *
 igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
 {
   struct igmp_group *group;
+  struct igmp_group *list_head = netif_igmp_data(ifp);
 
   /* Search if the group already exists */
   group = igmp_lookfor_group(ifp, addr);
@@ -248,7 +252,7 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
     /* Group already exists. */
     return group;
   }
-
+  
   /* Group doesn't exist yet, create a new one */
   group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
   if (group != NULL) {
@@ -257,9 +261,21 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
     group->group_state        = IGMP_GROUP_NON_MEMBER;
     group->last_reporter_flag = 0;
     group->use                = 0;
-    group->next               = netif_igmp_data(ifp);
 
-    netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
+    /* Ensure allsystems group is always first in list */    
+    if (list_head == NULL) {
+      /* this is the first entry in linked list */
+      LWIP_ASSERT("igmp_lookup_group: first group must be allsystems",
+        (ip4_addr_cmp(addr, &allsystems) != 0));
+      group->next = NULL;
+      netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
+    } else {
+      /* append _after_ first entry */
+      LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems",
+        (ip4_addr_cmp(addr, &allsystems) == 0));
+      group->next = list_head->next;
+      list_head->next = group;
+    }
   }
 
   LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to ")));
@@ -279,24 +295,19 @@ static err_t
 igmp_remove_group(struct netif* netif, struct igmp_group *group)
 {
   err_t err = ERR_OK;
+  struct igmp_group *tmp_group;
 
-  /* Is it the first group? */
-  if (netif_igmp_data(netif) == group) {
-    netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group->next);
-  } else {
-    /* look for group further down the list */
-    struct igmp_group *tmpGroup;
-    for (tmpGroup = netif_igmp_data(netif); tmpGroup != NULL; tmpGroup = tmpGroup->next) {
-      if (tmpGroup->next == group) {
-        tmpGroup->next = group->next;
-        break;
-      }
-    }
-    /* Group not found in the global igmp_group_list */
-    if (tmpGroup == NULL) {
-      err = ERR_ARG;
+  /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+  for (tmp_group = netif_igmp_data(netif); tmp_group != NULL; tmp_group = tmp_group->next) {
+    if (tmp_group->next == group) {
+      tmp_group->next = group->next;
+      break;
     }
   }
+  /* Group not found in the global igmp_group_list */
+  if (tmp_group == NULL) {
+    err = ERR_ARG;
+  }
 
   return err;
 }
@@ -368,11 +379,15 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
       }
 
       groupref = netif_igmp_data(inp);
+      
+      /* Do not send messages on the all systems group address! */
+      /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
+      if(groupref != NULL) {
+        groupref = groupref->next;
+      }
+
       while (groupref) {
-        /* Do not send messages on the all systems group address! */
-        if (!(ip4_addr_cmp(&(groupref->group_address), &allsystems))) {
-          igmp_delaying_member(groupref, igmp->igmp_maxresp);
-        }
+        igmp_delaying_member(groupref, igmp->igmp_maxresp);
         groupref = groupref->next;
       }
     } else {
@@ -658,6 +673,8 @@ igmp_timeout(struct netif *netif, struct igmp_group *group)
     ip4_addr_debug_print(IGMP_DEBUG, &(group->group_address));
     LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)netif));
 
+    group->group_state = IGMP_GROUP_IDLE_MEMBER;
+    
     IGMP_STATS_INC(igmp.tx_report);
     igmp_send(netif, group, IGMP_V2_MEMB_REPORT);
   }
@@ -711,11 +728,9 @@ igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
  * @param p the packet to send (p->payload points to the data, e.g. next
             protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
             IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
  *         IP  address of the netif used to send is used as source address)
  * @param dest the destination IP address to send the packet to
- * @param ttl the TTL value to be set in the IP header
- * @param proto the PROTOCOL to be set in the IP header
  * @param netif the netif on which to send this packet
  * @return ERR_OK if the packet was sent OK
  *         ERR_BUF if p doesn't have enough space for IP/LINK headers
@@ -743,7 +758,7 @@ igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
 {
   struct pbuf*     p    = NULL;
   struct igmp_msg* igmp = NULL;
-  ip4_addr_t   src  = *IP4_ADDR_ANY;
+  ip4_addr_t   src  = *IP4_ADDR_ANY4;
   ip4_addr_t*  dest = NULL;
 
   /* IP header + "router alert" option + IGMP header */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/ip4.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/ip4.c b/net/ip/lwip_base/src/core/ipv4/ip4.c
index 27747ea..4e4eb61 100644
--- a/net/ip/lwip_base/src/core/ipv4/ip4.c
+++ b/net/ip/lwip_base/src/core/ipv4/ip4.c
@@ -59,6 +59,10 @@
 
 #include <string.h>
 
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
 /** Set this to 0 in the rare case of wanting to call an extra function to
  * generate the IP checksum (in contrast to calculating it on-the-fly). */
 #ifndef LWIP_INLINE_IP_CHKSUM
@@ -177,7 +181,7 @@ ip4_route(const ip4_addr_t *dest)
   /* loopif is disabled, looopback traffic is passed through any netif */
   if (ip4_addr_isloopback(dest)) {
     /* don't check for link on loopback traffic */
-    if (netif_is_up(netif_default)) {
+    if (netif_default != NULL && netif_is_up(netif_default)) {
       return netif_default;
     }
     /* default netif is not up, just use any netif for loopback traffic */
@@ -222,13 +226,12 @@ ip4_route(const ip4_addr_t *dest)
  * that may not be forwarded, or whether datagrams to that destination
  * may be forwarded.
  * @param p the packet to forward
- * @param dest the destination IP address
  * @return 1: can forward 0: discard
  */
 static int
 ip4_canforward(struct pbuf *p)
 {
-  u32_t addr = htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
+  u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
 
   if (p->flags & PBUF_FLAG_LLBCAST) {
     /* don't route link-layer broadcasts */
@@ -405,7 +408,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
   /* calculate IP header length in bytes */
   iphdr_hlen *= 4;
   /* obtain ip length in bytes */
-  iphdr_len = ntohs(IPH_LEN(iphdr));
+  iphdr_len = lwip_ntohs(IPH_LEN(iphdr));
 
   /* Trim pbuf. This is especially required for packets < 60 bytes. */
   if (iphdr_len < p->tot_len) {
@@ -519,6 +522,15 @@ ip4_input(struct pbuf *p, struct netif *inp)
 #endif /* LWIP_AUTOIP */
       }
       if (first) {
+#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
+        /* Packets sent to the loopback address must not be accepted on an
+         * interface that does not have the loopback address assigned to it,
+         * unless a non-loopback interface is used for loopback traffic. */
+        if (ip4_addr_isloopback(ip4_current_dest_addr())) {
+          netif = NULL;
+          break;
+        }
+#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
         first = 0;
         netif = netif_list;
       } else {
@@ -545,7 +557,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
     if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
       struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
       LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n",
-        ntohs(udphdr->dest)));
+        lwip_ntohs(udphdr->dest)));
       if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
         LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
         netif = inp;
@@ -590,6 +602,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
     } else
 #endif /* IP_FORWARD */
     {
+      IP_STATS_INC(ip.drop);
       MIB2_STATS_INC(mib2.ipinaddrerrors);
       MIB2_STATS_INC(mib2.ipindiscards);
     }
@@ -600,7 +613,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
   if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
 #if IP_REASSEMBLY /* packet fragment reassembly code present? */
     LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n",
-      ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)));
+      lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)));
     /* reassemble the packet*/
     p = ip4_reass(p);
     /* packet not fully reassembled yet? */
@@ -611,7 +624,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
     pbuf_free(p);
     LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
-      ntohs(IPH_OFFSET(iphdr))));
+      lwip_ntohs(IPH_OFFSET(iphdr))));
     IP_STATS_INC(ip.opterr);
     IP_STATS_INC(ip.drop);
     /* unsupported protocol feature */
@@ -724,7 +737,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
  * @param p the packet to send (p->payload points to the data, e.g. next
             protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
             IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
  *         IP  address of the netif used to send is used as source address)
  * @param dest the destination IP address to send the packet to
  * @param ttl the TTL value to be set in the IP header
@@ -854,7 +867,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
     IPH_TTL_SET(iphdr, ttl);
     IPH_PROTO_SET(iphdr, proto);
 #if CHECKSUM_GEN_IP_INLINE
-    chk_sum += LWIP_MAKE_U16(proto, ttl);
+    chk_sum += PP_NTOHS(proto | (ttl << 8));
 #endif /* CHECKSUM_GEN_IP_INLINE */
 
     /* dest cannot be NULL here */
@@ -867,21 +880,21 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
     IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
     IPH_TOS_SET(iphdr, tos);
 #if CHECKSUM_GEN_IP_INLINE
-    chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl);
+    chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
 #endif /* CHECKSUM_GEN_IP_INLINE */
-    IPH_LEN_SET(iphdr, htons(p->tot_len));
+    IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
 #if CHECKSUM_GEN_IP_INLINE
     chk_sum += iphdr->_len;
 #endif /* CHECKSUM_GEN_IP_INLINE */
     IPH_OFFSET_SET(iphdr, 0);
-    IPH_ID_SET(iphdr, htons(ip_id));
+    IPH_ID_SET(iphdr, lwip_htons(ip_id));
 #if CHECKSUM_GEN_IP_INLINE
     chk_sum += iphdr->_id;
 #endif /* CHECKSUM_GEN_IP_INLINE */
     ++ip_id;
 
     if (src == NULL) {
-      ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY);
+      ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4);
     } else {
       /* src cannot be NULL here */
       ip4_addr_copy(iphdr->src, *src);
@@ -955,7 +968,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
  * @param p the packet to send (p->payload points to the data, e.g. next
             protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
             IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
  *         IP  address of the netif used to send is used as source address)
  * @param dest the destination IP address to send the packet to
  * @param ttl the TTL value to be set in the IP header
@@ -990,7 +1003,7 @@ ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
  * @param p the packet to send (p->payload points to the data, e.g. next
             protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
             IP header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
+ * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
  *         IP  address of the netif used to send is used as source address)
  * @param dest the destination IP address to send the packet to
  * @param ttl the TTL value to be set in the IP header
@@ -1041,19 +1054,19 @@ ip4_debug_print(struct pbuf *p)
                     (u16_t)IPH_V(iphdr),
                     (u16_t)IPH_HL(iphdr),
                     (u16_t)IPH_TOS(iphdr),
-                    ntohs(IPH_LEN(iphdr))));
+                    lwip_ntohs(IPH_LEN(iphdr))));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
   LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
-                    ntohs(IPH_ID(iphdr)),
-                    (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
-                    (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
-                    (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
-                    (u16_t)(ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
+                    lwip_ntohs(IPH_ID(iphdr)),
+                    (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
+                    (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
+                    (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
+                    (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
   LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
                     (u16_t)IPH_TTL(iphdr),
                     (u16_t)IPH_PROTO(iphdr),
-                    ntohs(IPH_CHKSUM(iphdr))));
+                    lwip_ntohs(IPH_CHKSUM(iphdr))));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
   LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
                     ip4_addr1_16(&iphdr->src),

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/ip4_addr.c b/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
index 7fe35c9..2d47992 100644
--- a/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
+++ b/net/ip/lwip_base/src/core/ipv4/ip4_addr.c
@@ -43,7 +43,7 @@
 #include "lwip/ip_addr.h"
 #include "lwip/netif.h"
 
-/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
+/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
 const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
 const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST);
 
@@ -183,10 +183,10 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
     }
     for (;;) {
       if (isdigit(c)) {
-        val = (val * base) + (int)(c - '0');
+        val = (val * base) + (u32_t)(c - '0');
         c = *++cp;
       } else if (base == 16 && isxdigit(c)) {
-        val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
+        val = (val << 4) | (u32_t)(c + 10 - (islower(c) ? 'a' : 'A'));
         c = *++cp;
       } else {
         break;
@@ -260,7 +260,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
     break;
   }
   if (addr) {
-    ip4_addr_set_u32(addr, htonl(val));
+    ip4_addr_set_u32(addr, lwip_htonl(val));
   }
   return 1;
 }
@@ -310,7 +310,7 @@ ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
     do {
       rem = *ap % (u8_t)10;
       *ap /= (u8_t)10;
-      inv[i++] = '0' + rem;
+      inv[i++] = (char)('0' + rem);
     } while (*ap);
     while (i--) {
       if (len++ >= buflen) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv4/ip4_frag.c b/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
index 50edd12..57fb44c 100644
--- a/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
+++ b/net/ip/lwip_base/src/core/ipv4/ip4_frag.c
@@ -160,7 +160,7 @@ static int
 ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
 {
   u16_t pbufs_freed = 0;
-  u8_t clen;
+  u16_t clen;
   struct pbuf *p;
   struct ip_reass_helper *iprh;
 
@@ -331,7 +331,7 @@ ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
  * will grow over time as  new pbufs are rx.
  * Also checks that the datagram passes basic continuity checks (if the last
  * fragment was received at least once).
- * @param root_p points to the 'root' pbuf for the current datagram being assembled.
+ * @param ipr points to the reassembly state
  * @param new_p points to the pbuf for the current fragment
  * @return 0 if invalid, >0 otherwise
  */
@@ -346,8 +346,8 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
 
   /* Extract length and fragment offset from current fragment */
   fraghdr = (struct ip_hdr*)new_p->payload;
-  len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
-  offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
+  len = lwip_ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
+  offset = (lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
 
   /* overwrite the fragment's ip header from the pbuf with our helper struct,
    * and setup the embedded helper structure. */
@@ -487,8 +487,7 @@ ip4_reass(struct pbuf *p)
   struct ip_hdr *fraghdr;
   struct ip_reassdata *ipr;
   struct ip_reass_helper *iprh;
-  u16_t offset, len;
-  u8_t clen;
+  u16_t offset, len, clen;
 
   IPFRAG_STATS_INC(ip_frag.recv);
   MIB2_STATS_INC(mib2.ipreasmreqds);
@@ -501,8 +500,8 @@ ip4_reass(struct pbuf *p)
     goto nullreturn;
   }
 
-  offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
-  len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
+  offset = (lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
+  len = lwip_ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
 
   /* Check if we are allowed to enqueue more datagrams. */
   clen = pbuf_clen(p);
@@ -530,7 +529,7 @@ ip4_reass(struct pbuf *p)
        fragment into the buffer. */
     if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
       LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
-        ntohs(IPH_ID(fraghdr))));
+        lwip_ntohs(IPH_ID(fraghdr))));
       IPFRAG_STATS_INC(ip_frag.cachehit);
       break;
     }
@@ -544,8 +543,8 @@ ip4_reass(struct pbuf *p)
       goto nullreturn;
     }
   } else {
-    if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
-      ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
+    if (((lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
+      ((lwip_ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
       /* ipr->iphdr is not the header from the first fragment, but fraghdr is
        * -> copy fraghdr into ipr->iphdr since we want to have the header
        * of the first fragment (for ICMP time exceeded and later, for copying
@@ -582,7 +581,7 @@ ip4_reass(struct pbuf *p)
     /* copy the original ip header back to the first pbuf */
     fraghdr = (struct ip_hdr*)(ipr->p->payload);
     SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
-    IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
+    IPH_LEN_SET(fraghdr, lwip_htons(ipr->datagram_len));
     IPH_OFFSET_SET(fraghdr, 0);
     IPH_CHKSUM_SET(fraghdr, 0);
     /* @todo: do we need to set/calculate the correct checksum? */
@@ -688,53 +687,41 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
   struct pbuf *rambuf;
 #if !LWIP_NETIF_TX_SINGLE_PBUF
   struct pbuf *newpbuf;
+  u16_t newpbuflen = 0;
+  u16_t left_to_copy;
 #endif
   struct ip_hdr *original_iphdr;
   struct ip_hdr *iphdr;
-  u16_t nfb;
-  u16_t left, cop;
-  u16_t mtu = netif->mtu;
-  u16_t ofo, omf;
-  u16_t last;
+  const u16_t nfb = (netif->mtu - IP_HLEN) / 8;
+  u16_t left, fragsize;
+  u16_t ofo;
+  int last;
   u16_t poff = IP_HLEN;
   u16_t tmp;
-#if !LWIP_NETIF_TX_SINGLE_PBUF
-  u16_t newpbuflen = 0;
-  u16_t left_to_copy;
-#endif
 
   original_iphdr = (struct ip_hdr *)p->payload;
   iphdr = original_iphdr;
+  LWIP_ERROR("ip4_frag() does not support IP options", IPH_HL(iphdr) * 4 == IP_HLEN, return ERR_VAL);
 
   /* Save original offset */
-  tmp = ntohs(IPH_OFFSET(iphdr));
+  tmp = lwip_ntohs(IPH_OFFSET(iphdr));
   ofo = tmp & IP_OFFMASK;
-  omf = tmp & IP_MF;
+  LWIP_ERROR("ip_frag(): MF already set", (tmp & IP_MF) == 0, return ERR_VAL);
 
   left = p->tot_len - IP_HLEN;
 
-  nfb = (mtu - IP_HLEN) / 8;
-
   while (left) {
-    last = (left <= mtu - IP_HLEN);
-
-    /* Set new offset and MF flag */
-    tmp = omf | (IP_OFFMASK & (ofo));
-    if (!last) {
-      tmp = tmp | IP_MF;
-    }
-
     /* Fill this fragment */
-    cop = last ? left : nfb * 8;
+    fragsize = LWIP_MIN(left, nfb * 8);
 
 #if LWIP_NETIF_TX_SINGLE_PBUF
-    rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM);
+    rambuf = pbuf_alloc(PBUF_IP, fragsize, PBUF_RAM);
     if (rambuf == NULL) {
       goto memerr;
     }
     LWIP_ASSERT("this needs a pbuf in one piece!",
       (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
-    poff += pbuf_copy_partial(p, rambuf->payload, cop, poff);
+    poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff);
     /* make room for the IP header */
     if (pbuf_header(rambuf, IP_HLEN)) {
       pbuf_free(rambuf);
@@ -758,16 +745,14 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
     SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
     iphdr = (struct ip_hdr *)rambuf->payload;
 
-    /* Can just adjust p directly for needed offset. */
-    p->payload = (u8_t *)p->payload + poff;
-    p->len -= poff;
-
-    left_to_copy = cop;
+    left_to_copy = fragsize;
     while (left_to_copy) {
       struct pbuf_custom_ref *pcr;
-      newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
+      u16_t plen = p->len - poff;
+      newpbuflen = LWIP_MIN(left_to_copy, plen);
       /* Is this pbuf already empty? */
       if (!newpbuflen) {
+        poff = 0;
         p = p->next;
         continue;
       }
@@ -777,7 +762,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
         goto memerr;
       }
       /* Mirror this pbuf, although we might not need all of it. */
-      newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen);
+      newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc,
+        (u8_t*)p->payload + poff, newpbuflen);
       if (newpbuf == NULL) {
         ip_frag_free_pbuf_custom_ref(pcr);
         pbuf_free(rambuf);
@@ -793,15 +779,23 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
       pbuf_cat(rambuf, newpbuf);
       left_to_copy -= newpbuflen;
       if (left_to_copy) {
+        poff = 0;
         p = p->next;
       }
     }
-    poff = newpbuflen;
+    poff += newpbuflen;
 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
 
     /* Correct header */
-    IPH_OFFSET_SET(iphdr, htons(tmp));
-    IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
+    last = (left <= netif->mtu - IP_HLEN);
+
+    /* Set new offset and MF flag */
+    tmp = (IP_OFFMASK & (ofo));
+    if (!last) {
+      tmp = tmp | IP_MF;
+    }
+    IPH_OFFSET_SET(iphdr, lwip_htons(tmp));
+    IPH_LEN_SET(iphdr, lwip_htons(fragsize + IP_HLEN));
     IPH_CHKSUM_SET(iphdr, 0);
 #if CHECKSUM_GEN_IP
     IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
@@ -823,7 +817,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
      */
 
     pbuf_free(rambuf);
-    left -= cop;
+    left -= fragsize;
     ofo += nfb;
   }
   MIB2_STATS_INC(mib2.ipfragoks);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ethip6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ethip6.c b/net/ip/lwip_base/src/core/ipv6/ethip6.c
index 1ae784f..8f9a91b 100644
--- a/net/ip/lwip_base/src/core/ipv6/ethip6.c
+++ b/net/ip/lwip_base/src/core/ipv6/ethip6.c
@@ -62,7 +62,9 @@
  * For IPv6 multicast, corresponding Ethernet addresses
  * are selected and the packet is transmitted on the link.
  *
- * For unicast addresses, ...
+ * For unicast addresses, ask the ND6 module what to do. It will either let us
+ * send the the packet right away, or queue the packet for later itself, unless
+ * an error occurs.
  *
  * @todo anycast addresses
  *
@@ -71,14 +73,14 @@
  * @param ip6addr The IP address of the packet destination.
  *
  * @return
- * - ERR_RTE No route to destination (no gateway to external networks),
- * or the return type of either etharp_query() or ethernet_output().
+ * - ERR_OK or the return value of @ref nd6_get_next_hop_addr_or_queue.
  */
 err_t
 ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
 {
   struct eth_addr dest;
-  s8_t i;
+  const u8_t *hwaddr;
+  err_t result;
 
   /* multicast destination IP address? */
   if (ip6_addr_ismulticast(ip6addr)) {
@@ -91,36 +93,26 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
     dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
 
     /* Send out. */
-    return ethernet_output(netif, q, (struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
+    return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
   }
 
   /* We have a unicast destination IP address */
   /* @todo anycast? */
-  /* Get next hop record. */
-  i = nd6_get_next_hop_entry(ip6addr, netif);
-  if (i < 0) {
-    /* failed to get a next hop neighbor record. */
-    return ERR_MEM;
-  }
 
-  /* Now that we have a destination record, send or queue the packet. */
-  if (neighbor_cache[i].state == ND6_STALE) {
-    /* Switch to delay state. */
-    neighbor_cache[i].state = ND6_DELAY;
-    neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+  /* Ask ND6 what to do with the packet. */
+  result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr);
+  if (result != ERR_OK) {
+    return result;
   }
-  /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */
-  if ((neighbor_cache[i].state == ND6_REACHABLE) ||
-      (neighbor_cache[i].state == ND6_DELAY) ||
-      (neighbor_cache[i].state == ND6_PROBE)) {
 
-    /* Send out. */
-    SMEMCPY(dest.addr, neighbor_cache[i].lladdr, 6);
-    return ethernet_output(netif, q, (struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
+  /* If no hardware address is returned, nd6 has queued the packet for later. */
+  if (hwaddr == NULL) {
+    return ERR_OK;
   }
 
-  /* We should queue packet on this interface. */
-  return nd6_queue_packet(i, q);
+  /* Send out the packet using the returned hardware address. */
+  SMEMCPY(dest.addr, hwaddr, 6);
+  return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
 }
 
 #endif /* LWIP_IPV6 && LWIP_ETHERNET */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ip6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ip6.c b/net/ip/lwip_base/src/core/ipv6/ip6.c
index 8cc9c01..f14e334 100644
--- a/net/ip/lwip_base/src/core/ipv6/ip6.c
+++ b/net/ip/lwip_base/src/core/ipv6/ip6.c
@@ -60,6 +60,10 @@
 #include "lwip/debug.h"
 #include "lwip/stats.h"
 
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
 /**
  * Finds the appropriate network interface for a given IPv6 address. It tries to select
  * a netif following a sequence of heuristics:
@@ -94,7 +98,8 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
   if (ip6_addr_islinklocal(dest)) {
     if (ip6_addr_isany(src)) {
       /* Use default netif, if Up. */
-      if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
+      if (netif_default == NULL || !netif_is_up(netif_default) ||
+          !netif_is_link_up(netif_default)) {
         return NULL;
       }
       return netif_default;
@@ -114,7 +119,8 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
     }
 
     /* netif not found, use default netif, if up */
-    if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) {
+    if (netif_default == NULL || !netif_is_up(netif_default) ||
+        !netif_is_link_up(netif_default)) {
       return NULL;
     }
     return netif_default;
@@ -142,15 +148,9 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
   }
 
   /* Get the netif for a suitable router. */
-  i = nd6_select_router(dest, NULL);
-  if (i >= 0) {
-    if (default_router_list[i].neighbor_entry != NULL) {
-      if (default_router_list[i].neighbor_entry->netif != NULL) {
-        if (netif_is_up(default_router_list[i].neighbor_entry->netif) && netif_is_link_up(default_router_list[i].neighbor_entry->netif)) {
-          return default_router_list[i].neighbor_entry->netif;
-        }
-      }
-    }
+  netif = nd6_find_route(dest);
+  if ((netif != NULL) && netif_is_up(netif) && netif_is_link_up(netif)) {
+    return netif;
   }
 
   /* try with the netif that matches the source address. */
@@ -172,7 +172,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
   /* loopif is disabled, loopback traffic is passed through any netif */
   if (ip6_addr_isloopback(dest)) {
     /* don't check for link on loopback traffic */
-    if (netif_is_up(netif_default)) {
+    if (netif_default != NULL && netif_is_up(netif_default)) {
       return netif_default;
     }
     /* default netif is not up, just use any netif for loopback traffic */
@@ -290,8 +290,9 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
 {
   struct netif *netif;
 
-  /* do not forward link-local addresses */
-  if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
+  /* do not forward link-local or loopback addresses */
+  if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
+      ip6_addr_isloopback(ip6_current_dest_addr())) {
     LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
     IP6_STATS_INC(ip6.rterr);
     IP6_STATS_INC(ip6.drop);
@@ -446,9 +447,11 @@ ip6_input(struct pbuf *p, struct netif *inp)
   ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest);
   ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src);
 
-  /* Don't accept virtual IPv6 mapped IPv4 addresses */
-  if (ip6_addr_isipv6mappedipv4(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
-     ip6_addr_isipv6mappedipv4(ip_2_ip6(&ip_data.current_iphdr_src))     ) {
+  /* Don't accept virtual IPv4 mapped IPv6 addresses.
+   * Don't accept multicast source addresses. */
+  if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) ||
+     ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) ||
+     ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) {
     IP6_STATS_INC(ip6.err);
     IP6_STATS_INC(ip6.drop);
     return ERR_OK;
@@ -509,12 +512,21 @@ ip6_input(struct pbuf *p, struct netif *inp)
           }
         }
       }
-      if (ip6_addr_islinklocal(ip6_current_dest_addr())) {
-        /* Do not match link-local addresses to other netifs. */
-        netif = NULL;
-        break;
-      }
       if (first) {
+        if (ip6_addr_islinklocal(ip6_current_dest_addr())
+#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
+            || ip6_addr_isloopback(ip6_current_dest_addr())
+#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
+        ) {
+          /* Do not match link-local addresses to other netifs. The loopback
+           * address is to be considered link-local and packets to it should be
+           * dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. This
+           * requirement cannot be implemented in the case that loopback
+           * traffic is sent across a non-loopback interface, however.
+           */
+          netif = NULL;
+          break;
+        }
         first = 0;
         netif = netif_list;
       } else {
@@ -709,7 +721,7 @@ netif_found:
 options_done:
 
   /* p points to IPv6 header again. */
-  pbuf_header_force(p, ip_data.current_ip_header_tot_len);
+  pbuf_header_force(p, (s16_t)ip_data.current_ip_header_tot_len);
 
   /* send to upper layers */
   LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n"));
@@ -809,8 +821,8 @@ ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
   const ip6_addr_t *src_used = src;
   if (dest != LWIP_IP_HDRINCL) {
     if (src != NULL && ip6_addr_isany(src)) {
-      src = ip_2_ip6(ip6_select_source_address(netif, dest));
-      if ((src == NULL) || ip6_addr_isany(src)) {
+      src_used = ip_2_ip6(ip6_select_source_address(netif, dest));
+      if ((src_used == NULL) || ip6_addr_isany(src_used)) {
         /* No appropriate source address was found for this packet. */
         LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n"));
         IP6_STATS_INC(ip6.rterr);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ip6_addr.c b/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
index 1792f62..aa06659 100644
--- a/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
+++ b/net/ip/lwip_base/src/core/ipv6/ip6_addr.c
@@ -132,8 +132,8 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
     } else if (isxdigit(*s)) {
       /* add current digit */
       current_block_value = (current_block_value << 4) +
-          (isdigit(*s) ? *s - '0' :
-          10 + (islower(*s) ? *s - 'a' : *s - 'A'));
+          (isdigit(*s) ? (u32_t)(*s - '0') :
+          (u32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A')));
     } else {
       /* unexpected digit, space? CRLF? */
       break;
@@ -152,7 +152,7 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
   /* convert to network byte order. */
   if (addr) {
     for (addr_index = 0; addr_index < 4; addr_index++) {
-      addr->addr[addr_index] = htonl(addr->addr[addr_index]);
+      addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]);
     }
   }
 
@@ -199,7 +199,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
 
   for (current_block_index = 0; current_block_index < 8; current_block_index++) {
     /* get the current 16-bit block */
-    current_block_value = htonl(addr->addr[current_block_index >> 1]);
+    current_block_value = lwip_htonl(addr->addr[current_block_index >> 1]);
     if ((current_block_index & 0x1) == 0) {
       current_block_value = current_block_value >> 16;
     }
@@ -218,7 +218,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
       if (empty_block_flag == 0) {
         /* generate empty block "::", but only if more than one contiguous zero block,
          * according to current formatting suggestions RFC 5952. */
-        next_block_value = htonl(addr->addr[(current_block_index + 1) >> 1]);
+        next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]);
         if ((current_block_index & 0x1) == 0x01) {
             next_block_value = next_block_value >> 16;
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/ip6_frag.c b/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
index f41d167..ff07f71 100644
--- a/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
+++ b/net/ip/lwip_base/src/core/ipv6/ip6_frag.c
@@ -147,7 +147,7 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
 {
   struct ip6_reassdata *prev;
   u16_t pbufs_freed = 0;
-  u8_t clen;
+  u16_t clen;
   struct pbuf *p;
   struct ip6_reass_helper *iprh;
 
@@ -262,7 +262,8 @@ ip6_reass(struct pbuf *p)
   struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
   struct ip6_frag_hdr *frag_hdr;
   u16_t offset, len;
-  u8_t clen, valid = 1;
+  u16_t clen;
+  u8_t valid = 1;
   struct pbuf *q;
 
   IP6_FRAG_STATS_INC(ip6_frag.recv);
@@ -278,12 +279,12 @@ ip6_reass(struct pbuf *p)
 
   clen = pbuf_clen(p);
 
-  offset = ntohs(frag_hdr->_fragment_offset);
+  offset = lwip_ntohs(frag_hdr->_fragment_offset);
 
   /* Calculate fragment length from IPv6 payload length.
    * Adjust for headers before Fragment Header.
    * And finally adjust by Fragment Header length. */
-  len = ntohs(ip6_current_header()->_plen);
+  len = lwip_ntohs(ip6_current_header()->_plen);
   len -= (u16_t)(((u8_t*)p->payload - (const u8_t*)ip6_current_header()) - IP6_HLEN);
   len -= IP6_FRAG_HLEN;
 
@@ -378,6 +379,7 @@ ip6_reass(struct pbuf *p)
     /* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4).
        This cannot fail since we already checked when receiving this fragment. */
     u8_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM);
+    LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
     LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
   }
 #else /* IPV6_FRAG_COPYHEADER */
@@ -529,6 +531,7 @@ ip6_reass(struct pbuf *p)
         if (IPV6_FRAG_REQROOM > 0) {
           /* hide the extra bytes borrowed from ip6_hdr for struct ip6_reass_helper */
           u8_t hdrerr = pbuf_header(next_pbuf, -(s16_t)(IPV6_FRAG_REQROOM));
+          LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
           LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
         }
 #endif
@@ -545,6 +548,7 @@ ip6_reass(struct pbuf *p)
     if (IPV6_FRAG_REQROOM > 0) {
       /* get back room for struct ip6_reass_helper (only required if sizeof(void*) > 4) */
       u8_t hdrerr = pbuf_header(ipr->p, -(s16_t)(IPV6_FRAG_REQROOM));
+      LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
       LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
     }
     iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->p->payload - IP6_HLEN);
@@ -559,7 +563,7 @@ ip6_reass(struct pbuf *p)
                          - IP6_HLEN);
 
     /* Set payload length in ip header. */
-    iphdr_ptr->_plen = htons(ipr->datagram_len);
+    iphdr_ptr->_plen = lwip_htons(ipr->datagram_len);
 
     /* Get the first pbuf. */
     p = ipr->p;
@@ -609,6 +613,7 @@ nullreturn:
 
 #if LWIP_IPV6 && LWIP_IPV6_FRAG
 
+#if !LWIP_NETIF_TX_SINGLE_PBUF
 /** Allocate a new struct pbuf_custom_ref */
 static struct pbuf_custom_ref*
 ip6_frag_alloc_pbuf_custom_ref(void)
@@ -637,6 +642,7 @@ ip6_frag_free_pbuf_custom(struct pbuf *p)
   }
   ip6_frag_free_pbuf_custom_ref(pcr);
 }
+#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
 
 /**
  * Fragment an IPv6 datagram if too large for the netif or path MTU.
@@ -657,7 +663,11 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
   struct ip6_hdr *ip6hdr;
   struct ip6_frag_hdr *frag_hdr;
   struct pbuf *rambuf;
+#if !LWIP_NETIF_TX_SINGLE_PBUF
   struct pbuf *newpbuf;
+  u16_t newpbuflen = 0;
+  u16_t left_to_copy;
+#endif
   static u32_t identification;
   u16_t nfb;
   u16_t left, cop;
@@ -665,8 +675,6 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
   u16_t fragment_offset = 0;
   u16_t last;
   u16_t poff = IP6_HLEN;
-  u16_t newpbuflen = 0;
-  u16_t left_to_copy;
 
   identification++;
 
@@ -685,6 +693,26 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
     /* Fill this fragment */
     cop = last ? left : nfb;
 
+#if LWIP_NETIF_TX_SINGLE_PBUF
+    rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM);
+    if (rambuf == NULL) {
+      IP6_FRAG_STATS_INC(ip6_frag.memerr);
+      return ERR_MEM;
+    }
+    LWIP_ASSERT("this needs a pbuf in one piece!",
+      (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
+    poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff);
+    /* make room for the IP header */
+    if (pbuf_header(rambuf, IP6_HLEN)) {
+      pbuf_free(rambuf);
+      IP6_FRAG_STATS_INC(ip6_frag.memerr);
+      return ERR_MEM;
+    }
+    /* fill in the IP header */
+    SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
+    ip6hdr = (struct ip6_hdr *)rambuf->payload;
+    frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
+#else
     /* When not using a static buffer, create a chain of pbufs.
      * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header.
      * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
@@ -696,7 +724,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
       return ERR_MEM;
     }
     LWIP_ASSERT("this needs a pbuf in one piece!",
-                (p->len >= (IP6_HLEN + IP6_FRAG_HLEN)));
+                (p->len >= (IP6_HLEN)));
     SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
     ip6hdr = (struct ip6_hdr *)rambuf->payload;
     frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
@@ -743,12 +771,13 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
       }
     }
     poff = newpbuflen;
+#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
 
     /* Set headers */
     frag_hdr->_nexth = original_ip6hdr->_nexth;
     frag_hdr->reserved = 0;
-    frag_hdr->_fragment_offset = htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG));
-    frag_hdr->_identification = htonl(identification);
+    frag_hdr->_fragment_offset = lwip_htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG));
+    frag_hdr->_identification = lwip_htonl(identification);
 
     IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT);
     IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/mld6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/mld6.c b/net/ip/lwip_base/src/core/ipv6/mld6.c
index 2ebcff3..9acb82f 100644
--- a/net/ip/lwip_base/src/core/ipv6/mld6.c
+++ b/net/ip/lwip_base/src/core/ipv6/mld6.c
@@ -564,7 +564,7 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
   ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
 
 #if CHECKSUM_GEN_ICMP6
-  IF__NETIF_CHECKSUM_ENABLED(group->netif, NETIF_CHECKSUM_GEN_ICMP6) {
+  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
     mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
       src_addr, &(group->group_address));
   }
@@ -573,6 +573,11 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
   /* Add hop-by-hop headers options: router alert with MLD value. */
   ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
 
+  if (type == ICMP6_TYPE_MLR) {
+    /* Remember we were the last to report */
+    group->last_reporter_flag = 1;
+  }
+
   /* Send the packet out. */
   MLD6_STATS_INC(mld6.xmit);
   ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/ipv6/nd6.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/ipv6/nd6.c b/net/ip/lwip_base/src/core/ipv6/nd6.c
index 7806f6e..0b36718 100644
--- a/net/ip/lwip_base/src/core/ipv6/nd6.c
+++ b/net/ip/lwip_base/src/core/ipv6/nd6.c
@@ -46,6 +46,7 @@
 #if LWIP_IPV6  /* don't build if not configured for use in lwipopts.h */
 
 #include "lwip/nd6.h"
+#include "lwip/priv/nd6_priv.h"
 #include "lwip/prot/nd6.h"
 #include "lwip/prot/icmp6.h"
 #include "lwip/pbuf.h"
@@ -59,9 +60,14 @@
 #include "lwip/mld6.h"
 #include "lwip/ip.h"
 #include "lwip/stats.h"
+#include "lwip/dns.h"
 
 #include <string.h>
 
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
 #error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK
 #endif
@@ -93,10 +99,13 @@ static void nd6_free_neighbor_cache_entry(s8_t i);
 static s8_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr);
 static s8_t nd6_new_destination_cache_entry(void);
 static s8_t nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif);
+static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif);
 static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif);
 static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif);
 static s8_t nd6_get_onlink_prefix(ip6_addr_t *prefix, struct netif *netif);
 static s8_t nd6_new_onlink_prefix(ip6_addr_t *prefix, struct netif *netif);
+static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif);
+static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q);
 
 #define ND6_SEND_FLAG_MULTICAST_DEST 0x01
 #define ND6_SEND_FLAG_ALLNODES_DEST 0x02
@@ -149,50 +158,27 @@ nd6_input(struct pbuf *p, struct netif *inp)
 
     /* Unsolicited NA?*/
     if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
+      ip6_addr_t target_address;
+      
       /* This is an unsolicited NA.
        * link-layer changed?
        * part of DAD mechanism? */
 
-      /* Check that link-layer address option also fits in packet. */
-      if (p->len < (sizeof(struct na_header) + 2)) {
-        /* @todo debug message */
-        pbuf_free(p);
-        ND6_STATS_INC(nd6.lenerr);
-        ND6_STATS_INC(nd6.drop);
-        return;
-      }
-
-      lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
-
-      if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
-        /* @todo debug message */
-        pbuf_free(p);
-        ND6_STATS_INC(nd6.lenerr);
-        ND6_STATS_INC(nd6.drop);
-        return;
-      }
-
-      /* Override ip6_current_dest_addr() so that we have an aligned copy. */
-      ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address));
+      /* Create an aligned copy. */
+      ip6_addr_set(&target_address, &(na_hdr->target_address));
 
 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS
       /* If the target address matches this netif, it is a DAD response. */
       for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
         if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) &&
-            ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
+            ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
           /* We are using a duplicate address. */
           netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID);
 
-#if LWIP_IPV6_MLD
-          /* Leave solicited node multicast group. */
-          ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(inp, i)->addr[3]);
-          mld6_leavegroup(netif_ip6_addr(inp, i), &multicast_address);
-#endif /* LWIP_IPV6_MLD */
-
 #if LWIP_IPV6_AUTOCONFIG
           /* Check to see if this address was autoconfigured. */
-          if (!ip6_addr_islinklocal(ip6_current_dest_addr())) {
-            i = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp);
+          if (!ip6_addr_islinklocal(&target_address)) {
+            i = nd6_get_onlink_prefix(&target_address, inp);
             if (i >= 0) {
               /* Mark this prefix as duplicate, so that we don't use it
                * to generate this address again. */
@@ -207,23 +193,44 @@ nd6_input(struct pbuf *p, struct netif *inp)
       }
 #endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */
 
+      /* Check that link-layer address option also fits in packet. */
+      if (p->len < (sizeof(struct na_header) + 2)) {
+        /* @todo debug message */
+        pbuf_free(p);
+        ND6_STATS_INC(nd6.lenerr);
+        ND6_STATS_INC(nd6.drop);
+        return;
+      }
+
+      lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+
+      if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
+        /* @todo debug message */
+        pbuf_free(p);
+        ND6_STATS_INC(nd6.lenerr);
+        ND6_STATS_INC(nd6.drop);
+        return;
+      }
+
       /* This is an unsolicited NA, most likely there was a LLADDR change. */
-      i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr());
+      i = nd6_find_neighbor_cache_entry(&target_address);
       if (i >= 0) {
         if (na_hdr->flags & ND6_FLAG_OVERRIDE) {
           MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
         }
       }
     } else {
+      ip6_addr_t target_address;
+
       /* This is a solicited NA.
        * neighbor address resolution response?
        * neighbor unreachability detection response? */
 
-      /* Override ip6_current_dest_addr() so that we have an aligned copy. */
-      ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address));
+      /* Create an aligned copy. */
+      ip6_addr_set(&target_address, &(na_hdr->target_address));
 
       /* Find the cache entry corresponding to this na. */
-      i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr());
+      i = nd6_find_neighbor_cache_entry(&target_address);
       if (i < 0) {
         /* We no longer care about this target address. drop it. */
         pbuf_free(p);
@@ -231,8 +238,6 @@ nd6_input(struct pbuf *p, struct netif *inp)
       }
 
       /* Update cache entry. */
-      neighbor_cache[i].netif = inp;
-      neighbor_cache[i].counter.reachable_time = reachable_time;
       if ((na_hdr->flags & ND6_FLAG_OVERRIDE) ||
           (neighbor_cache[i].state == ND6_INCOMPLETE)) {
         /* Check that link-layer address option also fits in packet. */
@@ -256,7 +261,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
 
         MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
       }
+
+      neighbor_cache[i].netif = inp;
       neighbor_cache[i].state = ND6_REACHABLE;
+      neighbor_cache[i].counter.reachable_time = reachable_time;
 
       /* Send queued packets, if any. */
       if (neighbor_cache[i].q != NULL) {
@@ -326,6 +334,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
         }
       }
     } else {
+      ip6_addr_t target_address;
+      
       /* Sender is trying to resolve our address. */
       /* Verify that they included their own link-layer address. */
       if (lladdr_opt == NULL) {
@@ -345,7 +355,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
 
           /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */
           neighbor_cache[i].state = ND6_DELAY;
-          neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+          neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
         }
       } else {
         /* Add their IPv6 address and link-layer address to neighbor cache.
@@ -366,14 +376,14 @@ nd6_input(struct pbuf *p, struct netif *inp)
         /* Receiving a message does not prove reachability: only in one direction.
          * Delay probe in case we get confirmation of reachability from upper layer (TCP). */
         neighbor_cache[i].state = ND6_DELAY;
-        neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+        neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
       }
 
-      /* Override ip6_current_dest_addr() so that we have an aligned copy. */
-      ip6_addr_set(ip6_current_dest_addr(), &(ns_hdr->target_address));
+      /* Create an aligned copy. */
+      ip6_addr_set(&target_address, &(ns_hdr->target_address));
 
       /* Send back a NA for us. Allocate the reply pbuf. */
-      nd6_send_na(inp, ip6_current_dest_addr(), ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE);
+      nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE);
     }
 
     break; /* ICMP6_TYPE_NS */
@@ -383,6 +393,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
     struct ra_header *ra_hdr;
     u8_t *buffer; /* Used to copy options. */
     u16_t offset;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+    /* There can by multiple RDNSS options per RA */
+    u8_t rdnss_server_idx = 0;
+#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */
 
     /* Check that RA header fits in packet. */
     if (p->len < sizeof(struct ra_header)) {
@@ -419,15 +433,15 @@ nd6_input(struct pbuf *p, struct netif *inp)
     }
 
     /* Re-set invalidation timer. */
-    default_router_list[i].invalidation_timer = htons(ra_hdr->router_lifetime);
+    default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime);
 
     /* Re-set default timer values. */
 #if LWIP_ND6_ALLOW_RA_UPDATES
     if (ra_hdr->retrans_timer > 0) {
-      retrans_timer = htonl(ra_hdr->retrans_timer);
+      retrans_timer = lwip_htonl(ra_hdr->retrans_timer);
     }
     if (ra_hdr->reachable_time > 0) {
-      reachable_time = htonl(ra_hdr->reachable_time);
+      reachable_time = lwip_htonl(ra_hdr->reachable_time);
     }
 #endif /* LWIP_ND6_ALLOW_RA_UPDATES */
 
@@ -478,9 +492,9 @@ nd6_input(struct pbuf *p, struct netif *inp)
       {
         struct mtu_option *mtu_opt;
         mtu_opt = (struct mtu_option *)buffer;
-        if (htonl(mtu_opt->mtu) >= 1280) {
+        if (lwip_htonl(mtu_opt->mtu) >= 1280) {
 #if LWIP_ND6_ALLOW_RA_UPDATES
-          inp->mtu = (u16_t)htonl(mtu_opt->mtu);
+          inp->mtu = (u16_t)lwip_htonl(mtu_opt->mtu);
 #endif /* LWIP_ND6_ALLOW_RA_UPDATES */
         }
         break;
@@ -495,18 +509,19 @@ nd6_input(struct pbuf *p, struct netif *inp)
             !ip6_addr_islinklocal(&(prefix_opt->prefix))) {
           /* Add to on-link prefix list. */
           s8_t prefix;
+          ip6_addr_t prefix_addr;
 
           /* Get a memory-aligned copy of the prefix. */
-          ip6_addr_set(ip6_current_dest_addr(), &(prefix_opt->prefix));
+          ip6_addr_set(&prefix_addr, &(prefix_opt->prefix));
 
           /* find cache entry for this prefix. */
-          prefix = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp);
+          prefix = nd6_get_onlink_prefix(&prefix_addr, inp);
           if (prefix < 0) {
             /* Create a new cache entry. */
-            prefix = nd6_new_onlink_prefix(ip6_current_dest_addr(), inp);
+            prefix = nd6_new_onlink_prefix(&prefix_addr, inp);
           }
           if (prefix >= 0) {
-            prefix_list[prefix].invalidation_timer = htonl(prefix_opt->valid_lifetime);
+            prefix_list[prefix].invalidation_timer = lwip_htonl(prefix_opt->valid_lifetime);
 
 #if LWIP_IPV6_AUTOCONFIG
             if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) {
@@ -526,6 +541,37 @@ nd6_input(struct pbuf *p, struct netif *inp)
         route_opt = (struct route_option *)buffer;*/
 
         break;
+#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
+      case ND6_OPTION_TYPE_RDNSS:
+      {
+        u8_t num, n;
+        struct rdnss_option * rdnss_opt;
+
+        rdnss_opt = (struct rdnss_option *)buffer;
+        num = (rdnss_opt->length - 1) / 2;
+        for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) {
+          ip_addr_t rdnss_address;
+
+          /* Get a memory-aligned copy of the prefix. */
+          ip_addr_copy_from_ip6(rdnss_address, rdnss_opt->rdnss_address[n]);
+
+          if (htonl(rdnss_opt->lifetime) > 0) {
+            /* TODO implement Lifetime > 0 */
+            dns_setserver(rdnss_server_idx++, &rdnss_address);
+          } else {
+            /* TODO implement DNS removal in dns.c */
+            u8_t s;
+            for (s = 0; s < DNS_MAX_SERVERS; s++) {
+              const ip_addr_t *addr = dns_getserver(s);
+              if(ip_addr_cmp(addr, &rdnss_address)) {
+                dns_setserver(s, NULL);
+              }
+            }
+          }
+        }
+        break;
+      }
+#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */
       default:
         /* Unrecognized option, abort. */
         ND6_STATS_INC(nd6.proterr);
@@ -541,6 +587,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
   {
     struct redirect_header *redir_hdr;
     struct lladdr_option *lladdr_opt;
+    ip6_addr_t tmp;
 
     /* Check that Redir header fits in packet. */
     if (p->len < sizeof(struct redirect_header)) {
@@ -563,10 +610,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
     }
 
     /* Copy original destination address to current source address, to have an aligned copy. */
-    ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->destination_address));
+    ip6_addr_set(&tmp, &(redir_hdr->destination_address));
 
     /* Find dest address in cache */
-    i = nd6_find_destination_cache_entry(ip6_current_src_addr());
+    i = nd6_find_destination_cache_entry(&tmp);
     if (i < 0) {
       /* Destination not in cache, drop packet. */
       pbuf_free(p);
@@ -580,20 +627,20 @@ nd6_input(struct pbuf *p, struct netif *inp)
     if (lladdr_opt != NULL) {
       if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) {
         /* Copy target address to current source address, to have an aligned copy. */
-        ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->target_address));
+        ip6_addr_set(&tmp, &(redir_hdr->target_address));
 
-        i = nd6_find_neighbor_cache_entry(ip6_current_src_addr());
+        i = nd6_find_neighbor_cache_entry(&tmp);
         if (i < 0) {
           i = nd6_new_neighbor_cache_entry();
           if (i >= 0) {
             neighbor_cache[i].netif = inp;
             MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
-            ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr());
+            ip6_addr_set(&(neighbor_cache[i].next_hop_address), &tmp);
 
             /* Receiving a message does not prove reachability: only in one direction.
              * Delay probe in case we get confirmation of reachability from upper layer (TCP). */
             neighbor_cache[i].state = ND6_DELAY;
-            neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+            neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
           }
         }
         if (i >= 0) {
@@ -602,7 +649,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
             /* Receiving a message does not prove reachability: only in one direction.
              * Delay probe in case we get confirmation of reachability from upper layer (TCP). */
             neighbor_cache[i].state = ND6_DELAY;
-            neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+            neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
           }
         }
       }
@@ -614,6 +661,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
     struct icmp6_hdr *icmp6hdr; /* Packet too big message */
     struct ip6_hdr *ip6hdr; /* IPv6 header of the packet which caused the error */
     u32_t pmtu;
+    ip6_addr_t tmp;
 
     /* Check that ICMPv6 header + IPv6 header fit in payload */
     if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) {
@@ -628,10 +676,10 @@ nd6_input(struct pbuf *p, struct netif *inp)
     ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr));
 
     /* Copy original destination address to current source address, to have an aligned copy. */
-    ip6_addr_set(ip6_current_src_addr(), &(ip6hdr->dest));
+    ip6_addr_set(&tmp, &(ip6hdr->dest));
 
     /* Look for entry in destination cache. */
-    i = nd6_find_destination_cache_entry(ip6_current_src_addr());
+    i = nd6_find_destination_cache_entry(&tmp);
     if (i < 0) {
       /* Destination not in cache, drop packet. */
       pbuf_free(p);
@@ -639,7 +687,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
     }
 
     /* Change the Path MTU. */
-    pmtu = htonl(icmp6hdr->data);
+    pmtu = lwip_htonl(icmp6hdr->data);
     destination_cache[i].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF);
 
     break; /* ICMP6_TYPE_PTB */
@@ -698,15 +746,15 @@ nd6_tmr(void)
       }
       break;
     case ND6_STALE:
-      neighbor_cache[i].counter.stale_time += ND6_TMR_INTERVAL;
+      neighbor_cache[i].counter.stale_time++;
       break;
     case ND6_DELAY:
-      if (neighbor_cache[i].counter.delay_time <= ND6_TMR_INTERVAL) {
+      if (neighbor_cache[i].counter.delay_time <= 1) {
         /* Change to PROBE state. */
         neighbor_cache[i].state = ND6_PROBE;
         neighbor_cache[i].counter.probes_sent = 0;
       } else {
-        neighbor_cache[i].counter.delay_time -= ND6_TMR_INTERVAL;
+        neighbor_cache[i].counter.delay_time--;
       }
       break;
     case ND6_PROBE:
@@ -821,13 +869,6 @@ nd6_tmr(void)
           netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED);
           /* @todo implement preferred and valid lifetimes. */
         } else if (netif->flags & NETIF_FLAG_UP) {
-#if LWIP_IPV6_MLD
-          if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) == 0) {
-            /* Join solicited node multicast group. */
-            ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, i)->addr[3]);
-            mld6_joingroup(netif_ip6_addr(netif, i), &multicast_address);
-          }
-#endif /* LWIP_IPV6_MLD */
           /* Send a NS for this address. */
           nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST);
           /* tentative: set next state by increasing by one */
@@ -1286,6 +1327,22 @@ nd6_new_destination_cache_entry(void)
 }
 
 /**
+ * Clear the destination cache.
+ *
+ * This operation may be necessary for consistency in the light of changing
+ * local addresses and/or use of the gateway hook.
+ */
+void
+nd6_clear_destination_cache(void)
+{
+  int i;
+
+  for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) {
+    ip6_addr_set_any(&destination_cache[i].destination_addr);
+  }
+}
+
+/**
  * Determine whether an address matches an on-link prefix.
  *
  * @param ip6addr the IPv6 address to match
@@ -1320,7 +1377,7 @@ nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif)
  * @return the default router entry index, or -1 if no suitable
  *         router is found
  */
-s8_t
+static s8_t
 nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
 {
   s8_t i;
@@ -1373,6 +1430,30 @@ nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
 }
 
 /**
+ * Find a router-announced route to the given destination.
+ *
+ * The caller is responsible for checking whether the returned netif, if any,
+ * is in a suitable state (up, link up) to be used for packet transmission.
+ *
+ * @param ip6addr the destination IPv6 address
+ * @return the netif to use for the destination, or NULL if none found
+ */
+struct netif *
+nd6_find_route(const ip6_addr_t *ip6addr)
+{
+  s8_t i;
+
+  i = nd6_select_router(ip6addr, NULL);
+  if (i >= 0) {
+    if (default_router_list[i].neighbor_entry != NULL) {
+      return default_router_list[i].neighbor_entry->netif; /* may be NULL */
+    }
+  }
+
+  return NULL;
+}
+
+/**
  * Find an entry for a default router.
  *
  * @param router_addr the IPv6 address of the router
@@ -1408,6 +1489,7 @@ static s8_t
 nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif)
 {
   s8_t router_index;
+  s8_t free_router_index;
   s8_t neighbor_index;
 
   /* Do we have a neighbor entry for this router? */
@@ -1431,12 +1513,22 @@ nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif)
   neighbor_cache[neighbor_index].isrouter = 1;
 
   /* Look for empty entry. */
-  for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) {
+  free_router_index = LWIP_ND6_NUM_ROUTERS;
+  for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) {
+    /* check if router already exists (this is a special case for 2 netifs on the same subnet
+       - e.g. wifi and cable) */
+    if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){ 
+      return router_index; 
+    } 
     if (default_router_list[router_index].neighbor_entry == NULL) {
-      default_router_list[router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
-      return router_index;
+      /* remember lowest free index to create a new entry */
+      free_router_index = router_index;
     }
   }
+  if (free_router_index < LWIP_ND6_NUM_ROUTERS) {
+    default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
+    return free_router_index;
+  }
 
   /* Could not create a router entry. */
 
@@ -1513,9 +1605,12 @@ nd6_new_onlink_prefix(ip6_addr_t *prefix, struct netif *netif)
  *         suitable next hop was found, ERR_MEM if no cache entry
  *         could be created
  */
-s8_t
+static s8_t
 nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
 {
+#ifdef LWIP_HOOK_ND6_GET_GW
+  const ip6_addr_t *next_hop_addr;
+#endif /* LWIP_HOOK_ND6_GET_GW */
   s8_t i;
 
 #if LWIP_NETIF_HWADDRHINT
@@ -1559,6 +1654,12 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
         /* Destination in local link. */
         destination_cache[nd6_cached_destination_index].pmtu = netif->mtu;
         ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr);
+#ifdef LWIP_HOOK_ND6_GET_GW
+      } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) {
+        /* Next hop for destination provided by hook function. */
+        destination_cache[nd6_cached_destination_index].pmtu = netif->mtu;
+        ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr);
+#endif /* LWIP_HOOK_ND6_GET_GW */
       } else {
         /* We need to select a router. */
         i = nd6_select_router(ip6addr, netif);
@@ -1626,7 +1727,7 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
  * @param q packet to be queued
  * @return ERR_OK if succeeded, ERR_MEM if out of memory
  */
-err_t
+static err_t
 nd6_queue_packet(s8_t neighbor_index, struct pbuf *q)
 {
   err_t result = ERR_MEM;
@@ -1762,6 +1863,7 @@ static void
 nd6_send_q(s8_t i)
 {
   struct ip6_hdr *ip6hdr;
+  ip6_addr_t dest;
 #if LWIP_ND6_QUEUEING
   struct nd6_q_entry *q;
 #endif /* LWIP_ND6_QUEUEING */
@@ -1778,10 +1880,10 @@ nd6_send_q(s8_t i)
     neighbor_cache[i].q = q->next;
     /* Get ipv6 header. */
     ip6hdr = (struct ip6_hdr *)(q->p->payload);
-    /* Override ip6_current_dest_addr() so that we have an aligned copy. */
-    ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest));
+    /* Create an aligned copy. */
+    ip6_addr_set(&dest, &(ip6hdr->dest));
     /* send the queued IPv6 packet */
-    (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, ip6_current_dest_addr());
+    (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, &dest);
     /* free the queued IP packet */
     pbuf_free(q->p);
     /* now queue entry can be freed */
@@ -1791,10 +1893,10 @@ nd6_send_q(s8_t i)
   if (neighbor_cache[i].q != NULL) {
     /* Get ipv6 header. */
     ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload);
-    /* Override ip6_current_dest_addr() so that we have an aligned copy. */
-    ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest));
+    /* Create an aligned copy. */
+    ip6_addr_set(&dest, &(ip6hdr->dest));
     /* send the queued IPv6 packet */
-    (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, ip6_current_dest_addr());
+    (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, &dest);
     /* free the queued IP packet */
     pbuf_free(neighbor_cache[i].q);
     neighbor_cache[i].q = NULL;
@@ -1802,6 +1904,61 @@ nd6_send_q(s8_t i)
 #endif /* LWIP_ND6_QUEUEING */
 }
 
+/**
+ * A packet is to be transmitted to a specific IPv6 destination on a specific
+ * interface. Check if we can find the hardware address of the next hop to use
+ * for the packet. If so, give the hardware address to the caller, which should
+ * use it to send the packet right away. Otherwise, enqueue the packet for
+ * later transmission while looking up the hardware address, if possible.
+ *
+ * As such, this function returns one of three different possible results:
+ *
+ * - ERR_OK with a non-NULL 'hwaddrp': the caller should send the packet now.
+ * - ERR_OK with a NULL 'hwaddrp': the packet has been enqueued for later.
+ * - not ERR_OK: something went wrong; forward the error upward in the stack.
+ *
+ * @param netif The lwIP network interface on which the IP packet will be sent.
+ * @param q The pbuf(s) containing the IP packet to be sent.
+ * @param ip6addr The destination IPv6 address of the packet.
+ * @param hwaddrp On success, filled with a pointer to a HW address or NULL (meaning
+ *        the packet has been queued).
+ * @return
+ * - ERR_OK on success, ERR_RTE if no route was found for the packet,
+ * or ERR_MEM if low memory conditions prohibit sending the packet at all.
+ */
+err_t
+nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp)
+{
+  s8_t i;
+
+  /* Get next hop record. */
+  i = nd6_get_next_hop_entry(ip6addr, netif);
+  if (i < 0) {
+    /* failed to get a next hop neighbor record. */
+    return i;
+  }
+
+  /* Now that we have a destination record, send or queue the packet. */
+  if (neighbor_cache[i].state == ND6_STALE) {
+    /* Switch to delay state. */
+    neighbor_cache[i].state = ND6_DELAY;
+    neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
+  }
+  /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */
+  if ((neighbor_cache[i].state == ND6_REACHABLE) ||
+      (neighbor_cache[i].state == ND6_DELAY) ||
+      (neighbor_cache[i].state == ND6_PROBE)) {
+
+    /* Tell the caller to send out the packet now. */
+    *hwaddrp = neighbor_cache[i].lladdr;
+    return ERR_OK;
+  }
+
+  /* We should queue packet on this interface. */
+  *hwaddrp = NULL;
+  return nd6_queue_packet(i, q);
+}
+
 
 /**
  * Get the Path MTU for a destination.
@@ -1908,4 +2065,38 @@ nd6_cleanup_netif(struct netif *netif)
   }
 }
 
+#if LWIP_IPV6_MLD
+/**
+ * The state of a local IPv6 address entry is about to change. If needed, join
+ * or leave the solicited-node multicast group for the address.
+ *
+ * @param netif The netif that owns the address.
+ * @param addr_idx The index of the address.
+ * @param new_state The new (IP6_ADDR_) state for the address.
+ */
+void
+nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state)
+{
+  u8_t old_state, old_member, new_member;
+
+  old_state = netif_ip6_addr_state(netif, addr_idx);
+
+  /* Determine whether we were, and should be, a member of the solicited-node
+   * multicast group for this address. For tentative addresses, the group is
+   * not joined until the address enters the TENTATIVE_1 (or VALID) state. */
+  old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_TENTATIVE);
+  new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_TENTATIVE);
+
+  if (old_member != new_member) {
+    ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]);
+
+    if (new_member) {
+      mld6_joingroup_netif(netif, &multicast_address);
+    } else {
+      mld6_leavegroup_netif(netif, &multicast_address);
+    }
+  }
+}
+#endif /* LWIP_IPV6_MLD */
+
 #endif /* LWIP_IPV6 */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/mem.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/mem.c b/net/ip/lwip_base/src/core/mem.c
index 40f4cb9..db3b7cc 100644
--- a/net/ip/lwip_base/src/core/mem.c
+++ b/net/ip/lwip_base/src/core/mem.c
@@ -61,9 +61,13 @@
 #include "lwip/err.h"
 
 #include <string.h>
-#include <stdlib.h>
+
+#if MEM_LIBC_MALLOC
+#include <stdlib.h> /* for malloc()/free() */
+#endif
 
 #if MEM_LIBC_MALLOC || MEM_USE_POOLS
+
 /** mem_init is not used when using pools instead of a heap or using
  * C library malloc().
  */
@@ -162,7 +166,7 @@ void *
 mem_malloc(mem_size_t size)
 {
   void *ret;
-  struct memp_malloc_helper *element;
+  struct memp_malloc_helper *element = NULL;
   memp_t poolnr;
   mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f52033e9/net/ip/lwip_base/src/core/memp.c
----------------------------------------------------------------------
diff --git a/net/ip/lwip_base/src/core/memp.c b/net/ip/lwip_base/src/core/memp.c
index 19198eb..58fab1a 100644
--- a/net/ip/lwip_base/src/core/memp.c
+++ b/net/ip/lwip_base/src/core/memp.c
@@ -71,11 +71,10 @@
 #include "netif/ppp/ppp_opts.h"
 #include "lwip/netdb.h"
 #include "lwip/dns.h"
-#include "lwip/nd6.h"
+#include "lwip/priv/nd6_priv.h"
 #include "lwip/ip6_frag.h"
 #include "lwip/mld6.h"
 
-
 #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
 #include "lwip/priv/memp_std.h"
 
@@ -84,6 +83,10 @@ const struct memp_desc* const memp_pools[MEMP_MAX] = {
 #include "lwip/priv/memp_std.h"
 };
 
+#ifdef LWIP_HOOK_FILENAME
+#include LWIP_HOOK_FILENAME
+#endif
+
 #if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2
 #undef MEMP_OVERFLOW_CHECK
 /* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */
@@ -205,11 +208,11 @@ memp_overflow_check_all(void)
   SYS_ARCH_PROTECT(old_level);
 
   for (i = 0; i < MEMP_MAX; ++i) {
-    p = (struct memp *)(size_t)(memp_pools[i]->base);
+    p = (struct memp*)LWIP_MEM_ALIGN(memp_pools[i]->base);
     for (j = 0; j < memp_pools[i]->num; ++j) {
       memp_overflow_check_element_overflow(p, memp_pools[i]);
       memp_overflow_check_element_underflow(p, memp_pools[i]);
-      p = (struct memp*)(size_t)((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED);
+      p = LWIP_ALIGNMENT_CAST(struct memp*, ((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED));
     }
   }
   SYS_ARCH_UNPROTECT(old_level);
@@ -301,15 +304,15 @@ do_memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int
   SYS_ARCH_PROTECT(old_level);
 
   memp = *desc->tab;
-
-#if MEMP_OVERFLOW_CHECK == 1
-  memp_overflow_check_element_overflow(memp, desc);
-  memp_overflow_check_element_underflow(memp, desc);
-#endif /* MEMP_OVERFLOW_CHECK */
 #endif /* MEMP_MEM_MALLOC */
 
   if (memp != NULL) {
 #if !MEMP_MEM_MALLOC
+#if MEMP_OVERFLOW_CHECK == 1
+    memp_overflow_check_element_overflow(memp, desc);
+    memp_overflow_check_element_underflow(memp, desc);
+#endif /* MEMP_OVERFLOW_CHECK */
+
     *desc->tab = memp->next;
 #if MEMP_OVERFLOW_CHECK
     memp->next = NULL;
@@ -471,6 +474,10 @@ memp_free(memp_t type, void *mem)
 
   LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;);
 
+  if (mem == NULL) {
+    return;
+  }
+
 #if MEMP_OVERFLOW_CHECK >= 2
   memp_overflow_check_all();
 #endif /* MEMP_OVERFLOW_CHECK >= 2 */