buglwIP - A Lightweight TCP/IP stack - Bugs: bug #36403, ip4_input() and ip6_input() always...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #36403: ip4_input() and ip6_input() always pass inp to higher layers

Submitter:  Ivan Delamer <idelamer>
Submitted:  Sat 05 May 2012 12:33:41 AM UTC
   
 
Category:  IPv4 Severity:  2 - Minor
Item Group:  Change Request Status:  Fixed
Privacy:  Public Assigned to:  goldsimon
Open/Closed:  Closed Planned Release:  None
lwIP version:  CVS Head

Jump to the original submission

Tue 17 Feb 2015 09:33:22 PM UTC, comment #6: 

This is what I did with ip_route():

diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c
index a2551d6..8223721 100644
--- a/src/core/ipv4/ip4.c
+++ b/src/core/ipv4/ip4.c
@@ -108,7 +108,7 @@
  * @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;
 
@@ -133,6 +133,19 @@
         return netif;
       }
     }
+  }
+  if (!ip_addr_isany(src)) {
+      for (netif = netif_list; netif != NULL; netif = netif->next) {
+        /* network mask matches? */
+        if (netif_is_up(netif)) {
+          if (ip_addr_cmp(src, &(netif->ip_addr))) {
+            if (!ip_addr_isany(&(netif->gw))) {
+                /* return netif on which to forward IP packet */
+                return netif;
+            }
+          }
+        }
+      }
   }
   if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
     LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
@@ -868,7 +881,7 @@
 
   LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
 
-  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/include/lwip/ip.h b/src/include/lwip/ip.h
index 350d51b..296de24 100644
--- a/src/include/lwip/ip.h
+++ b/src/include/lwip/ip.h
@@ -230,7 +230,7 @@
 #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)) : \
@@ -246,7 +246,7 @@
 #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(&ip_addr_any, 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/ip4.h b/src/include/lwip/ip4.h
index c49a771..d3dedc7 100644
--- a/src/include/lwip/ip4.h
+++ b/src/include/lwip/ip4.h
@@ -112,7 +112,7 @@
 
 
 #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);

Ivan Delamer <idelamer>
Group Member
Sun 15 Feb 2015 10:03:03 PM UTC, comment #5: 

It does and that's what I end up doing with my own modification.

So I guess the real question is: should we add the source address to the ip_route() algorithm? It is already part of the ip6_route() algorithm as per RFC.

Ivan Delamer <idelamer>
Group Member
Fri 13 Feb 2015 07:43:07 PM UTC, comment #4: 

Well, my point was there is no input netif in ip_route(): the input netif is only available during the recv callback. Given that, passing up inp leads to different results when sending to inp from the recv callback than sending the same packet via routing (as routing should select the 'accept' netif).

Given that, your routing problems should not depend on the change I made yesterday, do they?

What's your IP setup in this situation anyway? Would it make sense to use source-address-based-routing in this case?

Simon Goldschmidt <goldsimon>
Group administrator
Fri 13 Feb 2015 05:11:51 PM UTC, comment #3: 

Maybe we need to consider a change to ip_route() and ip6_route() so that we try responding on the input netif if possible.

I have cases with two netifs, e.g. WLAN and GPRS modem. I have requests coming in GPRS and sometimes reponses are sent back on WLAN because it is listed first.

I'll have to make a note to look into it a bit more.

Ivan Delamer <idelamer>
Group Member
Thu 12 Feb 2015 09:10:01 PM UTC, comment #2: 

Doesn't IPv6 pass up the accepting netif already?

Anyway, I've changed the code to pass up the accepting netif (as that seems more correct) while keeping the input netif available via 'ip_current_input_netif()' if someone really needs it.

Simon Goldschmidt <goldsimon>
Group administrator
Mon 13 Aug 2012 08:04:11 PM UTC, comment #1: 


> Intuitively I think we should be passing the accepted netif


For "simple" applications, I think so, too.

> but keeping a reference to inp means we can send response packets on the same netif that we received data


I think you can argue about that: from testing at work, I know that at least Windows XP sends out packets to the normal route, no matter where a packet has been received (yes, also ICMP responses).

So while the logical thing to do would be to respond on 'inp', I think that responding on the accepting netif would be just as good: if the caller delays its response, the accepting netif would be used anyway!

Simon Goldschmidt <goldsimon>
Group administrator
Sat 05 May 2012 12:33:41 AM UTC, original submission:  

Thanks to Enrico Lehmann for bringing this up.

Both ip4_input() and ip6_input() will go through all enabled netifs looking for an address match. We may accept a packet on a different netif than the one it was accepted on. This provides simple routing behavior.

When a packet is passed to the next layer, inp (receiving netif) is always passed.

Should we be passing inp, or netif (accepted) ?

Not sure if this is a bug or what consequences it has. Intuitively I think we should be passing the accepted netif, but keeping a reference to inp means we can send response packets on the same netif that we received data...

Comments?

Ivan Delamer <idelamer>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by idelamer (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-02-12 goldsimon CategoryNone IPv4
        Item GroupNone Change Request
        StatusNeed Info Fixed
        Assigned toNone goldsimon
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code