use Linux::Inotify2;
use base 'Exporter';
use JSON;
+use Digest::SHA;
use Encode qw(encode decode);
our @EXPORT_OK = qw(read_file write_file register_file);
\&read_etc_hostname,
\&write_etc_hostname);
+sub read_etc_hosts {
+ my ($filename, $fh) = @_;
+
+ my $raw = '';
+ my $data = '';
+
+ while (my $line = <$fh>) {
+ $raw .= $line;
+ if ($line =~ m/^\s*#/) {
+ $line = decode('UTF-8', $line);
+ }
+ $data .= $line;
+ }
+
+ return {
+ digest => Digest::SHA::sha1_hex($raw),
+ data => $data,
+ }
+}
+
+sub write_etc_hosts {
+ my ($filename, $fh, $hosts, @args) = @_;
+
+ # check validity of ips/names
+ for my $line (split("\n", $hosts)) {
+ next if $line =~ m/^\s*#/; # comments
+ next if $line =~ m/^\s*$/; # whitespace/empty lines
+
+ my ($ip, @names) = split(/\s+/, $line);
+
+ raise_param_exc({ 'data' => "Invalid IP '$ip'" })
+ if $ip !~ m/^$PVE::Tools::IPRE$/;
+
+ for my $name (@names) {
+ raise_param_exc({ 'data' => "Invalid Hostname '$name'" })
+ if $name !~ m/^[.\-a-zA-Z0-9]+$/;
+ }
+ }
+
+ die "write failed: $!" if !print $fh encode('UTF-8', $hosts);
+
+ return $hosts;
+}
+
+register_file('etchosts', "/etc/hosts",
+ \&read_etc_hosts,
+ \&write_etc_hosts);
+
sub read_etc_resolv_conf {
my ($filename, $fh) = @_;
'bridge-multicast-flood' => 1,
'bond_miimon' => 1,
'bond_xmit_hash_policy' => 1,
+ 'vlan-protocol' => 1,
'vxlan-id' => 1,
'vxlan-svcnodeip' => 1,
'vxlan-physdev' => 1,
$raw .= "\tbond-xmit-hash-policy $d->{'bond_xmit_hash_policy'}\n";
}
$done->{'bond_xmit_hash_policy'} = 1;
+ } elsif ($d->{type} eq 'vlan') {
+ die "$iface: wrong vlan-protocol $d->{'vlan-protocol'}\n"
+ if $d->{'vlan-protocol'} && $d->{'vlan-protocol'} ne '802.1ad' && $d->{'vlan-protocol'} ne '802.1q';
+
} elsif ($d->{type} eq 'vxlan') {
foreach my $k (qw(vxlan-id vxlan-svcnodeip vxlan-physdev vxlan-local-tunnelip)) {
if ($n->{type} eq 'bridge' && !$n->{bridge_vlan_aware}) {
die "vlan '$iface' - bridge vlan aware is not enabled on parent '$p'\n";
- } elsif ($n->{type} ne 'eth' && $n->{type} ne 'bridge' && $n->{type} ne 'bond') {
+ } elsif ($n->{type} ne 'eth' && $n->{type} ne 'bridge' && $n->{type} ne 'bond' && $n->{type} ne 'vlan') {
die "vlan '$iface' - wrong interface type on parent '$p' " .
- "('$n->{type}' != 'eth|bond|bridge' )\n";
+ "('$n->{type}' != 'eth|bond|bridge|vlan' )\n";
}
+
&$check_mtu($ifaces, $p, $iface);
+
}
}
# Please do NOT modify this file directly, unless you know what
# you're doing.
#
-# If you want to manage part of the network configuration manually,
+# If you want to manage parts of the network configuration manually,
# please utilize the 'source' or 'source-directory' directives to do
# so.
-# PVE will preserve these directives, but will NOT its network
+# PVE will preserve these directives, but will NOT read its network
# configuration from sourced files, so do not attempt to move any of
# the PVE managed interfaces into external files!
my $if_type_hash = {
loopback => 100000,
eth => 200000,
+ OVSPort => 200000,
+ OVSIntPort => 200000,
bond => 300000,
bridge => 400000,
+ OVSBridge => 400000,
vxlan => 500000,
};
my $lookup_type_prio = sub {
- my $iface = shift;
+ my ($iface, $ifaces) = @_;
- my $child = 0;
- if ($iface =~ m/^(\S+)(\.|:)\d+$/) {
- $iface = $1;
- $child = 1;
- }
+ my ($rootiface, @rest) = split(/[.:]/, $iface);
+ my $childlevel = scalar(@rest);
+ my $n = $ifaces->{$rootiface};
- my $pri;
- if ($iface eq 'lo') {
- $pri = $if_type_hash->{loopback};
- } elsif ($iface =~ m/^$PVE::Network::PHYSICAL_NIC_RE$/) {
- $pri = $if_type_hash->{eth} + $child;
- } elsif ($iface =~ m/^bond\d+$/) {
- $pri = $if_type_hash->{bond} + $child;
- } elsif ($iface =~ m/^vmbr\d+$/) {
- $pri = $if_type_hash->{bridge} + $child;
- }
+ my $pri = $if_type_hash->{$n->{type}} + $childlevel
+ if $n->{type} && $n->{type} ne 'unknown';
return $pri;
};
foreach my $iface (sort {
my $ref1 = $ifaces->{$a};
my $ref2 = $ifaces->{$b};
- my $tp1 = &$lookup_type_prio($a);
- my $tp2 = &$lookup_type_prio($b);
+ my $tp1 = &$lookup_type_prio($a, $ifaces);
+ my $tp2 = &$lookup_type_prio($b, $ifaces);
# Only recognized types are in relation to each other. If one type
# is unknown then only consider the interfaces' priority attributes.