Skip to content

Commit 6293304

Browse files
committed
Add hop-limit-except to Juniper
1 parent a33c44a commit 6293304

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

capirca/lib/juniper.py

+7
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ def __str__(self):
313313
self.term.forwarding_class_except or
314314
self.term.fragment_offset or
315315
self.term.hop_limit or
316+
self.term.hop_limit_except or
316317
self.term.next_ip or
317318
self.term.port or
318319
self.term.precedence or
@@ -544,6 +545,11 @@ def __str__(self):
544545
if self.term_type == 'inet6':
545546
config.Append('hop-limit %s;' % (self.term.hop_limit))
546547

548+
if self.term.hop_limit_except:
549+
# Only generate a hop-limit-except if inet6, inet4 has not hop-limit-except.
550+
if self.term_type == 'inet6':
551+
config.Append('hop-limit-except %s;' % (self.term.hop_limit_except))
552+
547553
# flexible-match
548554
if self.term.flexible_match_range:
549555
config.Append('flexible-match-range {')
@@ -911,6 +917,7 @@ def _BuildTokens(self):
911917
'forwarding_class_except',
912918
'fragment_offset',
913919
'hop_limit',
920+
'hop_limit_except',
914921
'icmp_code',
915922
'logging',
916923
'loss_priority',

capirca/lib/policy.py

+12
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ def __init__(self, obj):
444444
self.packet_length = None
445445
self.fragment_offset = None
446446
self.hop_limit = None
447+
self.hop_limit_except = None
447448
self.icmp_type = []
448449
self.icmp_code = []
449450
self.ether_type = []
@@ -904,6 +905,8 @@ def __eq__(self, other):
904905
return False
905906
if self.hop_limit != other.hop_limit:
906907
return False
908+
if self.hop_limit_except != other.hop_limit_except:
909+
return False
907910
if sorted(self.icmp_type) != sorted(other.icmp_type):
908911
return False
909912
if sorted(self.icmp_code) != sorted(other.icmp_code):
@@ -1240,6 +1243,8 @@ def AddObject(self, obj):
12401243
self.fragment_offset = obj.value
12411244
elif obj.var_type is VarType.HOP_LIMIT:
12421245
self.hop_limit = obj.value
1246+
elif obj.var_type is VarType.HOP_LIMIT_EXCEPT:
1247+
self.hop_limit_except = obj.value
12431248
elif obj.var_type is VarType.SINTERFACE:
12441249
self.source_interface = obj.value
12451250
elif obj.var_type is VarType.DINTERFACE:
@@ -1582,6 +1587,7 @@ class VarType:
15821587
SZONE = 65
15831588
DZONE = 66
15841589
TTL_EXCEPT = 67
1590+
HOP_LIMIT_EXCEPT = 68
15851591

15861592
def __init__(self, var_type, value):
15871593
self.var_type = var_type
@@ -1766,6 +1772,7 @@ def __ne__(self, other):
17661772
'FORWARDING_CLASS_EXCEPT',
17671773
'FRAGMENT_OFFSET',
17681774
'HOP_LIMIT',
1775+
'HOP_LIMIT_EXCEPT',
17691776
'APPLY_GROUPS',
17701777
'APPLY_GROUPS_EXCEPT',
17711778
'HEADER',
@@ -1854,6 +1861,7 @@ def __ne__(self, other):
18541861
'fragment-offset': 'FRAGMENT_OFFSET',
18551862
'hex': 'HEX',
18561863
'hop-limit': 'HOP_LIMIT',
1864+
'hop-limit-except': 'HOP_LIMIT_EXCEPT',
18571865
'apply-groups': 'APPLY_GROUPS',
18581866
'apply-groups-except': 'APPLY_GROUPS_EXCEPT',
18591867
'header': 'HEADER',
@@ -2039,6 +2047,7 @@ def p_term_spec(p):
20392047
| term_spec forwarding_class_except_spec
20402048
| term_spec fragment_offset_spec
20412049
| term_spec hop_limit_spec
2050+
| term_spec hop_limit_except_spec
20422051
| term_spec icmp_type_spec
20432052
| term_spec icmp_code_spec
20442053
| term_spec interface_spec
@@ -2207,6 +2216,9 @@ def p_hop_limit_spec(p):
22072216
else:
22082217
p[0] = VarType(VarType.HOP_LIMIT, str(p[4]) + '-' + str(p[6]))
22092218

2219+
def p_hop_limit_except_spec(p):
2220+
""" hop_limit_except_spec : HOP_LIMIT_EXCEPT ':' ':' INTEGER"""
2221+
p[0] = VarType(VarType.HOP_LIMIT_EXCEPT, p[4])
22102222

22112223
def p_one_or_more_dscps(p):
22122224
""" one_or_more_dscps : one_or_more_dscps DSCP_RANGE

doc/generators/juniper.md

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ The default format is _inet4_, and is implied if not other argument is given.
5454
* _forwarding-class_except::_ Do not match the specified forwarding classes.
5555
* _fragement-offset::_ specify a fragment offset of a fragmented packet
5656
* _hop-limit::_ Match the hop limit to the specified hop limit or set of hop limits.
57+
* _hop-limit-except::_ Allow all hop limits "except" the one specified.
5758
* _icmp-code::_ Specifies the ICMP code to filter on.
5859
* _icmp-type::_ Specify icmp-type code to match, see section [ICMP TYPES](PolicyFormat#ICMP_TYPES.md) for list of valid arguments
5960
* _logging::_ Specify that this packet should be logged via syslog.

tests/lib/juniper_test.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@
251251
action:: accept
252252
}
253253
"""
254+
GOOD_TERM_V6_HOP_LIMIT_EXCEPT = """
255+
term good-term-v6-hl {
256+
hop-limit-except:: 25
257+
action:: accept
258+
}
259+
"""
254260
GOOD_TERM_20_V6 = """
255261
term good-term-20-v6 {
256262
protocol-except:: icmpv6
@@ -588,7 +594,6 @@
588594
action:: deny
589595
}
590596
"""
591-
592597
MIXED_TESTING_TERM = """
593598
term good-term {
594599
protocol:: tcp
@@ -621,6 +626,7 @@
621626
'forwarding_class_except',
622627
'fragment_offset',
623628
'hop_limit',
629+
'hop_limit_except',
624630
'icmp_code',
625631
'icmp_type',
626632
'stateless_reply',
@@ -926,6 +932,20 @@ def testHopLimitInet(self):
926932
output = str(jcl)
927933
self.assertNotIn('hop-limit 25;', output, output)
928934

935+
def testHopLimitExcept(self):
936+
jcl = juniper.Juniper(policy.ParsePolicy(GOOD_HEADER_V6 +
937+
GOOD_TERM_V6_HOP_LIMIT_EXCEPT,
938+
self.naming), EXP_INFO)
939+
output = str(jcl)
940+
self.assertIn('hop-limit-except 25;', output, output)
941+
942+
def testHopLimitExceptInet(self):
943+
jcl = juniper.Juniper(policy.ParsePolicy(GOOD_HEADER +
944+
GOOD_TERM_V6_HOP_LIMIT_EXCEPT,
945+
self.naming), EXP_INFO)
946+
output = str(jcl)
947+
self.assertNotIn('hop-limit-except 25;', output, output)
948+
929949
def testProtocolExcept(self):
930950
jcl = juniper.Juniper(policy.ParsePolicy(GOOD_HEADER_V6 + GOOD_TERM_7,
931951
self.naming), EXP_INFO)

tests/lib/policy_test.py

+13
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,12 @@
457457
action:: accept
458458
}
459459
"""
460+
GOOD_TERM_V6_HOP_LIMIT_EXCEPT = """
461+
term good-term-v6-1 {
462+
hop-limit-except:: 5
463+
action:: accept
464+
}
465+
"""
460466

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

704+
def testHopLimitExcept(self):
705+
pol = HEADER_V6 + GOOD_TERM_V6_HOP_LIMIT_EXCEPT
706+
ret = policy.ParsePolicy(pol, self.naming)
707+
self.assertEqual(len(ret.filters), 1)
708+
_, terms = ret.filters[0]
709+
self.assertEqual(str(terms[0].hop_limit_except[0]), '5')
710+
698711
def testBadPortProtocols(self):
699712
pol = HEADER + BAD_TERM_3
700713
self.naming.GetServiceByProto('SNMP', 'tcp').AndReturn([])

0 commit comments

Comments
 (0)