1 | #!/usr/bin/perl |
---|
2 | |
---|
3 | use strict; |
---|
4 | use IO::File; |
---|
5 | use IO::Pipe; |
---|
6 | |
---|
7 | my $IFCONFIG = "/sbin/ifconfig"; |
---|
8 | my $ZEBRA= "/usr/lib/quagga/zebra"; |
---|
9 | my $OSPFD= "/usr/lib/quagga/ospfd"; |
---|
10 | |
---|
11 | my $ospffn = "/usr/local/federation/etc/ospfd.conf"; |
---|
12 | my $zebrafn = "/usr/local/federation/etc/zebra.conf"; |
---|
13 | my @live_ones; |
---|
14 | my @bits_in_quad; |
---|
15 | my %ainfo; |
---|
16 | |
---|
17 | sub quad_to_int { |
---|
18 | my($ip) = @_; |
---|
19 | my @q = split(/\./, $ip); |
---|
20 | return ($q[0] << 24) + ($q[1] << 16) + ($q[2] << 8) + $q[3]; |
---|
21 | } |
---|
22 | |
---|
23 | sub int_to_quad { |
---|
24 | my($i) = @_; |
---|
25 | return sprintf("%d.%d.%d.%d", ($i >> 24) & 0xff, ($i>>16) & 0xff, |
---|
26 | ($i >>8) & 0xff, $i & 0xff); |
---|
27 | } |
---|
28 | |
---|
29 | sub nbits { |
---|
30 | my($b) = @_; |
---|
31 | return 0 if $b == 0; |
---|
32 | my $r = 1; |
---|
33 | for (my $i = 1 ; $i < $b; $i++) { |
---|
34 | $r <<= 1; |
---|
35 | $r += 1; |
---|
36 | } |
---|
37 | for (my $i = $b; $i< 32; $i ++) { |
---|
38 | $r <<= 1; |
---|
39 | $r &= 0xfffffffe; |
---|
40 | } |
---|
41 | return $r; |
---|
42 | } |
---|
43 | |
---|
44 | sub netslash { |
---|
45 | my($ip, $slash) = @_; |
---|
46 | return int_to_quad(quad_to_int($ip) & nbits($slash)); |
---|
47 | } |
---|
48 | |
---|
49 | for (my $i =0; $i < 256; $i++) { |
---|
50 | $bits_in_quad[$i] = 0; |
---|
51 | } |
---|
52 | my $m = 0xff; |
---|
53 | for (my $i = 8; $i > 0; $i--) { |
---|
54 | $bits_in_quad[$m] = $i; |
---|
55 | $m <<= 1; |
---|
56 | $m &= 0xfe; |
---|
57 | } |
---|
58 | |
---|
59 | |
---|
60 | if ( !-x $OSPFD) { |
---|
61 | if (-x "/usr/bin/apt-get" ) { |
---|
62 | system("/usr/bin/apt-get", "-y", "update"); |
---|
63 | system("/usr/bin/apt-get", "-y", "install", "quagga"); |
---|
64 | } |
---|
65 | elsif (-x "/usr/bin/yum") { |
---|
66 | system("/usr/bin/yum", "-y", "install", "quagga"); |
---|
67 | } |
---|
68 | } |
---|
69 | |
---|
70 | chomp (my $cif = `/usr/local/etc/emulab/control_interface`); |
---|
71 | chomp (my $hostname = `hostname`); |
---|
72 | $hostname =~ s/\..*//; |
---|
73 | |
---|
74 | my $ifp = new IO::Pipe(); |
---|
75 | $ifp->reader("$IFCONFIG"); |
---|
76 | my $current = undef; |
---|
77 | while (<$ifp>) { |
---|
78 | /^(\S+)/ && do { |
---|
79 | my $ifname = $1; |
---|
80 | if ($ifname ne $cif && $ifname !~ "^lo" ) { |
---|
81 | push(@live_ones, $ifname); |
---|
82 | $current = $ifname; |
---|
83 | } |
---|
84 | else { $current = undef; } |
---|
85 | print "$ifname $current\n"; |
---|
86 | }; |
---|
87 | /inet addr:\s*(\S+)\s*\S*\s*mask:\s*(\S+)/i && do { |
---|
88 | next unless $current; |
---|
89 | print "$current $1 $2\n"; |
---|
90 | my $slash = 0; |
---|
91 | foreach my $quad (split(/\./, $2)) { |
---|
92 | if ($bits_in_quad[$quad] != 0 ) { $slash += $bits_in_quad[$quad];} |
---|
93 | else { last;} |
---|
94 | } |
---|
95 | $ainfo{$current} = [ $1, $slash ]; |
---|
96 | print $current, " ", @{$ainfo{$current}}, "\n"; |
---|
97 | } |
---|
98 | } |
---|
99 | $ifp->close(); |
---|
100 | |
---|
101 | my $f = new IO::File(">$zebrafn") || die "Can't open $zebrafn: $!\n"; |
---|
102 | print $f "hostname $hostname\n"; |
---|
103 | foreach my $i (@live_ones) { |
---|
104 | print $f "interface $i\n"; |
---|
105 | } |
---|
106 | # Allow overriding the default route on federated nodes in DETER |
---|
107 | print $f "ip route 192.168.252.0/22 192.168.1.254"; |
---|
108 | $f->close(); |
---|
109 | my $f = new IO::File(">$ospffn") || die "Can't open $ospffn: $!\n"; |
---|
110 | print $f "hostname $hostname\n"; |
---|
111 | print $f "router ospf\n"; |
---|
112 | foreach my $i (@live_ones) { |
---|
113 | print $f " network "; |
---|
114 | print $f netslash($ainfo{$i}->[0], $ainfo{$i}->[1]),"/",$ainfo{$i}->[1]," area 0.0.0.2\n"; |
---|
115 | } |
---|
116 | $f->close(); |
---|
117 | foreach my $fn ($zebrafn, $ospffn) { |
---|
118 | system("chmod 644 $fn"); |
---|
119 | } |
---|
120 | $f = new IO::File(">/proc/sys/net/ipv4/ip_forward") || |
---|
121 | die "Can't open sys forwarding file:$!\n"; |
---|
122 | print $f "1\n"; |
---|
123 | $f->close(); |
---|
124 | system("$ZEBRA -d -f $zebrafn"); |
---|
125 | system("$OSPFD -d -f $ospffn"); |
---|
126 | |
---|