Commit 923063cc authored by Robert Ricci's avatar Robert Ricci

Allow the user to give an estimated bandwidth for links and/or LANs.

This is in addition to the normal bandwidth, and the difference is
that the estimated bandwidth is not enforced. It's just fed to assign
for mapping decisions. The idea is to allow for more efficient
packings by doing non-conservative bandwidth allocation.

Not documented yet, because it might change a little after I made it
work properly with asymmetric links.
parent 9a21538b
......@@ -3373,19 +3373,21 @@ sub LoadVirtLans()
$memberof{$member} = $vname;
# Other fields we need below
my $delay = $rowref->{"delay"};
my $bandwidth = $rowref->{"bandwidth"};
my $lossrate = $rowref->{"lossrate"};
my $rdelay = $rowref->{"rdelay"};
my $rbandwidth = $rowref->{"rbandwidth"};
my $rlossrate = $rowref->{"rlossrate"};
my $widearea = $rowref->{"widearea"};
my $isemulated = $rowref->{"emulated"};
my $uselinkdelay = $rowref->{"uselinkdelay"};
my $nobwshaping = $rowref->{"nobwshaping"};
my $useveth = $rowref->{"usevethiface"};
my $trivial_ok = $rowref->{"trivial_ok"};
my $protocol = $rowref->{"protocol"};
my $delay = $rowref->{"delay"};
my $bandwidth = $rowref->{"bandwidth"};
my $est_bandwidth = $rowref->{"est_bandwidth"};
my $lossrate = $rowref->{"lossrate"};
my $rdelay = $rowref->{"rdelay"};
my $rbandwidth = $rowref->{"rbandwidth"};
my $rest_bandwidth = $rowref->{"rest_bandwidth"};
my $rlossrate = $rowref->{"rlossrate"};
my $widearea = $rowref->{"widearea"};
my $isemulated = $rowref->{"emulated"};
my $uselinkdelay = $rowref->{"uselinkdelay"};
my $nobwshaping = $rowref->{"nobwshaping"};
my $useveth = $rowref->{"usevethiface"};
my $trivial_ok = $rowref->{"trivial_ok"};
my $protocol = $rowref->{"protocol"};
# Extend the DB info with this stuff:
#
......@@ -3451,9 +3453,11 @@ sub LoadVirtLans()
$virt_lans{$vname}->{"DELAYINFO"}->{$member} =
[ $delay,
$bandwidth,
$est_bandwidth,
$lossrate,
$rdelay,
$rbandwidth,
$rest_bandwidth,
$rlossrate ];
#
......@@ -3543,7 +3547,35 @@ sub virtlanAP($) {
return $virt_lans{$_[0]}->{"ACCESSPOINT"}
if (defined($virt_lans{$_[0]}->{"ACCESSPOINT"}));
return undef;
};
}
# Return the (bandwidth, rbandwidth) to put into a top file for this link -
# this is _NOT_ the hard limit on bandwidth that the user asked for us to
# set up traffic shaping for.
sub virtlantopbw($$) {
my ($virtlan, $member) = @_;
my $node = (split(":",$member))[0];
my ($delay,$bw,$ebw,$loss,
$rdelay,$rbw,$rebw,$rloss) = virtlandelayinfo($virtlan,$member);
# Return the estimated bw if it was given; otherwise, return the normal
# bandwidth,
my ($return_bw, $return_rbw);
if (defined($ebw)) {
$return_bw = $ebw;
} else {
$return_bw = &getbandwidth($node, $virtlan, $bw);
}
if (defined($rebw)) {
$return_rbw = $rebw;
} else {
$return_rbw = &getbandwidth($node, $virtlan, $rbw);
}
return ($return_bw, $return_rbw);
}
#
# Ditto for virt_vtypes.
......@@ -3740,6 +3772,11 @@ sub CreateTopFile()
my $mustdelay = virtlanmustdelay($lan);
my $nobwshaping = virtlannobwshape($lan);
my $protocol = virtlanprotocol($lan);
#
# Count the types of nodes (simulated, virtual, real, etc.) in this
# LAN
#
foreach $member (@members) {
($node) = (split(":",$member))[0];
if (virtnodeissim($node)) {
......@@ -3771,6 +3808,7 @@ sub CreateTopFile()
$realnodes++;
}
}
if ($virtnodes > 0) {
$trivial_ok = virtlantrivok($lan);
if ($nonvirtnodes == 0 || $nonbsdnodes == 0) {
......@@ -3813,6 +3851,7 @@ sub CreateTopFile()
$virt_lans{$lan}->{"USEVETH"} = 0;
}
}
#
# If all nodes in a lan/link are simulated, the lan/link could certainly
# be hosted on the same physical node. Also, if the lan/link is cut and
......@@ -3826,6 +3865,7 @@ sub CreateTopFile()
$virt_lans{$lan}->{"USEVETH"} = 1;
$virt_lans{$lan}->{"ALLSIM"} = 1;
}
if ($protocol ne "ethernet") {
#
# This arrangement is temporary. For now, if its not a regular
......@@ -3839,24 +3879,33 @@ sub CreateTopFile()
$lannodes{"fakelan/$lan"} = 1;
foreach $member (@members) {
my $plink = "fakelan/$lan/$member";
my ($delay,$bw,$loss,
$rdelay,$rbw,$rloss) = virtlandelayinfo($lan, $member);
my ($delay,$bw,$ebw,$loss,
$rdelay,$rbw,$rebw,$rloss) = virtlandelayinfo($lan,$member);
my ($top_bw, $top_rbw) = virtlantopbw($lan,$member);
my ($node) = (split(":",$member))[0];
my $bandwidth = &getbandwidth($node, $lan, $bw);
print TOPFILE "link $plink $node fakelan/$lan $bandwidth " .
print TOPFILE "link $plink $node fakelan/$lan $top_bw " .
"0 0 $protocol\n";
}
}
elsif ($#members == 1) {
elsif (@members == 2) {
#
# We treat LANs with two members specially - they are just links
#
$expt_stats{"links"} += 1;
($nodeport0,$nodeport1) = @members;
$node0 = (split(":",$nodeport0))[0];
$node1 = (split(":",$nodeport1))[0];
($delay0,$bw0,$loss0,
$rdelay0,$rbw0,$rloss0) = virtlandelayinfo($lan, $nodeport0);
($delay1,$bw1,$loss1,
$rdelay1,$rbw1,$rloss1) = virtlandelayinfo($lan, $nodeport1);
my ($delay0,$bw0,$ebw0,$loss0,
$rdelay0,$rbw0,$rebw0,$rloss0)
= virtlandelayinfo($lan, $nodeport0);
my ($delay1,$bw1,$ebw1,$loss1,
$rdelay1,$rbw1,$rebw1,$rloss1)
= virtlandelayinfo($lan, $nodeport1);
# Here the r's aregoing to be 1->0 and the others 0->1
$delay = $delay0+$rdelay1;
$loss = 1-(1-$loss0)*(1-$rloss1);
......@@ -3864,8 +3913,19 @@ sub CreateTopFile()
$rdelay = $rdelay0+$delay1;
$rloss = 1-(1-$rloss0)*(1-$loss1);
$rbw = &min($rbw0,$bw1);
$bandwidth = &getbandwidth($node0,$lan,&min($bw0,$rbw1));
$rbandwidth = &getbandwidth($node1,$lan,&min($rbw0,$bw1));
$bandwidth = &getbandwidth($node0,$lan,$bw);
$rbandwidth = &getbandwidth($node1,$lan,$rbw);
#
# Get the bandwidth we're supposed to put into the top file, which
# may be different that what we're limiting the link to
#
my ($top_bw0, $top_rbw0) = virtlantopbw($lan,$nodeport0);
my ($top_bw1, $top_rbw1) = virtlantopbw($lan,$nodeport1);
$top_bw = &min($top_bw0,$top_rbw1);
$top_rbw = &min($top_rbw0, $top_bw1);
if (((($delay >= $delaythresh) ||
(!$nobwshaping && (requires_delay($node0, $lan, $bw) ||
requires_delay($node1, $lan, $bw))) ||
......@@ -3883,6 +3943,7 @@ sub CreateTopFile()
# simulated and a real node, we might need to put in delay
# nodes
($realnodes != 0)) {
$expt_stats{"shapedlinks"} += 1;
#
# We use a linkdelay if the link is emulated, globally forced,
......@@ -3893,9 +3954,9 @@ sub CreateTopFile()
if ($emulated ||
$forcelinkdelays || $uselinkdelays || $uselinkdelay) {
my $plink = "linksimple/$lan/$nodeport0,$nodeport1";
print(TOPFILE "link $plink $node0 $node1 ".
max($bw,$rbw) . " 0 0 ethernet " .
max($top_bw,$top_rbw) . " 0 0 ethernet " .
($emulated ? " emulated" : "") .
($trivial_ok ? " trivial_ok\n" : "\n"));
......@@ -3919,16 +3980,17 @@ sub CreateTopFile()
my $delayname = "tbsdelay" . $delayid++;
my $plink = "linksdelaysrc/$lan/$nodeport0,$nodeport1";
$delaylinks{$plink} = [$nodeport0,$delay,$bw,$loss,
$nodeport1,$rdelay,$rbw,$rloss, 0];
$delaylinks{$plink} = [$nodeport0,$delay,$top_bw,$loss,
$nodeport1,$rdelay,$top_rbw,$rloss,
0];
print TOPFILE "node $delayname delay\n";
print TOPFILE
"link linksdelaysrc/$lan/$nodeport0,$nodeport1 ".
"$node0 $delayname $bandwidth 0 0 ethernet\n";
"$node0 $delayname $top_bw 0 0 ethernet\n";
print TOPFILE
"link linksdelaydst/$lan/$nodeport1,$nodeport0 ".
"$node1 $delayname $bandwidth 0 0 ethernet\n";
"$node1 $delayname $top_bw 0 0 ethernet\n";
$delaynodes{$delayname} = $delayname;
......@@ -3948,11 +4010,13 @@ sub CreateTopFile()
my $plink = "linksimple/$lan/$nodeport0,$nodeport1";
print TOPFILE "link $plink $node0 $node1";
if ($emulated) {
print TOPFILE " " . max($bw,$rbw) . " 0 0 ethernet emulated";
print TOPFILE " " . max($top_bw,$top_rbw) .
" 0 0 ethernet emulated";
}
else {
print TOPFILE " $bandwidth 0 0 ethernet";
print TOPFILE " $top_bw 0 0 ethernet";
}
if ($trivial_ok) {
print TOPFILE " trivial_ok";
......@@ -3978,11 +4042,16 @@ sub CreateTopFile()
$expt_stats{"lans"} += 1;
$lannodes{"lan/$lan"} = 1;
foreach $member (@members) {
($delay,$bw,$loss,
$rdelay,$rbw,$rloss) = virtlandelayinfo($lan, $member);
my ($delay,$bw,$ebw,$loss,
$rdelay,$rbw,$rebw,$rloss) = virtlandelayinfo($lan, $member);
($node) = (split(":",$member))[0];
my ($top_bw, $top_rbw) = virtlantopbw($lan,$member);
$bandwidth = &getbandwidth($node,$lan,$bw);
$rbandwidth = &getbandwidth($node,$lan,$rbw);
# XXX The expression below should be modified for
# better bandwidth support. Probably needs to happen
# post assign somehow.
......@@ -4014,9 +4083,9 @@ sub CreateTopFile()
$delaylinks{$plink} =
[$member,$delay,$bw,$loss,
$member,$rdelay,$rbw,$rloss,0];
print(TOPFILE "link $plink $node lan/$lan " .
max($bw,$rbw) . " 0 0 ethernet" .
max($top_bw,$top_rbw) . " 0 0 ethernet" .
($emulated ? " emulated" : "") .
($trivial_ok ? " trivial_ok\n" : "\n"));
......@@ -4033,9 +4102,9 @@ sub CreateTopFile()
print TOPFILE "node $delayname delay\n";
print TOPFILE "link linkdelaysrc/$lan/$member" .
" $node $delayname $bandwidth 0 0 ethernet\n";
" $node $delayname $top_bw 0 0 ethernet\n";
print TOPFILE "link linkdelaydst/$lan/$member" .
" lan/$lan $delayname $bandwidth 0 0 ethernet\n";
" lan/$lan $delayname $top_bw 0 0 ethernet\n";
$delaynodes{$delayname} = $delayname;
......@@ -4052,8 +4121,8 @@ sub CreateTopFile()
}
else {
my $plink = "linklan/$lan/$member";
print TOPFILE "link $plink $node lan/$lan $bandwidth " .
print TOPFILE "link $plink $node lan/$lan $top_bw " .
"0 0 ethernet";
if ($emulated) {
print TOPFILE " emulated";
......
......@@ -218,6 +218,8 @@ LanLink instproc init {s nodes bw d type} {
# r* indicates the switch->node chars, others are node->switch
$self instvar bandwidth
$self instvar rbandwidth
$self instvar ebandwidth
$self instvar rebandwidth
$self instvar delay
$self instvar rdelay
$self instvar loss
......@@ -229,6 +231,9 @@ LanLink instproc init {s nodes bw d type} {
set nodepair [list $node [$node add_lanlink $self]]
set bandwidth($nodepair) $bw
set rbandwidth($nodepair) $bw
# Note - we don't set defaults for ebandwidth and rebandwidth - lack
# of an entry for a nodepair indicates that they should be left NULL
# in the output.
set delay($nodepair) [expr $d / 2.0]
set rdelay($nodepair) [expr $d / 2.0]
set loss($nodepair) 0
......@@ -487,6 +492,8 @@ Link instproc updatedb {DB} {
var_import ::GLOBALS::eid
$self instvar bandwidth
$self instvar rbandwidth
$self instvar ebandwidth
$self instvar rebandwidth
$self instvar delay
$self instvar rdelay
$self instvar loss
......@@ -550,9 +557,28 @@ Link instproc updatedb {DB} {
set nodeportraw [join $nodeport ":"]
set fields [list "vname" "member" "mask" "delay" "rdelay" "bandwidth" "rbandwidth" "lossrate" "rlossrate" "cost" "widearea" "emulated" "uselinkdelay" "nobwshaping" "usevethiface" "q_limit" "q_maxthresh" "q_minthresh" "q_weight" "q_linterm" "q_qinbytes" "q_bytes" "q_meanpsize" "q_wait" "q_setbit" "q_droptail" "q_red" "q_gentle" "trivial_ok"]
# Treat estimated bandwidths differently - leave them out of the lists
# unless the user gave a value - this way, they get the defaults if not
# specified
if { [info exists ebandwidth($nodeport)] } {
lappend fields "est_bandwidth"
}
if { [info exists rebandwidth($nodeport)] } {
lappend fields "rest_bandwidth"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $useveth $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok]
if { [info exists ebandwidth($nodeport)] } {
lappend values $ebandwidth($nodeport)
}
if { [info exists rebandwidth($nodeport)] } {
lappend values $rebandwidth($nodeport)
}
$sim spitxml_data "virt_lans" $fields $values
}
}
......@@ -565,6 +591,8 @@ Lan instproc updatedb {DB} {
var_import ::GLOBALS::eid
$self instvar bandwidth
$self instvar rbandwidth
$self instvar ebandwidth
$self instvar rebandwidth
$self instvar delay
$self instvar rdelay
$self instvar loss
......@@ -638,9 +666,28 @@ Lan instproc updatedb {DB} {
}
set fields [list "vname" "member" "mask" "delay" "rdelay" "bandwidth" "rbandwidth" "lossrate" "rlossrate" "cost" "widearea" "emulated" "uselinkdelay" "nobwshaping" "usevethiface" "q_limit" "q_maxthresh" "q_minthresh" "q_weight" "q_linterm" "q_qinbytes" "q_bytes" "q_meanpsize" "q_wait" "q_setbit" "q_droptail" "q_red" "q_gentle" "trivial_ok" "protocol" "is_accesspoint"]
# Treat estimated bandwidths differently - leave them out of the lists
# unless the user gave a value - this way, they get the defaults if not
# specified
if { [info exists ebandwidth($nodeport)] } {
lappend fields "est_bandwidth"
}
if { [info exists rebandwidth($nodeport)] } {
lappend fields "rest_bandwidth"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $useveth $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $protocol $is_accesspoint]
if { [info exists ebandwidth($nodeport)] } {
lappend values $ebandwidth($nodeport)
}
if { [info exists rebandwidth($nodeport)] } {
lappend values $rebandwidth($nodeport)
}
$sim spitxml_data "virt_lans" $fields $values
foreach setting_key [array names member_settings] {
......
......@@ -284,6 +284,32 @@ proc tb-set-link-loss {srclink args} {
}
}
# This takes two possible formats:
# tb-set-link-est-bandwidth <link> <loss>
# tb-set-link-est-bandwidth <src> <dst> <loss>
proc tb-set-link-est-bandwidth {srclink args} {
if {[llength $args] == 2} {
set dst [lindex $args 0]
set bw [lindex $args 1]
set sim [$srclink set sim]
set reallink [$sim find_link $srclink $dst]
if {$reallink == {}} {
perror "\[tb-set-link-est-bandwidth] No link between $srclink and $dst."
return
}
} else {
set reallink $srclink
set bw [lindex $args 0]
}
$reallink instvar bandwidth
$reallink instvar ebandwidth
$reallink instvar rebandwidth
foreach pair [array names bandwidth] {
set ebandwidth($pair) [parse_bw $bw]
set rebandwidth($pair) [parse_bw $bw]
}
}
proc tb-set-lan-loss {lan lossrate} {
var_import ::TBCOMPAT::FLOAT
if {[$lan info class] != "Lan"} {
......@@ -303,6 +329,21 @@ proc tb-set-lan-loss {lan lossrate} {
}
}
proc tb-set-lan-est-bandwidth {lan bw} {
if {[$lan info class] != "Lan"} {
perror "\[tb-set-lan-est-bandwidth] $lan is not a lan."
return
}
$lan instvar bandwidth
$lan instvar ebandwidth
$lan instvar rebandwidth
foreach pair [array names bandwidth] {
set ebandwidth($pair) [parse_bw $bw]
set rebandwidth($pair) [parse_bw $bw]
}
}
proc tb-set-node-lan-delay {node lan delay} {
if {[$node info class] != "Node"} {
perror "\[tb-set-node-lan-delay] $node is not a node."
......@@ -320,23 +361,42 @@ proc tb-set-node-lan-delay {node lan delay} {
$lan set delay([list $node $port]) [parse_delay $delay]
$lan set rdelay([list $node $port]) [parse_delay $delay]
}
proc tb-set-node-lan-bandwidth {node lan bw} {
if {[$node info class] != "Node"} {
perror "\[tb-set-node-lan-delay] $node is not a node."
perror "\[tb-set-node-lan-bandwidth] $node is not a node."
return
}
if {[$lan info class] != "Lan"} {
perror "\[tb-set-node-lan-delay] $lan is not a lan."
perror "\[tb-set-node-lan-bandwidth] $lan is not a lan."
return
}
set port [$lan get_port $node]
if {$port == {}} {
perror "\[tb-set-node-lan-delay] $node is not in $lan."
perror "\[tb-set-node-lan-bandwidth] $node is not in $lan."
return
}
$lan set bandwidth([list $node $port]) [parse_bw $bw]
$lan set rbandwidth([list $node $port]) [parse_bw $bw]
}
proc tb-set-node-lan-est-bandwidth {node lan bw} {
if {[$node info class] != "Node"} {
perror "\[tb-set-node-lan-est-bandwidth] $node is not a node."
return
}
if {[$lan info class] != "Lan"} {
perror "\[tb-set-node-lan-est-bandwidth] $lan is not a lan."
return
}
set port [$lan get_port $node]
if {$port == {}} {
perror "\[tb-set-node-lan-est-bandwidth] $node is not in $lan."
return
}
$lan set ebandwidth([list $node $port]) [parse_bw $bw]
$lan set rebandwidth([list $node $port]) [parse_bw $bw]
}
proc tb-set-node-lan-loss {node lan loss} {
var_import ::TBCOMPAT::FLOAT
if {[$node info class] != "Node"} {
......
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