---
 src/PVE/LXC/Setup/Debian.pm                        | 74 +++++++++++++++++++++-
 src/test/test-debian-012/config                    |  2 +
 src/test/test-debian-012/etc/debian_version        |  1 +
 src/test/test-debian-012/etc/network/interfaces    |  2 +
 .../test-debian-012/etc/network/interfaces.exp     | 21 ++++++
 5 files changed, 98 insertions(+), 2 deletions(-)
 create mode 100644 src/test/test-debian-012/config
 create mode 100644 src/test/test-debian-012/etc/debian_version
 create mode 100644 src/test/test-debian-012/etc/network/interfaces
 create mode 100644 src/test/test-debian-012/etc/network/interfaces.exp

diff --git a/src/PVE/LXC/Setup/Debian.pm b/src/PVE/LXC/Setup/Debian.pm
index 4b423cc..2db8066 100644
--- a/src/PVE/LXC/Setup/Debian.pm
+++ b/src/PVE/LXC/Setup/Debian.pm
@@ -5,6 +5,7 @@ use warnings;
 use Data::Dumper;
 use PVE::Tools qw($IPV6RE);
 use PVE::LXC;
+use PVE::Network;
 use File::Path;
 
 use PVE::LXC::Setup::Base;
@@ -67,6 +68,49 @@ sub setup_init {
     $self->ct_file_set_contents($filename, $inittab);
 }
 
+sub remove_gateway_scripts {
+    my ($attr) = @_;
+    my $length = scalar(@$attr);
+    for (my $i = 0; $i < $length; ++$i) {
+       my $a = $attr->[$i];
+       if ($a =~ m@^\s*post-up\s+.*route.*add.*default.*(?:gw|via)\s+(\S+)@) {
+           my $gw = $1;
+           if ($i > 0 && $attr->[$i-1] =~ 
m@^\s*post-up\s+.*route.*add.*\Q$1\E@) {
+               --$i;
+               splice @$attr, $i, 2;
+               $length -= 2;
+           } else {
+               splice @$attr, $i, 1;
+               $length -= 1;
+           }
+           --$i;
+           next;
+       }
+       if ($a =~ m@^\s*pre-down\s+.*route.*del.*default.*(?:gw|via)\s+(\S+)@) {
+           my $gw = $1;
+           if ($attr->[$i+1] =~ m@^\s*pre-down\s+.*route.*del.*\Q$1\E@) {
+               splice @$attr, $i, 2;
+               $length -= 2;
+           } else {
+               splice @$attr, $i, 1;
+               $length -= 1;
+           }
+           --$i;
+           next;
+       }
+    }
+}
+
+sub make_gateway_scripts {
+    my ($ifname, $gw) = @_;
+    return <<"SCRIPTS";
+\tpost-up ip route add $gw dev $ifname
+\tpost-up ip route add default via $gw
+\tpre-down ip route del default via $gw
+\tpre-down ip route del $gw dev $ifname
+SCRIPTS
+}
+
 sub setup_network {
     my ($self, $conf) = @_;
 
@@ -77,6 +121,7 @@ sub setup_network {
        my $d = PVE::LXC::parse_lxc_network($conf->{$k});
        if ($d->{name}) {
            my $net = {};
+           my $cidr;
            if (defined($d->{ip})) {
                if ($d->{ip} =~ /^(?:dhcp|manual)$/) {
                    $net->{address} = $d->{ip};
@@ -84,11 +129,17 @@ sub setup_network {
                    my $ipinfo = PVE::LXC::parse_ipv4_cidr($d->{ip});
                    $net->{address} = $ipinfo->{address};
                    $net->{netmask} = $ipinfo->{netmask};
+                   $cidr = $d->{ip};
                }
            }
            if (defined($d->{'gw'})) {
                $net->{gateway} = $d->{'gw'};
+               if (defined($cidr) && !PVE::Network::is_ip_in_cidr($d->{gw}, 
$cidr, 4)) {
+                   # gateway is not reachable, need an extra route
+                   $net->{needsroute} = 1;
+               }
            }
+           $cidr = undef;
            if (defined($d->{ip6})) {
                if ($d->{ip6} =~ /^(?:auto|dhcp|manual)$/) {
                    $net->{address6} = $d->{ip6};
@@ -97,10 +148,15 @@ sub setup_network {
                } else {
                    $net->{address6} = $1;
                    $net->{netmask6} = $2;
+                   $cidr = $d->{ip6};
                }
            }
            if (defined($d->{'gw6'})) {
                $net->{gateway6} = $d->{'gw6'};
+               if (defined($cidr) && !PVE::Network::is_ip_in_cidr($d->{gw6}, 
$cidr, 6)) {
+                   # gateway is not reachable, need an extra route
+                   $net->{needsroute6} = 1;
+               }
            }
            $networks->{$d->{name}} = $net if keys %$net;
        }
@@ -137,7 +193,14 @@ sub setup_network {
                $interfaces .= "iface $ifname inet static\n";
                $interfaces .= "\taddress $net->{address}\n" if 
defined($net->{address});
                $interfaces .= "\tnetmask $net->{netmask}\n" if 
defined($net->{netmask});
-               $interfaces .= "\tgateway $net->{gateway}\n" if 
defined($net->{gateway});
+               if (defined(my $gw = $net->{gateway})) {
+                   remove_gateway_scripts($section->{attr});
+                   if ($net->{needsroute}) {
+                       $interfaces .= make_gateway_scripts($ifname, $gw);
+                   } else {
+                       $interfaces .= "\tgateway $gw\n";
+                   }
+               }
                foreach my $attr (@{$section->{attr}}) {
                    $interfaces .= "\t$attr\n";
                }
@@ -154,7 +217,14 @@ sub setup_network {
                $interfaces .= "iface $ifname inet6 static\n";
                $interfaces .= "\taddress $net->{address6}\n" if 
defined($net->{address6});
                $interfaces .= "\tnetmask $net->{netmask6}\n" if 
defined($net->{netmask6});
-               $interfaces .= "\tgateway $net->{gateway6}\n" if 
defined($net->{gateway6});
+               if (defined(my $gw = $net->{gateway6})) {
+                   remove_gateway_scripts($section->{attr});
+                   if ($net->{needsroute6}) {
+                       $interfaces .= make_gateway_scripts($ifname, $gw);
+                   } else {
+                       $interfaces .= "\tgateway $net->{gateway6}\n" if 
defined($net->{gateway6});
+                   }
+               }
                foreach my $attr (@{$section->{attr}}) {
                    $interfaces .= "\t$attr\n";
                }
diff --git a/src/test/test-debian-012/config b/src/test/test-debian-012/config
new file mode 100644
index 0000000..1aeb8c8
--- /dev/null
+++ b/src/test/test-debian-012/config
@@ -0,0 +1,2 @@
+net0: 
name=eth0,hwaddr=11:22:33:44:55:66,bridge=vmbr0,ip=10.0.0.100/32,gw=11.0.0.1
+net1: 
name=eth1,hwaddr=22:33:44:55:66:77,bridge=vmbr0,ip6=fc00::1/64,gw6=fc00:1::ff
diff --git a/src/test/test-debian-012/etc/debian_version 
b/src/test/test-debian-012/etc/debian_version
new file mode 100644
index 0000000..cc40bca
--- /dev/null
+++ b/src/test/test-debian-012/etc/debian_version
@@ -0,0 +1 @@
+8.0
diff --git a/src/test/test-debian-012/etc/network/interfaces 
b/src/test/test-debian-012/etc/network/interfaces
new file mode 100644
index 0000000..f1bd92e
--- /dev/null
+++ b/src/test/test-debian-012/etc/network/interfaces
@@ -0,0 +1,2 @@
+auto lo
+iface lo inet loopback
diff --git a/src/test/test-debian-012/etc/network/interfaces.exp 
b/src/test/test-debian-012/etc/network/interfaces.exp
new file mode 100644
index 0000000..4606578
--- /dev/null
+++ b/src/test/test-debian-012/etc/network/interfaces.exp
@@ -0,0 +1,21 @@
+auto lo
+iface lo inet loopback
+
+auto eth0
+iface eth0 inet static
+       address 10.0.0.100
+       netmask 255.255.255.255
+       post-up ip route add 11.0.0.1 dev eth0
+       post-up ip route add default via 11.0.0.1
+       pre-down ip route del default via 11.0.0.1
+       pre-down ip route del 11.0.0.1 dev eth0
+
+auto eth1
+iface eth1 inet6 static
+       address fc00::1
+       netmask 64
+       post-up ip route add fc00:1::ff dev eth1
+       post-up ip route add default via fc00:1::ff
+       pre-down ip route del default via fc00:1::ff
+       pre-down ip route del fc00:1::ff dev eth1
+
-- 
2.1.4


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to