This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: DHCP over multiple interfaces


Andrew Lunn wrote:
On Wed, Jan 23, 2008 at 04:11:11PM +0000, Dave Lawrence wrote:
I can't seem to get DHCP work over multiple interfaces.

The eCos DHCP client used to work with multiple interfaces. This is why there is the half up states, so that it can force the packet out the correct interface and the clearing of routes when performing DHCP transactions.

If it does not work, i suggest you work your way back and see which
patch broke it.

Andrew


I had a look on an older platform that uses an older ecos tree. It does work but there were some problems:
* Packets could come out on the wrong interface if two threads were simultaneously calling do_dhcp (on different interfaces)
* Our application was also interfering with the routing tables in response to detecting devices going up / down


So I don't have any opinion about whether my fixes are of use to the wider ecos world but I've attached a patch in case. It does the following:

* Provide dhcp_get_lock and dhcp_release_lock as global functions which the application can use to ensure interference is avoided
* Use these functions at the entry and exit points of do_dhcp to prevent it functioning reetrantly (is that a word?)


Unfortunately I'm no closer to fixing the original problem - on my new platform packets for 255.255.255.255 *always* come out on eth1.

Was I correct to continue with this thread or should I have switched to the patches list?
Index: net/common/current/include/dhcp.h
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/common/current/include/dhcp.h,v
retrieving revision 1.2
diff -u -5 -r1.2 dhcp.h
--- net/common/current/include/dhcp.h	16 Oct 2003 08:13:46 -0000	1.2
+++ net/common/current/include/dhcp.h	25 Jan 2008 17:02:34 -0000
@@ -241,9 +241,15 @@
 
 extern int
 do_dhcp_release(const char *intf, struct bootp *res,
         cyg_uint8 *pstate, struct dhcp_lease *lease);
 
+extern void
+    dhcp_get_lock (void);
+
+extern void
+    dhcp_release_lock (void);
+
 #endif // CYGPKG_NET_DHCP
 
 #endif // CYGONCE_NET_TCPIP_DHCP_H
 // EOF dhcp.h
Index: net/common/current/src/dhcp_prot.c
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/common/current/src/dhcp_prot.c,v
retrieving revision 1.20
diff -u -5 -r1.20 dhcp_prot.c
--- net/common/current/src/dhcp_prot.c	5 Mar 2006 12:48:37 -0000	1.20
+++ net/common/current/src/dhcp_prot.c	25 Jan 2008 17:02:35 -0000
@@ -88,10 +88,12 @@
     CYG_ASSERT( (strlen(hostname)<=CYGNUM_NET_DHCP_OPTION_HOST_NAME_LEN), "dhcp hostname too long" );
     strncpy(dhcp_hostname, hostname, CYGNUM_NET_DHCP_OPTION_HOST_NAME_LEN);
 }
 #endif
 
+static cyg_sem_t dhcp_sem;
+
 /* Forward reference prototypes. */
 static int unset_tag( struct bootp *ppkt, unsigned char tag );
 
 // ------------------------------------------------------------------------
 // Returns a pointer to the end of dhcp message (or NULL if invalid)
@@ -691,10 +693,12 @@
     struct bootp *received = &rx_local;
     struct bootp *xmit = res;
     struct bootp xmit2;
     int xlen;
 
+    dhcp_get_lock ();
+
     // First, get a socket on the interface in question.  But Zeroth, if
     // needs be, bring it to the half-up broadcast only state if needs be.
     
     if ( DHCPSTATE_INIT      == oldstate
          || DHCPSTATE_FAILED == oldstate
@@ -1044,10 +1048,11 @@
                     }
                 }
             }
 
             // Otherwise, nothing whatsoever to do...
+            dhcp_release_lock ();
             return true;
 
         case DHCPSTATE_RENEWING:
             // Just send what you got with a DHCPREQUEST in the message
             // type UNICAST straight to the server.  Then wait for an ACK.
@@ -1295,27 +1300,30 @@
                     }
                 }
             }
 
             // Otherwise, nothing whatsoever to do...
+            dhcp_release_lock ();
             return true;
 
         case DHCPSTATE_NOTBOUND:
             // All done with socket
             close(s);
             // No lease active
             no_lease( lease );
             // Leave interface up so app can tidy.
+            dhcp_release_lock ();
             return true;
 
         case DHCPSTATE_FAILED:
             // All done with socket
             close(s);
             // No lease active
             no_lease( lease );
             // Unconditionally down the interface.
             do_dhcp_down_net( intf, res, &oldstate, lease );
+            dhcp_release_lock ();
             return false;
 
         case DHCPSTATE_DO_RELEASE:
             // We have been forced here by external means, to release the
             // lease for graceful shutdown.
@@ -1362,17 +1370,19 @@
             break;
 
         default:
             no_lease( lease );
             close(s);
+            dhcp_release_lock ();
             return false;
         }
     }
 out:
     if (s != -1) 
       close (s);
     
+    dhcp_release_lock ();
     return false;
 }
 
 // ------------------------------------------------------------------------
 // Bring an interface down, failed to initialize it or lease is expired
@@ -1484,10 +1494,33 @@
         cyg_thread_delay( 100 );             // to let it leave the building
     }
     return true;
 }
 
+void dhcp_get_lock (void)
+{
+    static int dhcp_sem_initialised;
+
+    cyg_scheduler_lock ();
+
+    if (!dhcp_sem_initialised)
+    {
+        cyg_semaphore_init (&dhcp_sem, 1);
+        dhcp_sem_initialised = true;
+    }
+
+   cyg_scheduler_unlock ();
+
+   cyg_semaphore_wait (&dhcp_sem);
+}
+
+void dhcp_release_lock (void)
+{
+   cyg_semaphore_post (&dhcp_sem);
+}
+
+
 // ------------------------------------------------------------------------
 
 #endif // CYGPKG_NET_DHCP
 
 // EOF dhcp_prot.c

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]