Commit 05bc3bd4 authored by Shashi Guruprasad's avatar Shashi Guruprasad

NSE related changes:

  - Fixes the routing problem
  - A new type "sim" has been created but not in the DB. node_types and
    nodes remain unchanged. This will change after we figure out how
    to represent in the DB the local multiple virtnodes in one phynode case
    The frontend tb_compat.tcl adds the sim type and ptopgen associates
    a huge number of sim nodes to all local PCs.
  - All simulated nodes go into one pc untill I finish coding the distributed
    nse case. Also, sim nodes go through assign but with an explicit
    "fix-node" directive in the top file. A random free pc is chosen using
    the avail script in assign_wrapper. If we don't fix node it, assign
    maps sim nodes to multiple phy nodes even when a valid all to one
    mapping is possible.
  - Syntax for nse:

   $ns make-simulated {

       set simnode1 [$ns node]
       set simnode2 [$ns node]

   }
   ...

   The old syntax

   set nsenode [$ns nsenode]
   $nsenode make-simulated {
   }

   is deprecated

  - All 38 frontend tests in the testsuite pass

  - A new table v2pmap has been added to handle multiple virt nodes to
    one phy node mapping. This is used in "tmcc hostnames" currently.

  - The phy node that is picked to run nse is loaded with a custom image
    FBSD45-NSE . This can use the default FBSD kernel if there is a mechanism
    to run at 1000HZ, have options IPFIREWALL_FORWARD and PERFMON turned on.
    The image is in the 'testbed' group. Do not delete this image.

  - Static routes now adds routes for the case dst == nexthop. The routing
    graph would be disconnected otherwise and I need to traverse this in
    assign_wrapper for nse. On the client side, such a route is filtered out in
    libsetup.pm

  - sim nodes are also correctly visualized
parent 09e5437c
......@@ -4,8 +4,10 @@
TBDBNAME=tbdb
WWWDEFS=shash-emulab
TBOPSEMAIL=shash@cs.utah.edu
TBLOGSEMAIL=shash@cs.utah.edu
TBAUDITEMAIL=shash@cs.utah.edu
TBOPSEMAIL=shash+emulab-ops@cs.utah.edu
TBLOGSEMAIL=shash+emulab-log@cs.utah.edu
TBACTIVEARCHIVE=shash+activearch@cs.utah.edu
TBUSERSARCHIVE=shash+usersarch@cs.utah.edu
BOSSNODE=boss.emulab.net
USERNODE=users.emulab.net
FSNODE=fs.emulab.net
......@@ -15,5 +17,5 @@ IPBASE=192.168
FSDIR_GROUPS=/q/groups
FSDIR_PROJ=/q/proj
FSDIR_USERS=/users
TBSTATEDEMAIL=shash@cs.utah.edu
TBTESTSUITEEMAIL=shash@cs.utah.edu
TBSTATEDEMAIL=shash+stated@cs.utah.edu
TBTESTSUITEEMAIL=shash+testsuite@cs.utah.edu
#!/bin/sh
if [ ! -d ns-2 ]; then
if [ ! -d /ns-allinone-2.1b9 ]; then
echo "Downloading ns2.1b9 source ..."
fetch http://www.emulab.net/ns-allinone-2.1b9.tar.gz
tar xzf ns-allinone-2.1b9.tar.gz
......
This diff is collapsed.
......@@ -63,15 +63,14 @@ Node instproc init {s} {
$self set failureaction "fatal"
$self set fixed ""
$self set nseconfig ""
$self set realtime 0
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
if { $simulated == 1 } {
$self set simulated 1
$self set nsenode $curnsenode
} else {
$self set simulated 0
$self set nsenode ""
$self set realtime 0
}
$self set nsenode_vportlist {}
}
......@@ -116,17 +115,11 @@ Node instproc updatedb {DB} {
$self instvar agentlist
$self instvar routelist
$self instvar sim
$self instvar simulated
$self instvar nseconfig
$self instvar realtime
var_import ::GLOBALS::pid
var_import ::GLOBALS::eid
var_import ::GLOBALS::default_ip_routing_type
# currently we don't want to update the DB for simulated nodes
if { $simulated == 1 } {
return
}
# If we haven't specified a osid so far then we should fill it
# with the id from the node_types table now.
if {$osid == {}} {
......@@ -145,19 +138,6 @@ Node instproc updatedb {DB} {
foreach agent $agentlist {
$agent updatedb $DB
append nseconfig [$agent get_nseconfig]
}
if {$nseconfig != {}} {
set nsecfg_script ""
set simu [lindex [Simulator info instances] 0]
append nsecfg_script "set $simu \[new Simulator]\n"
append nsecfg_script "\$$simu use-scheduler RealTime\n\n"
append nsecfg_script $nseconfig
# update the per-node nseconfigs table in the DB
sql exec $DB "insert into nseconfigs (pid,eid,vname,nseconfig) values ('$pid','$eid','$self','$nsecfg_script')";
}
$self add_routes_to_DB $DB
......
......@@ -57,3 +57,7 @@ Simulator instproc run {args} {
Simulator instproc nsenode {args} {
return [new NSENode]
}
Simulator instproc make-simulated {args} {
uplevel 1 eval $args
}
......@@ -208,10 +208,6 @@ namespace eval GLOBALS {
# is being parsed should go into a NSE simulation or not
variable simulated 0
# If simulated is 1, then curnsenode gives us the name
# of the physical node on which the simulation script
# should go into
variable curnsenode ""
}
# Connect to the DB
......@@ -238,7 +234,6 @@ source ${GLOBALS::libdir}/nsobject.tcl
source ${GLOBALS::libdir}/sim.tcl
source ${GLOBALS::libdir}/lanlink.tcl
source ${GLOBALS::libdir}/node.tcl
source ${GLOBALS::libdir}/nsenode.tcl
source ${GLOBALS::libdir}/null.tcl
source ${GLOBALS::libdir}/traffic.tcl
source ${GLOBALS::libdir}/vtype.tcl
......
......@@ -55,6 +55,9 @@ Simulator instproc init {args} {
$self set event_list {}
$self set event_count 0
# global nse config file. to be split later
$self set nseconfig ""
# Program list.
$self instvar prog_list;
array set prog_list {}
......@@ -75,7 +78,6 @@ Simulator instproc rename {old new} {
Simulator instproc node {args} {
var_import ::GLOBALS::last_class
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
$self instvar id_counter
$self instvar node_list
......@@ -86,44 +88,16 @@ Simulator instproc node {args} {
set curnode tbnode-n[incr id_counter]
Node $curnode $self
# not adding simulated nodes to the node_list
if { $simulated == 0 } {
set node_list($curnode) {}
# simulated nodes have type 'sim'
if { $simulated == 1 } {
tb-set-hardware $curnode sim
}
set node_list($curnode) {}
set last_class $curnode
return $curnode
}
# nsenode
# this method does pretty much what the node proc does
# with some XXXXX
Simulator instproc nsenode {args} {
var_import ::GLOBALS::last_class
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
$self instvar id_counter
$self instvar node_list
if {($args != {})} {
punsup "Arguments for node: $args"
}
set curnode tbnsenode-n[incr id_counter]
NSENode $curnode $self
# not adding simulated nodes to the node_list
if { $simulated == 0 } {
set node_list($curnode) {}
} else {
$curnode set simulated 1
$curnode set nsenode $curnsenode
}
set last_class $curnode
return $curnode
}
# duplex-link <node1> <node2> <bandwidth> <delay> <type>
# This adds a new link to the topology. <bandwidth> can be in any
# form accepted by parse_bw and <delay> in any form accepted by
......@@ -131,7 +105,6 @@ Simulator instproc nsenode {args} {
Simulator instproc duplex-link {n1 n2 bw delay type args} {
var_import ::GLOBALS::last_class
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
$self instvar id_counter
$self instvar lanlink_list
$self instvar link_map
......@@ -148,62 +121,27 @@ Simulator instproc duplex-link {n1 n2 bw delay type args} {
perror "\[duplex-link] $n2 is not a node."
set error 1
}
if { $simulated == 1 && ( [$n1 set simulated] == 0 || [$n2 set simulated] == 0 ) } {
set simulated 0
perror "\[duplex-link] Please define links between real and simulated nodes outside make-simulated"
set simulated 1
set error 1
}
if {$error} {return}
# Convert bandwidth and delay
set rbw [parse_bw $bw]
set rdelay [parse_delay $delay]
set n1sim [$n1 set simulated]
set n2sim [$n2 set simulated]
set n1node $n1
set n2node $n2
set simnode ""
# If one of the nodes is a real node, we
# create a link between the real node and
# the physical node corresponding to the
# simulated node. If both are simulated
# nodes, we don't need to do anything
if { $n1sim == 1 && $n2sim == 0 } {
set simnode $n1
set n1node [$n1 set nsenode]
} elseif { $n1sim == 0 && $n2sim == 1 } {
set simnode $n2
set n2node [$n2 set nsenode]
} elseif { $n1sim == 1 && $n2sim == 1 } {
return ""
}
# At this point we have one of the nodes of
# the link to be real. We need to make sure
# that this is not being defined in make-simulated.
# In other words links or lans from real nodes and
# simulated nodes should happen outside make-simulated
if { $simulated == 1 } {
set simulated 0
perror "Please define links between real and simulated nodes outside make-simulated"
set simulated 1
return ""
}
set curlink tblink-l[incr id_counter]
Link $curlink $self "$n1node $n2node" $rbw $rdelay $type
Link $curlink $self "$n1 $n2" $rbw $rdelay $type
set lanlink_list($curlink) {}
set link_map($n1node:$n2node) $curlink
set link_map($n2node:$n1node) $curlink
# get the vport number on nsenode on which we make
# the link and store it in the simulated node that
# goes into NSE
if { $simnode != {} } {
set vport [[$simnode set nsenode] find_port $curlink]
set vportlist [$simnode set nsenode_vportlist]
lappend vportlist $vport
$simnode set nsenode_vportlist $vportlist
}
set link_map($n1:$n2) $curlink
set link_map($n2:$n1) $curlink
set last_class $curlink
return $curlink
}
......@@ -215,7 +153,6 @@ Simulator instproc duplex-link {n1 n2 bw delay type args} {
Simulator instproc make-lan {nodelist bw delay args} {
var_import ::GLOBALS::last_class
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
$self instvar id_counter
$self instvar lanlink_list
......@@ -223,56 +160,34 @@ Simulator instproc make-lan {nodelist bw delay args} {
punsup "Arguments for make-lan: $args"
}
set modified_nodelist ""
set realnode_present 0
set simnode_list ""
foreach node $nodelist {
if { [$node set simulated] == 1 } {
append modified_nodelist [$node set nsenode]
append simnode_list $node
} else {
append modified_nodelist "$node "
set realnode_present 1
}
}
if { $realnode_present == 1 } {
# At this point we have one of the nodes of
# the lan to be real. We need to make sure
# that this is not being defined in make-simulated.
# In other words links or lans from real nodes and
# simulated nodes should happen outside make-simulated
if { $simulated == 1 } {
set simulated 0
perror "Please define links between real and simulated nodes outside make-simulated"
set simulated 1
return ""
}
# At this point we have one of the nodes of
# the lan to be real. We need to make sure
# that this is not being defined in make-simulated.
# In other words links or lans from real nodes and
# simulated nodes should happen outside make-simulated
if { $simulated == 1 } {
set curlan tblan-lan[incr id_counter]
# Convert bandwidth and delay
set rbw [parse_bw $bw]
set rdelay [parse_delay $delay]
Lan $curlan $self $modified_nodelist $rbw $rdelay {}
set lanlink_list($curlan) {}
set last_class $curlan
# get the vport number on nsenode on which we make
# the lan and store it in the simulated node that
# goes into NSE
foreach simnode $simnode_list {
set vport [[$simnode set nsenode] find_port $curlan]
$simnode set nsenode_vport $vport
foreach node $nodelist {
if { [$node set simulated] == 0 } {
set simulated 0
perror "Please define lans between real and simulated nodes outside make-simulated"
set simulated 1
return ""
}
}
return $curlan
} else {
return ""
}
set curlan tblan-lan[incr id_counter]
# Convert bandwidth and delay
set rbw [parse_bw $bw]
set rdelay [parse_delay $delay]
Lan $curlan $self $nodelist $rbw $rdelay {}
set lanlink_list($curlan) {}
set last_class $curlan
return $curlan
}
# run
......@@ -285,6 +200,8 @@ Simulator instproc run {} {
$self instvar node_list
$self instvar event_list
$self instvar prog_list
$self instvar simulated
$self instvar nseconfig
var_import ::GLOBALS::pid
var_import ::GLOBALS::eid
var_import ::GLOBALS::errors
......@@ -346,6 +263,22 @@ Simulator instproc run {} {
# If we are running in impotent mode we stop here
if {$impotent == 1} {return}
# update the global nseconfigs using a bogus vname
# i.e. instead of the node on which nse is gonna run
# which was the original vname field, we just put $ns
# for now. Once assign runs, the correct value will be
# entered into the database
if { $nseconfig != {} } {
set nsecfg_script ""
set simu [lindex [Simulator info instances] 0]
append nsecfg_script "set $simu \[new Simulator]\n"
append nsecfg_script "\$$simu use-scheduler RealTime\n\n"
append nsecfg_script $nseconfig
sql exec $DB "insert into nseconfigs (pid,eid,vname,nseconfig) values ('$pid', '$eid', '$self', '$nsecfg_script')"
}
# Update the DB
foreach node [lsort [array names node_list]] {
......@@ -421,7 +354,6 @@ Simulator instproc connect {src dst} {
# ...
Simulator instproc at {time eventstring} {
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
# ignore at statement for simulated case
if { $simulated == 1 } {
......@@ -661,6 +593,7 @@ Simulator instproc at {time eventstring} {
return
}
}
set event_count [expr $event_count + 1]
lappend event_list [list $time $vnode $vname $otype $etype $args $atstring]
}
......@@ -672,7 +605,6 @@ Simulator instproc at {time eventstring} {
Simulator instproc rtproto {type args} {
var_import ::GLOBALS::default_ip_routing_type
var_import ::GLOBALS::simulated
var_import ::GLOBALS::curnsenode
# ignore at statement for simulated case
if { $simulated == 1 } {
......@@ -832,3 +764,32 @@ Simulator instproc cost {src dst c} {
set reallink [$self find_link $src $dst]
$reallink set cost([list $src [$reallink get_port $src]]) $c
}
# Now we have an experiment wide
# simulation specification. Virtual to physical
# mapping will be done in later stages
Simulator instproc make-simulated {args} {
var_import ::GLOBALS::simulated
$self instvar nseconfig
$self instvar simcode_present
set simulated 1
global script
set script [string trim $args "\{\}"]
if { $script == {} } {
set simulated 0
return
}
set simcode_present 1
# we ignore any type of errors coz they have
# been caught when we ran the script through NSE
uplevel 1 eval $script
append nseconfig $script
set simulated 0
}
......@@ -70,6 +70,10 @@ namespace eval TBCOMPAT {
}
sql endquery $DB
# NSE hack: sim type is not in DB. Just adding it now
set hwtypes(sim) 1
set isremote(sim) 0
# The permissions table. Entries in this table indicate who is allowed
# to use nodes of a particular type. No entries means anyone can use it.
#
......
......@@ -395,7 +395,9 @@ Agent/TCP/FullTcp instproc connect {dst} {
$self set proto "tcp"
$dst set proto "tcp"
$node set osid "FBSD-STD"
$node set realtime 1
$dest set osid "FBSD-STD"
$dest set realtime 1
}
# Agent/Null
......
......@@ -133,6 +133,10 @@ $result->finish;
$sharklinks = "";
# XXX NSE hack
foreach $node (keys(%nodes)) {
if ($node =~ /^sh/) {
print "node $node shark-shelf:1\n";
......@@ -141,6 +145,14 @@ foreach $node (keys(%nodes)) {
$delay_capacity = $nodetypes{$nodes{$node}};
if ($delay_capacity > 0) {
$text .= " delay:$delay_capacity";
##################################################################################
### NSE Node hack. Instead of adding sim nodes into the database schema,
### I'm just adding it here for now untill we can figure out how to add sim nodes
### into the nodes table.
### One assumption is that if we the node type can support delay nodes,
### then it is a local node and therefore we can support sim nodes
#################################################################################
$text .= " sim:100000";
}
print "$text\n";
}
......
......@@ -324,41 +324,55 @@ foreach my $route (keys(%routes)) {
my $hop = $routes{$route};
my $type = 'host';
# XXX NSE hack: We need all routes
# Installing the route in the directly connected case is harmless
#
# If directly connected, skip.
#
if ($dst eq $hop) {
next;
}
#if ($dst eq $hop) {
# next;
#}
#
# This is the lan that contains the src and hop. (the link).
#
my $srclan = $rlans{"$src:$hop"};
my $dstlan;
# XXX NSE hack: We need all the routes
if ($dst eq $hop) {
#
# Now we need to find the destination lan (link) by stepping through
# each hop till we get to it.
#
my $nhop = $hop;
while (1) {
$dstlan = $srclan;
if ($debug) {
print "$src --> $dst : $hop:$dst\n";
}
} else {
#
# Now we need to find the destination lan (link) by stepping through
# each hop till we get to it.
#
my $nhop = $hop;
while (1) {
# Next hop to destination.
if (!defined($routes{"$nhop:$dst"})) {
die("*** $0:\n".
" Failed to find route: $nhop:$dst!\n");
die("*** $0:\n".
" Failed to find route: $nhop:$dst!\n");
}
my $nnhop = $routes{"$nhop:$dst"};
# Last hop to destination.
if ($nnhop eq $dst) {
last;
last;
}
$nhop = $nnhop;
}
my $dstlan = $rlans{"$nhop:$dst"};
if ($debug) {
}
$dstlan = $rlans{"$nhop:$dst"};
if ($debug) {
print "$src --> $dst : $nhop:$dst\n";
}
}
#
......
......@@ -93,6 +93,7 @@ sub cleanup {
DBQueryWarn("DELETE from delays where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from vlans where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from tunnels where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from v2pmap where pid='$pid' and eid='$eid'");
SetExpState($pid, $eid, EXPTSTATE_SWAPPED);
}
......
......@@ -171,6 +171,8 @@ DBQueryWarn("DELETE from vlans where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from tunnels where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from v2pmap where pid='$pid' and eid='$eid'")
or $errors++;
# Accounting info.
TBSetExpSwapTime($pid, $eid);
......
......@@ -136,6 +136,7 @@ sub TMCCCMD_VNODELIST() { "vnodelist"; }
sub TMCCCMD_ISALIVE() { "isalive"; }
sub TMCCCMD_SFSHOSTID() { "sfshostid"; }
sub TMCCCMD_SFSMOUNTS() { "sfsmounts"; }
sub TMCCCMD_ROUTELIST() { "routelist"; }
#
# Some things never change.
......@@ -746,6 +747,12 @@ sub dorouterconfig ()
my $cost = $5;
my $routearg = inet_ntoa(inet_aton($gate) & inet_aton($dmask));
# NSE hack: staticroutes added routes for the case when dst == hop
# Filtering it on the client side
if ( $dip eq $routearg ) {
next;
}
if (! defined($upmap{$routearg})) {
$upmap{$routearg} = [];
$downmap{$routearg} = [];
......@@ -1386,6 +1393,9 @@ sub dotrafficconfig()
# storing the output of a few tmcc commands in
# $SETUPDIR files for use by NSE
#
# Also nse stuff is mixed up with traffic config right
# now because of having FullTcp based traffic generation.
# Needs to move to a different place
if (! REMOTE()) {
my $record_sep;
......@@ -1397,6 +1407,13 @@ sub dotrafficconfig()
print IFCFG <$TM>;
close(IFCFG);
CLOSETMCC($TM);
$TM = OPENTMCC(TMCCCMD_ROUTELIST);
open(ROUTELIST, ">$SETUPDIR/tmcc.routelist") or
die "Cannot open file $SETUPDIR/tmcc.routelist: $!";
print ROUTELIST <$TM>;
close(ROUTELIST);
CLOSETMCC($TM);
$/ = $record_sep;
open(TRAFCFG, ">$SETUPDIR/tmcc.trafgens") or
......
......@@ -136,6 +136,7 @@ sub TMCCCMD_VNODELIST() { "vnodelist"; }
sub TMCCCMD_ISALIVE() { "isalive"; }
sub TMCCCMD_SFSHOSTID() { "sfshostid"; }
sub TMCCCMD_SFSMOUNTS() { "sfsmounts"; }
sub TMCCCMD_ROUTELIST() { "routelist"; }
#
# Some things never change.
......@@ -746,6 +747,12 @@ sub dorouterconfig ()
my $cost = $5;
my $routearg = inet_ntoa(inet_aton($gate) & inet_aton($dmask));
# NSE hack: staticroutes added routes for the case when dst == hop
# Filtering it on the client side
if ( $dip eq $routearg ) {
next;
}
if (! defined($upmap{$routearg})) {
$upmap{$routearg} = [];
$downmap{$routearg} = [];
......@@ -1386,6 +1393,9 @@ sub dotrafficconfig()
# storing the output of a few tmcc commands in
# $SETUPDIR files for use by NSE
#
# Also nse stuff is mixed up with traffic config right
# now because of having FullTcp based traffic generation.
# Needs to move to a different place
if (! REMOTE()) {
my $record_sep;
......@@ -1397,6 +1407,13 @@ sub dotrafficconfig()
print IFCFG <$TM>;
close(IFCFG);
CLOSETMCC($TM);
$TM = OPENTMCC(TMCCCMD_ROUTELIST);
open(ROUTELIST, ">$SETUPDIR/tmcc.routelist") or
die "Cannot open file $SETUPDIR/tmcc.routelist: $!";
print ROUTELIST <$TM>;
close(ROUTELIST);
CLOSETMCC($TM);
$/ = $record_sep;
open(TRAFCFG, ">$SETUPDIR/tmcc.trafgens") or
......
......@@ -1542,10 +1542,16 @@ COMMAND_PROTOTYPE(dohosts)
* for the canonical host table. Join it with the reserved
* table to get the node_id at the same time (saves a step).
*/
res = mydb_query("select v.vname,v.ips,r.node_id from virt_nodes as v "
"left join reserved as r on "
" v.vname=r.vname and v.pid=r.pid and v.eid=r.eid "
" where v.pid='%s' and v.eid='%s' order by r.node_id",
/*
XXX NSE hack: Using the v2pmap table instead of reserved because
of multiple simulated to one physical node mapping. Currently,
reserved table contains a vname which is generated in the case of
nse
*/
res = mydb_query("select v.vname,v.ips,v2p.node_id from virt_nodes as v "
"left join v2pmap as v2p on "
" v.vname=v2p.vname and v.pid=v2p.pid and v.eid=v2p.eid "
" where v.pid='%s' and v.eid='%s' order by v2p.node_id",
3, pid, eid);
if (!res) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment