[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