|
|
@ -153,15 +153,16 @@ class OspfFileTopologyParser:
|
|
|
|
# already be created, so the only issue is resolving the correct
|
|
|
|
# already be created, so the only issue is resolving the correct
|
|
|
|
# VertexIDs for the networks.
|
|
|
|
# VertexIDs for the networks.
|
|
|
|
# Since these are networks, the process is generally different for each version of OSPF
|
|
|
|
# Since these are networks, the process is generally different for each version of OSPF
|
|
|
|
if self.version is None:
|
|
|
|
if len(self.future_transit_networks_edges) > 0:
|
|
|
|
# TODO: logger?
|
|
|
|
if self.version is None:
|
|
|
|
print('WARNING: At this point the OSPF version should have been guessed!')
|
|
|
|
# TODO: logger?
|
|
|
|
# We need some sort of directive for this. We make one up.
|
|
|
|
print('WARNING: At this point the OSPF version should have been guessed!')
|
|
|
|
directive = 'network ' + self.future_transit_networks_edges[0][1]
|
|
|
|
# We need some sort of directive for this. We make one up.
|
|
|
|
self.guess_version(directive)
|
|
|
|
directive = 'network ' + self.future_transit_networks_edges[0][1]
|
|
|
|
if self.version == 2: return self.add_transit_network_edges_ospfv2(result)
|
|
|
|
self.guess_version(directive)
|
|
|
|
if self.version == 3: return self.add_transit_network_edges_ospfv3(result)
|
|
|
|
if self.version == 2: return self.add_transit_network_edges_ospfv2(result)
|
|
|
|
raise RuntimeError('Bug? Unreachable point of code.')
|
|
|
|
if self.version == 3: return self.add_transit_network_edges_ospfv3(result)
|
|
|
|
|
|
|
|
raise RuntimeError('Bug? Unreachable point of code.')
|
|
|
|
|
|
|
|
|
|
|
|
def add_transit_network_edges_ospfv2(self, result):
|
|
|
|
def add_transit_network_edges_ospfv2(self, result):
|
|
|
|
for src, tgt, cost, count in self.future_transit_networks_edges:
|
|
|
|
for src, tgt, cost, count in self.future_transit_networks_edges:
|
|
|
@ -192,6 +193,7 @@ class OspfFileTopologyParser:
|
|
|
|
# determine the network. (We are dealing with a single topology, so
|
|
|
|
# determine the network. (We are dealing with a single topology, so
|
|
|
|
# it must match.)
|
|
|
|
# it must match.)
|
|
|
|
dr_id, discr = tgt.lstrip(r'[').rstrip(']').split('-')
|
|
|
|
dr_id, discr = tgt.lstrip(r'[').rstrip(']').split('-')
|
|
|
|
|
|
|
|
dr_id = self.parse_fake_ip(dr_id)
|
|
|
|
candidates = list(filter(lambda vid: vid.dr_id == dr_id and vid.discriminator == discr, result.vertices))
|
|
|
|
candidates = list(filter(lambda vid: vid.dr_id == dr_id and vid.discriminator == discr, result.vertices))
|
|
|
|
if len(candidates) != 1: raise OspfFileParseError(f'Multiple or no candidates for uniquely determined network {tgt}')
|
|
|
|
if len(candidates) != 1: raise OspfFileParseError(f'Multiple or no candidates for uniquely determined network {tgt}')
|
|
|
|
tgtid = candidates[0]
|
|
|
|
tgtid = candidates[0]
|
|
|
@ -226,7 +228,7 @@ class OspfFileTopologyParser:
|
|
|
|
# moment this will crash and only then will we implement that
|
|
|
|
# moment this will crash and only then will we implement that
|
|
|
|
# feature. (We could guess the format right away, but that would
|
|
|
|
# feature. (We could guess the format right away, but that would
|
|
|
|
# only be a guess.)
|
|
|
|
# only be a guess.)
|
|
|
|
tag, router = line.split
|
|
|
|
tag, router = line.split()
|
|
|
|
rid = self.parse_fake_ip(router)
|
|
|
|
rid = self.parse_fake_ip(router)
|
|
|
|
peer_id = VertexID(family=None, address=None, is_router=True, router_id=rid, dr_id=None, discriminator=None)
|
|
|
|
peer_id = VertexID(family=None, address=None, is_router=True, router_id=rid, dr_id=None, discriminator=None)
|
|
|
|
future_edges[peer_id] += 1
|
|
|
|
future_edges[peer_id] += 1
|
|
|
@ -323,12 +325,12 @@ class OspfFileTopologyParser:
|
|
|
|
if tag != 'network': raise RuntimeError('Bug? Guessing from a non-network. (No tasseography here.)')
|
|
|
|
if tag != 'network': raise RuntimeError('Bug? Guessing from a non-network. (No tasseography here.)')
|
|
|
|
# For OSPFv2, networks can be identified by DR RID on l3, but it will
|
|
|
|
# For OSPFv2, networks can be identified by DR RID on l3, but it will
|
|
|
|
# not contain iface ID. (Ref: BIRD source @ ecbae010 proto/ospf/ospf.c:1084)
|
|
|
|
# not contain iface ID. (Ref: BIRD source @ ecbae010 proto/ospf/ospf.c:1084)
|
|
|
|
self.version = 3 if ident.contains(r'-') else 2
|
|
|
|
self.version = 3 if r'-' in ident else 2
|
|
|
|
|
|
|
|
|
|
|
|
def get_vertex_for_l2_network_ospfv3(self, directive, details):
|
|
|
|
def get_vertex_for_l2_network_ospfv3(self, directive, details):
|
|
|
|
_tag, ident = directive.split()
|
|
|
|
_tag, ident = directive.split()
|
|
|
|
# In OSPFv3, the ID is always '[DRID-iface]'
|
|
|
|
# In OSPFv3, the ID is always '[DRID-iface]'
|
|
|
|
dr, discr = directive.rstrip(r'[').rstrip(r']').split(r'-')
|
|
|
|
dr, discr = ident.lstrip(r'[').rstrip(r']').split(r'-')
|
|
|
|
dr = self.parse_fake_ip(dr)
|
|
|
|
dr = self.parse_fake_ip(dr)
|
|
|
|
addresses = []
|
|
|
|
addresses = []
|
|
|
|
for line, chld in details:
|
|
|
|
for line, chld in details:
|
|
|
|