# HG changeset patch # User asl # Date 1050402681 0 # Node ID cf8d8ca2ed1dcc1e8a273f190908815978509d17 # Parent b4d06891fe1aad36500be2d02884e997e938729a * host/rawether.c (tap_init): Set the persistent flag on the tap device if requested by the user. This allows dhcpd and radvd to keep running on the tap device between invocations of the synth target. * doc/syntheth.sgml: Documentation for the persistent option. diff --git a/packages/devs/eth/synth/ecosynth/current/ChangeLog b/packages/devs/eth/synth/ecosynth/current/ChangeLog --- a/packages/devs/eth/synth/ecosynth/current/ChangeLog +++ b/packages/devs/eth/synth/ecosynth/current/ChangeLog @@ -1,3 +1,11 @@ +2003-04-08 Andrew Lunn + + * host/rawether.c (tap_init): Set the persistent flag on the tap + device if requested by the user. This allows dhcpd and radvd to + keep running on the tap device between invocations of the synth + target. + * doc/syntheth.sgml: Documentation for the persistent option. + 2003-04-01 Andrew Lunn * src/syntheth.c (synth_eth_init): Set the flag IFF_ALLMULTI when diff --git a/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml b/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml --- a/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml +++ b/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml @@ -339,6 +339,30 @@ address information. Instead the eCos co or static addresses. +When rawether exits, the tap interface is removed +by the kernel. By adding the parameter persistent +rawether will set the persistent flag on the tap +device. + + +synth_device ethernet { + eth0 ethertap tap3 00:01:02:03:FE:05 + eth1 ethertap tap4 00:01:02:03:FE:06 persistent + … +} + + +With this flag set the kernel will not remove the interface when +rawether exits. This means applications such as +dhcpd, radvd, and +tcpdump will continue to run on the interface +between invocations of synthetic targets. As a result the target can +dynamically obtain its IP addresses from these daemons. Note it is a +good idea to specify a MAC address otherwise a different random MAC +address will be used each time and the dhcpd daemon will not be able +to reissue the same IP address. + + An alternative approach would be to set up the Linux box as a network bridge, using commands like brctl to connect the virtual network interface tap3 to a physical diff --git a/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl b/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl --- a/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl +++ b/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl @@ -165,7 +165,7 @@ namespace eval ethernet { # Do some validation here, before the rawether process is started. # Typical entries would look like # eth0 real eth1 - # eth1 ethertap [[tap-device] [MAC]] + # eth1 ethertap [[tap-device] [MAC] [persistent]] set junk "" set optional "" set mac "" @@ -176,7 +176,7 @@ namespace eval ethernet { if { ! [regexp -- {^tap[0-9]+\s*(.*)$} $optional junk mac ] } { synth::report_error "Cannot instantiate ethernet device $name\n \ Invalid entry \"$use\" in target definition file $synth::target_definition\n \ - Should be \"ethertap \[ \[\]\]\"\n" + Should be \"ethertap \[ \[\]\] [persistent]\"\n" return "" } if { "" != $mac } { diff --git a/packages/devs/eth/synth/ecosynth/current/host/rawether.c b/packages/devs/eth/synth/ecosynth/current/host/rawether.c --- a/packages/devs/eth/synth/ecosynth/current/host/rawether.c +++ b/packages/devs/eth/synth/ecosynth/current/host/rawether.c @@ -32,7 +32,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): bartv -// Contact(s): bartv +// Contact(s): bartv, andrew.lunn@ascom.ch // Date: 2002/08/07 // Version: 0.01 // Description: @@ -525,6 +525,8 @@ tap_init(int argc, char** argv) { char* devname = NULL; struct ifreq ifr; + int persistent = 0; + int have_mac = 0; tx_fn = &tap_handle_tx; rx_fn = &tap_handle_rx; @@ -542,31 +544,46 @@ tap_init(int argc, char** argv) // but the user can specify one to avoid a source of randomness. // This MAC address is not actually needed by any of the code here, // but should be returned to eCos. - if (2 == argc) { + if (2 <= argc) { unsigned int mac_data[6]; // sscanf() needs unsigned ints - int result = sscanf(argv[1], "%x:%x:%x:%x:%x:%x", - &(mac_data[0]), &(mac_data[1]), &(mac_data[2]), - &(mac_data[3]), &(mac_data[4]), &(mac_data[5])); - if (6 != result) { - snprintf(msg, MSG_SIZE, "Invalid MAC address %s\n", argv[1]); - report_error(msg); - } - MAC[0] = mac_data[0]; - MAC[1] = mac_data[1]; - MAC[2] = mac_data[2]; - MAC[3] = mac_data[3]; - MAC[4] = mac_data[4]; - MAC[5] = mac_data[5]; - } else { - srand(time(NULL)); - MAC[0] = 0; - MAC[1] = 0x0FF; - MAC[2] = rand() & 0x0FF; - MAC[3] = rand() & 0x0FF; - MAC[4] = rand() & 0x0FF; - MAC[5] = rand() & 0x0FF; + int result = sscanf(argv[1], "%x:%x:%x:%x:%x:%x", + &(mac_data[0]), &(mac_data[1]), &(mac_data[2]), + &(mac_data[3]), &(mac_data[4]), &(mac_data[5])); + if (6 != result) { + if (strncmp(argv[1], "persistent", 10)) { + snprintf(msg, MSG_SIZE, "Invalid MAC address %s\n", argv[1]); + report_error(msg); + } + } else { + MAC[0] = mac_data[0]; + MAC[1] = mac_data[1]; + MAC[2] = mac_data[2]; + MAC[3] = mac_data[3]; + MAC[4] = mac_data[4]; + MAC[5] = mac_data[5]; + argv += 1; + argc -= 1; + have_mac = 1; + } + } + if ( 1 != have_mac) { + srand(time(NULL)); + MAC[0] = 0; + MAC[1] = 0x0FF; + MAC[2] = rand() & 0x0FF; + MAC[3] = rand() & 0x0FF; + MAC[4] = rand() & 0x0FF; + MAC[5] = rand() & 0x0FF; } + // Should we make the TAP device persistent. When persistence is + // enabled, the tap device is not removed when rawether + // exits. This makes daemons happier. They can keep running + // between invocations of rawether. + if (2 <= argc ) { + persistent = !strncmp(argv[1], "persistent", 10); + } + ether_fd = open("/dev/net/tun", O_RDWR); if (ether_fd < 0) { snprintf(msg, MSG_SIZE, "Failed to open /dev/net/tun, errno %s (%d)\n", (errno < sys_nerr) ? sys_errlist[errno] : "", errno); @@ -586,6 +603,14 @@ tap_init(int argc, char** argv) // Supporting multicasts is a no-op multicast_supported = 1; + if (persistent) { + if (ioctl(ether_fd, TUNSETPERSIST, 1) < 0) { + snprintf(msg, MSG_SIZE, "Failed to set persistent flag, errno %s (%d)\n", + ( errno < sys_nerr) ? + sys_errlist[errno] : "", errno); + report_error(msg); + } + } // All done. } #else @@ -770,3 +795,4 @@ main(int argc, char**argv) return 0; } +