Commit cd473380 authored by Shashi Guruprasad's avatar Shashi Guruprasad

> > >An optimization that would be nice, and perhaps this was intended to do this,

> > >is to collapse stuff like:
> > >
> > >         192.168.3          192.168.2.2        UGSc        0       12  veth6
> > >         192.168.3.2        192.168.2.2        UGHS        0        9  veth6
> > >         192.168.3.4        192.168.2.2        UGHS        0       12  veth6
> > >
> > >into the single net route.

Found the problem. My code took care of the case where the net route was
calculated first and if a host route came up for the same subnet with the
same hop, it would skip adding the host route. However, if the host route
were added first before the net route, it was a problem. To illustrate the
problem, the host route to 3.2 is added on FG1 when the net route was
calculated for node 'A' at 7.0 . At this point however, the net route for
3.0 hasn't been defined yet coz that'll come later in the route to dst
'AS1'. Experiment testbed/vroutetest.

The solution is to consider adding host routes only after all net routes
have been added to the DB. Changes to the code weren't trivial this time.
Also, when adding host routes, I add the first one as a net route. If
subsequent host routes have the same hop, they'll get skipped. Otherwise,
a host route with a longer prefix will take precedence. With all these
changes, the number of routes in testbed/vroutetest experiment came down
from 361 (> NxN) to 162 (< NxN) where NxN is 289 . Mike, let me know if
things are alright after rebooting vnodes in your experiment.
parent 93971eef
......@@ -297,7 +297,7 @@ my %netroutes = ();
# Host route ips for interfaces of a dst node besides the nearest one
# This is indexed by a node (i.e. a "src:dst" node) and is a list of dst ips
# The hop info is obtained from the shortest path route
my %hostrouteips = ();
my %hostroutes = ();
foreach my $result (@results) {
my ($src, $dst, $hop);
......@@ -340,6 +340,7 @@ foreach my $route (keys(%routes)) {
my $hop = $routes{$route};
my $type = 'host';
my $directlyconn = 0;
my $netroutedefined = 0;
# remember the port for which we have dstip
my $dstport;
......@@ -444,16 +445,32 @@ foreach my $route (keys(%routes)) {
die("*** $0:\n".
" network route mismatch: $src:$dst:$hop!\n");
}
goto HOSTROUTES;
$netroutedefined = 1;
} else {
$netroutes{"$src:$newip"} = $hop;
$type = "net";
$dstip = $newip;
}
$netroutes{"$src:$newip"} = $hop;
$type = "net";
$dstip = $newip;
}
HOSTROUTES:
#
# Scan srcmembers to find the IPs for the src and hop.
#
foreach my $member (@srcmembers) {
my ($node,$port) = split(":", $member);
if ($node eq $src) {
$srcip = $ips{$member};
next;
}
if ($node eq $hop) {
$hopip = $ips{$member};
next;
}
}
# Construct host routes for the other interfaces of dst
foreach my $port (@{$nodeportlist{$dst}}) {
......@@ -470,103 +487,120 @@ HOSTROUTES:
if ( defined($netroutes{"$src:$newipsubnet"}) &&
$netroutes{"$src:$newipsubnet"} eq $hop ) {
next;
} else {
if (! defined($hostrouteips{"$src:$dst"}) ) {
$hostrouteips{"$src:$dst"} = [];
}
push( @{$hostrouteips{"$src:$dst"}}, $newip );
} else {
$hostroutes{"$src:$srcip-$dst:$newip"} = "$hop:$hopip";
}
}
#
# Scan srcmembers to find the IPs for the src and hop.
#
foreach my $member (@srcmembers) {
my ($node,$port) = split(":", $member);
if ($node eq $src) {
$srcip = $ips{$member};
next;
}
if ($node eq $hop) {
$hopip = $ips{$member};
next;
}
# We had to run till here to store hostroutes
# that may have to be added later. However,
# we can skip for directly connected neighbors
# or if net route was already defined
if ($directlyconn || $netroutedefined) {
next;
}
if ($impotent) {
if ($debug) {
if ( ! $directlyconn ) {
printf(STDERR "%s: %-23s --> %-23s - %s\n",
($type eq "net" ? "n" : "h"),
"$src:$srcip", "$dst:$dstip", "$hop:$hopip");
}
foreach my $ip (@{$hostrouteips{"$src:$dst"}}) {
printf(STDERR "%s: %-23s --> %-23s - %s\n",
"h",
"$src:$srcip", "$dst:$ip", "$hop:$hopip");
}
printf(STDERR "%s: %-23s --> %-23s - %s\n",
($type eq "net" ? "n" : "h"),
"$src:$srcip", "$dst:$dstip", "$hop:$hopip");
}
if ($format eq "ns") {
if ( ! $directlyconn ) {
print "\$${src} add-route ";
if ($type eq "host" && $linkcount{$dst} == 1) {
print "\$${dst} \$${hop}\n";
}
else {
print "\$${dstlan} \$${hop}\n";
}
print "\$${src} add-route ";
if ($type eq "host" && $linkcount{$dst} == 1) {
print "\$${dst} \$${hop}\n";
}
else {
print "\$${dstlan} \$${hop}\n";
}
# No need to print the host routes in the 'ns' case
# since we already have printed a route for $dst
}
elsif ($format eq "bsd") {
if ( ! $directlyconn ) {
if ($type eq "host") {
print "route add -host $dstip $hopip\n";
}
else {
print "route add -net $dstip $hopip $NETMASK\n";
}
if ($type eq "host") {
print "route add -host $dstip $hopip\n";
}
foreach my $ip (@{$hostrouteips{"$src:$dst"}}) {
print"route add -host $ip $hopip\n";
else {
print "route add -net $dstip $hopip $NETMASK\n";
}
}
elsif ($format eq "suxs") {
if ( ! $directlyconn ) {
if ($type eq "host") {
if ($type eq "host") {
print "route add -host $dstip gw $hopip\n";
}
else {
print "route add -net $dstip netmask $NETMASK gw $hopip\n";
}
}
foreach my $ip (@{$hostrouteips{"$src:$dst"}}) {
print"route add -host $ip gw $hopip\n";
else {
print "route add -net $dstip netmask $NETMASK gw $hopip\n";
}
}
}
else {
if ( ! $directlyconn ) {
DBQueryFatal("insert into virt_routes ".
" (pid,eid,vname,src,dst,nexthop,dst_type) ".
" values ('$pid', '$eid', '$src', '$srcip', '$dstip', ".
" '$hopip', '$type')");
DBQueryFatal("insert into virt_routes ".
" (pid,eid,vname,src,dst,nexthop,dst_type) ".
" values ('$pid', '$eid', '$src', '$srcip', '$dstip', ".
" '$hopip', '$type')");
}
}
# This part adds host routes for subnets that don't have a route.
# However, the first route will be added as a net route
# and if subsequent host routes are different from the first
# route we added, only then will the host routes get added.
foreach my $hostroute (keys(%hostroutes)) {
my ($srcinfo,$dstinfo) = split("-", $hostroute);
my ($src,$srcip) = split(":", $srcinfo);
my ($dst,$dstip) = split(":", $dstinfo);
my ($hop,$hopip) = split(":", $hostroutes{$hostroute});
my $type = 'host';
my $dstipsubnet = inet_ntoa(inet_aton($dstip) & inet_aton($NETMASK));
# If we already have a net route to dstipsubnet via the same hop,
# we don't need the host route
if ( defined($netroutes{"$src:$dstipsubnet"}) ) {
if ($netroutes{"$src:$dstipsubnet"} eq $hop ) {
next;
}
foreach my $ip (@{$hostrouteips{"$src:$dst"}}) {
DBQueryFatal("insert into virt_routes ".
" (pid,eid,vname,src,dst,nexthop,dst_type) ".
" values ('$pid', '$eid', '$src', '$srcip', '$ip', ".
" '$hopip', 'host')");
} else {
if ($optimize) {
$netroutes{"$src:$dstipsubnet"} = $hop;
$type = "net";
$dstip = $dstipsubnet;
}
}
if ($impotent) {
if ($debug) {
printf(STDERR "%s: %-23s --> %-23s - %s\n",
($type eq "net" ? "n" : "h"),
"$src:$srcip", "$dst:$dstip", "$hop:$hopip");
}
# No need to print the host routes in the 'ns' case
# since we already have printed a route for $dst
if ($format eq "bsd") {
if ($type eq "host") {
print "route add -host $dstip $hopip\n";
}
else {
print "route add -net $dstip $hopip $NETMASK\n";
}
}
elsif ($format eq "suxs") {
if ($type eq "host") {
print "route add -host $dstip gw $hopip\n";
}
else {
print "route add -net $dstip netmask $NETMASK gw $hopip\n";
}
}
}
else {
DBQueryFatal("insert into virt_routes ".
" (pid,eid,vname,src,dst,nexthop,dst_type) ".
" values ('$pid', '$eid', '$src', '$srcip', '$dstip', ".
" '$hopip', '$type')");
}
}
exit 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