All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit a72fd9f8 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Move the ddijkstra from common/libsetup.pm (revision 1.107) into here,

but now it is based on the topomap file (see tbsetup/gentopofile).
When the router type is static-ddijk, and there is a topomap file
present (gettopmap() returns valid) turn the topomap into input to
feed into the ddijkstra program. Take the output and feed that into
the parsing code.

NB: If we change the output of tmcd routing call, we have to change
the output of this program too. This will likely become a problem at
some point.
parent 8fd5c467
......@@ -62,6 +62,7 @@ sub doboot();
sub doshutdown();
sub doreconfig();
sub docleanup();
sub ddijkstra($);
# Parse command line.
if (! getopts($optlist, \%options)) {
......@@ -139,6 +140,15 @@ sub doboot()
return 0;
}
# Special case for distributed route calculation.
if ($type eq "static-ddijk") {
if (ddijkstra(\@routes)) {
close(RC);
fatal("Could not get routes from ddijkstra!");
}
$type = "static";
}
#
# Now convert static route info into OS route commands
# Also check for use of gated/manual and remember it.
......@@ -328,3 +338,156 @@ sub gatedsetup ()
return os_routing_enable_gated(TMGATEDCONFIG);
}
#
# Special case. If the routertype is "static-ddijk" then we run our
# dijkstra program on the linkmap, and use that to feed the code
# below (it outputs exactly the same goo).
#
# XXX: If we change the return from tmcd, the output of dijkstra will
# suddenly be wrong. Yuck, need a better solution.
#
# We have to generate the input file from the topomap.
#
sub ddijkstra ($)
{
my ($rptr) = @_;
my @routes = ();
my $linkmap = "$BOOTDIR/linkmap";
my $topomap;
my ($pid, $eid, $vname) = check_nickname();
if (gettopomap(\$topomap)) {
return -1;
}
# Gather up all the link info from the topomap
my %lans = ();
# The nodes section tells us the name of each node, and all its links.
foreach my $noderef (@{ $topomap->{"nodes"} }) {
my $vname = $noderef->{"vname"};
my $links = $noderef->{"links"};
# Links is a string of "$lan1:$ip1 $lan2:$ip2 ..."
foreach my $link (split(" ", $links)) {
my ($lan,$ip) = split(":", $link);
if (! defined($lans{$lan})) {
$lans{$lan} = {};
$lans{$lan}->{"members"} = {};
}
$lans{$lan}->{"members"}->{"$vname:$ip"} = $ip;
}
}
# The lans section tells us the masks and the costs.
foreach my $lanref (@{ $topomap->{"lans"} }) {
my $vname = $lanref->{"vname"};
my $cost = $lanref->{"cost"};
my $mask = $lanref->{"mask"};
$lans{$vname}->{"cost"} = $cost;
$lans{$vname}->{"mask"} = $mask;
}
#
# Construct input for Jon's dijkstra program.
#
if (! open(MAP, ">$linkmap")) {
warn("*** WARNING: Could not create $linkmap!\n");
@$rptr = ();
return -1;
}
# Count edges, but just once each.
my $edges = 0;
foreach my $lan (keys(%lans)) {
my @members = sort(keys(%{ $lans{$lan}->{"members"} }));
for (my $i = 0; $i < scalar(@members); $i++) {
for (my $j = $i; $j < scalar(@members); $j++) {
my $member1 = $members[$i];
my $member2 = $members[$j];
$edges++
if ($member1 ne $member2);
}
}
}
# Header line for Jon. numnodes numedges
print MAP scalar(@{ $topomap->{"nodes"} }) . " $edges\n";
# And then a list of edges: node1 ip1 node2 ip2 cost
foreach my $lan (keys(%lans)) {
my @members = sort(keys(%{ $lans{$lan}->{"members"} }));
my $cost = $lans{$lan}->{"cost"};
my $mask = $lans{$lan}->{"mask"};
for (my $i = 0; $i < scalar(@members); $i++) {
for (my $j = $i; $j < scalar(@members); $j++) {
my $member1 = $members[$i];
my $member2 = $members[$j];
if ($member1 ne $member2) {
my ($node1,$ip1) = split(":", $member1);
my ($node2,$ip2) = split(":", $member2);
print MAP "$node1 " . $ip1 . " " .
"$node2 " . $ip2 . " $cost\n";
}
}
}
}
close(MAP);
#
# Now run the dijkstra program on the input.
#
if (!open(DIJK, "cat $linkmap | $BINDIR/dijkstra $vname |")) {
warn("*** WARNING: Could not invoke dijkstra on linkmap!\n");
@$rptr = ();
return -1;
}
my $pat = q(ROUTE DEST=([0-9\.]*) DESTTYPE=(\w*) DESTMASK=([0-9\.]*) );
$pat .= q(NEXTHOP=([0-9\.]*) COST=([0-9]*) SRC=([0-9\.]*));
while (<DIJK>) {
if ($_ =~ /ROUTERTYPE=(.+)/) {
next;
}
if ($_ =~ /$pat/) {
my $dip = $1;
my $rtype = $2;
my $dmask = $3;
my $gate = $4;
my $cost = $5;
my $sip = $6;
my $rconfig = {};
$rconfig->{"IPADDR"} = $dip;
$rconfig->{"TYPE"} = $rtype;
$rconfig->{"IPMASK"} = $dmask;
$rconfig->{"GATEWAY"} = $gate;
$rconfig->{"COST"} = $cost;
$rconfig->{"SRCIPADDR"}= $sip;
push(@routes, $rconfig);
}
else {
warn("*** WARNING: Bad route config line: $_\n");
}
}
if (! close(DIJK)) {
if ($?) {
warn("*** WARNING: dijkstra exited with status $?!\n");
}
else {
warn("*** WARNING: Error closing dijkstra pipe: $!\n");
}
@$rptr = ();
return -1;
}
@$rptr = @routes;
return 0;
}
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