]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/INotify.pm
INotify: use cidr for address on config change
[pve-common.git] / src / PVE / INotify.pm
index 2aa70707cbdaaa0ff5a2d7f90856623024146399..6c1ebf530fb1455ef2652935fd49ba966eddffc1 100644 (file)
@@ -1,7 +1,6 @@
 package PVE::INotify;
 
 # todo: maybe we do not need update_file() ?
-
 use strict;
 use warnings;
 
@@ -960,6 +959,8 @@ sub __read_etc_network_interfaces {
                        'bond-primary' => 1,
                        'uplink-id' => 1,
                        'vlan-protocol' => 1,
+                       'vlan-raw-device' => 1,
+                       'vlan-id' => 1,
                        'vxlan-id' => 1,
                        'vxlan-svcnodeip' => 1,
                        'vxlan-physdev' => 1,
@@ -1076,12 +1077,14 @@ sub __read_etc_network_interfaces {
                $ifaces->{$1}->{exists} = 0;
                $d->{exists} = 0;
            }
-       } elsif ($iface =~ m/^(\S+)\.\d+$/) {
+       } elsif ($iface =~ m/^(\S+)\.\d+$/ || $d->{'vlan-raw-device'}) {
            $d->{type} = 'vlan';
-           if (defined ($ifaces->{$1})) {
-               $d->{exists} = $ifaces->{$1}->{exists};
+
+           my $raw_iface = $d->{'vlan-raw-device'} ? $d->{'vlan-raw-device'} : $1;
+           if (defined ($ifaces->{$raw_iface})) {
+               $d->{exists} = $ifaces->{$raw_iface}->{exists};
            } else {
-               $ifaces->{$1}->{exists} = 0;
+               $ifaces->{$raw_iface}->{exists} = 0;
                $d->{exists} = 0;
            }
        } elsif ($iface =~ m/^$PVE::Network::PHYSICAL_NIC_RE$/) {
@@ -1111,28 +1114,20 @@ sub __read_etc_network_interfaces {
        # map address and netmask to cidr
        if ($d->{address}) {
            if ($d->{netmask} && $d->{netmask} =~ m/^\d+$/) { # e.g. netmask 20
-               $d->{cidr} = $d->{address} . "/" . $d->{netmask};
+               $d->{address} = $d->{address} . "/" . $d->{netmask};
            } elsif ($d->{netmask} &&
                     (my $cidr = PVE::JSONSchema::get_netmask_bits($d->{netmask}))) { # e.g. netmask 255.255.255.0
-               $d->{cidr} = $d->{address} . "/" . $cidr;
-           } elsif ($d->{address} =~ m!^(.*)/(\d+)$!) {
-               $d->{cidr} = $d->{address};
-               $d->{address} = $1;
-               $d->{netmask} = $2;
-           } else {
-               $d->{cidr} = $d->{address};
+               $d->{address} = $d->{address} . "/" . $cidr;
            }
+           #for api compatibility
+           $d->{cidr} = $d->{address} 
        }
 
        # map address6 and netmask6 to cidr6
        if ($d->{address6}) {
-           $d->{cidr6} = $d->{address6};
-           if ($d->{netmask6}) {
-               $d->{cidr6} .= "/" . $d->{netmask6};
-           } elsif ($d->{address6} =~ m!^(.*)/(\d+)$!) {
-               $d->{address6} = $1;
-               $d->{netmask6} = $2;
-           }
+           $d->{address6} .= "/" . $d->{netmask6} if $d->{address6} !~ m!^(.*)/(\d+)$! && $d->{netmask6};
+            #for api compatibility
+           $d->{cidr6} = $d->{address6} 
        }
 
        $d->{method} = 'manual' if !$d->{method};
@@ -1181,9 +1176,7 @@ sub __interface_to_string {
 
     $raw .= "iface $iface $family " . $d->{"method$suffix"} . "\n";
     $raw .= "\taddress  " . $d->{"address$suffix"} . "\n" if $d->{"address$suffix"};
-    $raw .= "\tnetmask  " . $d->{"netmask$suffix"} . "\n" if $d->{"netmask$suffix"};
     $raw .= "\tgateway  " . $d->{"gateway$suffix"} . "\n" if $d->{"gateway$suffix"};
-    $raw .= "\tbroadcast  " . $d->{"broadcast$suffix"} . "\n" if $d->{"broadcast$suffix"};
 
     my $done = { type => 1, priority => 1, method => 1, active => 1, exists => 1,
                 comments => 1, autostart => 1, options => 1,
@@ -1494,10 +1487,31 @@ sub __write_etc_network_interfaces {
     # check vlan
     foreach my $iface (keys %$ifaces) {
        my $d = $ifaces->{$iface};
-       if ($d->{type} eq 'vlan' && $iface =~ m/^(\S+)\.\d+$/) {
-           my $p = $1;
+       if ($d->{type} eq 'vlan') {
+
+           my $p = undef;
+           my $vlanid = undef;
+
+           if ($iface =~ m/^(\S+)\.(\d+)$/) {
+               $p = $1;
+               $vlanid = $2;
+               delete $d->{'vlan-raw-device'} if $d->{'vlan-raw-device'};
+           } else {
+               die "missing vlan-raw-device option" if !$d->{'vlan-raw-device'};
+               $p = $d->{'vlan-raw-device'};
+
+               if ($iface =~ m/^vlan(\d+)$/) {
+                   $vlanid = $1;
+                   delete $d->{'vlan-id'} if $d->{'vlan-id'};
+               } else {
+                   die "custom vlan interface name need ifupdown2" if !$ifupdown2;
+                   die "missing vlan-id option" if !$d->{'vlan-id'};
+                   $vlanid = $d->{'vlan-id'};
+               }
+           }
            my $n = $ifaces->{$p};
 
+           die "vlan '$iface' - vlan-id $vlanid should be <= 4094\n" if $vlanid > 4094;
            die "vlan '$iface' - unable to find parent '$p'\n"
                if !$n;
 
@@ -1529,18 +1543,26 @@ sub __write_etc_network_interfaces {
     # check bridgeport option
     my $bridgeports = {};
     my $bridges = {};
-    foreach my $iface (keys %$ifaces) {
-       my $d = $ifaces->{$iface};
+    my $ifaces_copy = { %$ifaces };
+    foreach my $iface (keys %$ifaces_copy) {
+       my $d = $ifaces_copy->{$iface};
        if ($d->{type} eq 'bridge') {
            foreach my $p (split (/\s+/, $d->{bridge_ports})) {
-               $p =~ s/\.\d+$//;
-               my $n = $ifaces->{$p};
+               if($p =~ m/(\S+)\.(\d+)$/) {
+                   my $vlanparent = $1;
+                   if (!defined($ifaces_copy->{$p})) {
+                       $ifaces_copy->{$p}->{type} = 'vlan';
+                       $ifaces_copy->{$p}->{method} = 'manual';
+                       $ifaces_copy->{$p}->{method6} = 'manual';
+                       $ifaces_copy->{$p}->{mtu} = $ifaces_copy->{$vlanparent}->{mtu} if defined($ifaces_copy->{$1}->{mtu});
+                   }
+               }
+               my $n = $ifaces_copy->{$p};
                die "bridge '$iface' - unable to find bridge port '$p'\n" if !$n;
                die "iface $p - ip address can't be set on interface if bridged in $iface\n"
-                   if ($n->{method} eq 'static' && $n->{address} ne '0.0.0.0') ||
-                      ($n->{method6} eq 'static' && $n->{address} ne '::');
-
-               &$check_mtu($ifaces, $iface, $p);
+                   if ($n->{method} && $n->{method} eq 'static' && $n->{address} ne '0.0.0.0') ||
+                      ($n->{method6} && $n->{method6} eq 'static' && $n->{address} ne '::');
+               &$check_mtu($ifaces_copy, $p, $iface);
                $bridgeports->{$p} = $iface;
            }
            $bridges->{$iface} = $d;
@@ -1584,6 +1606,7 @@ NETWORKDOC
        bond => 300000,
        bridge => 400000,
        OVSBridge => 400000,
+       vlan => 500000,
        vxlan => 500000,
    };