]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/INotify.pm
add bridge_vlan_aware
[pve-common.git] / src / PVE / INotify.pm
index 630e62f2f1afe3812d625a4b4c3f4abb68f162a3..22f01d14c9c186c94c937edc93e0ae80c860f333 100644 (file)
@@ -827,7 +827,7 @@ sub __read_etc_network_interfaces {
            my $f = { method => $3 }; # by family, merged to $d with a $suffix
            (my $suffix = $family) =~ s/^inet//;
 
-           my $d = $ifaces->{$i};
+           my $d = $ifaces->{$i} ||= {};
            $d->{priority} = $priority++ if !$d->{priority};
            push @{$d->{families}}, $family;
 
@@ -874,6 +874,8 @@ sub __read_etc_network_interfaces {
                        }
                    } elsif ($id eq 'bridge_fd') {
                        $d->{$id} = $value;
+                   } elsif ($id eq 'bridge_vlan_aware') {
+                       $d->{$id} = 1;
                    } elsif ($id eq 'bond_miimon') {
                        $d->{$id} = $value;
                    } elsif ($id eq 'bond_xmit_hash_policy') {
@@ -996,6 +998,30 @@ sub __read_etc_network_interfaces {
        close ($proc_net_if_inet6);
     }
 
+    # OVS bridges create "allow-$BRIDGE $IFACE" lines which we need to remove
+    # from the {options} hash for them to be removed correctly.
+    @$options = grep {defined($_)} map {
+       my ($pri, $line) = @$_;
+       if ($line =~ /^allow-(\S+)\s+(.*)$/) {
+           my $bridge = $1;
+           my @ports = split(/\s+/, $2);
+           if (defined(my $br = $ifaces->{$bridge})) {
+               # if this port is part of a bridge, remove it
+               my %in_ovs_ports = map {$_=>1} split(/\s+/, $br->{ovs_ports});
+               @ports = grep { not $in_ovs_ports{$_} } @ports;
+           }
+           # create the allow line for the remaining ports, or delete if empty
+           if (@ports) {
+               [$pri, "allow-$bridge " . join(' ', @ports)];
+           } else {
+               undef;
+           }
+       } else {
+           # don't modify other lines
+           $_;
+       }
+    } @$options;
+
     return $config;
 }
 
@@ -1035,6 +1061,11 @@ sub __interface_to_string {
        $v = defined($d->{bridge_fd}) ? $d->{bridge_fd} : 0;
        $raw .= "\tbridge_fd $v\n";
        $done->{bridge_fd} = 1;
+
+       if( defined($d->{bridge_vlan_aware})) {
+           $raw .= "\tbridge_vlan_aware yes\n";
+       }
+       $done->{bridge_vlan_aware} = 1;
     
     } elsif ($d->{type} eq 'bond') {
 
@@ -1166,7 +1197,14 @@ sub __write_etc_network_interfaces {
            $d->{type} eq 'OVSBond') {
            my $brname = $used_ports->{$iface};
            if (!$brname || !$ifaces->{$brname}) { 
-               delete $ifaces->{$iface}; 
+               if ($iface =~ /^eth/) {
+                   $ifaces->{$iface} = { type => 'eth',
+                                         exists => 1,
+                                         method => 'manual',
+                                         families => ['inet'] };
+               } else {
+                   delete $ifaces->{$iface};
+               }
                next;
            }
            my $bd = $ifaces->{$brname};
@@ -1185,6 +1223,7 @@ sub __write_etc_network_interfaces {
                my $n = $ifaces->{$p};
                die "OVS bridge '$iface' - unable to find port '$p'\n"
                    if !$n;
+               $n->{autostart} = 0;
                if ($n->{type} eq 'eth') {
                    $n->{type} = 'OVSPort';
                    $n->{ovs_bridge} = $iface;              
@@ -1198,6 +1237,19 @@ sub __write_etc_network_interfaces {
        }
     }
 
+    # Remove autostart from linux bridge ports
+    foreach my $iface (keys %$ifaces) {
+       my $d = $ifaces->{$iface};
+       if ($d->{type} eq 'bridge' && $d->{bridge_ports}) {
+           foreach my $p (split (/\s+/, $d->{bridge_ports})) {
+               my $n = $ifaces->{$p};
+               die "bridge '$iface' - unable to find port '$p'\n"
+                   if !$n;
+               $n->{autostart} = 0;
+           }
+       }
+    }
+
     # check OVS bond ports
     foreach my $iface (keys %$ifaces) {
        my $d = $ifaces->{$iface};
@@ -1230,10 +1282,10 @@ NETWORKDOC
 
     my $if_type_hash = {
        unknown => 0,
-       loopback => 10,
-       eth => 20,
-       bond => 30,
-       bridge => 40,
+       loopback => 100000,
+       eth => 200000,
+       bond => 300000,
+       bridge => 400000,
    };
 
     my $lookup_type_prio = sub {
@@ -1265,24 +1317,21 @@ NETWORKDOC
        my $p1 = &$lookup_type_prio($a);
        my $p2 = &$lookup_type_prio($b);
 
-       return $p1 <=> $p2 if $p1 != $p2;
-
-       $p1 = $ref1->{priority} || 100000;
-       $p2 = $ref2->{priority} || 100000;
+       $p1 += $ref1->{priority} // 50000;
+       $p2 += $ref2->{priority} // 50000;
 
        return $p1 <=> $p2 if $p1 != $p2;
 
        return $a cmp $b;
-                      } keys %$ifaces) {
-
-       my $d = $ifaces->{$iface};
-
+    } keys %$ifaces) {
        next if $printed->{$iface};
 
-       if (@options && $options[0]->[0] < $d->{priority}) {
+       my $d = $ifaces->{$iface};
+       my $pri = $d->{priority} // 0;
+       if (@options && $options[0]->[0] < $pri) {
            do {
                $raw .= (shift @options)->[1] . "\n";
-           } while (@options && $options[0]->[0] < $d->{priority});
+           } while (@options && $options[0]->[0] < $pri);
            $raw .= "\n";
        }