Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions capirca/lib/iptables.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,21 @@ def __str__(self):

ret_str = []

# Don't render icmpv6 protocol terms under inet, or icmp under inet6
if ((self.af == 'inet6' and 'icmp' in self.term.protocol) or
(self.af == 'inet' and 'icmpv6' in self.term.protocol)):
# Determine the protocols to render for this address family.
if self.term.protocol:
protocol = self.term.protocol
else:
protocol = ['all']

# Don't render icmpv6 protocol terms under inet, or icmp under inet6.
# A term may specify both (e.g. 'protocol:: icmp icmpv6'); in that case
# render only the protocols matching this address family, skipping the
# term entirely only when none remain.
if self.af == 'inet':
protocol = [p for p in protocol if p != 'icmpv6']
elif self.af == 'inet6':
protocol = [p for p in protocol if p != 'icmp']
if not protocol:
logging.debug(self.NO_AF_LOG_PROTO.substitute(
term=self.term.name,
proto=', '.join(self.term.protocol),
Expand Down Expand Up @@ -180,11 +192,7 @@ def __str__(self):
return ('# skipped %s due to source or destination prefix rule' %
self.term.name)

# protocol
if self.term.protocol:
protocol = self.term.protocol
else:
protocol = ['all']
# protocol was determined above; skip 'hopopt' in IPv4 context.
if 'hopopt' in protocol and self.af == 'inet':
logging.warning('Term %s is using hopopt in IPv4 context.',
self.term_name)
Expand Down
25 changes: 25 additions & 0 deletions tests/lib/iptables_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@
}
"""

ICMP_AND_ICMPV6_TERM = """
term permit-icmp {
protocol:: icmp icmpv6
action:: accept
}
"""

HOPOPT_TERM = """
term hopopt-term {
protocol:: hopopt
Expand Down Expand Up @@ -1179,6 +1186,24 @@ def testIcmpInet6Mismatch(self, mock_debug):
' as it has icmp match specified but '
'the ACL is of inet6 address family.')

def testIcmpAndIcmpv6Protocol(self):
pol = policy.ParsePolicy(GOOD_HEADER_1 + ICMP_AND_ICMPV6_TERM, self.naming)
acl = iptables.Iptables(pol, EXP_INFO)
result = str(acl)
self.assertIn('-p icmp', result,
'icmp protocol should be rendered for inet.')
self.assertNotIn('ipv6-icmp', result,
'icmpv6 protocol should not be rendered for inet.')

def testIcmpAndIcmpv6ProtocolInet6(self):
pol = policy.ParsePolicy(IPV6_HEADER_1 + ICMP_AND_ICMPV6_TERM, self.naming)
acl = iptables.Iptables(pol, EXP_INFO)
result = str(acl)
self.assertIn('-p ipv6-icmp', result,
'icmpv6 protocol should be rendered for inet6.')
self.assertNotIn('-p icmp', result,
'icmp protocol should not be rendered for inet6.')

def testOwner(self):
pol = policy.ParsePolicy(GOOD_HEADER_1 + GOOD_TERM_10, self.naming)
acl = iptables.Iptables(pol, EXP_INFO)
Expand Down