[pve-devel] [PATCH firewall 6/7] ipfilter: imiplicitly add the default link local address
Wolfgang Bumiller
w.bumiller at proxmox.com
Tue Mar 1 12:20:20 CET 2016
When adding an ipset for a device via the 'ipfilter-net$NUM'
name we now implicitly add the default link local address
based on the device's MAC address and a 'nomatch' entry for
the rest of fe80::/10. This is comparable to an ARP/MAC
filter in IPv4 with the main difference that it explicitly
works at IP level.
---
src/PVE/Firewall.pm | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 50 insertions(+), 4 deletions(-)
diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index 2e2b2f7..7f8fe98 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -2972,12 +2972,18 @@ sub generate_std_chains {
}
sub generate_ipset_chains {
- my ($ipset_ruleset, $clusterfw_conf, $fw_conf) = @_; #fixme
+ my ($ipset_ruleset, $clusterfw_conf, $fw_conf, $device_ips) = @_; #fixme
foreach my $ipset (keys %{$fw_conf->{ipset}}) {
my $options = $fw_conf->{ipset}->{$ipset};
+ if ($device_ips && $ipset =~ /^ipfilter-(net\d+)$/) {
+ if (my $ips = $device_ips->{$1}) {
+ $options = [@$options, @$ips];
+ }
+ }
+
# remove duplicates
my $nethash = {};
foreach my $entry (@$options) {
@@ -3270,6 +3276,18 @@ sub compile_iptables_filter {
return $ruleset;
}
+sub mac_to_linklocal {
+ my ($macaddr) = @_;
+ my @parts = split(/:/, $macaddr);
+ # The standard link local address uses the fe80::/64 prefix with the
+ # modified EUI-64 identifier derived from the MAC address by flipping the
+ # universal/local bit and inserting FF:FE in the middle.
+ # See RFC 4291.
+ $parts[0] = sprintf("%02x", hex($parts[0]) ^ 0x02);
+ my @meui64 = (@parts[0,1,2], 'ff', 'fe', @parts[3,4,5]);
+ return "fe80::$parts[0]$parts[1]:$parts[2]FF:FE$parts[3]:$parts[4]$parts[5]";
+}
+
sub compile_ipsets {
my ($cluster_conf, $vmfw_configs, $vmdata) = @_;
@@ -3296,7 +3314,21 @@ sub compile_ipsets {
my $vmfw_conf = $vmfw_configs->{$vmid};
return if !$vmfw_conf;
- generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf);
+ my $device_ips = {};
+ foreach my $netid (keys %$conf) {
+ next if $netid !~ m/^net(\d+)$/;
+ my $net = PVE::QemuServer::parse_net($conf->{$netid});
+ next if !$net->{firewall};
+
+ my $macaddr = $net->{macaddr};
+ my $linklocal = mac_to_linklocal($macaddr);
+ $device_ips->{$netid} = [
+ { cidr => $linklocal },
+ { cidr => 'fe80::/10', nomatch => 1 }
+ ];
+ }
+
+ generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips);
};
warn $@ if $@; # just to be sure - should not happen
}
@@ -3308,12 +3340,26 @@ sub compile_ipsets {
my $vmfw_conf = $vmfw_configs->{$vmid};
return if !$vmfw_conf;
- generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf);
+ my $device_ips = {};
+ foreach my $netid (keys %$conf) {
+ next if $netid !~ m/^net(\d+)$/;
+ my $net = PVE::LXC::parse_lxc_network($conf->{$netid});
+ next if !$net->{firewall};
+
+ my $macaddr = $net->{hwaddr};
+ my $linklocal = mac_to_linklocal($macaddr);
+ $device_ips->{$netid} = [
+ { cidr => $linklocal },
+ { cidr => 'fe80::/10', nomatch => 1 }
+ ];
+ }
+
+ generate_ipset_chains($ipset_ruleset, $cluster_conf, $vmfw_conf, $device_ips);
};
warn $@ if $@; # just to be sure - should not happen
}
- generate_ipset_chains($ipset_ruleset, undef, $cluster_conf);
+ generate_ipset_chains($ipset_ruleset, undef, $cluster_conf, undef);
return $ipset_ruleset;
}
--
2.1.4
More information about the pve-devel
mailing list