[pve-devel] [RFC pve-container 1/4] debian: deal with gateways in external subnets
Wolfgang Bumiller
w.bumiller at proxmox.com
Fri Oct 16 15:57:10 CEST 2015
---
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
More information about the pve-devel
mailing list