Correctly parse aspath for both bird 1.x and 2.0.

Due to the change in the output of `show route for <prefix> 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>
    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 <prefix> (bgpmap)` shows an error icon.
This commit is contained in:
tamihiro 2019-06-09 18:35:20 +09:00
parent 85963901f8
commit eaf531eee2
1 changed files with 20 additions and 9 deletions

29
lg.py
View File

@ -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(" ")