]> git.proxmox.com Git - qemu-server.git/commitdiff
add vlan for testing
authorDerumier Alexandre <aderumier@odiso.com>
Mon, 19 Mar 2012 08:39:21 +0000 (09:39 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 20 Mar 2012 05:12:46 +0000 (06:12 +0100)
Signed-off-by: Derumier Alexandre <aderumier@odiso.com>
PVE/QemuServer.pm
pve-bridge

index db08e6a9f3caf5e691cc9e8d1f8d2d95702ec29e..6cda6df020d00c98653987bb4a7ec7641c2f1d8b 100644 (file)
@@ -404,7 +404,7 @@ my $nic_model_list_txt = join(' ', sort @$nic_model_list);
 my $netdesc = {
     optional => 1,
     type => 'string', format => 'pve-qm-net',
-    typetext => "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>]",
+    typetext => "MODEL=XX:XX:XX:XX:XX:XX [,bridge=<dev>][,rate=<mbps>][,vlan=<vlanid>]",
     description => <<EODESCR,
 Specify network devices.
 
@@ -1108,6 +1108,8 @@ sub parse_net {
            $res->{bridge} = $1;
        } elsif ($kvp =~ m/^rate=(\d+(\.\d+)?)$/) {
            $res->{rate} = $1;
+        } elsif ($kvp =~ m/^vlan=(\d+)$/) {
+            $res->{vlan} = $1;
        } else {
            return undef;
        }
@@ -1126,6 +1128,7 @@ sub print_net {
     $res .= "=$net->{macaddr}" if $net->{macaddr};
     $res .= ",bridge=$net->{bridge}" if $net->{bridge};
     $res .= ",rate=$net->{rate}" if $net->{rate};
+    $res .= ",vlan=$net->{vlan}" if $net->{vlan};
 
     return $res;
 }
index 2d826cfbda8f81a502aa96966a73c56a34d4e21e..faf50fa496e3358c1eebd5ff38910de01e60d0c9 100755 (executable)
@@ -3,6 +3,7 @@
 use strict;
 use PVE::QemuServer;
 use PVE::Tools qw(run_command);
+use PVE::Storage;
 
 my $iface = shift;
 
@@ -62,6 +63,58 @@ if ($net->{rate}) {
 
 }
 
+if ($net->{vlan}) {
+
+    my $vlan = $net->{vlan};
+    my $bridgevlan = $bridge."v".$vlan;
+
+    #check if we have an only one ethX or bondX interface in the bridge
+    my (undef, $interface) = PVE::Storage::dir_glob_regex("/sys/class/net/$bridge/brif/", '((eth|bond)\d+)');
+    die "No interface in bridge" if !$interface;
+    die "You can't have 2 physical interfaces on the same bridge" if(ref($interface) eq 'ARRAY');
+
+    my $interfacevlan = $interface.".".$vlan;
+
+    #create vlan on interface is not already exist
+    unless (-d "/sys/class/net/$interfacevlan") {
+    system ("/sbin/vconfig add $interface $vlan") == 0 ||
+        die "can't add vlan $vlan to interface $interface\n";
+    }
+
+    #be sure to have the interfacevlan up
+    system ("/sbin/ip link set $interfacevlan up") == 0 ||
+        die "can't up interface $interfacevlan\n";
+
+    # test if vlaninterface is already enslave in another bridge
+    my $path="/sys/class/net/$interfacevlan/brport/bridge";
+    if(-e $path) {
+        my $targetbridge = readlink($path);
+        if($targetbridge =~ m/([0-9A-Za-z]+)$/) {
+                die "Interface $interfacevlan already exist in bridge $targetbridge" if $1 ne $bridgevlan;
+        }
+    }
+
+    #add bridgevlan if it doesn't already exist
+    unless (-d "/sys/class/net/$bridgevlan") {
+        system ("/usr/sbin/brctl addbr $bridgevlan") == 0 ||
+            die "can't add bridge $bridgevlan\n";
+    }
+
+    #be sure to have the bridge up
+    system ("/sbin/ip link set $bridgevlan up") == 0 ||
+        die "can't up bridge $bridgevlan\n";
+
+    #add interfacevlan to the bridge
+    my (undef, $interfacevlanfound) = PVE::Storage::dir_glob_regex("/sys/class/net/$bridgevlan/brif/", "($interface\.$vlan)");
+    if (!defined($interfacevlanfound)) {
+     system ("/usr/sbin/brctl addif $bridgevlan $interfacevlan") == 0 ||
+     die "can't add interface $interfacevlan to bridge $bridgevlan\n";
+    }
+
+    $bridge=$bridgevlan;
+}
+
+
 system ("/usr/sbin/brctl addif $bridge $iface") == 0 ||
     die "can't add interface to bridge\n";