]> git.proxmox.com Git - pve-network.git/blame - PVE/Network/SDN/Zones/SimplePlugin.pm
zones: evpn|simple: add snat iptables rules
[pve-network.git] / PVE / Network / SDN / Zones / SimplePlugin.pm
CommitLineData
880ae857
AD
1package PVE::Network::SDN::Zones::SimplePlugin;
2
3use strict;
4use warnings;
5use PVE::Network::SDN::Zones::Plugin;
1d44ce70 6use PVE::Exception qw(raise raise_param_exc);
5ca07ed9
AD
7use PVE::Cluster;
8use PVE::Tools;
880ae857
AD
9
10use base('PVE::Network::SDN::Zones::Plugin');
11
12sub type {
13 return 'simple';
14}
15
16sub options {
880ae857 17 return {
efe1459b 18 nodes => { optional => 1},
880ae857
AD
19 mtu => { optional => 1 }
20 };
21}
22
23# Plugin implementation
24sub generate_sdn_config {
7024ec2b 25 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $controller, $subnet_cfg, $interfaces_config, $config) = @_;
880ae857 26
efe1459b
TL
27 return $config if$config->{$vnetid}; # nothing to do
28
880ae857
AD
29 my $ipv4 = $vnet->{ipv4};
30 my $ipv6 = $vnet->{ipv6};
31 my $mac = $vnet->{mac};
32 my $alias = $vnet->{alias};
33 my $mtu = $plugin_config->{mtu} if $plugin_config->{mtu};
34
efe1459b 35 # vnet bridge
880ae857 36 my @iface_config = ();
7024ec2b 37
e612faf6
AD
38 my $address = {};
39 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
40 foreach my $subnetid (sort keys %{$subnets}) {
41 my $subnet = $subnets->{$subnetid};
42 my $cidr = $subnetid =~ s/-/\//r;
43 my $gateway = $subnet->{gateway};
44 if ($gateway) {
45 push @iface_config, "address $gateway" if !defined($address->{$gateway});
46 $address->{$gateway} = 1;
47 }
48 #add route for /32 pointtopoint
49 my ($ip, $mask) = split(/\//, $cidr);
50 push @iface_config, "up ip route add $cidr dev $vnetid" if $mask == 32;
53b2cc90
AD
51 if ($subnet->{snat}) {
52 #find outgoing interface
53 my ($outip, $outiface) = PVE::Network::SDN::Zones::Plugin::get_local_route_ip('8.8.8.8');
54 if ($outip && $outiface) {
55 #use snat, faster than masquerade
56 push @iface_config, "post-up iptables -t nat -A POSTROUTING -s '$cidr' -o $outiface -j SNAT --to-source $outip";
57 push @iface_config, "post-down iptables -t nat -D POSTROUTING -s '$cidr' -o $outiface -j SNAT --to-source $outip";
58 #add conntrack zone once on outgoing interface
59 push @iface_config, "post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1";
60 push @iface_config, "post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1";
61 }
62 }
7024ec2b
AD
63 }
64
880ae857
AD
65 push @iface_config, "hwaddress $mac" if $mac;
66 push @iface_config, "bridge_ports none";
67 push @iface_config, "bridge_stp off";
68 push @iface_config, "bridge_fd 0";
efe1459b 69 if ($vnet->{vlanaware}) {
880ae857
AD
70 push @iface_config, "bridge-vlan-aware yes";
71 push @iface_config, "bridge-vids 2-4094";
72 }
73 push @iface_config, "mtu $mtu" if $mtu;
74 push @iface_config, "alias $alias" if $alias;
efe1459b
TL
75
76 push @{$config->{$vnetid}}, @iface_config;
880ae857
AD
77
78 return $config;
79}
80
81sub status {
82 my ($class, $plugin_config, $zone, $vnetid, $vnet, $status) = @_;
83
880ae857 84 # ifaces to check
efe1459b
TL
85 my $ifaces = [ $vnetid ];
86 my $err_msg = [];
880ae857
AD
87 foreach my $iface (@{$ifaces}) {
88 if (!$status->{$iface}->{status}) {
89 push @$err_msg, "missing $iface";
efe1459b 90 } elsif ($status->{$iface}->{status} ne 'pass') {
880ae857
AD
91 push @$err_msg, "error iface $iface";
92 }
93 }
94 return $err_msg;
95}
96
1d44ce70 97
5ca07ed9
AD
98sub vnet_update_hook {
99 my ($class, $vnet) = @_;
100
101 raise_param_exc({ tag => "vlan tag is not allowed on simple bridge"}) if defined($vnet->{tag});
102
103 if (!defined($vnet->{mac})) {
104 my $dc = PVE::Cluster::cfs_read_file('datacenter.cfg');
105 $vnet->{mac} = PVE::Tools::random_ether_addr($dc->{mac_prefix});
106 }
1d44ce70
AD
107}
108
880ae857
AD
1091;
110
111