1
0
Fork 0
mirror of https://github.com/NeoCloud/NeoNetwork synced 2024-07-01 22:28:44 +08:00

roa.py: update

This commit is contained in:
JerryXiao 2020-05-02 11:29:44 +08:00
parent 5e3e4777d2
commit 9504e56655
Signed by: Jerry
GPG key ID: 9D9CE43650FF2BAA

View file

@ -69,26 +69,36 @@ def route2roa(dirname, is_ipv6=False):
continue continue
fc = shell2dict(f.read_text()) fc = shell2dict(f.read_text())
nettype = IPv6Network if is_ipv6 else IPv4Network nettype = IPv6Network if is_ipv6 else IPv4Network
get_supernet = lambda s_net: None if not s_net else nettype(s_net, strict=True)
roa_entries_key = ("asn", "prefix", "supernet")
if fc.get('type') in ('lo', 'subnet'): if fc.get('type') in ('lo', 'subnet'):
asn = str2asn(fc.get('as')) asn = str2asn(fc.get('as'))
assert asn in ASNS assert asn in ASNS
route = f.name.replace(',', '/') route = f.name.replace(',', '/')
roa_entries.append([asn, nettype(route, strict=True)]) supernet = get_supernet(fc.get('supernet'))
roa_entries.append(dict(zip(roa_entries_key, [asn, nettype(route, strict=True), supernet])))
elif fc.get('type').startswith('tun'): elif fc.get('type').startswith('tun'):
assert NODE_TABLE[fc.get('downstream')] # extra check for downstream assert NODE_TABLE[fc.get('downstream')] # extra check for downstream
asn = NODE_TABLE[fc.get('upstream')] asn = NODE_TABLE[fc.get('upstream')]
assert asn in ASNS assert asn in ASNS
route = f.name.replace(',', '/') route = f.name.replace(',', '/')
roa_entries.append([asn, nettype(route, strict=True)]) supernet = get_supernet(fc.get('supernet'))
roa_entries.append(dict(zip(roa_entries_key, [asn, nettype(route, strict=True), supernet])))
else: else:
assert fc.get('type') in ('ptp',) assert fc.get('type') in ('ptp',)
except Exception: except Exception:
print("[!] Error while processing file", f) print("[!] Error while processing file", f)
raise raise
roa_entries.sort(key=lambda l: l[0]) roa_entries.sort(key=lambda l: l['asn'])
for en1, en2 in combinations(roa_entries, 2): for _net1, _net2 in combinations(roa_entries, 2):
if en1[1].overlaps(en2[1]): net1, net2 = sorted([_net1, _net2], key=lambda net: net['prefix'].prefixlen)
print("[!] Error: found", en1[1], "overlaps", en2[1]) if net1['prefix'].overlaps(net2['prefix']):
if net1['prefix'] != net2['prefix'] and net1['prefix'].supernet_of(net2['prefix']) \
and net2['supernet'] == net1['prefix']:
# This is allowed
pass
else:
print("[!] Error: found", net2, "overlaps", net1)
raise AssertionError raise AssertionError
return roa_entries return roa_entries
@ -114,38 +124,38 @@ if __name__ == "__main__":
roa4 = route2roa('route') roa4 = route2roa('route')
roa6 = route2roa('route6', True) roa6 = route2roa('route6', True)
roa4 = [r for r in roa4 if r[1].prefixlen <= args.max or r[1].prefixlen == IPv4Network(0).max_prefixlen] roa4 = [r for r in roa4 if r['prefix'].prefixlen <= args.max or r['prefix'].prefixlen == IPv4Network(0).max_prefixlen]
roa6 = [r for r in roa6 if r[1].prefixlen <= args.max6] roa6 = [r for r in roa6 if r['prefix'].prefixlen <= args.max6]
for r in roa4: for r in roa4:
if r[1].prefixlen == IPv4Network(0).max_prefixlen: if r['prefix'].prefixlen == IPv4Network(0).max_prefixlen:
r.append(IPv4Network(0).max_prefixlen) r['maxLength'] = IPv4Network(0).max_prefixlen
else: else:
r.append(args.max) r['maxLength'] = args.max
r[1] = r[1].with_prefixlen
for r in roa6: for r in roa6:
r.append(args.max6) r['maxLength'] = args.max6
r[1] = r[1].with_prefixlen for r in (*roa4, *roa6):
r['prefix'] = r['prefix'].with_prefixlen
output = "" output = ""
VALID_KEYS = ('asn', 'prefix', 'maxLength')
if args.json: if args.json:
import json, time import json, time
for r in (*roa4, *roa6):
r[0] = "AS%d" % r[0]
current = int(time.time()) current = int(time.time())
d_output = {"metadata": {"counts": len(roa4)+len(roa6), "generated": current, "valid": current+14*86400}, "roas": list()} d_output = {"metadata": {"counts": len(roa4)+len(roa6), "generated": current, "valid": current+14*86400}, "roas": list()}
for r in roa4: for r in (*roa4, *roa6):
d_output['roas'].append(dict(zip(['asn', 'prefix', 'maxLength'], r))) # some preprocessing
for r in roa6: r['asn'] = "AS%d" % r['asn']
d_output['roas'].append(dict(zip(['asn', 'prefix', 'maxLength'], r))) for r in (*roa4, *roa6):
d_output['roas'].append({k:v for k, v in r.items() if k in VALID_KEYS})
output = json.dumps(d_output, indent=2) output = json.dumps(d_output, indent=2)
else: else:
output += "# NeoNetwork ROA tool\n" output += "# NeoNetwork ROA tool\n"
pattern = 'route %s max %d as %d;' pattern = 'route %s max %d as %d;'
l_output = list() l_output = list()
for (asn, prefix, maxlen) in roa4: rdict2list = lambda d: [d[k] for k in VALID_KEYS]
l_output.append(pattern % (prefix, maxlen, asn)) for (asn, prefix, maxlen) in [rdict2list(r) for r in (*roa4, *roa6)]:
for (asn, prefix, maxlen) in roa6:
l_output.append(pattern % (prefix, maxlen, asn)) l_output.append(pattern % (prefix, maxlen, asn))
output += '\n'.join(l_output) output += '\n'.join(l_output)
if not args.output or args.output == '-': if not args.output or args.output == '-':