From cf50c7a90832939c5444400982a0aec84e5b0c6c Mon Sep 17 00:00:00 2001
From: Amir Shalem <amir.shalem@gmail.com>
Date: Sat, 29 Oct 2011 12:16:36 +0200
Subject: [PATCH 1/3] make ipv4 ip_route choose the netif by the source
 address also

Signed-off-by: Amir Shalem <amir.shalem@gmail.com>
---
 src/core/ipv4/ip4.c         |   10 ++++++----
 src/core/snmp/msg_out.c     |    2 +-
 src/core/tcp.c              |    4 ++--
 src/include/ipv4/lwip/ip4.h |    2 +-
 src/include/lwip/ip.h       |    4 ++--
 src/include/lwip/tcp_impl.h |    6 +++---
 src/netif/etharp.c          |    2 +-
 7 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c
index 73b17ea..7525c43 100644
--- a/src/core/ipv4/ip4.c
+++ b/src/core/ipv4/ip4.c
@@ -105,11 +105,12 @@ static u16_t ip_id;
  * if the masked IP address of the network interface equals the masked
  * IP address given to the function.
  *
+ * @param src the source IP address for which to find the route (optional)
  * @param dest the destination IP address for which to find the route
  * @return the netif on which to send to reach dest
  */
 struct netif *
-ip_route(ip_addr_t *dest)
+ip_route(ip_addr_t *src, ip_addr_t *dest)
 {
   struct netif *netif;
 
@@ -124,7 +125,8 @@ ip_route(ip_addr_t *dest)
   for (netif = netif_list; netif != NULL; netif = netif->next) {
     /* network mask matches? */
     if (netif_is_up(netif)) {
-      if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
+      if ((ip_addr_isany(src) || ip_addr_cmp(src, &(netif->ip_addr))) &&
+		  ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
         /* return netif on which to forward IP packet */
         return netif;
       }
@@ -206,7 +208,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
   }
 
   /* Find network interface where to forward this IP packet to. */
-  netif = ip_route(ip_current_dest_addr());
+  netif = ip_route(NULL, ip_current_dest_addr());
   if (netif == NULL) {
     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
       ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()),
@@ -803,7 +805,7 @@ ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
      gets altered as the packet is passed down the stack */
   LWIP_ASSERT("p->ref == 1", p->ref == 1);
 
-  if ((netif = ip_route(dest)) == NULL) {
+  if ((netif = ip_route(src, dest)) == NULL) {
     LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
       ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
     IP_STATS_INC(ip.rterr);
diff --git a/src/core/snmp/msg_out.c b/src/core/snmp/msg_out.c
index 4778bee..db67550 100644
--- a/src/core/snmp/msg_out.c
+++ b/src/core/snmp/msg_out.c
@@ -232,7 +232,7 @@ snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap)
       /* network order trap destination */
       ip_addr_copy(trap_msg.dip, td->dip);
       /* lookup current source address for this dst */
-      dst_if = ip_route(&td->dip);
+      dst_if = ip_route(0, &td->dip);
       ip_addr_copy(dst_ip, dst_if->ip_addr);
       /* @todo: what about IPv6? */
       trap_msg.sip_raw[0] = ip4_addr1(&dst_ip);
diff --git a/src/core/tcp.c b/src/core/tcp.c
index 3a03ac1..4ddaa2c 100644
--- a/src/core/tcp.c
+++ b/src/core/tcp.c
@@ -1577,9 +1577,9 @@ tcp_next_iss(void)
  * calculating the minimum of TCP_MSS and that netif's mtu (if set).
  */
 u16_t
-tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest
+tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest, ipX_addr_t *src
 #if LWIP_IPV6
-                     , ipX_addr_t *src, u8_t isipv6
+                     , u8_t isipv6
 #endif /* LWIP_IPV6 */
                      )
 {
diff --git a/src/include/ipv4/lwip/ip4.h b/src/include/ipv4/lwip/ip4.h
index 04b5b8a..594ec6d 100644
--- a/src/include/ipv4/lwip/ip4.h
+++ b/src/include/ipv4/lwip/ip4.h
@@ -112,7 +112,7 @@ PACK_STRUCT_END
 
 
 #define ip_init() /* Compatibility define, no init needed. */
-struct netif *ip_route(ip_addr_t *dest);
+struct netif *ip_route(ip_addr_t *src, ip_addr_t *dest);
 err_t ip_input(struct pbuf *p, struct netif *inp);
 err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
        u8_t ttl, u8_t tos, u8_t proto);
diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h
index 6de95b1..2468e5c 100644
--- a/src/include/lwip/ip.h
+++ b/src/include/lwip/ip.h
@@ -213,7 +213,7 @@ extern struct ip_globals ip_data;
 #define ipX_route(isipv6, src, dest) \
         ((isipv6) ? \
         ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)) : \
-        ip_route(ipX_2_ip(dest)))
+        ip_route(ipX_2_ip(src), ipX_2_ip(dest)))
 #define ipX_netif_get_local_ipX(isipv6, netif, dest) \
         ((isipv6) ? \
         ip6_netif_get_local_ipX(netif, ipX_2_ip6(dest)) : \
@@ -227,7 +227,7 @@ extern struct ip_globals ip_data;
 #define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \
         ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint)
 #define ipX_route(isipv6, src, dest) \
-        ip_route(ipX_2_ip(dest))
+        ip_route(ipX_2_ip(src), ipX_2_ip(dest))
 #define ipX_netif_get_local_ipX(isipv6, netif, dest) \
         ip_netif_get_local_ipX(netif)
 #define ipX_debug_print(is_ipv6, p) ip_debug_print(p)
diff --git a/src/include/lwip/tcp_impl.h b/src/include/lwip/tcp_impl.h
index e9be9d9..83d184e 100644
--- a/src/include/lwip/tcp_impl.h
+++ b/src/include/lwip/tcp_impl.h
@@ -449,15 +449,15 @@ void tcp_keepalive(struct tcp_pcb *pcb);
 void tcp_zero_window_probe(struct tcp_pcb *pcb);
 
 #if TCP_CALCULATE_EFF_SEND_MSS
-u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest
+u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest, ipX_addr_t *src
 #if LWIP_IPV6
-                           , ipX_addr_t *src, u8_t isipv6
+                           , u8_t isipv6
 #endif /* LWIP_IPV6 */
                            );
 #if LWIP_IPV6
 #define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6)
 #else /* LWIP_IPV6 */
-#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest)
+#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src)
 #endif /* LWIP_IPV6 */
 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
 
diff --git a/src/netif/etharp.c b/src/netif/etharp.c
index 8b333dd..1a15fae 100644
--- a/src/netif/etharp.c
+++ b/src/netif/etharp.c
@@ -538,7 +538,7 @@ etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
     ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
     ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
 
-  netif = ip_route(ipaddr);
+  netif = ip_route(NULL, ipaddr);
   if (netif == NULL) {
     return ERR_RTE;
   }
-- 
1.7.6.msysgit.0

