'bridge-vlan-aware' => 'bridge_vlan_aware',
'bridge-fd' => 'bridge_fd',
'bridge-stp' => 'bridge_stp',
- 'bridge-ports' => 'bridge_ports'
+ 'bridge-ports' => 'bridge_ports',
+ 'bridge-vids' => 'bridge_vids'
};
my $line;
} else {
$d->{$id} = 'off';
}
- } elsif ($id eq 'bridge_fd') {
+ } elsif ($id eq 'bridge_fd' || $id eq 'bridge_vids') {
$d->{$id} = $value;
} elsif ($id eq 'bridge_vlan_aware') {
$d->{$id} = 1;
}
}
$d->{$id} = $value;
+ } elsif ($id eq 'vxlan-id' || $id eq 'vxlan-svcnodeip' ||
+ $id eq 'vxlan-physdev' || $id eq 'vxlan-local-tunnelip') {
+ $d->{$id} = $value;
+ } elsif ($id eq 'vxlan-remoteip') {
+ push @{$d->{$id}}, $value;
} else {
push @{$f->{options}}, $option;
}
} elsif ($iface =~ m/^lo$/) {
$d->{type} = 'loopback';
} else {
- if (!$d->{ovs_type}) {
+ if ($d->{'vxlan-id'}) {
+ $d->{type} = 'vxlan';
+ } elsif (!$d->{ovs_type}) {
$d->{type} = 'unknown';
} elsif ($d->{ovs_type} eq 'OVSIntPort') {
$d->{type} = $d->{ovs_type};
}
sub __interface_to_string {
- my ($iface, $d, $family, $first_block) = @_;
+ my ($iface, $d, $family, $first_block, $ifupdown2) = @_;
(my $suffix = $family) =~ s/^inet//;
if( defined($d->{bridge_vlan_aware})) {
$raw .= "\tbridge-vlan-aware yes\n";
+ $v = defined($d->{bridge_vids}) ? $d->{bridge_vids} : "2-4094";
+ $raw .= "\tbridge-vids $v\n";
}
$done->{bridge_vlan_aware} = 1;
+ $done->{bridge_vids} = 1;
} elsif ($d->{type} eq 'bond') {
$raw .= "\tbond-xmit-hash-policy $d->{'bond_xmit_hash_policy'}\n";
}
$done->{'bond_xmit_hash_policy'} = 1;
+ } elsif ($d->{type} eq 'vxlan') {
+
+ foreach my $k (qw(vxlan-id vxlan-svcnodeip vxlan-physdev vxlan-local-tunnelip)) {
+ $raw .= "\t$k $d->{$k}\n" if $d->{$k};
+ $done->{$k} = 1;
+ }
+
+ if ($d->{'vxlan-remoteip'}) {
+ foreach my $remoteip (@{$d->{'vxlan-remoteip'}}) {
+ $raw .= "\tvxlan-remoteip $remoteip\n";
+ }
+ $done->{'vxlan-remoteip'} = 1;
+ }
} elsif ($d->{type} eq 'OVSBridge') {
$done->{ovs_type} = 1;
if ($d->{ovs_bridge}) {
- $raw = "allow-$d->{ovs_bridge} $iface\n$raw";
+
+ if ($ifupdown2) {
+ $raw = "auto $iface\n$raw";
+ } else {
+ $raw = "allow-$d->{ovs_bridge} $iface\n$raw";
+ }
+
$raw .= "\tovs_bridge $d->{ovs_bridge}\n";
$done->{ovs_bridge} = 1;
}
sub write_etc_network_interfaces {
my ($filename, $fh, $config) = @_;
- my $raw = __write_etc_network_interfaces($config);
+ my $ifupdown2 = -e '/usr/share/ifupdown2';
+ my $raw = __write_etc_network_interfaces($config, $ifupdown2);
PVE::Tools::safe_print($filename, $fh, $raw);
}
sub __write_etc_network_interfaces {
- my ($config) = @_;
+ my ($config, $ifupdown2) = @_;
my $ifaces = $config->{ifaces};
my @options = @{$config->{options}};
}
}
+ # check vxlan
+ my $vxlans = {};
+ foreach my $iface (keys %$ifaces) {
+ my $d = $ifaces->{$iface};
+
+ if ($d->{type} eq 'vxlan' && $d->{'vxlan-id'}) {
+ my $vxlanid = $d->{'vxlan-id'};
+ die "iface $iface : duplicate vxlan-id $vxlanid already used in $vxlans->{$vxlanid}\n" if $vxlans->{$vxlanid};
+ $vxlans->{$vxlanid} = $iface;
+ }
+
+ my $ips = 0;
+ ++$ips if defined $d->{'vxlan-svcnodeip'};
+ ++$ips if defined $d->{'vxlan-remoteip'};
+ ++$ips if defined $d->{'vxlan-local-tunnelip'};
+ if ($ips > 1) {
+ die "ifac $iface : vxlan-svcnodeip, vxlan-remoteip and vxlan-localtunnelip are mutually exclusive\n";
+ }
+
+ if (defined($d->{'vxlan-svcnodeip'}) != defined($d->{'vxlan-physdev'})) {
+ die "iface $iface : vxlan-svcnodeip and vxlan-physdev must be define together\n";
+ }
+ }
+
my $raw = <<'NETWORKDOC';
# network interface settings; autogenerated
# Please do NOT modify this file directly, unless you know what
eth => 200000,
bond => 300000,
bridge => 400000,
+ vxlan => 500000,
};
my $lookup_type_prio = sub {
$printed->{$iface} = 1;
$raw .= "auto $iface\n" if $d->{autostart};
my $i = 0; # some options should be printed only once
- $raw .= __interface_to_string($iface, $d, $_, !$i++) foreach @{$d->{families}};
+ $raw .= __interface_to_string($iface, $d, $_, !$i++, $ifupdown2) foreach @{$d->{families}};
}
$raw .= $_->[1] . "\n" foreach @options;