[pve-devel] Add support for OVS Trunk
Benjamin Lessani | Sonassi - The Magento Experts
ben at sonassi.com
Sun Sep 14 21:36:58 CEST 2014
This has been a bugbear for me for a while and put me off using Proxmox. As
it was never possible to pass a single interface with tagged VLANs on it
(versus multiple interfaces, all untagged).
Now that OVS is a part of Proxmox, it makes sense to be able to give guests
tagged ports (so that routers/firewalls can be put in guests). This isn't an
"elegant" set of patches, but merely enough to get the job done.
I hope this is of help, I don't mind refining it a little more if necessary.
diff --git a/usr/share/perl5/PVE/API2/Qemu.pm
b/usr/share/perl5/PVE/API2/Qemu.pm
index df6045c..db54d50 100644
--- a/usr/share/perl5/PVE/API2/Qemu.pm
+++ b/usr/share/perl5/PVE/API2/Qemu.pm
@@ -847,9 +847,9 @@ my $vmconfig_update_net = sub {
PVE::Network::tap_rate_limit($iface, $newnet->{rate});
}
- if(($newnet->{bridge} ne $oldnet->{bridge}) || ($newnet->{tag} ne
$oldnet->{tag}) || ($newnet->{tags} ne $oldnet->{tags}) ||
+ if(($newnet->{bridge} ne $oldnet->{bridge}) || ($newnet->{tag} ne
$oldnet->{tag}) || ($newnet->{firewall} ne $oldnet->{firew
PVE::Network::tap_unplug($iface);
- PVE::Network::tap_plug($iface, $newnet->{bridge},
$newnet->{tag}, $newnet->{tags}, $newnet->{firewall});
+ PVE::Network::tap_plug($iface, $newnet->{bridge},
$newnet->{tag}, $newnet->{firewall}, $newnet->{trunks});
}
}else{
diff --git a/usr/share/perl5/PVE/Network.pm b/usr/share/perl5/PVE/Network.pm
index a352c5e..869378e 100644
--- a/usr/share/perl5/PVE/Network.pm
+++ b/usr/share/perl5/PVE/Network.pm
@@ -113,11 +113,15 @@ my $bridge_add_interface = sub {
};
my $ovs_bridge_add_port = sub {
- my ($bridge, $iface, $tag, $internal) = @_;
+ my ($bridge, $iface, $tag, $internal, $trunks) = @_;
+
+ $trunks =~ s/;/,/g if $trunks;
my $cmd = "/usr/bin/ovs-vsctl add-port $bridge $iface";
$cmd .= " tag=$tag" if $tag;
+ $cmd .= " trunk=$trunks" if $trunks;
$cmd .= " -- set Interface $iface type=internal" if $internal;
+
system($cmd) == 0 ||
die "can't add ovs port '$iface'\n";
};
@@ -171,7 +175,7 @@ my $create_firewall_bridge_linux = sub {
};
my $create_firewall_bridge_ovs = sub {
- my ($iface, $bridge, $tag) = @_;
+ my ($iface, $bridge, $tag, $trunks) = @_;
my ($vmid, $devid) = &$parse_tap_devive_name($iface);
my ($fwbr, undef, undef, $ovsintport) = &$compute_fwbr_names($vmid,
$devid);
@@ -183,7 +187,7 @@ my $create_firewall_bridge_ovs = sub {
&$bridge_add_interface($fwbr, $iface);
- &$ovs_bridge_add_port($bridge, $ovsintport, $tag, 1);
+ &$ovs_bridge_add_port($bridge, $ovsintport, $tag, 1, $trunks);
# set the same mtu for ovs int port
PVE::Tools::run_command("/sbin/ifconfig $ovsintport mtu $bridgemtu");
@@ -216,7 +220,7 @@ my $cleanup_firewall_bridge = sub {
};
sub tap_plug {
- my ($iface, $bridge, $tag, $tags, $firewall) = @_;
+ my ($iface, $bridge, $tag, $firewall, $trunks) = @_;
#cleanup old port config from any openvswitch bridge
eval {run_command("/usr/bin/ovs-vsctl del-port $iface", outfunc => sub
{}, errfunc => sub {}) };
@@ -234,9 +238,9 @@ sub tap_plug {
&$cleanup_firewall_bridge($iface); # remove stale devices
if ($firewall) {
- &$create_firewall_bridge_ovs($iface, $bridge, $tag);
+ &$create_firewall_bridge_ovs($iface, $bridge, $tag, $trunks);
} else {
- &$ovs_bridge_add_port($bridge, $iface, $tag);
+ &$ovs_bridge_add_port($bridge, $iface, $tag, 0, $trunks);
}
}
}
diff --git a/usr/share/perl5/PVE/QemuServer.pm
b/usr/share/perl5/PVE/QemuServer.pm
index 9b1d342..85970f3 100644
--- a/usr/share/perl5/PVE/QemuServer.pm
+++ b/usr/share/perl5/PVE/QemuServer.pm
@@ -485,7 +485,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>][,queues=<nbqueues>][,rate=<mbps>][,tag=<vlanid>][,tags=<vlan
ids>][,firewall
+ typetext => "MODEL=XX:XX:XX:XX:XX:XX
[,bridge=<dev>][,queues=<nbqueues>][,rate=<mbps>][,tag=<vlanid>][,firewall=0
|1][,trunks=<vl
description => <<EODESCR,
Specify network devices.
@@ -1322,10 +1322,10 @@ sub parse_net {
$res->{rate} = $1;
} elsif ($kvp =~ m/^tag=(\d+)$/) {
$res->{tag} = $1;
- } elsif ($kvp =~ m/^tags=([0-9;]+)$/) {
- $res->{tags} = $1;
} elsif ($kvp =~ m/^firewall=(\d+)$/) {
$res->{firewall} = $1;
+ } elsif ($kvp =~ m/^trunks=([0-9;]+)$/) {
+ $res->{trunks} = $1;
} else {
return undef;
}
@@ -1345,8 +1345,8 @@ sub print_net {
$res .= ",bridge=$net->{bridge}" if $net->{bridge};
$res .= ",rate=$net->{rate}" if $net->{rate};
$res .= ",tag=$net->{tag}" if $net->{tag};
- $res .= ",tags=$net->{tags}" if $net->{tags};
$res .= ",firewall=$net->{firewall}" if $net->{firewall};
+ $res .= ",trunks=$net->{trunks}" if $net->{trunks};
return $res;
}
diff --git a/usr/share/pve-manager/ext4/pvemanagerlib.js
b/usr/share/pve-manager/ext4/pvemanagerlib.js
index 5353508..4866058 100644
--- a/usr/share/pve-manager/ext4/pvemanagerlib.js
+++ b/usr/share/pve-manager/ext4/pvemanagerlib.js
@@ -1304,6 +1304,8 @@ Ext.define('PVE.Parser', { statics: {
res.rate = match_res[1];
} else if ((match_res = p.match(/^tag=(\d+(\.\d+)?)$/)) !== null) {
res.tag = match_res[1];
+ } else if ((match_res = p.match(/^trunks=([0-9;]+)$/)) !== null) {
+ res.trunks = match_res[1];
} else if ((match_res = p.match(/^firewall=(\d+)$/)) !== null) {
res.firewall = match_res[1];
} else {
@@ -1330,6 +1332,9 @@ Ext.define('PVE.Parser', { statics: {
if (net.tag) {
netstr += ",tag=" + net.tag;
}
+ if (net.trunks) {
+ netstr += ",trunks=" + net.trunks;
+ }
if (net.firewall) {
netstr += ",firewall=" + net.firewall;
}
@@ -1441,7 +1446,8 @@ Ext.define('PVE.Parser', { statics: {
}
data['bridge'] = bridge_res[1];
data['tag'] = bridge_res[4];
- data['firewall'] = bridge_res[5] ? 1 : 0;
+ data['tag'] = bridge_res[5];
+ data['firewall'] = bridge_res[6] ? 1 : 0;
} else {
data[match_res[1]] = match_res[2];
}
@@ -1465,12 +1471,15 @@ Ext.define('PVE.Parser', { statics: {
Ext.Object.each(netif, function(iface, data) {
var tmparray = [];
- Ext.Array.each(['ifname', 'mac', 'bridge', 'host_ifname' ,
'host_mac', 'mac_filter', 'tag', 'firewall'], function(key) {
+ Ext.Array.each(['ifname', 'mac', 'bridge', 'host_ifname' ,
'host_mac', 'mac_filter', 'tag', 'trunks', 'firewall'], function(
var value = data[key];
if (key === 'bridge'){
if(data['tag']){
value = value + 'v' + data['tag'];
}
+ if(data['trunks']){
+ value = value + 'v' + data['trunks'];
+ }
if (data['firewall']){
value = value + 'f';
}
@@ -3999,6 +4008,18 @@ Ext.define('PVE.form.VlanField', {
me.callParent();
}
});
+Ext.define('PVE.form.VlansField', {
+ extend: 'Ext.form.field.Text',
+ alias: ['widget.pveVlansField'],
+
+ deleteEmpty: false,
+
+ emptyText: 'no VLANs',
+
+ fieldLabel: gettext('VLAN Trunks'),
+
+ allowBlank: true,
+});
Ext.define('PVE.form.Checkbox', {
extend: 'Ext.form.field.Checkbox',
alias: ['widget.pvecheckbox'],
@@ -15149,6 +15170,7 @@ Ext.define('PVE.qemu.MemoryEdit', {
} else if (values.networkmode === 'bridge') {
me.network.bridge = values.bridge;
me.network.tag = values.tag;
+ me.network.trunks = values.trunks;
me.network.firewall = values.firewall;
} else {
me.network.bridge = undefined;
@@ -15221,6 +15243,7 @@ Ext.define('PVE.qemu.MemoryEdit', {
me.down('field[name=bridge]').setDisabled(!value);
me.down('field[name=bridge]').validate();
me.down('field[name=tag]').setDisabled(!value);
+ me.down('field[name=trunks]').setDisabled(!value);
me.down('field[name=firewall]').setDisabled(!value);
}
}
@@ -15234,6 +15257,13 @@ Ext.define('PVE.qemu.MemoryEdit', {
},
me.bridgesel,
{
+ xtype: 'pveVlansField',
+ name: 'trunks',
+ value: '',
+ labelAlign: 'right'
+ },
+ me.bridgesel,
+ {
xtype: 'pvecheckbox',
fieldLabel: gettext('Firewall'),
name: 'firewall',
@@ -19211,6 +19241,11 @@ Ext.define('PVE.OpenVZ.NetIfEdit', {
value: cdata.tag,
},
{
+ xtype: 'pveVlansField',
+ name: 'trunks',
+ value: cdata.trunks
+ },
+ {
xtype: 'pvecheckbox',
fieldLabel: gettext('Firewall'),
name: 'firewall',
@@ -19564,7 +19599,7 @@ Ext.define('PVE.openvz.NetworkView', {
Ext.define('pve-openvz-network', {
extend: "Ext.data.Model",
proxy: { type: 'memory' },
- fields: [ 'id', 'type', 'value', 'ifname', 'mac', 'bridge',
'host_ifname', 'host_mac', 'tag', 'firewall' ]
+ fields: [ 'id', 'type', 'value', 'ifname', 'mac', 'bridge',
'host_ifname', 'host_mac', 'tag', 'trunks', 'firewall' ]
});
});
diff --git a/var/lib/qemu-server/pve-bridge b/var/lib/qemu-server/pve-bridge
index d6c5eb8..48f63f5 100755
--- a/var/lib/qemu-server/pve-bridge
+++ b/var/lib/qemu-server/pve-bridge
@@ -30,6 +30,6 @@ PVE::Network::tap_create($iface, $net->{bridge});
PVE::Network::tap_rate_limit($iface, $net->{rate}) if $net->{rate};
-PVE::Network::tap_plug($iface, $net->{bridge}, $net->{tag},
$net->{firewall});
+PVE::Network::tap_plug($iface, $net->{bridge}, $net->{tag},
$net->{firewall}, $net->{trunks});
exit 0;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.proxmox.com/pipermail/pve-devel/attachments/20140914/5c9254b7/attachment.htm>
More information about the pve-devel
mailing list