From e92206f19635c1a64afd0be16f5cda1a08b184c6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 23 Nov 2010 15:56:42 -0800 Subject: Use sockets to check if IP address is local Much faster to user perl sockets to test if IP address is okay, rather than scanning ip addresses. --- scripts/keepalived/vyatta-keepalived.pl | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/scripts/keepalived/vyatta-keepalived.pl b/scripts/keepalived/vyatta-keepalived.pl index 0ff876dd..981bd5a8 100755 --- a/scripts/keepalived/vyatta-keepalived.pl +++ b/scripts/keepalived/vyatta-keepalived.pl @@ -31,6 +31,7 @@ use Vyatta::Interface; use Vyatta::ConntrackSync; use Vyatta::Misc; use Getopt::Long; +use Socket; use strict; use warnings; @@ -40,19 +41,23 @@ my ( $conf_file, $changes_file ); my %HoA_sync_groups; my $ctsync_script = "/opt/vyatta/sbin/vyatta-vrrp-conntracksync.sh"; + +# To test if IP address is local use the kernel since +# Linux will only allow binding to local addresses +sub is_local_address { + my $addr = shift; + + socket( my $sock, PF_INET, SOCK_STREAM, 0) + or die "socket failed\n"; + + return bind($sock, sockaddr_in(0, inet_aton($addr))); +} + sub validate_source_addr { my ( $ifname, $source_addr ) = @_; - my @ipaddrs; if ( defined $source_addr ) { - my %config_ipaddrs; - my @ipaddrs = Vyatta::Misc::getInterfacesIPadresses('all'); - foreach my $ip (@ipaddrs) { - if ( $ip =~ /^([\d.]+)\/([\d.]+)$/ ) { # strip /mask - $config_ipaddrs{$1} = 1; - } - } - if ( !defined $config_ipaddrs{$source_addr} ) { + unless (is_local_address ( $source_addr )) { vrrp_log("no hello-source"); return "hello-source-address [$source_addr] must be " . "configured on the interface\n"; @@ -63,7 +68,7 @@ sub validate_source_addr { # if the hello-source-address wasn't configured, check that the # interface has an IPv4 address configured on it. my $intf = new Vyatta::Interface($ifname); - @ipaddrs = $intf->address(4); + my @ipaddrs = $intf->address(4); if ( scalar(@ipaddrs) < 1 ) { vrrp_log("no primary or hello-source"); return "must configure either a primary address on [$ifname] or" -- cgit v1.2.3