#!/usr/bin/perl use strict; use IO::File; use IO::Pipe; my $IFCONFIG = "/sbin/ifconfig"; my $ZEBRA= "/usr/lib/quagga/zebra"; my $OSPFD= "/usr/lib/quagga/ospfd"; my $ospffn = "/usr/local/federation/etc/ospfd.conf"; my $zebrafn = "/usr/local/federation/etc/zebra.conf"; my @live_ones; my @bits_in_quad; my %ainfo; sub quad_to_int { my($ip) = @_; my @q = split(/\./, $ip); return ($q[0] << 24) + ($q[1] << 16) + ($q[2] << 8) + $q[3]; } sub int_to_quad { my($i) = @_; return sprintf("%d.%d.%d.%d", ($i >> 24) & 0xff, ($i>>16) & 0xff, ($i >>8) & 0xff, $i & 0xff); } sub nbits { my($b) = @_; return 0 if $b == 0; my $r = 1; for (my $i = 1 ; $i < $b; $i++) { $r <<= 1; $r += 1; } for (my $i = $b; $i< 32; $i ++) { $r <<= 1; $r &= 0xfffffffe; } return $r; } sub netslash { my($ip, $slash) = @_; return int_to_quad(quad_to_int($ip) & nbits($slash)); } for (my $i =0; $i < 256; $i++) { $bits_in_quad[$i] = 0; } my $m = 0xff; for (my $i = 8; $i > 0; $i--) { $bits_in_quad[$m] = $i; $m <<= 1; $m &= 0xfe; } if ( !-x $OSPFD) { if (-x "/usr/bin/apt-get" ) { system("/usr/bin/apt-get", "-y", "update"); system("/usr/bin/apt-get", "-y", "install", "quagga"); } elsif (-x "/usr/bin/yum") { system("/usr/bin/yum", "-y", "install", "quagga"); } } chomp (my $cif = `/usr/local/etc/emulab/control_interface`); chomp (my $hostname = `hostname`); $hostname =~ s/\..*//; my $ifp = new IO::Pipe(); $ifp->reader("$IFCONFIG"); my $current = undef; while (<$ifp>) { /^(\S+)/ && do { my $ifname = $1; if ($ifname ne $cif && $ifname !~ "^lo" ) { push(@live_ones, $ifname); $current = $ifname; } else { $current = undef; } print "$ifname $current\n"; }; /inet addr:\s*(\S+)\s*\S*\s*mask:\s*(\S+)/i && do { next unless $current; print "$current $1 $2\n"; my $slash = 0; foreach my $quad (split(/\./, $2)) { if ($bits_in_quad[$quad] != 0 ) { $slash += $bits_in_quad[$quad];} else { last;} } $ainfo{$current} = [ $1, $slash ]; print $current, " ", @{$ainfo{$current}}, "\n"; } } $ifp->close(); my $f = new IO::File(">$zebrafn") || die "Can't open $zebrafn: $!\n"; print $f "hostname $hostname\n"; foreach my $i (@live_ones) { print $f "interface $i\n"; } # Allow overriding the default route on federated nodes in DETER print $f "ip route 192.168.252.0/22 192.168.1.254"; $f->close(); my $f = new IO::File(">$ospffn") || die "Can't open $ospffn: $!\n"; print $f "hostname $hostname\n"; print $f "router ospf\n"; foreach my $i (@live_ones) { print $f " network "; print $f netslash($ainfo{$i}->[0], $ainfo{$i}->[1]),"/",$ainfo{$i}->[1]," area 0.0.0.2\n"; } $f->close(); foreach my $fn ($zebrafn, $ospffn) { system("chmod 644 $fn"); } $f = new IO::File(">/proc/sys/net/ipv4/ip_forward") || die "Can't open sys forwarding file:$!\n"; print $f "1\n"; $f->close(); system("$ZEBRA -d -f $zebrafn"); system("$OSPFD -d -f $ospffn");