buglwIP - A Lightweight TCP/IP stack - Bugs: bug #31367, Cannot send a UDP datagram to a...

 
 

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

bug #31367: Cannot send a UDP datagram to a different valid subnet

Submitter:  Bill Auerbach <billauerbach>
Submitted:  Mon 18 Oct 2010 07:27:34 PM UTC
   
 
Category:  ARP Severity:  3 - Normal
Item Group:  None Status:  Invalid
Privacy:  Public Assigned to:  goldsimon
Open/Closed:  Closed Planned Release:  None
lwIP version:  CVS Head

Jump to the original submission

Sun 21 Nov 2010 01:28:45 PM UTC, comment #9: 

I'll close this as invalid. Please reopen if you think this is still wrong. In that case, I'd be specifically interested if this works on other OSes/stacks (with 2 non-AutoIP subnets, of course).

Simon Goldschmidt <goldsimon>
Group administrator
Sun 21 Nov 2010 01:27:26 PM UTC, comment #8: 

Pardon me for the confusion, but when trying to find an RFC that tells me how/when to update the ARP information on incoming IP packets, I found none. And this got me to the point again: updating the ARP table from non-ARP packets is not standardized since it is not recommended (unclear when routers are involved, high overhead for every incoming packet). I would even drop the whole code for that, but since we already have it...

As to RFC 1122, it does not forbid adding the source of your broadcast to the ARP cache, but it is quite clear about outbound routing. See chapter 3.3.1.1  Local/Remote Decision:

"(b)  If the IP destination address bits extracted by the
address mask match the IP source address bits extracted
by the same mask, then the destination is on the
corresponding connected network, and the datagram is to
be transmitted directly to the destination host.
(c)  If not, then the destination is accessible only through
a gateway."

To me, it's quite clear that in this case, an ARP entry for the address in question would not help, as the packet would have to be sent to a gateway according to the RFC.

However, in your special case, there's really a bug in lwIP: according to RFC 3927, there's a bug in our AutoIP implementation (I've filed a bug for that: bug #31722). See 2.6.2.  Forwarding Rules:

"If for any reason the host chooses
to send the packet with an IPv4 Link-Local source address (e.g., no
routable address is available on the selected interface), then it
MUST ARP for the destination address and then send its packet, with
an IPv4 Link-Local source address and a routable destination IPv4
address, directly to its destination on the same physical link.  The
host MUST NOT send the packet to any router for forwarding."

While this helps you for mixed communication of AutoIP/non-AutoIP devices, it does not help in the case where an application uses global broadcasts to find devices that are configured with an invalid IP address (like I did). The only solution here that does not violate the routing RFCs is to reply with a global broadcast, too.

Simon Goldschmidt <goldsimon>
Group administrator
Tue 19 Oct 2010 07:03:05 PM UTC, comment #7: 


>As to the ARP entry: I don't remember why, but there's a reason
>that entry isn't made. It's somewhere in the RFCs and I think it
>was to prevent the device having flood its ARP table


I see no reference to this after about an hour searching.  What I did see reference to: We  might have a lot larger risk of spoofed ARP requests and ARP floods causing problems than we do from trying to cache incoming broadcasts.

>If we had 1000 devices on a subnet and added an ARP entry for
>every broadcast, the ARP cache would grow very big very fast.


This also assumes every device broadcasts.  Perhaps the ARP entry can be delayed on a broadcast until it's known if a callback is going to handle it.  If no one handles it, there will be no outgoing data and nothing to cache.  If a callback is used for the broadcast packet, then an ARP entry created at that time would allow the callback to reply and have it get out.

Bill Auerbach <billauerbach>
Tue 19 Oct 2010 12:35:51 PM UTC, comment #6: 

The solution for me is easy - I will just make the if at the start of update_arp_entry be optionally removed.

In my case it might be more of a performance hit to make these tests for every ARP check versus just caching the few broadcasts that do come in.  I'll see how it goes.  Thanks for replying.

Bill Auerbach <billauerbach>
Tue 19 Oct 2010 12:23:24 PM UTC, comment #5: 

Even having ip_current_netif doesn't get me there because udp_sendto_if still won't send out without the ARP entry.

>Replying to UDP packets would be nice


Well, replying to UDP packets for me is a requirement, so I'll find a way.  Anyone who needs to work with an existing discovery protocol and needs to do this will also be stuck.  Besides the fact that it makes sense to be able to do this - why broadcast out a reply to the whole subnet to get to the one node that sent the broadcast looking for that one node?

I also think that a broadcast can make an ARP entry up to the point that doing so has to remove an entry that is current (how current needs to be resolved).  Then broadcast flooding won't replace ARP entries for active non-broadcast ARP entries.  This can also be something users turn on (compile time or runtime).  Most embedded devices are behind a router and not subjected to a lot of broadcasts.

Bill Auerbach <billauerbach>
Tue 19 Oct 2010 07:11:52 AM UTC, comment #4: 


> The simple solution is for the udp receive callback to be passed
> the netif of the incoming packet


We already have that information: ip_current_netif() returns the netif the currently processed IP packet was received on - this works for UDP, TCP and RAW pcbs.

Replying to UDP packets would be nice, but not at the risk of flooding our ARP cache. From testing, I see that windows seems to record the ARP entry on reception: when pinging A -> B, I see an ARP request from A asking for B, but not B asking for A (both hosts did not know each other before).

Even if we did solve this by always keeping the last broadcast ARP in an extra cache, it would stop to work if your application program would respond with a short delay (in which another broadcast could be received).

Simon Goldschmidt <goldsimon>
Group administrator
Mon 18 Oct 2010 09:53:26 PM UTC, comment #3: 

The simple solution is for the udp receive callback to be passed the netif of the incoming packet - or do we lose that information?  Then a udp_sendto_if can be used to reply via unicast addressing.  I guess this may be good for the raw API only.

I have only one netif and can simply use the global instance I have of it and use udp_sendto_if.

The incompatibility with other stacks remains for being able to reply to any UDP packet simply by using the remote IP address and port.

Unless you choose to support this you can close this report.

Bill Auerbach <billauerbach>
Mon 18 Oct 2010 08:54:39 PM UTC, comment #2: 

I use both types broadcasts - this test was global.  Subnet broadcasts do work because I use that with a utility that scans devices per PC NIC.

I don't have a problem adding the received broadcast entry to the ARP table before replying.  This isn't needed in Windows. I found this problem from the beginning and thought it was how it was supposed to be.  I have another embedded device as well as Windows both which do send unicast UDP to a subnet other than the subnet of the device or PC.  As for the embedded device, I have no information about its stack except to know that it replies to my broadcasts with a unicast address.  When I saw it work this way and it works in Windows is what prompted me to post this bug report.  At least it documents information that lwIP isn't completely compatible with IP addressing of other stacks.

As to the ARP table, I can see that this is not easy. Perhaps one broadcast ARP entry be kept - most likely the broadcast will be followed by a reply.  One is better than none and would solve this UDP broadcast-reply-unicast scenario.  Or a udp_sendto_hwa where we pass in the IP address and MAC address of the device.

Until I tried this I've been replying with a global broadcast which is really not very efficient to all the devices that will have to process these messages.

Bill Auerbach <billauerbach>
Mon 18 Oct 2010 08:06:58 PM UTC, comment #1: 

What Kind of broadcast did 192.168.1.100 send, a global broadcast (I.e. 255.255.255.255) or a subnet broadcast (I.e. 192.168.255.255). In the latter case, is it correct that this subnet broadcast is received by the autoip-device?

Next, how should the stack know that 192.168.1.100 is on the same subnet? Since it isn't on the same IP-subnet, it could only say "with autoip, everything is on the same subnet" unless we have another routable address assigned on the netif.

As to the ARP entry: I don't remember why, but there's a reason that entry isn't made. It's somewhere in the RFCs and I think it was to prevent the device having flood its ARP table: we want the ARP table to have a configurable size, but that size should be limited by the connections the device ales, not by the amount of other devices in the same subnet. If we had 1000 devices on a subnet and added an ARP entry for every broadcast, the ARP cache would grow very big very fast.

Simon Goldschmidt <goldsimon>
Group administrator
Mon 18 Oct 2010 07:27:34 PM UTC, original submission:  

Example:

UDP Broadcast from 192.168.1.100.  A device at 169.254.1.100 sees the broadcast and responds with a source of 169.254.1.100 and a destination of 192.168.1.100.  This is acceptable because the destination is on the subnet of the receiver.

The test at the end of etharp_output blocks the send. lwIP returns ERR_RTE.

There's a secondary issue as well - I don't think the broadcast received made an ARP entry.  I say this because etharp_query complains if I let it try to handle the output directly.  The complaint is an ICMP destination unreachable which isn't true.

lwIP appears to be based on RFC 950.  RFC 1122 changes and adds quite a bit to RFC 950 and doesn't add that allowing the above example is an error.

Bill Auerbach <billauerbach>

 

(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 billauerbach (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 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2010-11-21 goldsimon StatusNeed Info Invalid
        Assigned toNone goldsimon
        Open/ClosedOpen Closed
    2010-10-18 goldsimon StatusNone Need Info

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code