--- 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