Skip to content

Commit 6ff859e

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 6ff859e

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
@@ -81,6 +81,17 @@ def appendStringIfNotEmpty(s1, s2):
8181
return s1
8282

8383

84+
# nft names of the IPv6 extension headers, which can also be given as an ACL protocol number
85+
IP6_EXTHDR_NAMES = {0: "hbh", 43: "rt", 44: "frag", 60: "dst", 135: "mh"}
86+
87+
88+
def ip6ProtocolMatch(number):
89+
""" An extension header number is matched as that extension header, any other as the protocol """
90+
if number in IP6_EXTHDR_NAMES:
91+
return "exthdr %s exists" % IP6_EXTHDR_NAMES[number]
92+
return "meta l4proto %d" % number
93+
94+
8495
class CsPassword(CsDataBag):
8596

8697
TOKEN_FILE = "/tmp/passwdsrvrtoken"
@@ -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)