[En-Nut-Discussion] Duplicate ARPs (was: Time needed to get packet from RTL on ATmega128)

Harald Kipp harald.kipp at egnite.de
Tue Jan 11 11:50:27 CET 2005


Hi Dusan,

At 12:38 10.01.2005 +0100, you wrote:

>I also do not understand following change (if entry is seeded non zero 1st 
>block serves this, if it is zero then code proceeds at else where I cannot 
>imagine situation under which entry != 0
>  * $Log: arpcache.c,v $
>  * Revision 1.4  2004/07/27 19:38:30  drsung
>  * Under certain circumstances the same ARPENTRY was
>  * allocated twice.
>  *

I do not understand this change either. Looks useless to me
too.




>I noticed 2 ARP requests generated for a UDP output packet. I think that 
>in net/arpcache.c:NutArpCacheQuery() if incomplete ARP entry is found, 
>then 'else if' is skipped and new ARP request is generated for same entry. 
>This can happen e.g. if 2 threads are sending a UDP to a same IP. I think 
>that code can follow in a same way but without NutArpAllocNetBuf(), 
>NutArpOutput() and NutNetBufFree(). Decision can be made in 1st if block:
>
>...
>     u_char      fl_send;
>
>     if ((entry = NutArpCacheLookup(dev->dev_icb, ip)) != 0) {
>         if (entry->ae_flags & ATF_COM) {
>             memcpy(mac, ((ARPENTRY *) entry)->ae_ha, 6);
>             return 0;
>         }
>         else
>             fl_send = FALSE;            //already sent, but still pending
>     }
>     else {
>         if ((entry = NutArpCacheNew(dev->dev_icb, ip, 0, 0)) == 0) {
>             return -1;
>         else
>             fl_send = TRUE;
>     }
>
>I did that but I am still getting 2 ARPs for 1st UDP output packet.

What is the time difference between both sends? Note the 500 ms timeout
at

   while (retries--) {
     ...
     NutEventWait(&((ARPENTRY *) entry)->ae_tq, 500);
   }

which is a very simple (IMHO too simple) implementation.

But that's not all. If two threads enter NutArpCacheQuery(), we still
have a problem. Both threads do not know about each other, but only one
should send out requests. If one gives up, there is actually no reason
for the other one to continue.

My idea is to pass the query task to THREAD(NutArpExpire, arg).
The problem would be to avoid polling the ARP table.
What do you think?

Harald

P.S. I can already hear the crying demands for message queues, which
would simplify communication between NutArpExpire and the
waiting threads. Although there is an implementation available,
which had been contributed by Ralph Mason some time ago, it's
not used by the Nut/OS kernel. And I'd like to keep it this way
unless there are very good arguments and no simpler alternatives.
Over the time too many "features" will easily over-inflate the
kernel. In the future we have to take more care to keep the
kernel as small as possible and, for example, avoid such a mess
of counters like we got in timer.c.






More information about the En-Nut-Discussion mailing list