Add support for unified Bird daemons
Bird 2.0 includes IPv4 and IPv6 support in a single daemon. When UNIFIED_DAEMON is set to True, queries are always done with the "ipv4" backend (which handles both protocols), and distinctions between IPv4 and IPv4 are removed in the UI.
This commit is contained in:
parent
daaf981b32
commit
ddf86d02fb
4
lg.cfg
4
lg.cfg
@ -13,6 +13,10 @@ PROXY = {
|
||||
"h3": "h3.some.network:5000",
|
||||
}
|
||||
|
||||
# If True, queries are always done with the "ipv4" backend,
|
||||
# and the distinction between IPv4 and IPv6 is removed from the UI.
|
||||
UNIFIED_DAEMON = True
|
||||
|
||||
# Used for bgpmap
|
||||
ROUTER_IP = {
|
||||
"gw" : [ "91.224.148.2", "2a01:6600:8000::175" ],
|
||||
|
80
lg.py
80
lg.py
@ -32,7 +32,7 @@ from urllib import quote, unquote
|
||||
import json
|
||||
import random
|
||||
|
||||
from toolbox import mask_is_valid, ipv6_is_valid, ipv4_is_valid, resolve, save_cache_pickle, load_cache_pickle, unescape
|
||||
from toolbox import mask_is_valid, ip_is_valid, ipv6_is_valid, ipv4_is_valid, resolve, resolve_any, save_cache_pickle, load_cache_pickle, unescape
|
||||
#from xml.sax.saxutils import escape
|
||||
|
||||
|
||||
@ -119,7 +119,10 @@ def whois_command(query):
|
||||
|
||||
def bird_command(host, proto, query):
|
||||
"""Alias to bird_proxy for bird service"""
|
||||
return bird_proxy(host, proto, "bird", query)
|
||||
if app.config.get("UNIFIED_DAEMON", False):
|
||||
return bird_proxy(host, "ipv4", "bird", query)
|
||||
else:
|
||||
return bird_proxy(host, proto, "bird", query)
|
||||
|
||||
|
||||
def bird_proxy(host, proto, service, query):
|
||||
@ -305,16 +308,23 @@ def traceroute(hosts, proto):
|
||||
|
||||
set_session("traceroute", hosts, proto, q)
|
||||
|
||||
if proto == "ipv6" and not ipv6_is_valid(q):
|
||||
try:
|
||||
q = resolve(q, "AAAA")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (q, proto))
|
||||
if proto == "ipv4" and not ipv4_is_valid(q):
|
||||
try:
|
||||
q = resolve(q, "A")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (q, proto))
|
||||
if app.config.get("UNIFIED_DAEMON", False):
|
||||
if not ip_is_valid(q):
|
||||
try:
|
||||
q = resolve_any(q)
|
||||
except:
|
||||
return error_page("%s is unresolvable" % q)
|
||||
else:
|
||||
if proto == "ipv6" and not ipv6_is_valid(q):
|
||||
try:
|
||||
q = resolve(q, "AAAA")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (q, proto))
|
||||
if proto == "ipv4" and not ipv4_is_valid(q):
|
||||
try:
|
||||
q = resolve(q, "A")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (q, proto))
|
||||
|
||||
errors = []
|
||||
infos = {}
|
||||
@ -608,23 +618,37 @@ def show_route(request_type, hosts, proto):
|
||||
if len(expression.split("/")) == 2:
|
||||
expression, mask = (expression.split("/"))
|
||||
|
||||
if not mask and proto == "ipv4":
|
||||
mask = "32"
|
||||
if not mask and proto == "ipv6":
|
||||
mask = "128"
|
||||
if not mask_is_valid(mask):
|
||||
return error_page("mask %s is invalid" % mask)
|
||||
if app.config.get("UNIFIED_DAEMON", False):
|
||||
if not ip_is_valid(expression):
|
||||
try:
|
||||
expression = resolve_any(expression)
|
||||
except:
|
||||
return error_page("%s is unresolvable" % expression)
|
||||
|
||||
if proto == "ipv6" and not ipv6_is_valid(expression):
|
||||
try:
|
||||
expression = resolve(expression, "AAAA")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (expression, proto))
|
||||
if proto == "ipv4" and not ipv4_is_valid(expression):
|
||||
try:
|
||||
expression = resolve(expression, "A")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (expression, proto))
|
||||
if not mask and ipv4_is_valid(expression):
|
||||
mask = "32"
|
||||
if not mask and ipv6_is_valid(expression):
|
||||
mask = "128"
|
||||
if not mask_is_valid(mask):
|
||||
return error_page("mask %s is invalid" % mask)
|
||||
else:
|
||||
if not mask and proto == "ipv4":
|
||||
mask = "32"
|
||||
if not mask and proto == "ipv6":
|
||||
mask = "128"
|
||||
if not mask_is_valid(mask):
|
||||
return error_page("mask %s is invalid" % mask)
|
||||
|
||||
if proto == "ipv6" and not ipv6_is_valid(expression):
|
||||
try:
|
||||
expression = resolve(expression, "AAAA")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (expression, proto))
|
||||
if proto == "ipv4" and not ipv4_is_valid(expression):
|
||||
try:
|
||||
expression = resolve(expression, "A")
|
||||
except:
|
||||
return error_page("%s is unresolvable or invalid for %s" % (expression, proto))
|
||||
|
||||
if mask:
|
||||
expression += "/" + mask
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
{% for host in detail %}
|
||||
<h3>{{host}}/{{session.proto}}: {{command}}</h3>
|
||||
<h3>{{host}}{% if not config.UNIFIED_DAEMON %}/{{session.proto}}{% endif %}: {{command}}</h3>
|
||||
<i>{{ detail[host].status }}</i><br /><br />
|
||||
<pre>
|
||||
{{ detail[host].description|trim|safe }}
|
||||
|
@ -24,10 +24,12 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if not config.UNIFIED_DAEMON %}
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-primary proto" id="ipv4" href="#">ipv4</a>
|
||||
<a class="btn btn-primary proto" id="ipv6" href="#">ipv6</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<ul class="nav">
|
||||
<li class="nav-item dropdown request_type">
|
||||
@ -74,7 +76,7 @@
|
||||
{% for hosts, proto, request_type, request_args in session.history %}
|
||||
<a class="list-group-item list-group-item-action {% if loop.first %}active{% endif %}"
|
||||
href="/{{ [request_type, hosts, proto]|join("/") }}{% if request_args %}?q={{request_args}}{% endif %}">
|
||||
{{hosts}}/{{proto}}: {{ commands_dict[request_type]|replace("...", request_args) }}
|
||||
{{hosts}}{% if not config.UNIFIED_DAEMON %}/{{proto}}{% endif %}: {{ commands_dict[request_type]|replace("...", request_args) }}
|
||||
</a>
|
||||
|
||||
{% endfor %}
|
||||
|
11
toolbox.py
11
toolbox.py
@ -31,6 +31,14 @@ resolv.lifetime = 1
|
||||
def resolve(n, q):
|
||||
return str(resolv.query(n,q)[0])
|
||||
|
||||
def resolve_any(h):
|
||||
try:
|
||||
return resolve(h, "AAAA")
|
||||
except:
|
||||
pass
|
||||
return resolve(h, "A")
|
||||
|
||||
|
||||
def mask_is_valid(n):
|
||||
if not n:
|
||||
return True
|
||||
@ -40,6 +48,9 @@ def mask_is_valid(n):
|
||||
except:
|
||||
return False
|
||||
|
||||
def ip_is_valid(n):
|
||||
return ipv4_is_valid(n) or ipv6_is_valid(n)
|
||||
|
||||
def ipv4_is_valid(n):
|
||||
try:
|
||||
socket.inet_pton(socket.AF_INET, n)
|
||||
|
Loading…
x
Reference in New Issue
Block a user