Skip to content

Commit fd021d6

Browse files
Match IPv6 extension header protocol numbers as extension headers
An ACL rule given by the protocol number of an IPv6 extension header (0, 43, 44, 60, 135) is rendered as nft's "exthdr <name> exists" for that header, rather than as an upper-layer protocol. Signed-off-by: Brad House <bhouse@nexthop.ai>
1 parent 0769a49 commit fd021d6

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

‎systemvm/debian/opt/cloud/bin/configure.py‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ def removeUndesiredCidrs(cidrs, version):
7171
return None
7272

7373

74+
# nft names of the IPv6 extension headers, which can also be given as an ACL protocol number
75+
IP6_EXTHDR_NAMES = {0: "hbh", 43: "rt", 44: "frag", 60: "dst", 135: "mh"}
76+
77+
78+
def ip6ProtocolMatch(number):
79+
""" An extension header number is matched as that extension header, any other as the protocol """
80+
if number in IP6_EXTHDR_NAMES:
81+
return "exthdr %s exists" % IP6_EXTHDR_NAMES[number]
82+
return "meta l4proto %d" % number
83+
84+
7485
def appendStringIfNotEmpty(s1, s2):
7586
if s2:
7687
if not isinstance(s2, str):
@@ -527,7 +538,7 @@ def __process_ip6(self, direction, rule_list):
527538
if protocol != "all":
528539
icmp_type = ""
529540
if protocol == "protocol":
530-
protocol = "meta l4proto %d" % rule['protocol']
541+
protocol = ip6ProtocolMatch(rule['protocol'])
531542
proto = protocol
532543
if proto == "icmp":
533544
proto = proto_str = "icmpv6"

‎systemvm/test/TestCsAclIpv6.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ def test_protocol_number_rule_uses_meta_l4proto(self):
5858
egress = [r['rule'] for r in config.ipv6_acl if r.get('chain') == "eth3_egress_policy" and 'rule' in r]
5959
self.assertIn("ip6 daddr 2001:db8:1::/64 meta l4proto 50 accept", egress)
6060

61+
def test_extension_header_number_rule(self):
62+
config = FakeConfig()
63+
rules = [{"type": "protocol", "protocol": p, "cidr": "2001:db8::/64", "allowed": False} for p in (0, 43, 44, 60, 135)]
64+
obj = {"device": "eth3", "nic_ip": "10.1.1.1", "nic_netmask": "24", "nic_ip6_cidr": "fd00:1::/64",
65+
"ingress_rules": rules, "egress_rules": []}
66+
acl = CsAcl.AclDevice(obj, config)
67+
acl.create()
68+
69+
ingress = [r['rule'] for r in config.ipv6_acl if r.get('chain') == "eth3_ingress_policy" and 'rule' in r]
70+
for name in ("hbh", "rt", "frag", "dst", "mh"):
71+
self.assertIn("ip6 saddr 2001:db8::/64 exthdr %s exists drop" % name, ingress)
72+
6173

6274
if __name__ == '__main__':
6375
unittest.main()

0 commit comments

Comments
 (0)