Commit d266bd71 authored by Shashi Guruprasad's avatar Shashi Guruprasad
Browse files

Distributed NSE changes. In other words, simulation resources are

now mapped to more than one PC if required. The simnode_capacity
column in the node_types table determines how many sim nodes can
be packed on one PC. The packing factor can also be controlled via
tb-set-colocate-factor to be smaller than simnode_capacity.

- No frontend code changes. To summarize:
  $ns make-simulated {
    ...
  }
  is still the easy way to put a whole bunch of Tcl code to be
  in simulation.
  One unrelated fix in the frontend code is to fix the
  xmlencode() function which prior to this would knock off
  newlines from columns in the XML output. This affected
  nseconfigs since it is one of the few columns with embedded
  newlines. Also changed the event type and event object type
  in traffic.tcl from TRAFGEN/MODIFY to NSE/NSEEVENT.

- More Tcl code in a new directory tbsetup/nseparse
  -> Runs on ops similar to the main parser. This is invoked
     from assign_wrapper in the end if there are simnodes
  -> Partitions the Tcl code into multiple Tcl specifications
     and updates the nseconfigs table via xmlconvert
  -> Comes with a lot of caveats. Arbitrary Tcl code such as user
     specified objects or procedures will not be re-generated. For
     example, if a user wanted a procedure to be included in Tcl
     code for all partitions, there is no way for code in nseparse
     to do that. Besides that, it needs to be tested more thoroughly.

- xmlconvert has a new option -s. When invoked with this option,
  the experiments table is not allowed to be modified. Also,
  virtual tables are just updated (as opposed to deleting
  all rows in the first invocation before inserting new rows)

- nse.patch has all the IP address related changes committed in
  iversion 1.11 + 2 other changes. 1) MTU discovery support in
  the ICMP agent 2) "$ns rlink" mechanism for sim node to real
  node links

- nseinput.tcl includes several client side changes to add IP
  routes in NSE and the kernel routing table for packets crossing
  pnodes. Also made the parsing of tmcc command output more robust
  to new changes. Other client side changes in libsetup.pm and other
  scripts to run nse, are also in this commit

- Besides the expected changes in assign_wrapper for simulated nodes,
  the interfaces and veth_interfaces tables are updated with
  routing table identifiers (rtabid). The tmcd changes are already
  committed. This field is used only by sim hosts on the client side.
  Of course, they can be used by jails as well if desired.
parent de16d8e4
......@@ -1221,6 +1221,7 @@ else
event/trafgen/GNUmakefile \
event/proxy/GNUmakefile \
event/nsetrafgen/GNUmakefile \
event/nsetrafgen/nseinput.tcl \
event/delay-agent/GNUmakefile \
event/program-agent/GNUmakefile \
event/stated/waitForState \
......@@ -1294,7 +1295,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:1298: checking for a BSD compatible install" >&5
echo "configure:1299: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
......@@ -1396,7 +1397,9 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/snmpit tbsetup/ns2ir/GNUmakefile \
tbsetup/ns2ir/parse.tcl tbsetup/ns2ir/tb_compat.tcl \
tbsetup/ns2ir/parse-ns tbsetup/ns2ir/parse.proxy \
tbsetup/ns2ir/sim.tcl tbsetup/db2ns \
tbsetup/ns2ir/sim.tcl tbsetup/nseparse/GNUmakefile \
tbsetup/nseparse/nse.parse.proxy tbsetup/nseparse/parse-nse \
tbsetup/nseparse/nse.parse.tcl tbsetup/db2ns \
tbsetup/tbprerun tbsetup/tbswap tbsetup/tbend \
tbsetup/tbreport tbsetup/named_setup tbsetup/exports_setup \
tbsetup/checkpass/GNUmakefile tbsetup/assign_wrapper tbsetup/ptopgen \
......
......@@ -334,6 +334,7 @@ else
event/trafgen/GNUmakefile \
event/proxy/GNUmakefile \
event/nsetrafgen/GNUmakefile \
event/nsetrafgen/nseinput.tcl \
event/delay-agent/GNUmakefile \
event/program-agent/GNUmakefile \
event/stated/waitForState \
......@@ -439,7 +440,9 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/snmpit tbsetup/ns2ir/GNUmakefile \
tbsetup/ns2ir/parse.tcl tbsetup/ns2ir/tb_compat.tcl \
tbsetup/ns2ir/parse-ns tbsetup/ns2ir/parse.proxy \
tbsetup/ns2ir/sim.tcl tbsetup/db2ns \
tbsetup/ns2ir/sim.tcl tbsetup/nseparse/GNUmakefile \
tbsetup/nseparse/nse.parse.proxy tbsetup/nseparse/parse-nse \
tbsetup/nseparse/nse.parse.tcl tbsetup/db2ns \
tbsetup/tbprerun tbsetup/tbswap tbsetup/tbend \
tbsetup/tbreport tbsetup/named_setup tbsetup/exports_setup \
tbsetup/checkpass/GNUmakefile tbsetup/assign_wrapper tbsetup/ptopgen \
......
......@@ -24,10 +24,13 @@ sub usage()
exit(-1);
}
my $optlist = "x:nd";
my $optlist = "x:nds";
my $fromxml = 0;
my $impotent = 0;
my $debug = 0;
# Results of parsing nse specifications. Therefore different treatment.
# In particular, we don't expect updates to the experiments table
my $simparse = 0;
#
# Configure variables
......@@ -105,6 +108,9 @@ if (! getopts($optlist, \%options)) {
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"s"})) {
$simparse = 1;
}
if (defined($options{"x"})) {
$fromxml = 1;
$xmlfile = $options{"x"};
......@@ -181,6 +187,11 @@ sub readXML($$$) {
fatal($@)
if (eval { $parser->parse(*STDIN); return 1; } != 1);
# If these are the results of parsing the nse specifications,
# we don't expect updates to the experiments table
my %experiments_table;
if ( ! $simparse ) {
#
# Verify.
#
......@@ -191,11 +202,12 @@ sub readXML($$$) {
if (scalar(@{$virtual_tables{"experiments"}}) != 1) {
fatal("Must be exactly one experiments table row!");
}
my %experiments_table = %{@{$virtual_tables{"experiments"}}[0]};
%experiments_table = %{@{$virtual_tables{"experiments"}}[0]};
foreach my $key (keys(%experiments_table)) {
delete($experiments_table{$key})
if (!exists($experiment_fields{$key}));
}
}
#
# Okay, a hokey DoS check. Do not allow more than 10000 total rows!
......@@ -218,7 +230,7 @@ sub readXML($$$) {
# First the experiments table, which gets an update statement, if there
# is anything to update.
#
if (scalar(keys(%experiments_table))) {
if ( (! $simparse) && scalar(keys(%experiments_table))) {
my @setlist = ();
foreach my $key (keys(%experiments_table)) {
......@@ -257,10 +269,13 @@ sub readXML($$$) {
next
if ($table eq "experiments");
# Delete always.
# Delete only during the initial parsing and not
# during parsing of nse specifications
if ( ! $simparse ) {
DBQueryFatal("delete from $table ".
"where eid='$eid' and pid='$pid'")
if (!$impotent);
}
next
if (!defined($virtual_tables{$table}));
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -9,8 +9,8 @@ TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../..
SUBDIR = event/nsetrafgen
INSTALL_SUPDIR = /usr/testbed/sup/sup/FBSD45-STD/root
INSTALL_FILES = $(SRCDIR)/nseinput.tcl $(SRCDIR)/startnse
INSTALL_NSE = $(SRCDIR)/nse
INSTALL_FILES = nseinput.tcl $(SRCDIR)/startnse
INSTALL_NSE = nse
include $(OBJDIR)/Makeconf
......@@ -18,7 +18,7 @@ all: msg
msg:
@echo ""
@echo -n "WARNING! You must first do a \"make buildnse\""
@echo -n "WARNING! You must first do a \"make buildnse\" "
@echo "if nse is not built"
@echo "WARNING! It takes about 15 minutes for buildnse"
@echo ""
......@@ -30,19 +30,21 @@ include $(TESTBED_SRCDIR)/GNUmakerules
# the testbed as well as ns configure script, we need to resort
# to this kind of hack
buildnse:
ln -s $(SRCDIR)/tbevent.h .
ln -s $(SRCDIR)/tbevent.cc .
ln -s $(SRCDIR)/tbnexthop.h .
ln -s $(SRCDIR)/tbnexthop.cc .
ln -s $(SRCDIR)/ip_fw.h .
ln -s $(SRCDIR)/../../lib/libtb/log.h .
ln -s $(SRCDIR)/../../lib/libtb/tbdefs.h .
ln -s $(SRCDIR)/../lib/event.h .
ln -sf $(SRCDIR)/tbevent.h .
ln -sf $(SRCDIR)/tbevent.cc .
ln -sf $(SRCDIR)/tbnexthop.h .
ln -sf $(SRCDIR)/tbnexthop.cc .
ln -sf $(SRCDIR)/ip_fw.h .
ln -sf $(SRCDIR)/../../lib/libtb/log.h .
ln -sf $(SRCDIR)/../../lib/libtb/tbdefs.h .
ln -sf $(SRCDIR)/../lib/event.h .
$(SRCDIR)/nse-install $(SRCDIR)/nse.patch
sup-install:
cp -p $(INSTALL_FILES) $(INSTALL_SUPDIR)$(CLIENT_BINDIR)
cp -p $(INSTALL_NSE) $(INSTALL_SUPDIR)/usr/local/bin
-mkdir -p $(INSTALL_SUPDIR)/$(CLIENT_BINDIR)/
-cp $(INSTALL_FILES) $(INSTALL_SUPDIR)/$(CLIENT_BINDIR)
-mkdir -p $(INSTALL_SUPDIR)/usr/local/bin/
-cp $(INSTALL_NSE) $(INSTALL_SUPDIR)/usr/local/bin
client-install:
cp -p $(INSTALL_FILES) $(DESTDIR)$(CLIENT_BINDIR)
......
ns-2.26/trace/cmu-trace.cc
ns-2.26/tools/random.cc
ns-2.26/tcp/tcp-full.cc
ns-2.26/tcp/tcp-full.h
ns-2.26/tcp/tcp.h
ns-2.26/tcl/lib/ns-address.tcl
ns-2.26/tcl/lib/ns-default.tcl
ns-2.26/tcl/lib/ns-lib.tcl
ns-2.26/tcl/lib/ns-link.tcl
ns-2.26/tcl/lib/ns-node.tcl
ns-2.26/tcl/lib/ns-rtmodule.tcl
ns-2.26/apps/telnet.cc
ns-2.26/classifier/classifier-hash.h
ns-2.26/classifier/classifier.cc
ns-2.26/classifier/classifier.h
ns-2.26/common/ip.h
ns-2.26/common/packet.h
ns-2.26/common/scheduler.cc
ns-2.26/common/scheduler.h
ns-2.26/common/simulator.cc
ns-2.26/common/simulator.h
ns-2.26/common/tclAppInit.cc
ns-2.26/common/timer-handler.cc
ns-2.26/common/timer-handler.h
ns-2.26/routing/address.cc
ns-2.26/routing/address.h
ns-2.26/emulate/iptap.cc
ns-2.26/emulate/iptap.h
ns-2.26/emulate/icmp.cc
ns-2.26/emulate/icmp.h
ns-2.26/emulate/net-ip.cc
ns-2.26/emulate/net-pcap.cc
ns-2.26/emulate/net.cc
ns-2.26/emulate/net.h
ns-2.26/emulate/tap.cc
ns-2.26/emulate/tap.h
ns-2.26/emulate/tcptap.cc
ns-2.26/link/delay.h
ns-2.26/mcast/lms.h
ns-2.26/Makefile.in
ns-2.26/config.h
install
......@@ -17,3 +17,5 @@ fi
cd ns-allinone-2.26
./install
cp ns-2.26/nse ..
cd ..
strip nse
This diff is collapsed.
......@@ -2,10 +2,13 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# All rights reserved.
#
global CLIENTVARDIR
set CLIENTVARDIR @CLIENT_VARDIR@
# consults tmcc hostnames database to translate hostname to IP
# returns ip address of name
proc getipaddr {name} {
......@@ -19,7 +22,17 @@ proc getipaddr {name} {
set hostnamelist [split [exec tmcc hostnames] "\n"]
foreach hostname $hostnamelist {
scan $hostname "NAME=%s IP=%s ALIASES=\'%s\'" hname ip aliases
if { $hostname == {} } {
continue
}
set ret1 [regexp -- {NAME=([-\w\.]+) } $hostname Matchvar hname]
set ret2 [regexp -- {IP=([0-9\.]*) } $hostname Matchvar ip]
set ret3 [regexp -- {ALIASES='([-\w\. ]*)'} $hostname Matchvar aliases]
if { $ret == 0 || $ret1 == 0 || $ret2 == 0 } {
puts stderr "NSE: tmcc hostnames format has changed."
puts stderr "NSE: Contact testbed operations to fix this."
exit -1
}
set aliaslist [split $aliases " "]
foreach alias $aliaslist {
if { $alias == $name } {
......@@ -31,35 +44,77 @@ proc getipaddr {name} {
return ""
}
# consults tmcc ifconfig and findif to find the interface name
# returns the interface name for ipaddr
proc getif {ipaddr} {
set tmccifconfig [open /var/emulab/boot/tmcc.ifconfig r]
# Reads tmcc ifconfig output and constructs an array of
# IP address to MAC address mappings
proc readifconfig {} {
global CLIENTVARDIR
set tmccifconfig [open $CLIENTVARDIR/boot/tmcc.ifconfig r]
set ifconf [read $tmccifconfig]
close $tmccifconfig
global tbiptomac
global tbiptortabid
set ifconfiglist [split $ifconf "\n"]
foreach ifconfig $ifconfiglist {
scan $ifconfig "%*s INET=%s MASK=%s MAC=%s " inet mask mac
if { $inet == $ipaddr } {
return [exec findif $mac]
if { $ifconfig == {} } {
continue
}
set ret [regexp -- {IFACETYPE=(\w*) } $ifconfig Matchvar ifacetype]
if { $ret == 0 } {
puts stderr "NSE: tmcc ifconfig format has changed."
puts stderr "NSE: Contact testbed operations to fix this."
exit -1
}
if { $ifacetype == "veth" } {
set ret [regexp -- {VMAC=(\w*) } $ifconfig Matchvar mac]
} else {
set ret [regexp -- {MAC=(\w*) } $ifconfig Matchvar mac]
}
set ret1 [regexp -- {INET=([0-9\.]*) } $ifconfig Matchvar inet]
set ret2 [regexp -- {MASK=([0-9\.]*) } $ifconfig Matchvar mask]
set ret3 [regexp -- {RTABID=(\d*)} $ifconfig Matchvar rtabid]
if { $ret == 0 || $ret1 == 0 || $ret2 == 0 || $ret3 == 0 } {
puts stderr "NSE: tmcc ifconfig format has changed."
puts stderr "NSE: Contact testbed operations to fix this."
exit -1
}
set tbiptomac($inet) $mac
set tbiptortabid($inet) $rtabid
}
}
puts stderr "NSE: Could not find the interface name for $ipaddr"
# consults info from tmcc ifconfig and findif to find the interface name
# returns the interface name for ipaddr
proc getif {ipaddr} {
global tbiptomac
if { [info exists tbiptomac($ipaddr)] } {
return [exec findif $tbiptomac($ipaddr)]
}
puts stderr "NSE: getif: Could not find the interface name for $ipaddr"
return ""
}
# consults info from tmcc ifconfig and findif to find the interface name
# returns the interface name for ipaddr
proc getrtabid {ipaddr} {
global tbiptortabid
if { [info exists tbiptortabid($ipaddr)] } {
return $tbiptortabid($ipaddr)
}
puts stderr "NSE: getrtabid: Could not find the rtabid for $ipaddr"
return ""
}
proc getmac {ipaddr} {
global tbiptomac
set tmccifconfig [open /var/emulab/boot/tmcc.ifconfig r]
set ifconf [read $tmccifconfig]
close $tmccifconfig
set ifconfiglist [split $ifconf "\n"]
foreach ifconfig $ifconfiglist {
scan $ifconfig "%*s INET=%s MASK=%s MAC=%s " inet mask mac
if { $inet == $ipaddr } {
if { [info exists tbiptomac($ipaddr)] } {
set mac $tbiptomac($ipaddr)
set macaddrchars [split $mac ""]
set i 0
while { $i < [llength $macaddrchars] } {
......@@ -68,34 +123,13 @@ proc getmac {ipaddr} {
}
return [join $mac2chars ":"]
}
}
puts stderr "NSE: Could not find the interface name for $ipaddr"
puts stderr "NSE: getmac: Could not find the interface name for $ipaddr"
return ""
}
# This is temporary. Needs to be done from libsetup.pm
proc installipfwfwd {} {
set tmccroutelist [open /var/emulab/boot/tmcc.routelist r]
set routeliststr [read $tmccroutelist]
close $tmccroutelist
set ipfw /sbin/ipfw
set routelist [split $routeliststr "\n"]
foreach route $routelist {
set ret [scan $route "ROUTE NODE=%s SRC=%s DEST=%s DESTTYPE=%s DESTMASK=%s NEXTHOP=%s COST=%s" \
node src dst dsttype dstmask nexthop cost]
# we ensure that by expecting all 7 conversions in scan to happen for correct lines
# probably a ROUTERTYPE line if the conversion fails
if { $ret == 7 } {
exec $ipfw add fwd $nexthop ip from $src to $dst:$dstmask out
}
}
}
proc findcpuspeed {} {
if { [catch {set speed [exec sysctl -n machdep.tsc_freq]}] == 0 } {
if { [catch {set speed [exec sysctl -n machdep.tsc_freq]}] == 0 && $speed != {} } {
return $speed
}
set dmesgfd [open /var/run/dmesg.boot r]
......@@ -122,12 +156,36 @@ proc findcpuspeed {} {
}
}
proc readroutes {} {
global CLIENTVARDIR
set tmccroutelist [open $CLIENTVARDIR/boot/tmcc.routelist r]
set routeliststr [read $tmccroutelist]
close $tmccroutelist
global tbroutes
set routelist [split $routeliststr \n]
unset routeliststr
foreach route $routelist {
if { $route == {} } {
continue
}
set ret [scan $route "ROUTE NODE=%s SRC=%s DEST=%s DESTTYPE=%s DESTMASK=%s NEXTHOP=%s COST=%s" \
node src dst dsttype dstmask nexthop cost]
# we ensure that by expecting all 7 conversions in scan to happen for correct lines
# probably a ROUTERTYPE line if the conversion fails
if { $ret == 7 } {
lappend tbroutes($node) "$dst:$dstmask:$nexthop"
}
}
}
# call it after evaluating nseconfigs
# This will parse tmcc routelist and
# store a list of routes for all source nodes that are
# in this simulation
set tmccnseconfigs [open /var/emulab/boot/tmcc.nseconfigs r]
set tmccnseconfigs [open $CLIENTVARDIR/boot/tmcc.nseconfigs r]
set nseconfig [read $tmccnseconfigs]
close $tmccnseconfigs
......@@ -141,23 +199,25 @@ set nsetrafgen_present 0
set simcode_present 0
# since we ran the original script through NSE (without running the simulation),
# we can ignore all sorts of errors
# we can ignore all sorts of errors.
# XXX: Hmm not true anymore. Need to fix this later.
if { [catch {eval $nseconfig} errMsg] == 1 } {
puts stderr "NSE: syntax error evaluating script: $errMsg"
}
# XXX: don't uncomment. causes incorrect behaviour
#if { $nsetrafgen_present == 1 || $simcode_present == 1 } {
# installipfwfwd
#}
# ifconfig
readifconfig
# Routes
readroutes
# the name of the simulator instance variable might not
# always be 'ns', coming from the TB parser
set ns [Simulator instance]
# we only need 1 RAW IP socket for introducing packets into the network
set ipnet [new Network/IP]
$ipnet open writeonly
set ipnetcommon [new Network/IP]
$ipnetcommon open writeonly
# configuring NSE FullTcp traffic generators
set objnamelist ""
......@@ -193,7 +253,7 @@ if { $nsetrafgen_present == 1 } {
# emulation scenario
if { [$tcpobj set objname] != {} } {
$ns attach-agent $n0_FullTcp $tcpobj
lappend objnamelist [$tcpobj set objname]
#lappend objnamelist [$tcpobj set objname]
}
}
}
......@@ -206,7 +266,7 @@ if { $nsetrafgen_present == 1 } {
# as a result of a combined simulation and
# emulation scenario
if { [$ftpobj set objname] != {} } {
lappend objnamelist [$ftpobj set objname]
#lappend objnamelist [$ftpobj set objname]
}
}
......@@ -218,7 +278,7 @@ if { $nsetrafgen_present == 1 } {
# as a result of a combined simulation and
# emulation scenario
if { [$telnetobj set objname] != {} } {
lappend objnamelist [$telnetobj set objname]
#lappend objnamelist [$telnetobj set objname]
}
}
......@@ -227,7 +287,7 @@ if { $nsetrafgen_present == 1 } {
# TCPTap along with the required Live and RAW IP objects. Set the filter and interface
# after learning it from tmcc commands and other scripts in /var/emulab
set tmcctrafgens [open /var/emulab/boot/tmcc.trafgens r]
set tmcctrafgens [open $CLIENTVARDIR/boot/tmcc.trafgens r]
set tmcctraf [read $tmcctrafgens]
close $tmcctrafgens
set trafgenlist [split $tmcctraf "\n"]
......@@ -268,7 +328,7 @@ if { $nsetrafgen_present == 1 } {
# associate the 2 network objects in the TCPTap object
$tcptap($i) network-incoming $bpf_tcp($i)
$tcptap($i) network-outgoing $ipnet
$tcptap($i) network-outgoing $ipnetcommon
# attach the TCPTap agent to node n1_FullTcp
$ns attach-agent $n1_FullTcp $tcptap($i)
......@@ -289,60 +349,18 @@ if { $simcode_present == 1 } {
# Now, we configure IPTaps for links between real and simulated nodes
set i 0
# Routing table id. 0 is the main table, so we skip that
set rtabid 1
foreach nodeinst [concat [Node info instances] [Node/MobileNode info instances]] {
if { [$nodeinst info vars nsenode_ipaddrlist] != {} } {
set nodeinst_ipaddrlist [$nodeinst set nsenode_ipaddrlist]
foreach nodeinst_ipaddr $nodeinst_ipaddrlist {
set iface [getif $nodeinst_ipaddr]
# one iptap per node that has real - simulated link
set iptap($i) [new Agent/IPTap]
# open the bpf, set the filter for capturing incoming ip packets
# except for the current host itself
set bpf_ip($i) [new Network/Pcap/Live]
set dev_ip($i) [$bpf_ip($i) open readonly $iface]
set nodeinst_mac [getmac $nodeinst_ipaddr]
if { $nodeinst_mac != {} } {
$bpf_ip($i) filter "ip and not dst host $nodeinst_ipaddr and not ether src $nodeinst_mac"
} else {
$bpf_ip($i) filter "ip and not dst host $nodeinst_ipaddr"
}
# associate the 2 network objects in the IPTap object
$iptap($i) network-outgoing $ipnet
$iptap($i) network-incoming $bpf_ip($i)
# The emulab default netmask
set ipmask 255.255.255.0
$iptap($i) ipmask $ipmask
$ns attach-agent $nodeinst $iptap($i)
# Need to figure out the correct way to do this i.e. I need the
# nexthop ip here. Workaround hack is to add the net route
$ns add-ip-mask-target $nodeinst_ipaddr $ipmask $iptap($i)
set ipmasked [expr [$ns inet-aton $nodeinst_ipaddr] & [$ns inet-aton $ipmask]]
$nodeinst add-route $ipmasked $iptap($i)
if { [$nodeinst info vars tbname] != {} } {
set tbnodename [$nodeinst set tbname]
# We do not connect iptaps coz they figure out their
# destination node address dynamically using routing tables
incr i
}
}
if { [$nodeinst info vars routes] != {} } {
set routelist [split [$nodeinst set routes] "\n"]
foreach route $routelist {
scan $route "DST=%s DST_MASK=%s NEXTHOP=%s" dstip dstmask nexthop
$nodeinst add-route-to-ip $dstip $nexthop $dstmask
if { [info exists tbroutes($tbnodename)] } {
foreach route $tbroutes($tbnodename) {
set rt [split $route ":"]
# format is dst:dstmask:nexthop
# add-route-to-ip ip nhopip mask
$nodeinst add-route-to-ip [lindex $rt 0] [lindex $rt 2] [lindex $rt 1]
# We dont really consider the case where different routes
# have different masks. A complete longest prefix match
# implementation that is also efficient for nse may
......@@ -350,36 +368,81 @@ if { $simcode_present == 1 } {
}
}
}
}
# Perhaps create the veths right here
foreach rlink [Rlink info instances] {
if { $rlink == {} } {
continue
}
set iptap [$rlink target]
set ip [$rlink srcipaddr]
set iface [getif $ip]
set rtabid [getrtabid $ip]
$iptap ipaddr $ip
# except for the current host itself
set bpf_ip [new Network/Pcap/Live]
set dev_ip [$bpf_ip open readonly $iface]
set devname [$bpf_ip open readonly $iface]
set mac [getmac $ip]
if { $mac != {} } {
$bpf_ip filter "ip and not ether src $mac"
} else {
$bpf_ip filter "ip"
}
# associate the 2 network objects in the IPTap object
$iptap network-incoming $bpf_ip
set srcnode [$rlink src]
if { [info exists $ipnet($srcnode)] } {
if { [info exists ipnet($srcnode)] } {
$iptap network-outgoing $ipnet($srcnode)
$iptap icmpagent $icmpagt($srcnode)
} else {
set ipnet($srcnode) [new Network/IP]
$ipnet($srcnode) open writeonly
$ipnet($srcnode) rtabid $rtabid
$ipnet($srcnode) setrtabid $rtabid
$iptap network-outgoing $ipnet($srcnode)
incr rtabid
}
# associate the 2 network objects in the IPTap object
$iptap network-incoming $bpf_ip
set icmpagt($srcnode) [new Agent/IcmpAgent]
$ns attach-agent $srcnode $icmpagt($srcnode)
$iptap icmpagent $icmpagt($srcnode)
if { [$srcnode info vars tbname] != {} } {
set tbnodename [$srcnode set tbname]
if { [info exists tbroutes($tbnodename)] } {
# We don't wanna be flushing the main
# routing table's routes or we'll be
# cutting off the control net.
if { $rtabid > 0 } {
exec route flush -rtabid $rtabid
}
foreach route $tbroutes($tbnodename) {
set rt [split $route ":"]
set ip [lindex $rt 0]
set nhopip [lindex $rt 2]
set mask [lindex $rt 1]
# Need to add routes for nodes that have
# rlinks so that packets that leave the