aboutsummaryrefslogtreecommitdiff
path: root/dgd
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2015-05-23 15:27:03 +0300
committerSergey Poznyakoff <gray@gnu.org>2015-05-23 15:27:03 +0300
commitffe7c151508b63fbe7f345df684305ece27c473a (patch)
tree3588f0f2f07a44a7258e48f0171580bdb160817e /dgd
parent1866566b9abb7ee4d3cd4f04fe9a88959db8fc4e (diff)
downloaddnstools-ffe7c151508b63fbe7f345df684305ece27c473a.tar.gz
dnstools-ffe7c151508b63fbe7f345df684305ece27c473a.tar.bz2
dgd: various improvements.
* dgd/dgd (get_default_gw): Rename to get_default_iface. Compare gateway interface name, instead of the gw address. All uses changed. (scan_links): Add missing conditional. Never exit on 'no active link configured'. (updown): If $name argument is a hash reference, read link parameters from it and pass it to the script in the command line. (serialize_link, cmplinks): New functions. (SIGHUP handler): Save away active link before reconfiguring. Call 'down', if it was removed.
Diffstat (limited to 'dgd')
-rwxr-xr-xdgd/dgd84
1 files changed, 60 insertions, 24 deletions
diff --git a/dgd/dgd b/dgd/dgd
index 1aeac04..dba3bb1 100755
--- a/dgd/dgd
+++ b/dgd/dgd
@@ -324,18 +324,20 @@ sub readconfig {
return $err;
}
-sub get_default_gw {
- my $gw;
+sub get_default_iface {
+ my $ret;
open(my $fd, '-|', "netstat -rn")
or abend(EX_OSFILE, "can't start netstat: $!");
while (<$fd>) {
- if (/^0\.0\.0\.0\s+(\S+)/) {
- $gw = $1;
+ chomp;
+ my ($dest,$gw,undef,undef,undef,undef,undef,$iface) = split /\s+/;
+ if ($dest eq "0.0.0.0") {
+ $ret = $iface;
last;
}
}
close $fd;
- return $gw;
+ return $ret;
}
sub scan_links {
@@ -356,24 +358,28 @@ sub scan_links {
for ($active_link = 0; $active_link <= $#links; ++$active_link) {
last if $links[$active_link]->{name} eq $config{core}{active};
}
- error("no link corresponding to the active one");
- $active_link = undef;
- delete $config{core}{active};
+ if ($active_link > $#links) {
+ error("no link corresponding to the active one");
+ $active_link = undef;
+ delete $config{core}{active};
+ }
}
unless (defined($active_link)) {
- my $gw = get_default_gw();
- if (defined($gw)) {
- debug(1, "default gw $gw");
+ my $iface = get_default_iface();
+ if (defined($iface)) {
+ debug(1, "default gw via $iface");
for ($active_link = 0; $active_link <= $#links; ++$active_link) {
- last if $links[$active_link]->{gw} eq $gw;
+ last if $links[$active_link]->{if} eq $iface;
}
- abend(EX_CONFIG, "no active link configured")
- if ($active_link > $#links);
-
- debug(1, "active link $links[$active_link]->{name}");
+ if ($active_link > $#links) {
+ debug(1, "no active link configured");
+ $active_link = undef;
+ } else {
+ debug(1, "active link $links[$active_link]->{name}");
+ }
} else {
debug(1, "no active link configured");
$active_link = undef;
@@ -403,12 +409,13 @@ sub runcmd {
sub updown {
my ($what, $name) = @_;
-
- my $cmd = defined($config{link}{$name}{$what})
- ? $config{link}{$name}{$what}
- : $config{core}{$what};
+ my $link = (ref($name) eq 'HASH') ? $name : $config{link}{$name};
+ my $cmd = defined($link->{$what}) ? $link->{$what} : $config{core}{$what};
if (defined($cmd)) {
- runcmd("$cmd $name");
+ $cmd .= " '$link->{name}'";
+ $cmd .= " '$link->{if}' '$link->{ip}' '$link->{gw}' '$link->{ns}' '$link->{net}'"
+ if (ref($name) eq 'HASH');
+ runcmd($cmd);
} elsif ($what eq 'up') {
runcmd("route add default gw $config{link}{gw}");
} elsif ($what eq 'down') {
@@ -429,7 +436,7 @@ sub check_links {
foreach $link (@links) {
$link->{alive} = 0;
}
- debug(1, "checking links");
+ debug(1, "checking links ".($#links+1).", probes $config{core}{probes}");
my $p = Net::Ping->new("icmp", $config{core}{timeout});
for (my $i = 0; $i < $config{core}{probes}; $i++) {
foreach $link (@links) {
@@ -467,6 +474,23 @@ sub newlink {
error("no fallback link");
}
+sub serialize_link {
+ my $link = shift;
+
+ my $s;
+ foreach my $k (sort keys %{$link}) {
+ next if ($k eq 'alive');
+ $s .= ';' if defined $s;
+ $s .= "$k=$link->{$k}";
+ }
+ return $s;
+}
+
+sub cmplinks {
+ my ($aref, $bref) = @_;
+ return serialize_link($aref) eq serialize_link($bref);
+}
+
# ########
my $foreground;
@@ -528,12 +552,24 @@ unless ($foreground) {
}
$SIG{HUP} = sub {
+ my %save_link = %{$links[$active_link]} if defined $active_link;
my %t = %defconfig;
diag('info', "re-reading configuration file");
if (readconfig($conffile, \%t) == 0) {
%config = %t;
@links = ();
scan_links;
+ if (keys(%save_link)) {
+ my $i;
+ for ($i = 0; $i <= $#links; ++$i) {
+ last if cmplinks(\%save_link, $links[$i]);
+ }
+ if ($i > $#links) {
+ debug(1, "active link $save_link{name} was removed");
+ updown('down', \%save_link);
+ $active_link = undef;
+ }
+ }
}
};
@@ -673,8 +709,8 @@ marked as I<alive>. Default is 2
=item B<active => I<STRING>
-Name of the active link. If not defined, the link whose B<gw> variable
-matches the default gateway address is assumed active.
+Name of the active link. If not defined, the link whose B<if> variable
+matches the interface name of the default gateway is assumed active.
=item B<logpriority => B<0>|B<1>

Return to:

Send suggestions and report system problems to the System administrator.