Index: core/netif.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/netif.c,v
retrieving revision 1.52
diff -u -r1.52 netif.c
--- core/netif.c	16 Jun 2007 13:32:10 -0000	1.52
+++ core/netif.c	24 Jun 2007 11:45:28 -0000
@@ -105,6 +105,9 @@
   netif->state = state;
   netif->num = netifnum++;
   netif->input = input;
+#if NETIF_HWADDRHINT
+  netif->addr_hint = NULL;
+#endif /* NETIF_HWADDRHINT*/
 
   netif_set_addr(netif, ipaddr, netmask, gw);
 
Index: core/raw.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/raw.c,v
retrieving revision 1.13
diff -u -r1.13 raw.c
--- core/raw.c	8 Jun 2007 07:22:21 -0000	1.13
+++ core/raw.c	24 Jun 2007 11:58:00 -0000
@@ -248,7 +248,13 @@
     src_ip = &(pcb->local_ip);
   }
 
+#if NETIF_HWADDRHINT
+  netif->addr_hint = &(pcb->addr_hint);
+#endif /* NETIF_HWADDRHINT*/
   err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
+#if NETIF_HWADDRHINT
+  netif->addr_hint = NULL;
+#endif /* NETIF_HWADDRHINT*/
 
   /* did we chain a header earlier? */
   if (q != p) {
Index: core/tcp_out.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/tcp_out.c,v
retrieving revision 1.55
diff -u -r1.55 tcp_out.c
--- core/tcp_out.c	22 Jun 2007 20:50:22 -0000	1.55
+++ core/tcp_out.c	24 Jun 2007 11:27:56 -0000
@@ -455,8 +455,21 @@
     tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
           IP_PROTO_TCP, p->tot_len);
 #endif
+#if NETIF_HWADDRHINT
+    {
+      struct netif *netif;
+      netif = ip_route(&pcb->remote_ip);
+      if(netif != NULL){
+        netif->addr_hint = &(pcb->addr_hint);
+        ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
+                     pcb->tos, IP_PROTO_TCP, netif);
+        netif->addr_hint = NULL;
+      }
+    }
+#else /* NETIF_HWADDRHINT*/
     ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
         IP_PROTO_TCP);
+#endif /* NETIF_HWADDRHINT*/
     pbuf_free(p);
 
     return ERR_OK;
@@ -601,8 +614,21 @@
 #endif
   TCP_STATS_INC(tcp.xmit);
 
+#if NETIF_HWADDRHINT
+  {
+    struct netif *netif;
+    netif = ip_route(&pcb->remote_ip);
+    if(netif != NULL){
+      netif->addr_hint = &(pcb->addr_hint);
+      ip_output_if(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
+                   pcb->tos, IP_PROTO_TCP, netif);
+      netif->addr_hint = NULL;
+    }
+  }
+#else /* NETIF_HWADDRHINT*/
   ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
       IP_PROTO_TCP);
+#endif /* NETIF_HWADDRHINT*/
 }
 
 /**
@@ -775,7 +801,20 @@
   TCP_STATS_INC(tcp.xmit);
 
    /* Send output to IP */
+#if NETIF_HWADDRHINT
+    {
+      struct netif *netif;
+      netif = ip_route(&pcb->remote_ip);
+      if(netif != NULL){
+        netif->addr_hint = &(pcb->addr_hint);
+        ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
+                     0, IP_PROTO_TCP, netif);
+        netif->addr_hint = NULL;
+      }
+    }
+#else /* NETIF_HWADDRHINT*/
   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
+#endif /* NETIF_HWADDRHINT*/
 
   pbuf_free(p);
 
Index: core/udp.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/udp.c,v
retrieving revision 1.89
diff -u -r1.89 udp.c
--- core/udp.c	12 Jun 2007 07:03:32 -0000	1.89
+++ core/udp.c	24 Jun 2007 11:24:38 -0000
@@ -438,7 +438,13 @@
 #endif /* CHECKSUM_CHECK_UDP */
     /* output to IP */
     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
+#if NETIF_HWADDRHINT
+    netif->addr_hint = &(pcb->addr_hint);
+#endif /* NETIF_HWADDRHINT*/
     err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);    
+#if NETIF_HWADDRHINT
+    netif->addr_hint = NULL;
+#endif /* NETIF_HWADDRHINT*/
   } else
 #endif /* LWIP_UDPLITE */
   {      /* UDP */
@@ -455,7 +461,13 @@
     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
     /* output to IP */
+#if NETIF_HWADDRHINT
+    netif->addr_hint = &(pcb->addr_hint);
+#endif /* NETIF_HWADDRHINT*/
     err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    
+#if NETIF_HWADDRHINT
+    netif->addr_hint = NULL;
+#endif /* NETIF_HWADDRHINT*/
   }
   /* TODO: must this be increased even if error occured? */
   snmp_inc_udpoutdatagrams();
Index: core/ipv4/ip.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/ipv4/ip.c,v
retrieving revision 1.49
diff -u -r1.49 ip.c
--- core/ipv4/ip.c	10 Jun 2007 20:02:43 -0000	1.49
+++ core/ipv4/ip.c	24 Jun 2007 11:19:21 -0000
@@ -96,6 +96,11 @@
       return netif;
     }
   }
+  if (netif_default == NULL) {
+    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_route: No route to 0x%"X32_F"\n", dest->addr));
+    IP_STATS_INC(ip.rterr);
+    snmp_inc_ipoutnoroutes();
+  }
   /* no matching netif found, use default netif */
   return netif_default;
 }
@@ -515,10 +520,6 @@
   struct netif *netif;
 
   if ((netif = ip_route(dest)) == NULL) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
-
-    IP_STATS_INC(ip.rterr);
-    snmp_inc_ipoutnoroutes();
     return ERR_RTE;
   }
 
Index: include/ipv4/lwip/ip.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/ipv4/lwip/ip.h,v
retrieving revision 1.21
diff -u -r1.21 ip.h
--- include/ipv4/lwip/ip.h	17 May 2007 12:22:11 -0000	1.21
+++ include/ipv4/lwip/ip.h	24 Jun 2007 11:20:42 -0000
@@ -83,7 +83,9 @@
    /* Type Of Service */ \
   u8_t tos;              \
   /* Time To Live */     \
-  u8_t ttl
+  u8_t ttl;              \
+  /* link layer address resolution hint */ \
+  u8_t addr_hint
 
 /*
  * Option flags per-socket. These are the same like SO_XXX.
Index: include/ipv6/lwip/ip.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/ipv6/lwip/ip.h,v
retrieving revision 1.10
diff -u -r1.10 ip.h
--- include/ipv6/lwip/ip.h	3 Jun 2007 18:10:38 -0000	1.10
+++ include/ipv6/lwip/ip.h	24 Jun 2007 11:21:01 -0000
@@ -69,7 +69,9 @@
    /* Type Of Service */ \
   u8_t tos;              \
   /* Time To Live */     \
-  u8_t ttl
+  u8_t ttl;              \
+  /* link layer address resolution hint */ \
+  u8_t addr_hint
 
 
 /* The IPv6 header. */
Index: include/lwip/netif.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/netif.h,v
retrieving revision 1.35
diff -u -r1.35 netif.h
--- include/lwip/netif.h	18 Jun 2007 21:45:35 -0000	1.35
+++ include/lwip/netif.h	24 Jun 2007 11:19:54 -0000
@@ -155,6 +155,9 @@
   /* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
   err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
 #endif /* LWIP_IGMP */
+#if NETIF_HWADDRHINT
+  u8_t *addr_hint;
+#endif /* NETIF_HWADDRHINT */
 };
 
 #if LWIP_SNMP
Index: netif/etharp.c
===================================================================
RCS file: /sources/lwip/lwip/src/netif/etharp.c,v
retrieving revision 1.119
diff -u -r1.119 etharp.c
--- netif/etharp.c	22 Jun 2007 20:50:22 -0000	1.119
+++ netif/etharp.c	24 Jun 2007 11:58:43 -0000
@@ -110,8 +110,13 @@
 #define ETHARP_TRY_HARD 1
 #define ETHARP_FIND_ONLY  2
 
-static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags);
-static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
+#if NETIF_HWADDRHINT
+static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif);
+#else /* NETIF_HWADDRHINT */
+static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags
+#endif /* NETIF_HWADDRHINT */
+
+                       static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
 
 /**
  * Initializes ARP module.
@@ -221,7 +226,11 @@
  * entry is found or could be recycled.
  */
 static s8_t
+#if NETIF_HWADDRHINT
+find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif)
+#else /* NETIF_HWADDRHINT */
 find_entry(struct ip_addr *ipaddr, u8_t flags)
+#endif /* NETIF_HWADDRHINT */
 {
   s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
   s8_t empty = ARP_TABLE_SIZE;
@@ -237,10 +246,33 @@
    * same address. If so, we're really fast! */
   if (ipaddr) {
     /* ipaddr to search for was given */
+#if NETIF_HWADDRHINT
+    /* for tests only: count cache-hits and misses */
+    static u32_t overall=0, miss=0, hit=0;
+    if ((netif != NULL) && (netif->addr_hint != NULL)) {
+      /* per-pcb cached entry was given */
+      u8_t per_pcb_cache = *(netif->addr_hint);
+      overall++;
+      if ((per_pcb_cache < ARP_TABLE_SIZE) && arp_table[per_pcb_cache].state == ETHARP_STATE_STABLE) {
+        /* the per-pcb-cached entry is stable */
+        if (ip_addr_cmp(ipaddr, &arp_table[per_pcb_cache].ipaddr)) {
+          /* per-pcb cached entry was the right one! */
+          hit++;
+          return per_pcb_cache;
+        }
+      }
+      miss++;
+    }
+#endif /* #if NETIF_HWADDRHINT */
     if (arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE) {
       /* the cached entry is stable */
       if (ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr)) {
         /* cached entry was the right one! */
+#if NETIF_HWADDRHINT
+        if ((netif != NULL) && (netif->addr_hint != NULL)) {
+          *(netif->addr_hint) = i;
+        }
+#endif /* #if NETIF_HWADDRHINT */
         return etharp_cached_entry;
       }
     }
@@ -274,6 +306,11 @@
       if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
         LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching pending entry %"U16_F"\n", (u16_t)i));
         /* found exact IP address match, simply bail out */
+#if NETIF_HWADDRHINT
+        if ((netif != NULL) && (netif->addr_hint != NULL)) {
+          *(netif->addr_hint) = i;
+        }
+#endif /* #if NETIF_HWADDRHINT */
         etharp_cached_entry = i;
         return i;
 #if ARP_QUEUEING
@@ -298,6 +335,11 @@
       if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
         LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching stable entry %"U16_F"\n", (u16_t)i));
         /* found exact IP address match, simply bail out */
+#if NETIF_HWADDRHINT
+        if ((netif != NULL) && (netif->addr_hint != NULL)) {
+          *(netif->addr_hint) = i;
+        }
+#endif /* #if NETIF_HWADDRHINT */
         etharp_cached_entry = i;
         return i;
       /* remember entry with oldest stable entry in oldest, its age in maxtime */
@@ -374,6 +416,11 @@
     ip_addr_set(&arp_table[i].ipaddr, ipaddr);
   }
   arp_table[i].ctime = 0;
+#if NETIF_HWADDRHINT
+  if ((netif != NULL) && (netif->addr_hint != NULL)) {
+    *(netif->addr_hint) = i;
+  }
+#endif /* #if NETIF_HWADDRHINT */
   etharp_cached_entry = i;
   return (err_t)i;
 }
@@ -416,7 +463,11 @@
     return ERR_ARG;
   }
   /* find or create ARP entry */
+#if NETIF_HWADDRHINT
+  i = find_entry(ipaddr, flags, netif);
+#else /* NETIF_HWADDRHINT */
   i = find_entry(ipaddr, flags);
+#endif /* NETIF_HWADDRHINT */
   /* bail out if no entry could be found */
   if (i < 0)
     return (err_t)i;
@@ -488,7 +539,11 @@
 {
   s8_t i;
 
+#if NETIF_HWADDRHINT
+  i = find_entry(ipaddr, ETHARP_FIND_ONLY, NULL);
+#else /* NETIF_HWADDRHINT */
   i = find_entry(ipaddr, ETHARP_FIND_ONLY);
+#endif /* NETIF_HWADDRHINT */
   if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) {
       *eth_ret = &arp_table[i].ethaddr;
       *ip_ret = &arp_table[i].ipaddr;
@@ -808,7 +863,11 @@
   }
 
   /* find entry in ARP cache, ask to create entry if queueing packet */
+#if NETIF_HWADDRHINT
+  i = find_entry(ipaddr, ETHARP_TRY_HARD, netif);
+#else /* NETIF_HWADDRHINT */
   i = find_entry(ipaddr, ETHARP_TRY_HARD);
+#endif /* NETIF_HWADDRHINT */
 
   /* could not find or create entry? */
   if (i < 0) {
