From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12135 invoked by alias); 4 Aug 2003 09:56:40 -0000 Mailing-List: contact ecos-maintainers-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: ecos-maintainers-owner@sources.redhat.com Received: (qmail 12127 invoked from network); 4 Aug 2003 09:56:38 -0000 Date: Mon, 04 Aug 2003 09:56:00 -0000 From: Andrew Lunn To: eCos Maintainers Subject: FWD: Proposal: Keep codes compact with multiple interfaces Message-ID: <20030804095633.GD1771@biferten.ma.tech.ascom.ch> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-Filter-Version: 1.11a (ascomax) X-SW-Source: 2003-08/txt/msg00006.txt.bz2 Hi Maintainers. What's your opinion on this? I've played with the patch a little and it builds OK with a few different configurations and seems to work OK. One side of the argument is "If its not broken don't fix it". For one ethernet device it probably takes a little bit more memory. The other side of the argument is, its more readable so more maintainable. For multiple devices it probably takes a little less memory. Andrew P.S. The patch has been mangled by a mail system somewhere. I have another version at home which does apply cleanly. Shout if you want it. ----- Forwarded message from Motoya Kurotsu ----- Date: Tue, 29 Jul 2003 18:37:25 +0900 From: Motoya Kurotsu To: ecos-patches@sources.redhat.com Subject: Proposal: Keep codes compact with multiple interfaces Hi, all; The attachment is the proposal how to keep codes compact when two or more than two interfaces are implemented. Extenal variables such as ethX_name, ethX_up, ethX_bootp_data, ethX_dhcpstate and ethX_lease are left external due to backward compatibility. Motoya Kurotsu Allied Telesis K.K. diff -Nur common.orig/current/ChangeLog common/current/ChangeLog --- common.orig/current/ChangeLog Fri Jul 25 03:07:45 2003 +++ common/current/ChangeLog Tue Jul 29 18:28:25 2003 @@ -1,3 +1,17 @@ +2003-07-29 Motoya Kurotsu + + * cdl/net.cdl: CYGHWR_NET_DRIVER_ETHX_ADDRS is defined and + the default is set zero. + * include/network.h: + * src/dhcp_support.c: + * src/network_support.c: + To keep codes compact even if two or more than two interfaces are + implemented, made a new structure 'net_eth' which stores the pointers + to the external variables such as ethX_name, ethX_up, ethX_bootp_data, + ethX_dhcpstate and ethX_lease. When all interfaces needs to be + checked, trace on the array 'net_eth[]' rather than write similar codes + repeatedly. + 2003-07-24 Nick Garnett * src/dhcp_prot.c: Added a declaration for cyg_arc4random() to diff -Nur common.orig/current/cdl/net.cdl common/current/cdl/net.cdl --- common.orig/current/cdl/net.cdl Wed Apr 23 17:52:08 2003 +++ common/current/cdl/net.cdl Tue Jul 29 18:18:27 2003 @@ -498,7 +498,7 @@ cdl_component CYGHWR_NET_DRIVER_ETH0_ADDRS { display "Address setups for 'eth0'" implements CYGHWR_NET_DRIVER_ETH0_SETUP - no_define + default_value 0 description " These options let you configure all the initialization data @@ -625,7 +625,7 @@ cdl_component CYGHWR_NET_DRIVER_ETH1_ADDRS { display "Address setups for 'eth1'" implements CYGHWR_NET_DRIVER_ETH1_SETUP - no_define + default_value 0 description " These options let you configure all the initialization data diff -Nur common.orig/current/include/network.h common/current/include/network.h --- common.orig/current/include/network.h Wed Apr 23 17:52:08 2003 +++ common/current/include/network.h Tue Jul 29 18:18:27 2003 @@ -55,16 +55,33 @@ #include #include -#ifdef CYGHWR_NET_DRIVER_ETH0 -extern struct bootp eth0_bootp_data; -extern cyg_bool_t eth0_up; -extern const char *eth0_name; -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 -extern struct bootp eth1_bootp_data; -extern cyg_bool_t eth1_up; -extern const char *eth1_name; -#endif +struct eth_ip_addrs { + const char *ip; + const char *netmask; + const char *broadcast; + const char *gateway; + const char *server; + const char *ipv6_prefix; +}; +struct eth_setup { + cyg_bool_t bootp; + cyg_bool_t dhcp; + cyg_bool_t bootpshow; + cyg_bool_t addrs_ip; + cyg_bool_t manual; + cyg_bool_t ipv6; +}; +struct net_eth { + struct eth_setup *setup; + struct bootp *bootp_data; + cyg_bool_t *up; + const char **name; + cyg_uint8 *dhcpstate; + struct dhcp_lease *lease; + struct eth_ip_addrs *ip_addrs; +}; + +extern struct net_eth net_eth[]; __externC void init_all_network_interfaces(void); diff -Nur common.orig/current/src/dhcp_support.c common/current/src/dhcp_support.c --- common.orig/current/src/dhcp_support.c Sun Jan 12 13:53:28 2003 +++ common/current/src/dhcp_support.c Tue Jul 29 18:18:27 2003 @@ -91,68 +91,58 @@ // or whatever... int dhcp_bind( void ) { + cyg_uint8 old_eth_dhcpstate[] = { #ifdef CYGHWR_NET_DRIVER_ETH0 - cyg_uint8 old_eth0_dhcpstate = eth0_dhcpstate; + eth0_dhcpstate, #endif #ifdef CYGHWR_NET_DRIVER_ETH1 - cyg_uint8 old_eth1_dhcpstate = eth1_dhcpstate; + eth1_dhcpstate, #endif + }; + cyg_uint8 eth_dhcpstate = 0; + struct net_eth *e; // If there are no interfaces at all, init it every time, doesn't // matter. In case we are called from elsewhere... - if ( 1 -#ifdef CYGHWR_NET_DRIVER_ETH0 - && eth0_dhcpstate == 0 -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 - && eth1_dhcpstate == 0 -#endif - ) + e = &net_eth[0]; + while(e->setup) { + eth_dhcpstate |= *e->dhcpstate; + e++; + } + if ( !eth_dhcpstate ) cyg_semaphore_init( &dhcp_needs_attention, 0 ); // Run the state machine... -#ifdef CYGHWR_NET_DRIVER_ETH0 - if (eth0_up - && DHCPSTATE_FAILED != eth0_dhcpstate ) - eth0_up = do_dhcp(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease); -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 - if (eth1_up - && DHCPSTATE_FAILED != eth1_dhcpstate ) - eth1_up = do_dhcp(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease); -#endif + e = &net_eth[0]; + while(e->setup) { + if (*e->up && DHCPSTATE_FAILED != *e->dhcpstate ) + *e->up = do_dhcp(*e->name, e->bootp_data, e->dhcpstate, e->lease); + e++; + } // If the interface newly came up, initialize it: // (this duplicates the code in init_all_network_interfaces() really). -#ifdef CYGHWR_NET_DRIVER_ETH0 - if ( eth0_up - && eth0_dhcpstate == DHCPSTATE_BOUND - && old_eth0_dhcpstate != eth0_dhcpstate ) { - if (!init_net(eth0_name, ð0_bootp_data)) { - eth0_up = false; - } - } -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 - if ( eth1_up - && eth1_dhcpstate == DHCPSTATE_BOUND - && old_eth1_dhcpstate != eth1_dhcpstate ) { - if (!init_net(eth1_name, ð1_bootp_data)) { - eth1_up = false; - } + e = &net_eth[0]; + while(e->setup) { + int i = e - &net_eth[0]; + if (*e->up + && *e->dhcpstate == DHCPSTATE_BOUND + && old_eth_dhcpstate[i] != *e->dhcpstate ) { + if (!init_net(*e->name, e->bootp_data)) { + *e->up = false; + } + } + e++; } -#endif -#ifdef CYGHWR_NET_DRIVER_ETH0 - if ( old_eth0_dhcpstate == DHCPSTATE_BOUND && - eth0_dhcpstate == DHCPSTATE_NOTBOUND ) - return 0; // a lease timed out; we became unbound -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 - if ( old_eth1_dhcpstate == DHCPSTATE_BOUND && - eth1_dhcpstate == DHCPSTATE_NOTBOUND ) - return 0; // a lease timed out; we became unbound -#endif + e = &net_eth[0]; + while(e->setup) { + int i = e - &net_eth[0]; + if ( old_eth_dhcpstate[i] == DHCPSTATE_BOUND && + *e->dhcpstate == DHCPSTATE_NOTBOUND ) + return 0; // a lease timed out; we became unbound + e++; + } return 1; // all is well } @@ -160,20 +150,16 @@ // Shutdown any interface whose state is DHCPSTATE_NOTBOUND. int dhcp_halt( void ) { -#ifdef CYGHWR_NET_DRIVER_ETH0 - if ( eth0_up - && eth0_dhcpstate != DHCPSTATE_FAILED ) { - do_dhcp_down_net(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease); - } - eth0_up = false; -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 - if ( eth1_up - && eth1_dhcpstate != DHCPSTATE_FAILED ) { - do_dhcp_down_net(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease); + struct net_eth *e; + + e = &net_eth[0]; + while(e->setup) { + if ( *e->up && *e->dhcpstate != DHCPSTATE_FAILED ) { + do_dhcp_down_net(*e->name, e->bootp_data, e->dhcpstate, e->lease); + } + *e->up = false; + e++; } - eth1_up = false; -#endif return 1; } @@ -182,14 +168,14 @@ // closing down. (unlikely but maybe useful for testing) int dhcp_release( void ) { -#ifdef CYGHWR_NET_DRIVER_ETH0 - if (eth0_up) - do_dhcp_release(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease); -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 - if (eth1_up) - do_dhcp_release(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease); -#endif + struct net_eth *e; + + e = &net_eth[0]; + while(e->setup) { + if (*e->up) + do_dhcp_release(*e->name, e->bootp_data, e->dhcpstate, e->lease); + e++; + } return 1; } diff -Nur common.orig/current/src/network_support.c common/current/src/network_support.c --- common.orig/current/src/network_support.c Mon May 26 16:33:06 2003 +++ common/current/src/network_support.c Tue Jul 29 18:19:25 2003 @@ -93,12 +93,120 @@ struct bootp eth0_bootp_data; cyg_bool_t eth0_up = false; const char *eth0_name = "eth0"; +static struct eth_ip_addrs eth0_ip_addrs = { +#ifdef CYGHWR_NET_DRIVER_ETH0_ADDRS + string(CYGHWR_NET_DRIVER_ETH0_ADDRS_IP), + string(CYGHWR_NET_DRIVER_ETH0_ADDRS_NETMASK), + string(CYGHWR_NET_DRIVER_ETH0_ADDRS_BROADCAST), + string(CYGHWR_NET_DRIVER_ETH0_ADDRS_GATEWAY), + string(CYGHWR_NET_DRIVER_ETH0_ADDRS_SERVER)), +#else + 0,0,0,0,0, +#endif +# ifdef CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX + string(CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX), +# else + 0, +# endif +}; +static struct eth_setup eth0_setup = { +#ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP + true, +#else + false, #endif +#ifdef CYGHWR_NET_DRIVER_ETH0_DHCP + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP_SHOW + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH0_ADDRS + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH0_MANUAL + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX + true, +#else + false, +#endif +}; +#endif // CYGHWR_NET_DRIVER_ETH0 #ifdef CYGHWR_NET_DRIVER_ETH1 struct bootp eth1_bootp_data; cyg_bool_t eth1_up = false; const char *eth1_name = "eth1"; +static struct eth_ip_addrs eth1_ip_addrs = { +#ifdef CYGHWR_NET_DRIVER_ETH1_ADDRS + string(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP), + string(CYGHWR_NET_DRIVER_ETH1_ADDRS_NETMASK), + string(CYGHWR_NET_DRIVER_ETH1_ADDRS_BROADCAST), + string(CYGHWR_NET_DRIVER_ETH1_ADDRS_GATEWAY), + string(CYGHWR_NET_DRIVER_ETH1_ADDRS_SERVER)), +#else + 0,0,0,0,0, +#endif +# ifdef CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX + string(CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX), +# else + 0, +# endif +}; +static struct eth_setup eth1_setup = { +#ifdef CYGHWR_NET_DRIVER_ETH1_BOOTP + true, +#else + false, #endif +#ifdef CYGHWR_NET_DRIVER_ETH1_DHCP + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH1_BOOTP_SHOW + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH1_ADDRS + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH1_MANUAL + true, +#else + false, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX + true, +#else + false, +#endif +}; +#endif // CYGHWR_NET_DRIVER_ETH1 + +struct net_eth net_eth[] = { +#ifdef CYGHWR_NET_DRIVER_ETH0 + { ð0_setup, ð0_bootp_data, ð0_up, ð0_name, ð0_dhcpstate, + ð0_lease, ð0_ip_addrs }, +#endif +#ifdef CYGHWR_NET_DRIVER_ETH1 + { ð1_setup, ð1_bootp_data, ð1_up, ð1_name, ð1_dhcpstate, + ð1_lease, ð1_ip_addrs }, +#endif + { (struct eth_setup *)0 } // stop +}; #define _string(s) #s #define string(s) _string(s) @@ -290,6 +398,7 @@ #ifdef CYGOPT_NET_IPV6_ROUTING_THREAD int rs_wait = 40; #endif + struct net_eth *e; cyg_scheduler_lock(); while ( in_init_all_network_interfaces ) { @@ -301,148 +410,91 @@ in_init_all_network_interfaces = 1; cyg_scheduler_unlock(); -#ifdef CYGHWR_NET_DRIVER_ETH0 - if ( ! eth0_up ) { // Make this call idempotent + e = &net_eth[0]; + while(e->setup) { + if ( ! *e->up ) { // Make this call idempotent #ifdef CYGPKG_IO_PCMCIA - if ((t = eth_drv_netdev("eth0")) != (cyg_netdevtab_entry_t *)NULL) { - int tries = 0; - while (t->status != CYG_NETDEVTAB_STATUS_AVAIL) { - if (tries == 0) { - diag_printf("... Waiting for PCMCIA device 'eth0'\n"); - } - if (++tries == 5) { - diag_printf("... Giving up on PCMCIA device 'eth0'\n"); - goto bail_eth0; - } - cyg_thread_delay(100); - } - } + if((t = eth_drv_netdev(*e->name)) != (cyg_netdevtab_entry_t *)NULL) { + int tries = 0; + while (t->status != CYG_NETDEVTAB_STATUS_AVAIL) { + if (tries == 0) { + diag_printf("... Waiting for PCMCIA device '%s'\n", + *e->name); + } + if (++tries == 5) { + diag_printf("... Giving up on PCMCIA device '%s'\n", + *e->name); + goto bail; + } + cyg_thread_delay(100); + } + } #endif // CYGPKG_IO_PCMCIA -#ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP - // Perform a complete initialization, using BOOTP/DHCP - eth0_up = true; -#ifdef CYGHWR_NET_DRIVER_ETH0_DHCP - eth0_dhcpstate = 0; // Says that initialization is external to dhcp - if (do_dhcp(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease)) -#else -#ifdef CYGPKG_NET_DHCP - eth0_dhcpstate = DHCPSTATE_BOOTP_FALLBACK; - // so the dhcp machine does no harm if called -#endif - if (do_bootp(eth0_name, ð0_bootp_data)) -#endif - { -#ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP_SHOW - show_bootp(eth0_name, ð0_bootp_data); -#endif - } else { - diag_printf("BOOTP/DHCP failed on eth0\n"); - eth0_up = false; - } -#elif defined(CYGHWR_NET_DRIVER_ETH0_ADDRS_IP) - eth0_up = true; - build_bootp_record(ð0_bootp_data, - eth0_name, - string(CYGHWR_NET_DRIVER_ETH0_ADDRS_IP), - string(CYGHWR_NET_DRIVER_ETH0_ADDRS_NETMASK), - string(CYGHWR_NET_DRIVER_ETH0_ADDRS_BROADCAST), - string(CYGHWR_NET_DRIVER_ETH0_ADDRS_GATEWAY), - string(CYGHWR_NET_DRIVER_ETH0_ADDRS_SERVER)); - show_bootp(eth0_name, ð0_bootp_data); -#endif -#ifdef CYGPKG_IO_PCMCIA - bail_eth0: -#endif - } -#endif // CYGHWR_NET_DRIVER_ETH0 -#ifdef CYGHWR_NET_DRIVER_ETH1 - if ( ! eth1_up ) { // Make this call idempotent -#ifdef CYGPKG_IO_PCMCIA - if ((t = eth_drv_netdev("eth1")) != (cyg_netdevtab_entry_t *)NULL) { - int tries = 0; - while (t->status != CYG_NETDEVTAB_STATUS_AVAIL) { - if (tries == 0) { - diag_printf("... Waiting for PCMCIA device 'eth1'\n"); - } - if (++tries == 5) { - diag_printf("... Giving up on PCMCIA device 'eth1'\n"); - goto bail_eth1; - } - cyg_thread_delay(100); - } - } -#endif // CYGPKG_IO_PCMCIA -#ifdef CYGHWR_NET_DRIVER_ETH1_BOOTP - // Perform a complete initialization, using BOOTP/DHCP - eth1_up = true; -#ifdef CYGHWR_NET_DRIVER_ETH1_DHCP - eth1_dhcpstate = 0; // Says that initialization is external to dhcp - if (do_dhcp(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease)) -#else + // Perform a complete initialization, using BOOTP/DHCP + if(e->setup->bootp) { + *e->up = true; + if(e->setup->dhcp) { + // Says that initialization is external to dhcp + *e->dhcpstate = 0; + if(do_dhcp(*e->name, e->bootp_data, e->dhcpstate, e->lease)){ + if(e->setup->bootpshow) + show_bootp(*e->name, e->bootp_data); + } else { + diag_printf("BOOTP/DHCP failed on %s\n", *e->name); + *e->up = false; + } + } + else { #ifdef CYGPKG_NET_DHCP - eth1_dhcpstate = DHCPSTATE_BOOTP_FALLBACK; - // so the dhcp machine does no harm if called -#endif - if (do_bootp(eth1_name, ð1_bootp_data)) -#endif - { -#ifdef CYGHWR_NET_DRIVER_ETH1_BOOTP_SHOW - show_bootp(eth1_name, ð1_bootp_data); -#endif - } else { - diag_printf("BOOTP/DHCP failed on eth1\n"); - eth1_up = false; - } -#elif defined(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP) - eth1_up = true; - build_bootp_record(ð1_bootp_data, - eth1_name, - string(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP), - string(CYGHWR_NET_DRIVER_ETH1_ADDRS_NETMASK), - string(CYGHWR_NET_DRIVER_ETH1_ADDRS_BROADCAST), - string(CYGHWR_NET_DRIVER_ETH1_ADDRS_GATEWAY), - string(CYGHWR_NET_DRIVER_ETH1_ADDRS_SERVER)); - show_bootp(eth1_name, ð1_bootp_data); + *e->dhcpstate = DHCPSTATE_BOOTP_FALLBACK; + // so the dhcp machine does no harm if called #endif + if (do_bootp(*e->name, e->bootp_data)) { + if(e->setup->bootpshow) + show_bootp(*e->name, e->bootp_data); + } else { + diag_printf("BOOTP/DHCP failed on %s\n", *e->name); + *e->up = false; + } + } + } + else if(e->setup->addrs_ip) { + *e->up = true; + build_bootp_record(e->bootp_data, + *e->name, + e->ip_addrs->ip, + e->ip_addrs->netmask, + e->ip_addrs->broadcast, + e->ip_addrs->gateway, + e->ip_addrs->server); + show_bootp(*e->name, e->bootp_data); + } #ifdef CYGPKG_IO_PCMCIA - bail_eth1: -#endif - } -#endif // CYGHWR_NET_DRIVER_ETH1 -#ifdef CYGHWR_NET_DRIVER_ETH0 -#ifndef CYGHWR_NET_DRIVER_ETH0_MANUAL - if (eth0_up) { - if (!init_net(eth0_name, ð0_bootp_data)) { - diag_printf("Network initialization failed for eth0\n"); - eth0_up = false; - } -#ifdef CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX - if (!init_net_IPv6(eth0_name, ð0_bootp_data, - string(CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX))) { - diag_printf("Static IPv6 network initialization failed for eth0\n"); - eth0_up = false; // ??? - } + bail: #endif + } + e++; } + + e = &net_eth[0]; + while(e->setup) { + if ( !e->setup->manual && *e->up ) { + if (!init_net(*e->name, e->bootp_data)) { + diag_printf("Network initialization failed for %s\n", *e->name); + *e->up = false; + } +#ifdef INET6 + if(e->setup->ipv6) { + if (!init_net_IPv6(*e->name, e->bootp_data, + e->ip_addrs->ipv6_prefix)) { + diag_printf("Static IPv6 network initialization failed for %s\n", *e->name); + *e->up = false; // ??? + } + } #endif -#endif -#ifdef CYGHWR_NET_DRIVER_ETH1 -#ifndef CYGHWR_NET_DRIVER_ETH1_MANUAL - if (eth1_up) { - if (!init_net(eth1_name, ð1_bootp_data)) { - diag_printf("Network initialization failed for eth1\n"); - eth1_up = false; - } -#ifdef CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX - if (!init_net_IPv6(eth1_name, ð1_bootp_data, - string(CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX))) { - diag_printf("Static IPv6 network initialization failed for eth1\n"); - eth1_up = false; // ??? - } -#endif + } + e++; } -#endif -#endif #ifdef CYGPKG_NET_NLOOP #if 0 < CYGPKG_NET_NLOOP ----- End forwarded message -----