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

_______________________________________________
pve-devel mailing list
[email protected]
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to