From eaf531eee213ec0bb5936f982497b6a8b548d614 Mon Sep 17 00:00:00 2001 From: tamihiro Date: Sun, 9 Jun 2019 18:35:20 +0900 Subject: [PATCH] Correctly parse aspath for both bird 1.x and 2.0. Due to the change in the output of `show route for all` since bird-2.0, this patch is necessary to correctly parse aspaths. Without this patch, `build_as_tree_from_raw_bird_ouput()` fails with the following exception if the backend is bird-2.0. ``` Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__ return self.wsgi_app(environ, start_response) File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "./lg.py", line 522, in show_bgpmap response = Response(graph.create_png(), mimetype='image/png') File "/usr/lib/python2.7/dist-packages/pydot.py", line 1735, in lambda f=frmt, prog=self.prog: self.create(format=f, prog=prog) File "/usr/lib/python2.7/dist-packages/pydot.py", line 1905, in create self.write(tmp_name) File "/usr/lib/python2.7/dist-packages/pydot.py", line 1830, in write data = self.to_string() File "/usr/lib/python2.7/dist-packages/pydot.py", line 1600, in to_string graph.append(node.to_string() + '\n') File "/usr/lib/python2.7/dist-packages/pydot.py", line 865, in to_string node += ' [' + node_attr + ']' TypeError: unsupported operand type(s) for +=: 'NoneType' and 'str' ``` Consequently, `show route for (bgpmap)` shows an error icon. --- lg.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lg.py b/lg.py index 40caa95..daf3973 100644 --- a/lg.py +++ b/lg.py @@ -538,21 +538,29 @@ def build_as_tree_from_raw_bird_ouput(host, proto, text): path = None paths = [] net_dest = None + peer_protocol_name = None for line in text: line = line.strip() - expr = re.search(r'(.*)via\s+([0-9a-fA-F:\.]+)\s+on.*\[(\w+)\s+', line) + expr = re.search(r'(.*)unicast\s+\[(\w+)\s+', line) if expr: + if expr.group(1).strip(): + net_dest = expr.group(1).strip() + peer_protocol_name = expr.group(2).strip() + + expr2 = re.search(r'(.*)via\s+([0-9a-fA-F:\.]+)\s+on\s+\w+(\s+\[(\w+)\s+)?', line) + if expr2: if path: path.append(net_dest) paths.append(path) path = None - if expr.group(1).strip(): - net_dest = expr.group(1).strip() + if expr2.group(1).strip(): + net_dest = expr2.group(1).strip() - peer_ip = expr.group(2).strip() - peer_protocol_name = expr.group(3).strip() + peer_ip = expr2.group(2).strip() + if expr2.group(4): + peer_protocol_name = expr2.group(4).strip() # Check if via line is a internal route for rt_host, rt_ips in app.config["ROUTER_IP"].iteritems(): # Special case for internal routing @@ -564,15 +572,18 @@ def build_as_tree_from_raw_bird_ouput(host, proto, text): path = [ peer_protocol_name ] # path = ["%s\r%s" % (peer_protocol_name, get_as_name(get_as_number_from_protocol_name(host, proto, peer_protocol_name)))] - expr2 = re.search(r'(.*)unreachable\s+\[(\w+)\s+', line) - if expr2: + expr3 = re.search(r'(.*)unreachable\s+\[(\w+)\s+', line) + if expr3: if path: path.append(net_dest) paths.append(path) path = None - if expr2.group(1).strip(): - net_dest = expr2.group(1).strip() + if path is None: + path = [ expr3.group(2).strip() ] + + if expr3.group(1).strip(): + net_dest = expr3.group(1).strip() if line.startswith("BGP.as_path:"): ASes = line.replace("BGP.as_path:", "").strip().split(" ")