[pve-devel] [PATCH 2/2] improve arp setup

Dietmar Maurer dietmar at proxmox.com
Tue Aug 27 11:29:18 CEST 2013


Autodetect external network and try to extract infos fro dhcp.
---
 pve-routed |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 76 insertions(+), 7 deletions(-)

diff --git a/pve-routed b/pve-routed
index 183dbd2..3073cad 100755
--- a/pve-routed
+++ b/pve-routed
@@ -3,8 +3,64 @@
 use strict;
 use PVE::QemuServer;
 use PVE::Tools qw(run_command);
+use Net::IP;
 use PVE::Network;
 
+# TODO: move those function to PVE::Network
+
+sub enable_proxyarp {
+    my ($ifname) = @_;
+
+    PVE::Tools::run_command("echo 1 > /proc/sys/net/ipv4/conf/$ifname/proxy_arp");
+}
+
+sub find_external_iface {
+    my ($ip) = @_;
+
+    my $devinfo;
+    my $gateway;
+    my $ipobj = new Net::IP($ip);
+
+    my $parser = sub {
+	my $line = shift;
+
+	if ($line =~ m/^default via (\S+) dev (\S+)/) { # gateway
+	    my ($gw, $dev) = ($1, $2);
+	    next if $gateway; # already found
+	    $gateway = $gw;
+	} elsif ($line =~m/^(\S+) (via (\S+) )?dev (\S+) /) {
+	    my ($subnet, $gw, $dev) = ($1, $3, $4);
+	    return if $devinfo; # already found
+	    return if $dev =~ m/^tap\d+i\d+$/; # skip VM tap devices
+
+	    eval {
+		my $net = new Net::IP($subnet);
+		if ($net->overlaps($ipobj) == $IP_B_IN_A_OVERLAP) {
+		    $devinfo = { 
+			iface => $dev,
+			net => $net,
+		    };
+		    $devinfo->{gateway} = $gw if $gw;
+		}
+	    };
+	    warn $@ if $@;
+	};
+    };
+
+    PVE::Tools::run_command("ip route list", outfunc => $parser);
+
+    if ($gateway && !$devinfo->{gateway}) {
+	eval {
+	    if ($devinfo->{net}->overlaps(Net::IP->new($gateway)) == $IP_B_IN_A_OVERLAP) {
+		$devinfo->{gateway} = $gateway;
+	    }
+	};
+	warn $@ if $@;
+    }
+
+    return $devinfo;
+}
+
 my $iface = shift;
 
 die "no interface specified\n" if !$iface;
@@ -27,17 +83,30 @@ die "unable to parse network config '$netid'\n" if !$net;
 
 die "missing ip address\n" if !$net->{ip};
 
-sub enable_proxyarp {
-    my ($ifname) = @_;
-
-    PVE::Tools::run_command("echo 1 > /proc/sys/net/ipv4/conf/$ifname/proxy_arp");
-}
 
 PVE::Tools::run_command("ifconfig $iface up");
 enable_proxyarp($iface);
 
-my $external_iface = 'vmbr0'; # fixme: autotetect?
-enable_proxyarp($external_iface);
+my $netinfo =  find_external_iface($net->{ip}) ||
+    die "unable to find external interface for '$net->{ip}'\n";
+
+my $external_iface = $netinfo->{iface};
+
+my $network = $netinfo->{net}; # useful for DHCP setup
+my $gateway = $netinfo->{gateway}; # useful for DHCP setup
+
+print "DHCP SETUP FOR CLIENT\n";
+print "Network: " . $netinfo->{net}->print() . "\n";
+print "Address: $net->{ip}\n";
+print "Gateway: $netinfo->{gateway}\n";
+
+# add entry to local ARP cache
+my $cmd = "ip neigh add proxy $net->{ip} dev ${external_iface}";
+PVE::Tools::run_command($cmd);
+
+# Send ARP request to update neighbour ARP caches
+$cmd = "arpsend -c 1 -w 1 -U -i $net->{ip} -e $net->{ip} ${external_iface}";
+PVE::Tools::run_command($cmd);
 
 PVE::Tools::run_command("route add -net $net->{ip} netmask 255.255.255.255 dev $iface");
 
-- 
1.7.10.4




More information about the pve-devel mailing list