Skip to content

Commit

Permalink
Add hop-limit-except to Juniper
Browse files Browse the repository at this point in the history
  • Loading branch information
nward committed Sep 10, 2022
1 parent a33c44a commit fbb1c0c
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 1 deletion.
7 changes: 7 additions & 0 deletions capirca/lib/juniper.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def __str__(self):
self.term.forwarding_class_except or
self.term.fragment_offset or
self.term.hop_limit or
self.term.hop_limit_except or
self.term.next_ip or
self.term.port or
self.term.precedence or
Expand Down Expand Up @@ -544,6 +545,11 @@ def __str__(self):
if self.term_type == 'inet6':
config.Append('hop-limit %s;' % (self.term.hop_limit))

if self.term.hop_limit_except:
# Only generate a hop-limit-except if inet6, inet4 has not hop-limit-except.
if self.term_type == 'inet6':
config.Append('hop-limit-except %s;' % (self.term.hop_limit_except))

# flexible-match
if self.term.flexible_match_range:
config.Append('flexible-match-range {')
Expand Down Expand Up @@ -911,6 +917,7 @@ def _BuildTokens(self):
'forwarding_class_except',
'fragment_offset',
'hop_limit',
'hop_limit_except',
'icmp_code',
'logging',
'loss_priority',
Expand Down
12 changes: 12 additions & 0 deletions capirca/lib/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ def __init__(self, obj):
self.packet_length = None
self.fragment_offset = None
self.hop_limit = None
self.hop_limit_except = None
self.icmp_type = []
self.icmp_code = []
self.ether_type = []
Expand Down Expand Up @@ -904,6 +905,8 @@ def __eq__(self, other):
return False
if self.hop_limit != other.hop_limit:
return False
if self.hop_limit_except != other.hop_limit_except:
return False
if sorted(self.icmp_type) != sorted(other.icmp_type):
return False
if sorted(self.icmp_code) != sorted(other.icmp_code):
Expand Down Expand Up @@ -1240,6 +1243,8 @@ def AddObject(self, obj):
self.fragment_offset = obj.value
elif obj.var_type is VarType.HOP_LIMIT:
self.hop_limit = obj.value
elif obj.var_type is VarType.HOP_LIMIT_EXCEPT:
self.hop_limit_except = obj.value
elif obj.var_type is VarType.SINTERFACE:
self.source_interface = obj.value
elif obj.var_type is VarType.DINTERFACE:
Expand Down Expand Up @@ -1582,6 +1587,7 @@ class VarType:
SZONE = 65
DZONE = 66
TTL_EXCEPT = 67
HOP_LIMIT_EXCEPT = 68

def __init__(self, var_type, value):
self.var_type = var_type
Expand Down Expand Up @@ -1766,6 +1772,7 @@ def __ne__(self, other):
'FORWARDING_CLASS_EXCEPT',
'FRAGMENT_OFFSET',
'HOP_LIMIT',
'HOP_LIMIT_EXCEPT',
'APPLY_GROUPS',
'APPLY_GROUPS_EXCEPT',
'HEADER',
Expand Down Expand Up @@ -1854,6 +1861,7 @@ def __ne__(self, other):
'fragment-offset': 'FRAGMENT_OFFSET',
'hex': 'HEX',
'hop-limit': 'HOP_LIMIT',
'hop-limit-except': 'HOP_LIMIT_EXCEPT',
'apply-groups': 'APPLY_GROUPS',
'apply-groups-except': 'APPLY_GROUPS_EXCEPT',
'header': 'HEADER',
Expand Down Expand Up @@ -2039,6 +2047,7 @@ def p_term_spec(p):
| term_spec forwarding_class_except_spec
| term_spec fragment_offset_spec
| term_spec hop_limit_spec
| term_spec hop_limit_except_spec
| term_spec icmp_type_spec
| term_spec icmp_code_spec
| term_spec interface_spec
Expand Down Expand Up @@ -2207,6 +2216,9 @@ def p_hop_limit_spec(p):
else:
p[0] = VarType(VarType.HOP_LIMIT, str(p[4]) + '-' + str(p[6]))

def p_hop_limit_except_spec(p):
""" hop_limit_except_spec : HOP_LIMIT_EXCEPT ':' ':' INTEGER"""
p[0] = VarType(VarType.HOP_LIMIT_EXCEPT, p[4])

def p_one_or_more_dscps(p):
""" one_or_more_dscps : one_or_more_dscps DSCP_RANGE
Expand Down
1 change: 1 addition & 0 deletions doc/generators/juniper.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ The default format is _inet4_, and is implied if not other argument is given.
* _forwarding-class_except::_ Do not match the specified forwarding classes.
* _fragement-offset::_ specify a fragment offset of a fragmented packet
* _hop-limit::_ Match the hop limit to the specified hop limit or set of hop limits.
* _hop-limit-except::_ Allow all hop limits "except" the one specified.
* _icmp-code::_ Specifies the ICMP code to filter on.
* _icmp-type::_ Specify icmp-type code to match, see section [ICMP TYPES](PolicyFormat#ICMP_TYPES.md) for list of valid arguments
* _logging::_ Specify that this packet should be logged via syslog.
Expand Down
22 changes: 21 additions & 1 deletion tests/lib/juniper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@
action:: accept
}
"""
GOOD_TERM_V6_HOP_LIMIT_EXCEPT = """
term good-term-v6-hl {
hop-limit-except:: 25
action:: accept
}
"""
GOOD_TERM_20_V6 = """
term good-term-20-v6 {
protocol-except:: icmpv6
Expand Down Expand Up @@ -588,7 +594,6 @@
action:: deny
}
"""

MIXED_TESTING_TERM = """
term good-term {
protocol:: tcp
Expand Down Expand Up @@ -621,6 +626,7 @@
'forwarding_class_except',
'fragment_offset',
'hop_limit',
'hop_limit_except',
'icmp_code',
'icmp_type',
'stateless_reply',
Expand Down Expand Up @@ -926,6 +932,20 @@ def testHopLimitInet(self):
output = str(jcl)
self.assertNotIn('hop-limit 25;', output, output)

def testHopLimitExcept(self):
jcl = juniper.Juniper(policy.ParsePolicy(GOOD_HEADER_V6 +
GOOD_TERM_V6_HOP_LIMIT_EXCEPT,
self.naming), EXP_INFO)
output = str(jcl)
self.assertIn('hop-limit-except 25;', output, output)

def testHopLimitExceptInet(self):
jcl = juniper.Juniper(policy.ParsePolicy(GOOD_HEADER +
GOOD_TERM_V6_HOP_LIMIT_EXCEPT,
self.naming), EXP_INFO)
output = str(jcl)
self.assertNotIn('hop-limit-except 25;', output, output)

def testProtocolExcept(self):
jcl = juniper.Juniper(policy.ParsePolicy(GOOD_HEADER_V6 + GOOD_TERM_7,
self.naming), EXP_INFO)
Expand Down
13 changes: 13 additions & 0 deletions tests/lib/policy_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,12 @@
action:: accept
}
"""
GOOD_TERM_V6_HOP_LIMIT_EXCEPT = """
term good-term-v6-1 {
hop-limit-except:: 5
action:: accept
}
"""

TERM_SUPER_2 = """
term term-super {
Expand Down Expand Up @@ -695,6 +701,13 @@ def testHopLimitRange(self):
_, terms = ret.filters[0]
self.assertEqual(str(terms[0].hop_limit[2]), '7')

def testHopLimitExcept(self):
pol = HEADER_V6 + GOOD_TERM_V6_HOP_LIMIT_EXCEPT
ret = policy.ParsePolicy(pol, self.naming)
self.assertEqual(len(ret.filters), 1)
_, terms = ret.filters[0]
self.assertEqual(str(terms[0].hop_limit_except[0]), '5')

def testBadPortProtocols(self):
pol = HEADER + BAD_TERM_3
self.naming.GetServiceByProto('SNMP', 'tcp').AndReturn([])
Expand Down
1 change: 1 addition & 0 deletions tests/lib/srxlo_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
'forwarding_class_except',
'fragment_offset',
'hop_limit',
'hop_limit_except',
'icmp_code',
'icmp_type',
'stateless_reply',
Expand Down

0 comments on commit fbb1c0c

Please sign in to comment.