Currently when you create a rule with an inverse GeoIP match, it also matches the various reserved IP ranges that do not have a specific geographical region (ie. RFC1918 addresses).
Example of a rule that is supposed to block everything except for networks in Canada and US:
```
set firewall ipv4 name XYZ-FORWARD-IPV4 rule 10 action 'drop'
set firewall ipv4 name XYZ-FORWARD-IPV4 rule 10 destination geoip country-code 'us'
set firewall ipv4 name XYZ-FORWARD-IPV4 rule 10 destination geoip country-code 'ca'
set firewall ipv4 name XYZ-FORWARD-IPV4 rule 10 destination geoip inverse-match
```
The db-ip (https://db-ip.com/) databases lumps these all into a 'zz' country code:
```
zcat /usr/share/vyos-geoip/dbip-country-lite.csv.gz | grep ZZ
0.0.0.0,0.255.255.255,ZZ
10.0.0.0,10.255.255.255,ZZ
100.64.0.0,100.127.255.255,ZZ
127.0.0.0,127.255.255.255,ZZ
169.254.0.0,169.254.255.255,ZZ
172.16.0.0,172.31.255.255,ZZ
192.0.0.0,192.0.0.255,ZZ
192.0.2.0,192.0.2.255,ZZ
192.88.99.0,192.88.99.255,ZZ
192.168.0.0,192.168.255.255,ZZ
198.18.0.0,198.19.255.255,ZZ
198.51.100.0,198.51.100.255,ZZ
203.0.113.0,203.0.113.255,ZZ
224.0.0.0,255.255.255.255,ZZ
::,1fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff,ZZ
2001:db8::,2001:db8:ffff:ffff:ffff:ffff:ffff:ffff,ZZ
fc00::,fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff,ZZ
fe80::,febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff,ZZ
```
In my opinion this is incorrect behaviour as these IPs do not necessarily exist in any specific country. I am curious to know what the preferred way to get around this is? Default to adding the 'zz' addresses when an inverse-match rule exists? Or add 'zz' as an option to be specified in rules?
This patch will automatically add country code 'zz' to any rule with inverse-match defined:
```
$ diff -rupP /usr/lib/python3/dist-packages/vyos/firewall.py.orig /usr/lib/python3/dist-packages/vyos/firewall.py
--- /usr/lib/python3/dist-packages/vyos/firewall.py.orig 2023-11-21 16:01:02.557535168 +0000
+++ /usr/lib/python3/dist-packages/vyos/firewall.py 2023-11-21 19:32:23.892547815 +0000
@@ -584,6 +584,10 @@ def geoip_update(firewall, force=False):
# Map country codes to set names
for codes, path in dict_search_recursive(firewall, 'country_code'):
+ # If inverse-match is set, add country zz (reserved IPs)
+ # as they don't belong to a specific country.
+ if dict_search_args(firewall, *(path[:-1] + ['inverse_match'])) != None:
+ codes.append('zz')
set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}'
if ( path[0] == 'ipv4'):
for code in codes:
```