diff options
author | sarthurdev <965089+sarthurdev@users.noreply.github.com> | 2022-01-12 00:59:53 +0100 |
---|---|---|
committer | sarthurdev <965089+sarthurdev@users.noreply.github.com> | 2022-01-12 11:26:47 +0100 |
commit | a132ba993e786994a3b129c72fb0024931339619 (patch) | |
tree | ddec5f51433c572143c293d0dcb43282d765d862 | |
parent | 391ce22b76190309f81e048ebffab778b0fdee1d (diff) | |
download | vyos-1x-a132ba993e786994a3b129c72fb0024931339619.tar.gz vyos-1x-a132ba993e786994a3b129c72fb0024931339619.zip |
firewall: T4160: Fix support for inverse matches
-rw-r--r-- | python/vyos/firewall.py | 35 | ||||
-rwxr-xr-x | src/validators/port-multi | 2 |
2 files changed, 30 insertions, 7 deletions
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 414ec89c1..66dc8bc40 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -45,13 +45,19 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): if 'state' in rule_conf and rule_conf['state']: states = ",".join([s for s, v in rule_conf['state'].items() if v == 'enable']) - output.append(f'ct state {{{states}}}') + + if states: + output.append(f'ct state {{{states}}}') if 'protocol' in rule_conf and rule_conf['protocol'] != 'all': proto = rule_conf['protocol'] + operator = '' + if proto[0] == '!': + operator = '!=' + proto = proto[1:] if proto == 'tcp_udp': proto = '{tcp, udp}' - output.append('meta l4proto ' + proto) + output.append(f'meta l4proto {operator} {proto}') for side in ['destination', 'source']: if side in rule_conf: @@ -59,7 +65,10 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): side_conf = rule_conf[side] if 'address' in side_conf: - output.append(f'{ip_name} {prefix}addr {side_conf["address"]}') + suffix = side_conf['address'] + if suffix[0] == '!': + suffix = f'!= {suffix[1:]}' + output.append(f'{ip_name} {prefix}addr {suffix}') if 'mac_address' in side_conf: suffix = side_conf["mac_address"] @@ -69,15 +78,27 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): if 'port' in side_conf: proto = rule_conf['protocol'] - port = side_conf["port"] + port = side_conf['port'].split(',') - if isinstance(port, list): - port = ",".join(port) + ports = [] + negated_ports = [] + + for p in port: + if p[0] == '!': + negated_ports.append(p[1:]) + else: + ports.append(p) if proto == 'tcp_udp': proto = 'th' - output.append(f'{proto} {prefix}port {{{port}}}') + if ports: + ports_str = ','.join(ports) + output.append(f'{proto} {prefix}port {{{ports_str}}}') + + if negated_ports: + negated_ports_str = ','.join(negated_ports) + output.append(f'{proto} {prefix}port != {{{negated_ports_str}}}') if 'group' in side_conf: group = side_conf['group'] diff --git a/src/validators/port-multi b/src/validators/port-multi index 017ea78fb..cef371563 100755 --- a/src/validators/port-multi +++ b/src/validators/port-multi @@ -22,6 +22,8 @@ if __name__ == '__main__': services = get_services() for port in ports: + if port and port[0] == '!': + port = port[1:] if re.match('^[0-9]{1,5}-[0-9]{1,5}$', port): port_1, port_2 = port.split('-') if int(port_1) not in range(1, 65536) or int(port_2) not in range(1, 65536): |