diff --git a/systemvm/debian/opt/cloud/bin/configure.py b/systemvm/debian/opt/cloud/bin/configure.py index bf48be66694c..44dc45abf114 100755 --- a/systemvm/debian/opt/cloud/bin/configure.py +++ b/systemvm/debian/opt/cloud/bin/configure.py @@ -449,7 +449,7 @@ def __process_routing_ip4(self, direction, rule_list): if protocol != "all": icmp_type = "" if protocol == "protocol": - protocol = "ip nexthdr %d" % rule['protocol'] + protocol = "ip protocol %d" % rule['protocol'] proto = protocol if proto == "icmp": proto = proto_str = "icmp" diff --git a/systemvm/test/TestCsAclRouting.py b/systemvm/test/TestCsAclRouting.py new file mode 100644 index 000000000000..7d67d711fb9e --- /dev/null +++ b/systemvm/test/TestCsAclRouting.py @@ -0,0 +1,67 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import unittest +from configure import CsAcl + + +class FakeConfig: + + def __init__(self): + self.fw = [] + self.ipv6_acl = [] + self.nft_ipv4_acl = [] + + def get_fw(self): + return self.fw + + def get_ipv6_acl(self): + return self.ipv6_acl + + def get_nft_ipv4_acl(self): + return self.nft_ipv4_acl + + def is_vpc(self): + return True + + def is_routed(self): + return True + + +class TestCsAclRouting(unittest.TestCase): + + def test_protocol_number_rule(self): + config = FakeConfig() + obj = {"device": "eth3", "nic_ip": "10.1.1.1", "nic_netmask": "24", "nic_ip6_cidr": "fd00:1::/64", + "ingress_rules": [{"type": "protocol", "protocol": 47, "cidr": "1.2.3.4/32,2001:db8::/64", "allowed": True}], + "egress_rules": [{"type": "protocol", "protocol": 47, "cidr": "5.6.7.8/32", "allowed": False}]} + acl = CsAcl.AclDevice(obj, config) + acl.create() + + # nexthdr is an IPv6 header field, nft rejects it in an ip rule + ip4 = [r['rule'] for r in config.nft_ipv4_acl if r.get('chain') == "eth3_ingress_policy" and 'rule' in r] + self.assertIn("ip saddr 1.2.3.4/32 ip protocol 47 accept", ip4) + ip6 = [r['rule'] for r in config.ipv6_acl if r.get('chain') == "eth3_ingress_policy" and 'rule' in r] + # the IPv4 match must not leak into the IPv6 rule + self.assertTrue(any(r.startswith("ip6 saddr 2001:db8::/64 ") and r.endswith(" 47 accept") for r in ip6)) + self.assertFalse(any("ip protocol" in r for r in ip6)) + ip4 = [r['rule'] for r in config.nft_ipv4_acl if r.get('chain') == "eth3_egress_policy" and 'rule' in r] + self.assertIn("ip daddr 5.6.7.8/32 ip protocol 47 drop", ip4) + + +if __name__ == '__main__': + unittest.main()