Index: trunk/src/VBox/Devices/Network/lwip-new/CHANGELOG
===================================================================
--- trunk/src/VBox/Devices/Network/lwip-new/CHANGELOG	(revision 50173)
+++ trunk/src/VBox/Devices/Network/lwip-new/CHANGELOG	(revision 50185)
@@ -80,4 +80,10 @@
 
  ++ Bugfixes:
+
+  2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt
+  * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback
+
+  2014-01-16: Stathis Voukelatos
+  * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0
 
   2014-01-14: "Freddie Chopin"
Index: trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c
===================================================================
--- trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c	(revision 50173)
+++ trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv4/ip4.c	(revision 50185)
@@ -880,9 +880,9 @@
     /* Packet to self, enqueue it for loopback */
     LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
-    return netif_loop_output(netif, p, dest);
+    return netif_loop_output(netif, p);
   }
 #if LWIP_IGMP
   if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
-    netif_loop_output(netif, p, dest);
+    netif_loop_output(netif, p);
   }
 #endif /* LWIP_IGMP */
Index: trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c
===================================================================
--- trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c	(revision 50173)
+++ trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c	(revision 50185)
@@ -948,8 +948,15 @@
 
 #if ENABLE_LOOPBACK
-  /* TODO implement loopback for v6
-  if (ip6_addr_cmp(dest, netif_ip6_addr(0))) {
-    return netif_loop_output(netif, p, dest);
-  }*/
+  {
+    int i;
+    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))) {
+        /* Packet to self, enqueue it for loopback */
+        LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
+        return netif_loop_output(netif, p);
+      }
+    }
+  }
 #endif /* ENABLE_LOOPBACK */
 #if LWIP_IPV6_FRAG
@@ -960,5 +967,5 @@
 #endif /* LWIP_IPV6_FRAG */
 
-  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()"));
+  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
   return netif->output_ip6(netif, p, dest);
 }
Index: trunk/src/VBox/Devices/Network/lwip-new/src/core/netif.c
===================================================================
--- trunk/src/VBox/Devices/Network/lwip-new/src/core/netif.c	(revision 50173)
+++ trunk/src/VBox/Devices/Network/lwip-new/src/core/netif.c	(revision 50185)
@@ -89,5 +89,17 @@
 #endif /* LWIP_IPV6 */
 
+#if LWIP_IPV6
+#define ipX_input(in, netif) (IP6H_V((const struct ip6_hdr *)in->payload) == 6) ? ip6_input(in, netif) : ip_input(in, netif)
+#else
+#define ipX_input(in, netif) ip_input(in, netif)
+#endif
+
 #if LWIP_HAVE_LOOPIF
+static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, ip_addr_t* addr);
+#if LWIP_IPV6
+static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, ip6_addr_t* addr);
+#endif
+
+
 static struct netif loop_netif;
 
@@ -109,5 +121,8 @@
   netif->name[0] = 'l';
   netif->name[1] = 'o';
-  netif->output = netif_loop_output;
+  netif->output = netif_loop_output_ipv4;
+#if LWIP_IPV6
+  netif->output_ip6 = netif_loop_output_ipv6;
+#endif
   return ERR_OK;
 }
@@ -128,4 +143,13 @@
   netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input);
 #endif /* NO_SYS */
+
+#if LWIP_IPV6
+  loop_netif.ip6_addr[0].addr[0] = 0;
+  loop_netif.ip6_addr[0].addr[1] = 0;
+  loop_netif.ip6_addr[0].addr[2] = 0;
+  loop_netif.ip6_addr[0].addr[3] = PP_HTONL(0x00000001UL);
+  loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID;
+#endif /* LWIP_IPV6 */
+
   netif_set_up(&loop_netif);
 
@@ -656,11 +680,9 @@
  * @param netif the lwip network interface structure
  * @param p the (IP) packet to 'send'
- * @param ipaddr the ip address to send the packet to (not used)
  * @return ERR_OK if the packet has been sent
  *         ERR_MEM if the pbuf used to copy the packet couldn't be allocated
  */
 err_t
-netif_loop_output(struct netif *netif, struct pbuf *p,
-       ip_addr_t *ipaddr)
+netif_loop_output(struct netif *netif, struct pbuf *p)
 {
   struct pbuf *r;
@@ -680,5 +702,4 @@
 #endif /* LWIP_SNMP */
   SYS_ARCH_DECL_PROTECT(lev);
-  LWIP_UNUSED_ARG(ipaddr);
 
   /* Allocate a new pbuf */
@@ -741,4 +762,21 @@
   return ERR_OK;
 }
+
+static err_t
+netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, ip_addr_t* addr)
+{
+  LWIP_UNUSED_ARG(addr);
+  return netif_loop_output(netif, p);
+}
+
+#if LWIP_IPV6
+static err_t
+netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, ip6_addr_t* addr)
+{
+  LWIP_UNUSED_ARG(addr);
+  return netif_loop_output(netif, p);
+}
+#endif
+
 
 /**
@@ -770,5 +808,14 @@
       struct pbuf *in_end = in;
 #if LWIP_LOOPBACK_MAX_PBUFS
-      u8_t clen = pbuf_clen(in);
+      u8_t clen = 1;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+      while (in_end->len != in_end->tot_len) {
+        LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
+        in_end = in_end->next;
+#if LWIP_LOOPBACK_MAX_PBUFS
+        clen++;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+      }
+#if LWIP_LOOPBACK_MAX_PBUFS
       /* adjust the number of pbufs on queue */
       LWIP_ASSERT("netif->loop_cnt_current underflow",
@@ -776,8 +823,5 @@
       netif->loop_cnt_current -= clen;
 #endif /* LWIP_LOOPBACK_MAX_PBUFS */
-      while (in_end->len != in_end->tot_len) {
-        LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
-        in_end = in_end->next;
-      }
+
       /* 'in_end' now points to the last pbuf from 'in' */
       if (in_end == netif->loop_last) {
@@ -799,5 +843,5 @@
       snmp_inc_ifinucastpkts(stats_if);
       /* loopback packets are always IP packets! */
-      if (ip_input(in, netif) != ERR_OK) {
+      if (ipX_input(in, netif) != ERR_OK) {
         pbuf_free(in);
       }
Index: trunk/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h
===================================================================
--- trunk/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h	(revision 50173)
+++ trunk/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/ip6_addr.h	(revision 50185)
@@ -171,4 +171,8 @@
                              ((ip6addr)->addr[3] == 0)))
 
+#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \
+                                      ((ip6addr)->addr[1] == 0UL) && \
+                                      ((ip6addr)->addr[2] == 0UL) && \
+                                      ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
 
 #define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL))
Index: trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h
===================================================================
--- trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h	(revision 50173)
+++ trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/netif.h	(revision 50185)
@@ -360,5 +360,5 @@
 
 #if ENABLE_LOOPBACK
-err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip);
+err_t netif_loop_output(struct netif *netif, struct pbuf *p);
 void netif_poll(struct netif *netif);
 #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
