use warnings;
use PVE::Network::SDN::Zones::Plugin;
use PVE::Exception qw(raise raise_param_exc);
+use PVE::Cluster;
+use PVE::Tools;
use base('PVE::Network::SDN::Zones::Plugin');
# vnet bridge
my @iface_config = ();
- my @subnets = PVE::Tools::split_list($vnet->{subnets}) if $vnet->{subnets};
- foreach my $subnet (@subnets) {
- next if !defined($subnet_cfg->{ids}->{$subnet});
- push @iface_config, "address $subnet_cfg->{ids}->{$subnet}->{gateway}" if $subnet_cfg->{ids}->{$subnet}->{gateway};
+ my $address = {};
+ my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
+ foreach my $subnetid (sort keys %{$subnets}) {
+ my $subnet = $subnets->{$subnetid};
+ my $cidr = $subnetid =~ s/-/\//r;
+ my $gateway = $subnet->{gateway};
+ if ($gateway) {
+ push @iface_config, "address $gateway" if !defined($address->{$gateway});
+ $address->{$gateway} = 1;
+ }
+ #add route for /32 pointtopoint
+ my ($ip, $mask) = split(/\//, $cidr);
+ push @iface_config, "up ip route add $cidr dev $vnetid" if $mask == 32;
+ if ($subnet->{snat}) {
+ #find outgoing interface
+ my ($outip, $outiface) = PVE::Network::SDN::Zones::Plugin::get_local_route_ip('8.8.8.8');
+ if ($outip && $outiface) {
+ #use snat, faster than masquerade
+ push @iface_config, "post-up iptables -t nat -A POSTROUTING -s '$cidr' -o $outiface -j SNAT --to-source $outip";
+ push @iface_config, "post-down iptables -t nat -D POSTROUTING -s '$cidr' -o $outiface -j SNAT --to-source $outip";
+ #add conntrack zone once on outgoing interface
+ push @iface_config, "post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1";
+ push @iface_config, "post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1";
+ }
+ }
}
push @iface_config, "hwaddress $mac" if $mac;
return $err_msg;
}
-sub verify_tag {
- my ($class, $tag) = @_;
- raise_param_exc({ tag => "vlan tag is not allowed on simple bridge"}) if defined($tag);
+sub vnet_update_hook {
+ my ($class, $vnet) = @_;
+
+ raise_param_exc({ tag => "vlan tag is not allowed on simple bridge"}) if defined($vnet->{tag});
+
+ if (!defined($vnet->{mac})) {
+ my $dc = PVE::Cluster::cfs_read_file('datacenter.cfg');
+ $vnet->{mac} = PVE::Tools::random_ether_addr($dc->{mac_prefix});
+ }
}
1;