--- ./stack/ipv4/route.c.orig	2006-05-26 12:04:10.000000000 +0200
+++ ./stack/ipv4/route.c	2006-05-29 09:44:00.000000000 +0200
@@ -359,6 +359,8 @@
     struct host_route   *new_route;
     struct host_route   *rt;
     unsigned int        key;
+    u32                 saddr;
+    
 
 
     rtdm_lock_get_irqsave(&rtdev->rtdev_lock, context);
@@ -371,8 +373,10 @@
 
     rtdm_lock_put_irqrestore(&rtdev->rtdev_lock, context);
 
+    saddr = rtdev->local_ip;
     if ((new_route = rt_alloc_host_route()) != NULL) {
         new_route->dest_host.ip    = addr;
+        new_route->dest_host.saddr = saddr;
         new_route->dest_host.rtdev = rtdev;
         memcpy(new_route->dest_host.dev_addr, dev_addr, rtdev->addr_len);
     }
@@ -383,8 +387,9 @@
 
     rt = host_hash_tbl[key];
     while (rt != NULL) {
-        if (rt->dest_host.ip == addr) {
+        if ((rt->dest_host.ip == addr) && (rt->dest_host.saddr == saddr))  {
             rt->dest_host.rtdev = rtdev;
+            rt->dest_host.saddr = saddr;
             memcpy(rt->dest_host.dev_addr, dev_addr, rtdev->addr_len);
 
             if (new_route)
@@ -420,22 +425,24 @@
 /***
  *  rt_ip_route_del_host - deletes specified host route
  */
-int rt_ip_route_del_host(u32 addr)
+int rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev)
 {
     rtdm_lockctx_t      context;
     struct host_route   *rt;
     struct host_route   **last_ptr;
     unsigned int        key;
-
+    u32                 saddr;
 
     key = ntohl(addr) & HOST_HASH_KEY_MASK;
     last_ptr = &host_hash_tbl[key];
 
     rtdm_lock_get_irqsave(&host_table_lock, context);
-
+    
+    saddr = rtdev->local_ip;
+    
     rt = host_hash_tbl[key];
     while (rt != NULL) {
-        if (rt->dest_host.ip == addr) {
+        if ((rt->dest_host.ip == addr) && (rt->dest_host.saddr == saddr)) {  
             *last_ptr = rt->next;
 
             rt_free_host_route(rt);
@@ -494,7 +501,7 @@
     }
 
     if ((ip = rtdev->local_ip) != 0)
-        rt_ip_route_del_host(ip);
+        rt_ip_route_del_host(ip, rtdev);
 }
 
 
@@ -652,7 +659,7 @@
  *
  *  Note: increments refcount on returned rtdev in rt_buf
  */
-int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr)
+int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr)
 {
     rtdm_lockctx_t      context;
     struct host_route   *host_rt;
@@ -670,13 +677,18 @@
 
   restart:
 #endif /* !CONFIG_RTNET_RTIPV4_NETROUTING */
+
     key = ntohl(daddr) & HOST_HASH_KEY_MASK;
 
     rtdm_lock_get_irqsave(&host_table_lock, context);
 
     host_rt = host_hash_tbl[key];
     while (host_rt != NULL) {
-        if (host_rt->dest_host.ip == daddr) {
+        if ((host_rt->dest_host.ip == daddr) 
+#ifdef RTNET_ROUTE_CHECK_SOURCE_IP
+            && ((saddr == INADDR_ANY) ||  (host_rt->dest_host.saddr == saddr))
+#endif            
+           ) {
             memcpy(rt_buf->dev_addr, &host_rt->dest_host.dev_addr,
                    sizeof(rt_buf->dev_addr));
             rt_buf->rtdev = host_rt->dest_host.rtdev;
--- ./stack/ipv4/udp.c.orig	2006-05-29 09:15:15.000000000 +0200
+++ ./stack/ipv4/udp.c	2006-05-29 09:11:16.000000000 +0200
@@ -566,7 +566,7 @@
         return -EINVAL;
 
     /* get output route */
-    err = rt_ip_route_output(&rt, daddr);
+    err = rt_ip_route_output(&rt, daddr, saddr);
     if (err)
         return err;
 
--- ./stack/ipv4/icmp.c.orig	2006-05-29 09:26:19.000000000 +0200
+++ ./stack/ipv4/icmp.c	2006-05-29 09:35:57.000000000 +0200
@@ -307,7 +307,7 @@
     icmp_param->head.icmph.checksum = 0;
     icmp_param->csum = 0;
 
-    if ((err = rt_ip_route_output(&rt, daddr)) < 0)
+    if ((err = rt_ip_route_output(&rt, daddr, INADDR_ANY)) < 0)
         return err;
 
     /* TODO: add support for fragmented ICMP packets */
--- ./stack/include/ipv4/route.h.orig	2006-05-29 08:32:47.000000000 +0200
+++ ./stack/include/ipv4/route.h	2006-05-29 09:37:02.000000000 +0200
@@ -30,9 +30,12 @@
 
 #include <rtdev.h>
 
+/* Enable this to extend the routing to check also the source IP address */
+#define RTNET_ROUTE_CHECK_SOURCE_IP 1
 
 struct dest_route {
     u32                 ip;
+    u32                 saddr;
     unsigned char       dev_addr[MAX_ADDR_LEN];
     struct rtnet_device *rtdev;
 };
@@ -40,7 +43,7 @@
 
 int rt_ip_route_add_host(u32 addr, unsigned char *dev_addr,
                          struct rtnet_device *rtdev);
-int rt_ip_route_del_host(u32 addr);
+int rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev);
 void rt_ip_route_del_all(struct rtnet_device *rtdev);
 
 #ifdef CONFIG_RTNET_RTIPV4_NETROUTING
@@ -52,7 +55,7 @@
 extern int rt_ip_route_forward(struct rtskb *rtskb, u32 daddr);
 #endif /* CONFIG_RTNET_RTIPV4_ROUTER */
 
-extern int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr);
+extern int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr);
 
 extern int __init rt_ip_routing_init(void);
 extern void rt_ip_routing_release(void);
