Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Commit

Permalink
Merge djmitche/build-fwunit:issue36 (PR #36)
Browse files Browse the repository at this point in the history
  • Loading branch information
djmitche committed May 19, 2015
2 parents 003a79a + 7cd5f68 commit 6679619
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 7 deletions.
20 changes: 17 additions & 3 deletions fwunit/srx/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,37 @@ def __init__(self):
#: true if this destination is local (no next-hop IP)
self.is_local = None

#: true if this is a "Reject" (blackhole) route
self.reject = False

def __str__(self):
return "%s via %s" % (self.destination, self.interface)

@classmethod
def _from_xml(cls, rt_elt):
valid = False
route = cls()
route.destination = IP(rt_elt.find('rt-destination').text)
for entry in rt_elt.findall('rt-entry'):
if entry.findall('.//current-active'):
vias = entry.findall('.//via')
if vias:
route.interface = vias[0].text
valid = True
route.is_local = not bool(
entry.findall('.//to'))
# only return a Route if we found something useful (omitting
# nh-local-interface)
if route.interface:
nh_types = entry.findall('.//nh-type')
if nh_types:
if nh_types[0].text == 'Reject':
route.reject = True
valid = True

# don't pretend blackholes are local
if route.reject:
route.is_local = False

# only return a Route if we found something useful
if valid:
return route


Expand Down
9 changes: 5 additions & 4 deletions fwunit/srx/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ def process_interface_ips(routes):
matched = IPSet()
interface_ips = {}
for r in routes:
if not r.interface:
continue
destset = IPSet([r.destination])
interface_ips[r.interface] = interface_ips.get(
r.interface, IPSet()) + (destset - matched)
if r.interface and not r.reject:
interface_ips[r.interface] = interface_ips.get(
r.interface, IPSet()) + (destset - matched)
# consider the route matched even if it didn't have an
# interface or is a blackhole
matched = matched + destset
return interface_ips

Expand Down
9 changes: 9 additions & 0 deletions fwunit/test/unit/test_srx_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from fwunit.ip import IP, IPSet
from fwunit.srx import parse
from nose.tools import eq_
from fwunit.test.util.srx_xml import route_xml_blackhole
from fwunit.test.util.srx_xml import route_xml_11_4R6
from fwunit.test.util.srx_xml import zones_empty_xml
from fwunit.test.util.srx_xml import FakeSRX
Expand Down Expand Up @@ -142,6 +143,14 @@ def test_parse_zones_empty():
eq_(sorted(z.addresses.keys()), sorted(['any', 'any-ipv6', 'any-ipv4']))


def test_parse_route_blackhole():
elt = parse_xml(route_xml_blackhole, './/rt')
r = parse.Route._from_xml(elt)
eq_(r.destination, IP('20.0.0.0/8'))
eq_(r.interface, None)
eq_(r.is_local, False)


def test_parse_route_11_4R6():
elt = parse_xml(route_xml_11_4R6, './/rt')
r = parse.Route._from_xml(elt)
Expand Down
35 changes: 35 additions & 0 deletions fwunit/test/unit/test_srx_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from fwunit.common import ApplicationMap
from fwunit.test.util import ipset
from fwunit.types import Rule
from fwunit import IP

APP_MAP = ApplicationMap(dict(application_map={'junos-ssh': 'ssh'}))
ZONE_NETS = {
Expand Down Expand Up @@ -95,3 +96,37 @@ def test_process_rules_any_app():
}
[ruleset.sort() for ruleset in exp.itervalues()]
eq_(res, exp)


def mkroute(**kwargs):
kwargs['destination'] = IP(kwargs['destination'])
kwargs.setdefault('is_local', False)
rt = parse.Route()
for k, v in kwargs.iteritems():
setattr(rt, k, v)
return rt


def test_process_interface_ips():
routes = [
# reth2 is the route to the Internet
mkroute(destination="0.0.0.0/0", interface='reth2'),
# reth1 is the gateway to the rest of the private space
mkroute(destination="10.0.0.0/8", interface='reth1'),
# reth7 is the peer link to some other private /16's
mkroute(destination="10.128.0.0/16", interface='reth7'),
mkroute(destination="10.130.0.0/15", interface='reth7'),
# 10.129.0.0/16 is ours, but has only one active subnet,
# with the rest blackholed
mkroute(destination="10.129.0.0/16", reject=True),
mkroute(destination="10.129.210.0/24",
interface='reth0.210', is_local=True),
]
interface_ips = process.process_interface_ips(routes)
exp = {
'reth0.210': ipset('10.129.210.0/24'),
'reth1': ipset('10.0.0.0/8') - ipset('10.128.0.0/14'), # 10.{128-131}
'reth2': ipset('0.0.0.0/0') - ipset('10.0.0.0/8'),
'reth7': ipset('10.128.0.0/16') + ipset('10.130.0.0/15'),
}
eq_(interface_ips, exp)
31 changes: 31 additions & 0 deletions fwunit/test/util/srx_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,37 @@
</rpc-reply>
"""

route_xml_blackhole = """\
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.1X44/junos">
<route-information xmlns="http://xml.juniper.net/junos/12.1X44/junos-routing">
<!-- keepalive -->
<route-table>
<table-name>inet.0</table-name>
<destination-count>273</destination-count>
<total-route-count>410</total-route-count>
<active-route-count>273</active-route-count>
<holddown-route-count>0</holddown-route-count>
<hidden-route-count>0</hidden-route-count>
<rt junos:style="brief">
<rt-destination>20.0.0.0/8</rt-destination>
<rt-entry>
<active-tag>*</active-tag>
<current-active/>
<last-active/>
<protocol-name>Aggregate</protocol-name>
<preference>130</preference>
<age junos:seconds="33111187">54w5d 05:33:07</age>
<nh-type>Reject</nh-type>
</rt-entry>
</rt>
</route-table>
</route-information>
<cli>
<banner>{primary:node1}</banner>
</cli>
</rpc-reply>
"""

route_xml_11_4R6 = """\
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/11.4R6/junos">
<route-information xmlns="http://xml.juniper.net/junos/11.4R6/junos-routing">
Expand Down

0 comments on commit 6679619

Please sign in to comment.