Compare commits

..

No commits in common. "52b52aa53623d535689d71c033eeafc6a18ece26" and "ed92df8fce96260a04a6786e635f547901544717" have entirely different histories.

8 changed files with 0 additions and 1215 deletions

View file

View file

@ -1,33 +0,0 @@
import json
import re
from dataclasses import dataclass
from typing import Optional
reasn = re.compile(r"^AS(\d+)$")
def parse_asn(text: str) -> Optional[int]:
match = reasn.match(text)
if match:
return int(match.group(1))
@dataclass
class ASPA:
customer: int
providers: list[int]
ta: str
@classmethod
def from_dict(cls, d):
try:
customer = parse_asn(d['customer'])
providers = list(map(parse_asn, d['providers']))
return cls(customer, providers, d['ta'])
except (KeyError, TypeError):
return None
def parse_json(data: str) -> list[ASPA]:
data = json.loads(data)
return list(filter(None, map(ASPA.from_dict, data.get('aspas', []))))

View file

@ -1,822 +0,0 @@
{
"metadata": {
"generated": 1730172244,
"generatedTime": "2024-10-29T03:24:04Z"
},
"aspas": [
{
"customer": "AS11358",
"providers": [
"AS835",
"AS924",
"AS6939",
"AS20473",
"AS34927"
],
"ta": "arin"
},
{
"customer": "AS13852",
"providers": [
"AS6939",
"AS20473",
"AS34927",
"AS41051",
"AS52025"
],
"ta": "arin"
},
{
"customer": "AS15562",
"providers": [
"AS2914",
"AS8283",
"AS51088",
"AS206238"
],
"ta": "ripe"
},
{
"customer": "AS19330",
"providers": [
"AS393577"
],
"ta": "arin"
},
{
"customer": "AS28584",
"providers": [
"AS28605"
],
"ta": "lacnic"
},
{
"customer": "AS33733",
"providers": [
"AS174",
"AS6939",
"AS12186",
"AS47787",
"AS200454"
],
"ta": "arin"
},
{
"customer": "AS40544",
"providers": [
"AS924",
"AS6939",
"AS12186",
"AS52025"
],
"ta": "arin"
},
{
"customer": "AS41720",
"providers": [
"AS174",
"AS1299",
"AS9002",
"AS50877",
"AS60068",
"AS203446",
"AS212508"
],
"ta": "ripe"
},
{
"customer": "AS44324",
"providers": [
"AS945",
"AS955",
"AS1299",
"AS3204",
"AS6939",
"AS7720",
"AS8772",
"AS8849",
"AS15353",
"AS18041",
"AS20473",
"AS29632",
"AS32595",
"AS34465",
"AS34927",
"AS41051",
"AS43426",
"AS47272",
"AS51087",
"AS53667",
"AS53808",
"AS59538",
"AS61112",
"AS134823",
"AS138997",
"AS139317",
"AS151364",
"AS199545",
"AS199765",
"AS200105",
"AS206499",
"AS207656",
"AS207841",
"AS209554",
"AS209735",
"AS212483"
],
"ta": "ripe"
},
{
"customer": "AS47272",
"providers": [
"AS835",
"AS924",
"AS1299",
"AS6830",
"AS6939",
"AS20473",
"AS21738",
"AS25759",
"AS34927",
"AS35133",
"AS41051",
"AS48605",
"AS50391",
"AS50917",
"AS52025",
"AS52210",
"AS58057",
"AS210667",
"AS212514",
"AS212895"
],
"ta": "ripe"
},
{
"customer": "AS47689",
"providers": [
"AS924",
"AS1299",
"AS6939",
"AS21738",
"AS34465",
"AS34549",
"AS34927",
"AS395823"
],
"ta": "ripe"
},
{
"customer": "AS48070",
"providers": [
"AS174",
"AS1299"
],
"ta": "ripe"
},
{
"customer": "AS48606",
"providers": [
"AS30893",
"AS54681",
"AS57974",
"AS59678",
"AS210691",
"AS212276"
],
"ta": "ripe"
},
{
"customer": "AS50224",
"providers": [
"AS6939",
"AS15353",
"AS26930",
"AS34465",
"AS37988",
"AS50104",
"AS52025",
"AS52210",
"AS59920",
"AS60841",
"AS210475",
"AS400304"
],
"ta": "ripe"
},
{
"customer": "AS50391",
"providers": [
"AS6939",
"AS20473",
"AS48070"
],
"ta": "ripe"
},
{
"customer": "AS51019",
"providers": [
"AS6939",
"AS34549",
"AS34927",
"AS52025",
"AS207841"
],
"ta": "ripe"
},
{
"customer": "AS51396",
"providers": [
"AS6939",
"AS30823",
"AS44066",
"AS49581",
"AS60223",
"AS203446",
"AS214995",
"AS215436"
],
"ta": "ripe"
},
{
"customer": "AS52025",
"providers": [
"AS174",
"AS835",
"AS906",
"AS917",
"AS924",
"AS1299",
"AS3257",
"AS6204",
"AS6939",
"AS7720",
"AS8860",
"AS12186",
"AS18041",
"AS20473",
"AS21700",
"AS21738",
"AS25369",
"AS29802",
"AS32097",
"AS34549",
"AS34927",
"AS35133",
"AS35661",
"AS36369",
"AS37988",
"AS39409",
"AS47787",
"AS48070",
"AS48605",
"AS50917",
"AS51519",
"AS52210",
"AS56655",
"AS57695",
"AS61138",
"AS197216",
"AS199545",
"AS209022",
"AS209533",
"AS394177",
"AS396998",
"AS397423",
"AS400304",
"AS400587"
],
"ta": "ripe"
},
{
"customer": "AS52210",
"providers": [
"AS174",
"AS835",
"AS6939",
"AS52025",
"AS62513",
"AS210667"
],
"ta": "ripe"
},
{
"customer": "AS54148",
"providers": [
"AS835",
"AS924",
"AS6939",
"AS20473",
"AS21738",
"AS34927",
"AS37988",
"AS47272",
"AS50917",
"AS53667"
],
"ta": "arin"
},
{
"customer": "AS54218",
"providers": [
"AS917",
"AS16509",
"AS37988",
"AS53667",
"AS59678"
],
"ta": "arin"
},
{
"customer": "AS56762",
"providers": [
"AS47689"
],
"ta": "ripe"
},
{
"customer": "AS57194",
"providers": [
"AS924",
"AS52210"
],
"ta": "ripe"
},
{
"customer": "AS57984",
"providers": [
"AS8283",
"AS48112",
"AS206763"
],
"ta": "ripe"
},
{
"customer": "AS59678",
"providers": [
"AS6939",
"AS34927",
"AS54218",
"AS55081"
],
"ta": "ripe"
},
{
"customer": "AS60223",
"providers": [
"AS945",
"AS49581"
],
"ta": "ripe"
},
{
"customer": "AS60431",
"providers": [
"AS34927",
"AS41495",
"AS50917"
],
"ta": "ripe"
},
{
"customer": "AS60841",
"providers": [
"AS30456",
"AS400304"
],
"ta": "ripe"
},
{
"customer": "AS149301",
"providers": [
"AS20473",
"AS61138"
],
"ta": "apnic"
},
{
"customer": "AS151642",
"providers": [
"AS20473",
"AS61138"
],
"ta": "apnic"
},
{
"customer": "AS198136",
"providers": [
"AS0"
],
"ta": "ripe"
},
{
"customer": "AS199376",
"providers": [
"AS47311",
"AS61112",
"AS150249",
"AS151544",
"AS199762",
"AS209533",
"AS215379"
],
"ta": "ripe"
},
{
"customer": "AS199762",
"providers": [
"AS945",
"AS6939",
"AS8849",
"AS15353",
"AS34927",
"AS44817",
"AS47311",
"AS48605",
"AS140731",
"AS150249"
],
"ta": "ripe"
},
{
"customer": "AS200242",
"providers": [
"AS835",
"AS6939",
"AS21738",
"AS34465",
"AS34927",
"AS52025",
"AS59678",
"AS60841",
"AS210475"
],
"ta": "ripe"
},
{
"customer": "AS200351",
"providers": [
"AS34927",
"AS47272",
"AS209022",
"AS210475"
],
"ta": "arin"
},
{
"customer": "AS200454",
"providers": [
"AS174",
"AS6424",
"AS6939",
"AS9186",
"AS12186"
],
"ta": "ripe"
},
{
"customer": "AS202076",
"providers": [
"AS207960"
],
"ta": "ripe"
},
{
"customer": "AS202359",
"providers": [
"AS30740",
"AS33920",
"AS41495"
],
"ta": "ripe"
},
{
"customer": "AS202881",
"providers": [
"AS205329"
],
"ta": "ripe"
},
{
"customer": "AS203619",
"providers": [
"AS200454"
],
"ta": "ripe"
},
{
"customer": "AS203843",
"providers": [
"AS6939",
"AS20473",
"AS53667"
],
"ta": "ripe"
},
{
"customer": "AS204857",
"providers": [
"AS50224",
"AS59920",
"AS60841",
"AS400304"
],
"ta": "ripe"
},
{
"customer": "AS204931",
"providers": [
"AS34927",
"AS44103",
"AS207656"
],
"ta": "ripe"
},
{
"customer": "AS205329",
"providers": [
"AS945",
"AS983",
"AS6939",
"AS7720",
"AS8894",
"AS9409",
"AS20473",
"AS34927",
"AS41051",
"AS131657",
"AS134823",
"AS151364"
],
"ta": "ripe"
},
{
"customer": "AS205603",
"providers": [
"AS38074",
"AS59105"
],
"ta": "ripe"
},
{
"customer": "AS205663",
"providers": [
"AS20473",
"AS61138"
],
"ta": "arin"
},
{
"customer": "AS205789",
"providers": [
"AS200242",
"AS207960"
],
"ta": "ripe"
},
{
"customer": "AS205848",
"providers": [
"AS1299",
"AS6939",
"AS34549",
"AS34927",
"AS52025",
"AS209022"
],
"ta": "ripe"
},
{
"customer": "AS207487",
"providers": [
"AS20473"
],
"ta": "ripe"
},
{
"customer": "AS207841",
"providers": [
"AS174",
"AS6939",
"AS137409"
],
"ta": "ripe"
},
{
"customer": "AS207960",
"providers": [
"AS6939",
"AS20473",
"AS34854",
"AS34927",
"AS136620",
"AS202359",
"AS207968"
],
"ta": "ripe"
},
{
"customer": "AS210561",
"providers": [
"AS207960"
],
"ta": "ripe"
},
{
"customer": "AS212068",
"providers": [
"AS6939",
"AS13237",
"AS62240",
"AS207960"
],
"ta": "ripe"
},
{
"customer": "AS212245",
"providers": [
"AS917",
"AS57695",
"AS212068"
],
"ta": "ripe"
},
{
"customer": "AS212934",
"providers": [
"AS835",
"AS6939",
"AS34927",
"AS52210",
"AS53667",
"AS61138",
"AS62513",
"AS209533",
"AS210667"
],
"ta": "ripe"
},
{
"customer": "AS215028",
"providers": [
"AS216107"
],
"ta": "ripe"
},
{
"customer": "AS215131",
"providers": [
"AS8283",
"AS34927"
],
"ta": "ripe"
},
{
"customer": "AS215147",
"providers": [
"AS47263",
"AS207252",
"AS215828"
],
"ta": "ripe"
},
{
"customer": "AS215436",
"providers": [
"AS6762",
"AS6939",
"AS51396",
"AS60223"
],
"ta": "ripe"
},
{
"customer": "AS215664",
"providers": [
"AS1299",
"AS3204",
"AS6939",
"AS34549",
"AS41720",
"AS56382",
"AS203446",
"AS212508"
],
"ta": "ripe"
},
{
"customer": "AS215778",
"providers": [
"AS34465",
"AS39249",
"AS41051",
"AS207656",
"AS209533",
"AS393577"
],
"ta": "ripe"
},
{
"customer": "AS215828",
"providers": [
"AS6204",
"AS6939",
"AS8772",
"AS29390",
"AS29632",
"AS34465",
"AS34927",
"AS39249",
"AS41051",
"AS44592",
"AS48752",
"AS50917",
"AS51019",
"AS58057",
"AS62403",
"AS152726",
"AS197071",
"AS199524",
"AS203686",
"AS207656",
"AS209533",
"AS210464",
"AS216324",
"AS216360",
"AS393577"
],
"ta": "ripe"
},
{
"customer": "AS215849",
"providers": [
"AS215828"
],
"ta": "ripe"
},
{
"customer": "AS216107",
"providers": [
"AS924",
"AS6939",
"AS16509",
"AS20473",
"AS21738",
"AS34927",
"AS63473",
"AS209022",
"AS211588"
],
"ta": "ripe"
},
{
"customer": "AS216311",
"providers": [
"AS6939",
"AS13852",
"AS20473",
"AS34927",
"AS52025"
],
"ta": "ripe"
},
{
"customer": "AS267386",
"providers": [
"AS6939",
"AS25933",
"AS28220",
"AS28649",
"AS267613"
],
"ta": "lacnic"
},
{
"customer": "AS270470",
"providers": [
"AS53062"
],
"ta": "lacnic"
},
{
"customer": "AS393577",
"providers": [
"AS1299",
"AS6939",
"AS32097",
"AS40676",
"AS137409"
],
"ta": "arin"
},
{
"customer": "AS401111",
"providers": [
"AS945",
"AS6939",
"AS17676"
],
"ta": "arin"
}
]
}

View file

@ -1,23 +0,0 @@
from aspa.data import ASPA
def generate_bird(aspas: list[ASPA]) -> str:
lines = [
'function is_aspa_invalid_pair(int upstream_asn; int downstream_asn) {',
' case downstream_asn {'
]
for aspa in aspas:
if aspa.providers:
asns = ', '.join(map(str, aspa.providers))
lines.append(f' {aspa.customer}: if upstream_asn !~ [{asns}] then return true;')
else:
lines.append(f' {aspa.customer}: return true;')
lines += [
' }',
' return false;',
'}'
]
return '\n'.join(lines)

View file

@ -1,174 +0,0 @@
import unittest
from pathlib import Path
from aspa.data import ASPA, parse_json
from aspa.validate import BirdValidator, Validator
class ParserTest(unittest.TestCase):
def test_parse(self):
with open(Path(__file__).parent / 'example.json') as f:
result = parse_json(f.read())
self.assertEqual(len(result), 69)
for aspa in result:
if aspa.customer == 54148:
self.assertEqual(aspa.providers, [835, 924, 6939, 20473, 21738, 34927, 37988, 47272, 50917, 53667])
self.assertEqual(aspa.ta, 'arin')
class CustomerTest(unittest.TestCase):
validator_class = Validator
def setUp(self):
self.validator = self.validator_class([
ASPA(64500, [64501], 'test'),
ASPA(64501, [64502], 'test'),
ASPA(64502, [64503], 'test'),
ASPA(64503, [64504], 'test'),
])
def test_all_valid(self):
self.assertFalse(self.validator.is_aspa_invalid_customer(64501, [64500]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64502, [64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64503, [64502, 64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64504, [64503, 64502, 64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64504, [64503, 64502, 64501]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64504, [64503, 64502]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64504, [64503]))
def test_some_unknown(self):
self.assertFalse(self.validator.is_aspa_invalid_customer(64505, [64504, 64503, 64502, 64501]))
self.assertFalse(self.validator.is_aspa_invalid_customer(64503, [64502, 64501, 64505]))
def test_all_unknown(self):
self.assertFalse(self.validator.is_aspa_invalid_customer(64506, [64507, 64508]))
def test_some_invalid(self):
self.assertTrue(self.validator.is_aspa_invalid_customer(64505, [64504, 64503, 64501, 64501]))
self.assertTrue(self.validator.is_aspa_invalid_customer(64504, [64503, 64502, 64506, 64500]))
class PeerTest(unittest.TestCase):
validator_class = Validator
def setUp(self):
self.validator = self.validator_class([
ASPA(64500, [64501], 'test'),
ASPA(64501, [64502], 'test'),
ASPA(64502, [64503], 'test'),
ASPA(64503, [64504], 'test'),
])
def test_all_valid(self):
self.assertFalse(self.validator.is_aspa_invalid_peer(64501, [64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64502, [64502, 64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64503, [64503, 64502, 64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64504, [64504, 64503, 64502, 64501]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64504, [64504, 64503, 64502]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64504, [64504, 64503]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64504, [64504]))
def test_prepend_valid(self):
self.assertFalse(self.validator.is_aspa_invalid_peer(64501, [64501, 64500, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64502, [64502, 64502, 64501, 64501, 64500]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64503, [64503, 64502, 64502, 64501, 64500, 64500]))
def test_some_unknown(self):
self.assertFalse(self.validator.is_aspa_invalid_peer(64505, [64505, 64504, 64503, 64502]))
self.assertFalse(self.validator.is_aspa_invalid_peer(64503, [64503, 64503, 64502, 64505]))
def test_all_unknown(self):
self.assertFalse(self.validator.is_aspa_invalid_customer(64506, [64506, 64507, 64508]))
def test_some_invalid(self):
self.assertTrue(self.validator.is_aspa_invalid_peer(64505, [64505, 64505, 64503, 64503]))
self.assertTrue(self.validator.is_aspa_invalid_peer(64504, [64504, 64503, 64506, 64500]))
def test_peer_originated(self):
for i in [64500, 64501, 64502, 64503, 64504, 64505]:
self.assertFalse(self.validator.is_aspa_invalid_peer(i, [i]))
class UpstreamTest(unittest.TestCase):
validator_class = Validator
def setUp(self):
# 6451x are tier 1 ISPs
# 6452x are tier 2 ISPs
# 6453x are tier 3 ISPs
self.validator = self.validator_class([
ASPA(64510, [], 'test'),
ASPA(64511, [], 'test'),
ASPA(64512, [], 'test'),
ASPA(64514, [], 'test'),
ASPA(64520, [64510, 64511], 'test'),
ASPA(64521, [64512, 64513], 'test'),
ASPA(64522, [64511, 64512], 'test'),
ASPA(64530, [64520], 'test'),
ASPA(64531, [64521, 64523], 'test'),
])
def test_all_valid(self):
self.assertFalse(self.validator.is_aspa_invalid_upstream(64530, [64520, 64510, 64512, 64521, 64531]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64520, [64510, 64512, 64521, 64531]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64521, [64512, 64510, 64520, 64520, 64530]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64531, [64521, 64512, 64510, 64520, 64530]))
def test_valid_edge(self):
self.assertFalse(self.validator.is_aspa_invalid_upstream(64530, [64520, 64510]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64530, [64520]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64520, [64510]))
def test_tier_1_tier_2_peer(self):
self.assertFalse(self.validator.is_aspa_invalid_upstream(64530, [64520, 64512, 64521, 64531]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64521, [64510, 64510, 64520, 64520, 64530]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64531, [64521, 64510, 64520, 64530]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64531, [64521, 64510, 64510, 64520, 64520]))
def test_some_unknown(self):
self.assertFalse(self.validator.is_aspa_invalid_upstream(64530, [64520, 64510, 64513, 64521, 64531]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64520, [64510, 64513, 64521, 64531]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64521, [64510, 64510, 64520, 64520, 64530]))
self.assertFalse(self.validator.is_aspa_invalid_upstream(64531, [64521, 64510, 64520, 64530]))
def test_invalid_downramp(self):
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64510, 64512, 64522, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64510, 64512, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64521, 64512, 64510, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64521, 64512, 64510, 64522, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64512, 64522, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64521, [64510, 64510, 64520, 64522, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64521, [64510, 64510, 64522, 64520, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64510, 64522, 64531]))
def test_invalid_upramp(self):
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64513, 64512, 64521, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64521, 64510, 64512, 64521, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64520, 64512, 64510, 64520, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64521, 64511, 64510, 64520, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64514, 64521, 64521, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64521, 64510, 64521, 64531, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64520, 64512, 64520, 64520, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64521, 64514, 64520, 64530, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64520, 64520, 64514, 64521, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64530, [64521, 64510, 64510, 64521, 64531]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64520, 64512, 64512, 64520, 64530]))
self.assertTrue(self.validator.is_aspa_invalid_upstream(64531, [64521, 64521, 64514, 64520, 64530]))
class BirdCustomerTest(CustomerTest):
validator_class = BirdValidator
class BirdPeerTest(PeerTest):
validator_class = BirdValidator
class BirdUpstreamTest(UpstreamTest):
validator_class = BirdValidator
if __name__ == '__main__':
unittest.main()

View file

@ -1,96 +0,0 @@
from itertools import chain, dropwhile
from aspa.data import ASPA
class Validator:
def __init__(self, aspas: list[ASPA]):
self.aspas = {aspa.customer: aspa for aspa in aspas}
def is_invalid_pair(self, upstream: int, downstream: int) -> bool:
if downstream not in self.aspas:
return False
return upstream not in self.aspas[downstream].providers
def is_aspa_invalid_customer(self, my_asn: int, bgp_path: list[int]) -> bool:
for prev_asn, asn in zip(chain([my_asn], bgp_path), bgp_path):
# Ignore AS-path prepends
if prev_asn == asn:
continue
if self.is_invalid_pair(prev_asn, asn):
return True
return False
def is_aspa_invalid_peer(self, peer_asn: int, bgp_path: list[int]) -> bool:
remove_peer = list(dropwhile(lambda asn: asn != peer_asn, bgp_path))
for prev_asn, asn in zip(chain([peer_asn], remove_peer), remove_peer):
if prev_asn == asn:
continue
if self.is_invalid_pair(prev_asn, asn):
return True
return False
def is_aspa_invalid_upstream(self, my_asn: int, bgp_path: list[int]) -> bool:
max_up_ramp = len(bgp_path)
min_down_ramp = 0
for i, (prev_asn, asn) in enumerate(zip(chain([my_asn], bgp_path), bgp_path)):
if prev_asn == asn:
continue
if self.is_invalid_pair(asn, prev_asn):
max_up_ramp = min(max_up_ramp, i)
if self.is_invalid_pair(prev_asn, asn):
min_down_ramp = max(min_down_ramp, i)
return min_down_ramp > max_up_ramp
class BirdValidator(Validator):
"""Validator coded with only language features available in bird DSL."""
def is_aspa_invalid_customer(self, my_asn: int, bgp_path: list[int]) -> bool:
prev_asn = my_asn
for asn in bgp_path:
if prev_asn != asn and self.is_invalid_pair(prev_asn, asn):
return True
prev_asn = asn
return False
def is_aspa_invalid_peer(self, peer_asn: int, bgp_path: list[int]) -> bool:
prev_asn = peer_asn
for asn in bgp_path:
if asn != peer_asn and prev_asn != asn and self.is_invalid_pair(prev_asn, asn):
return True
prev_asn = asn
return False
def is_aspa_invalid_upstream(self, my_asn: int, bgp_path: list[int]) -> bool:
prev_asn = my_asn
max_up_ramp = len(bgp_path)
min_down_ramp = 0
i = 0
for asn in bgp_path:
if prev_asn != asn:
if self.is_invalid_pair(asn, prev_asn) and max_up_ramp > i:
max_up_ramp = i
if self.is_invalid_pair(prev_asn, asn) and min_down_ramp < i:
min_down_ramp = i
prev_asn = asn
i += 1
return min_down_ramp > max_up_ramp

View file

@ -1,46 +0,0 @@
function is_aspa_invalid_customer() {
int prev_asn = MY_ASN;
for int cur_asn in bgp_path do {
if prev_asn != cur_asn && is_aspa_invalid_pair(prev_asn, cur_asn) then
return true;
prev_asn = cur_asn;
}
return false;
}
function is_aspa_invalid_peer(int peer_asn) {
int prev_asn = peer_asn;
for int cur_asn in bgp_path do {
if cur_asn != peer_asn && prev_asn != cur_asn &&
is_aspa_invalid_pair(prev_asn, cur_asn) then
return true;
prev_asn = cur_asn;
}
return false;
}
function is_aspa_invalid_upstream() {
int prev_asn = MY_ASN;
int max_up_ramp = bgp_path.len;
int min_down_ramp = 0;
int i = 0;
for int cur_asn in bgp_path do {
if prev_asn != cur_asn then {
if is_aspa_invalid_pair(cur_asn, cur_asn) && max_up_ramp > i then
max_up_ramp = i;
if is_aspa_invalid_pair(prev_asn, cur_asn) && min_down_ramp < i then
min_down_ramp = i;
}
prev_asn = cur_asn;
i = i + 1;
}
return min_down_ramp > max_up_ramp;
}

View file

@ -1,21 +0,0 @@
#!/usr/bin/env python3
import argparse
from aspa.data import parse_json
from aspa.generate import generate_bird
def main():
parser = argparse.ArgumentParser(description='Generates is_aspa_invalid_pair function for bird')
parser.add_argument('aspa_json', type=str, help='the JSON file with ASPA data')
args = parser.parse_args()
with open(args.aspa_json) as f:
aspas = parse_json(f.read())
print(generate_bird(aspas))
if __name__ == '__main__':
main()