14
14
"""Unittest for Nftables rendering module."""
15
15
16
16
import datetime
17
+ import re
17
18
from unittest import mock
18
19
from absl import logging
19
20
from absl .testing import absltest
@@ -129,7 +130,24 @@ def __init__(self, in_dict: dict):
129
130
}
130
131
"""
131
132
132
- # TODO(gfm): Noverbose testing once Term handling is added.
133
+ HEADER_MIXED_AF = """
134
+ header {
135
+ target:: nftables mixed output
136
+ }
137
+ """
138
+
139
+ HEADER_IPV4_AF = """
140
+ header {
141
+ target:: nftables inet output
142
+ }
143
+ """
144
+
145
+ HEADER_IPV6_AF = """
146
+ header {
147
+ target:: nftables inet6 output
148
+ }
149
+ """
150
+
133
151
HEADER_NOVERBOSE = """
134
152
header {
135
153
target:: nftables mixed output noverbose
@@ -154,6 +172,13 @@ def __init__(self, in_dict: dict):
154
172
}
155
173
"""
156
174
175
+ DENY_TERM = """
176
+ term deny-term {
177
+ comment:: "Dual-stack IPv4/v6 deny all"
178
+ action:: deny
179
+ }
180
+ """
181
+
157
182
ESTABLISHED_OPTION_TERM = """
158
183
term established-term {
159
184
protocol:: udp
@@ -541,6 +566,36 @@ def testSkippedTerm(self, termdata, messagetxt):
541
566
record = ctx .records [1 ]
542
567
self .assertEqual (record .message , messagetxt )
543
568
569
+ @parameterized .parameters (
570
+ (HEADER_MIXED_AF + ICMPV6_TERM , 'ip protocol icmp' ),
571
+ (HEADER_IPV4_AF + ICMPV6_TERM , 'meta l4proto icmpv6' ),
572
+ (HEADER_IPV6_AF + ICMP_TERM , 'ip protocol icmp' ),
573
+ )
574
+ def testRulesetGeneratorICMPmismatch (self , pol_data , doesnotcontain ):
575
+ # This test ensures that ICMPv6 only term isn't rendered in a mixed header.
576
+ nftables .Nftables (
577
+ policy .ParsePolicy (pol_data , self .naming ), EXP_INFO )
578
+ nft = str (
579
+ nftables .Nftables (
580
+ policy .ParsePolicy (pol_data , self .naming ), EXP_INFO ))
581
+ self .assertNotRegex (nft , doesnotcontain )
582
+
583
+ def testRulesetGeneratorUniqueChain (self ):
584
+ # This test is intended to verify that on mixed address family rulesets
585
+ # no duplicate instance of a simple deny is rendered within a mixed chain.
586
+ expected_term_rule = 'drop comment "Dual-stack IPv4/v6 deny all"'
587
+ count = 0
588
+ nftables .Nftables (
589
+ policy .ParsePolicy (HEADER_MIXED_AF + DENY_TERM , self .naming ), EXP_INFO )
590
+ nft = str (
591
+ nftables .Nftables (
592
+ policy .ParsePolicy (
593
+ HEADER_MIXED_AF + DENY_TERM , self .naming ), EXP_INFO ))
594
+ matching_lines = re .findall (expected_term_rule , nft )
595
+ for match in matching_lines :
596
+ count += 1
597
+ self .assertEqual (count , 1 )
598
+
544
599
@parameterized .parameters (
545
600
(GOOD_HEADER_1 + GOOD_TERM_2 , 'inet6' ),
546
601
(GOOD_HEADER_1 + ICMPV6_TERM , 'inet6' ),
0 commit comments