Commit b76c72cb authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Checkpoint addition of the virt_bridges table. Make bridges explicit

in the NS file (which is in TCL is derived from the node class). For
example.

set nodea    [$ns node]
set bridge1  [$ns bridge]
set bridge2  [$ns bridge]
set nodec    [$ns node]

set link0 [$ns duplex-link $nodea $bridge1 * 0ms DropTail]
set link1 [$ns duplex-link $nodec $bridge1 * 0ms DropTail]

With changes to the mapper, this allows the mapper to map multiple
bridge nodes to a single physical node, like we do for delay nodes
when there are enough interfaces.

As a convenience to users, now named_setup adds CNAMES for the
additional multiple mapped nodes.
parent 5af4ead9
......@@ -80,6 +80,7 @@ sub Create($$$$)
$self->{'VNODES'} = {};
$self->{'DELAYNODES'} = {};
$self->{'LANNODES'} = {};
$self->{'BRIDGES'} = {};
$self->{'VLANS'} = {};
$self->{'VPATHS'} = {};
$self->{'MEMBEROF'} = {};
......@@ -126,6 +127,7 @@ sub virtexperiment($) { return $_[0]->{'VIRTEXPT'}; }
sub flags($) { return $_[0]->{'FLAGS'}; }
sub vnodes($) { return $_[0]->{'VNODES'}; }
sub delaynodes($) { return $_[0]->{'DELAYNODES'}; }
sub bridges($) { return $_[0]->{'BRIDGES'}; }
sub lannodes($) { return $_[0]->{'LANNODES'}; }
sub vlans($) { return $_[0]->{'VLANS'}; }
sub memberof($) { return $_[0]->{'MEMBEROF'}; }
......@@ -164,6 +166,7 @@ sub virt_nodes($) { return $_[0]->virt_table("virt_nodes"); }
sub virt_lans($) { return $_[0]->virt_table("virt_lans"); }
sub virt_lan_lans($) { return $_[0]->virt_table("virt_lan_lans"); }
sub virt_paths($) { return $_[0]->virt_table("virt_paths"); }
sub virt_bridges($) { return $_[0]->virt_table("virt_bridges"); }
sub virt_desires($) { return $_[0]->virt_table("virt_node_desires"); }
sub virt_startloc($) { return $_[0]->virt_table("virt_node_startloc"); }
sub virt_trafgens($) { return $_[0]->virt_table("virt_trafgens"); }
......@@ -1539,7 +1542,7 @@ sub LoadVirtLans($)
$virtlan->shapedmembers()->{"$vlanmember"} = 0;
$vlanmember->_shaped(0);
$virtlan->_delayed(0);
$vlanmember->_bridged(undef);
$vlanmember->_bridged(0);
#
# XXX - Whenever a delay node is inserted, port speeds are set to
......@@ -1575,29 +1578,62 @@ sub LoadVirtLans($)
}
}
#
# Load up the virt_bridges.
#
foreach my $virt_bridge ($self->virt_bridges()->Rows()) {
my $bridgename = $virt_bridge->vname();
my $bridgevlan = $virt_bridge->vlink();
my $bridgeport = $virt_bridge->vport();
if (!exists($self->vlans()->{$bridgevlan})) {
tberror("virt_bridge: no such vlan $bridgevlan\n");
return -1;
}
if (!exists($self->vnodes()->{$bridgename})) {
tberror("virt_bridge: no such node $bridgename\n");
return -1;
}
my $memberof = $self->memberof()->{"$bridgename:$bridgeport"};
if (!defined($memberof)) {
tberror("virt_bridge: ".
"$bridgename:$bridgeport is not in $bridgevlan\n");
return -1;
}
my $vlan = $self->vlans()->{$bridgevlan};
my $member = $vlan->members()->{"$bridgename:$bridgeport"};
$self->bridges()->{$bridgename} = {}
if (!exists($self->bridges()->{$bridgename}));
# Store the list of members of this bridge. We assume that
# a lan is not in a bridge more then once.
$self->bridges()->{$bridgename}->{"$member"} = $member;
}
#
# Check the bridge requests and set the cross links.
#
foreach my $virtlan (values(%{ $self->vlans() })) {
foreach my $member ($virtlan->memberlist()) {
next
if (!defined($member->bridged_vname()));
my $bridged_vname = $member->bridged_vname();
my $bridged_vnode = $member->bridged_vnode();
my $bridged_vport = $member->bridged_vport();
my $bridged_member =
$self->memberof()->{"$bridged_vnode:$bridged_vport"};
if (!defined($member->bridge_vname()));
if (!defined($bridged_member)) {
tberror("$member is bridged to nonexistent member\n");
my $bridge_vname = $member->bridge_vname();
if (!exists($self->bridges()->{$bridge_vname})) {
tberror("$virtlan: no such bridge $bridge_vname\n");
return -1;
}
if (!$member->virt_node()->_isbridge()) {
tberror("$member is bridged but is not a bridge\n");
return -1;
}
$member->_bridged($bridged_member);
my $bridged_member = $self->bridges()->{$bridge_vname}->{"$member"};
if (!defined($bridged_member)) {
tberror("$member is bridged to nonexistent member\n");
return -1;
}
$member->_bridged(1);
$virtlan->_bridged(1);
$self->printdb("$virtlan bridge: $member to $bridged_member\n");
}
......@@ -1884,6 +1920,9 @@ sub GenVirtNodes($)
($nodeweight) = $query_result->fetchrow_array();
}
}
elsif ($vnode->_isbridge()) {
$type = ($type eq "pc" ? "delay" : "delay-" . $type);
}
$self->createNode($vname, $vnode->_cmurn(),
$type, $nodeweight, $desires, $others, \@interfaces);
......@@ -5065,30 +5104,13 @@ sub InterpLinks($)
#
# Go through and look for bridge nodes.
#
foreach my $virtual (keys(%{ $self->solution_v2p() })) {
my $pnode = $self->pnodes()->{$self->solution_v2p()->{$virtual}};
my $virtnode = $self->vnodes()->{$virtual};
next
if (!$virtnode->_isbridge());
# Links that are connected to this bridge.
my @virtlans = $virtnode->memberlist();
# Find the members that are connected through this bridge.
my @members;
foreach my $virtlan (@virtlans) {
foreach my $member ($virtlan->memberlist()) {
if ($member->virt_node()->vname() eq $virtnode->vname()) {
push(@members, $member);
}
}
}
foreach my $bridgename (keys(%{ $self->bridges() })) {
my @members = values(%{ $self->bridges()->{$bridgename} });
# Can only bridge two links.
my ($member0,$member1) = @members;
$self->AddBridge($member0, $member1);
$self->AddBridge($bridgename, $member0, $member1);
}
#
......@@ -6889,9 +6911,9 @@ sub AddLinkDelay($$$$$$)
#
# Add a bridge. At the moment, bridges are just delay nodes.
#
sub AddBridge($$$)
sub AddBridge($$$$)
{
my ($self, $member0, $member1) = @_;
my ($self, $bridgename, $member0, $member1) = @_;
my $iface0 = $member0->_pport();
my $iface1 = $member1->_pport();
my $pnodename = $member0->_pnode();
......@@ -6913,10 +6935,8 @@ sub AddBridge($$$)
my $eid = $experiment->eid();
my $idx = $experiment->idx();
# The name of the bridge (as for the delay agent) is the name of node.
# Might have to change this if we want to use a pnode for more then
# one bridge.
my $vname = $pnodename;
# The name of the bridge (as for the delay agent).
my $vname = $bridgename;
$self->printdb(" Bridge:$bridgeidx $iface0:$pnodename:$iface1\n");
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -92,6 +92,7 @@ if ((my $locked = TBScriptLock("named", 1)) != TBSCRIPTLOCK_OKAY()) {
exit(0)
if ($locked == TBSCRIPTLOCK_IGNORE);
fatal("Could not get the lock after a long time!\n");
}
#
......@@ -128,6 +129,19 @@ $db_result =
" i.role='" . TBDB_IFACEROLE_GW() . "') ");
process_nodes($db_result);
# Get the v2pmap table since that holds the additional name mappings.
my %p2vmap = ();
$db_result =
DBQueryFatal("select v.vname,v.node_id from reserved as r ".
"left join v2pmap as v on v.node_id=r.node_id and ".
" v.exptidx=r.exptidx and v.vname!=r.vname ".
"where v.vname is not null");
while (my ($vname,$node_id) = $db_result->fetchrow_array()) {
$p2vmap{$node_id} = []
if (!exists($p2vmap{$node_id}));
push(@{ $p2vmap{$node_id} }, $vname);
}
#
# Get the list of currently-reserved nodes so that we can make CNAMEs for them
#
......@@ -160,8 +174,22 @@ while (my ($node_id,$pid,$eid,$vname,$erole) = $db_result->fetchrow_array()) {
($erole eq "ops" || $erole eq "ops+fs")) {
push @{$cnames{$node_id}}, "event-server.$eid.$pid";
}
}
#
# And add additional names in v2pmap, which can happen for delay and
# bridge nodes.
#
if (exists($p2vmap{$node_id})) {
my @extras = @{ $p2vmap{$node_id} };
foreach my $extra (@extras) {
next
if ($extra eq $vname);
push @{$cnames{$node_id}}, "$extra.$eid.$pid";
}
}
}
#
# Make the zone file for routable IP addresses
......
......@@ -302,6 +302,14 @@ LanLink instproc init {s nodes bw d type} {
set lq q[incr new_counter]
Queue lq$lq $self $type $node
set linkq($nodepair) lq$lq
#
# Look for bridge connections, and cross link.
#
if {[$node info class] == "Bridge"} {
$node addbridgelink $self
set bridge_links($nodepair) $node
}
}
}
......@@ -460,35 +468,6 @@ LanLink instproc get_port {node} {
return {}
}
# Set the bridge link field
LanLink instproc bridge {srcport link node dstport} {
$self instvar bridge_links
set nodepair [list $node $srcport]
set bridge_links($nodepair) [list $link $node $dstport]
}
#
# Bridge from a LanLink to another Lanlink via node.
#
LanLink instproc bridge_with {link node} {
set srcvport [$self get_port $node]
set dstvport [$link get_port $node]
if {$srcvport == {}} {
perror "bridge_with: $node is not a member of $self";
return
}
if {$dstvport == {}} {
perror "bridge_with: $node is not a member of $link";
return
}
# Cross link
$self bridge $srcvport $link $node $dstvport
$link bridge $dstvport $self $node $srcvport
$node set_role "bridge"
}
#
# Find the queue object for a node on a link.
#
......@@ -619,10 +598,13 @@ LanLink instproc fill_ips {} {
$lan instvar bridge_links
foreach nodeport [array names bridge_links] {
set linkage $bridge_links($nodeport)
set nextlan [lindex $linkage 0]
if {! [info exists reachable($nextlan)]} {
lappend lanlist $nextlan
set bridge $bridge_links($nodeport)
set nextlanlist [$bridge set bridgelist]
foreach nextlan $nextlanlist {
if {! [info exists reachable($nextlan)]} {
lappend lanlist $nextlan
}
}
}
}
......@@ -670,7 +652,7 @@ LanLink instproc fill_ips {} {
if {$subnet == {}} {
if {$isremote} {
set subnet [$sim get_subnet_remote]
} else
} else {
set subnet [$sim get_subnet $netmask]
}
}
......@@ -1093,17 +1075,10 @@ Link instproc updatedb {DB} {
# Look for a bridge to a nodepair in another link or lan.
#
if { [info exists bridge_links($nodeport)] } {
set dest $bridge_links($nodeport)
set bridge_vname [lindex $dest 0]
set bridge_vnode [lindex $dest 1]
set bridge_vport [lindex $dest 2]
set bridge_vname $bridge_links($nodeport)
lappend fields "bridged_vname"
lappend fields "bridge_vname"
lappend values $bridge_vname
lappend fields "bridged_vnode"
lappend values $bridge_vnode
lappend fields "bridged_vport"
lappend values $bridge_vport
}
lappend fields "vindex"
......@@ -1299,17 +1274,10 @@ Lan instproc updatedb {DB} {
# Look for a bridge to a nodepair in another link or lan.
#
if { [info exists bridge_links($nodeport)] } {
set dest $bridge_links($nodeport)
set bridge_vname [lindex $dest 0]
set bridge_vnode [lindex $dest 1]
set bridge_vport [lindex $dest 2]
set bridge_vname $bridge_links($nodeport)
lappend fields "bridged_vname"
lappend fields "bridge_vname"
lappend values $bridge_vname
lappend fields "bridged_vnode"
lappend values $bridge_vnode
lappend fields "bridged_vport"
lappend values $bridge_vport
}
lappend fields "vindex"
......
......@@ -19,6 +19,7 @@
######################################################################
Class Node -superclass NSObject
Class Bridge -superclass Node
Node instproc init {s} {
$self set sim $s
......@@ -79,6 +80,9 @@ Node instproc init {s} {
$self instvar desirelist
array set desirelist {}
# If this is a bridge, list of the link members that connect to it.
$self set bridgelist {}
# These are just various strings that we pass through to the DB.
$self set cmdline ""
$self set rpms ""
......@@ -116,6 +120,13 @@ Node instproc init {s} {
$self set numeric_id {}
}
Bridge instproc init {s} {
$self next $s
$self instvar role
set role "bridge"
}
# The following procs support renaming (see README)
Node instproc rename {old new} {
$self instvar portlist
......@@ -133,6 +144,8 @@ Node instproc rename {old new} {
Node instproc rename_lanlink {old new} {
$self instvar portlist
$self instvar bridgelist
set newportlist {}
foreach node $portlist {
if {$node == $old} {
......@@ -142,6 +155,16 @@ Node instproc rename_lanlink {old new} {
}
}
set portlist $newportlist
set newbridgelist {}
foreach link $bridgelist {
if {$link == $old} {
lappend newbridgelist $new
} else {
lappend newbridgelist $link
}
}
set bridgelist $newbridgelist
}
# updatedb DB
......@@ -693,9 +716,31 @@ Node instproc set_numeric_id {myid} {
set numeric_id $myid
}
Node instproc set_role {newrole} {
$self instvar role
#
# Add a link to this bridge.
#
Bridge instproc addbridgelink {link} {
$self instvar bridgelist
set role $newrole
lappend bridgelist $link
}
Bridge instproc updatedb {DB} {
$self next $DB
$self instvar bridgelist
$self instvar sim
foreach link $bridgelist {
set port [$self find_port $link]
if {$port == {}} {
perror "Bridge $self is not a member of $link";
return
}
set fields [list "vname" "vlink" "vport"]
set values [list $self $link $port]
$sim spitxml_data "virt_bridges" $fields $values
}
}
# -*- tcl -*-
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -154,6 +154,31 @@ Simulator instproc node {args} {
return $curnode
}
#
# A bridge is really a node.
#
Simulator instproc bridge {args} {
var_import ::GLOBALS::last_class
var_import ::GLOBALS::simulated
$self instvar id_counter
$self instvar node_list
if {($args != {})} {
punsup "Arguments for node: $args"
}
set curnode tbnode-n[incr id_counter]
Bridge $curnode $self
set node_list($curnode) {}
set last_class $curnode
$self instvar new_node_config;
$curnode topography $new_node_config(-topography)
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
......
Supports Markdown
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