SichangHe / internet_route_verification

RPSLyzer: Parse Routing Policy Specification Language from IRR and compare BGP routes against it
MIT License
1 stars 0 forks source link

Data analysis for route verification reports allowing implicit customer exports #28

Closed SichangHe closed 1 year ago

SichangHe commented 1 year ago

Following #24

SichangHe commented 1 year ago

AS pair stats

Polars output in Evcxr. ```elixir Generated stats of 176636 AS pairs in 1989609ms. shape: (176_636, 11) ┌────────┬───────┬───────────┬───────────┬─────────────┬─────────────┬────────────┬────────────┬────────────┬────────────┬──────────────┐ │ from ┆ to ┆ import_ok ┆ export_ok ┆ import_skip ┆ export_skip ┆ import_meh ┆ export_meh ┆ import_err ┆ export_err ┆ relationship │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ u64 ┆ u64 ┆ u32 ┆ u32 ┆ u32 ┆ u32 ┆ u32 ┆ u32 ┆ u32 ┆ u32 ┆ str │ ╞════════╪═══════╪═══════════╪═══════════╪═════════════╪═════════════╪════════════╪════════════╪════════════╪════════════╪══════════════╡ │ 28907 ┆ 6939 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ 8 ┆ 8 ┆ peer │ │ 137575 ┆ 24516 ┆ 0 ┆ 0 ┆ 80 ┆ 80 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ up │ │ 48399 ┆ 3327 ┆ 0 ┆ 123 ┆ 0 ┆ 37 ┆ 160 ┆ 0 ┆ 0 ┆ 0 ┆ up │ │ 13883 ┆ 6128 ┆ 0 ┆ 0 ┆ 28 ┆ 28 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ up │ │ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │ │ 50098 ┆ 56630 ┆ 0 ┆ 114 ┆ 0 ┆ 0 ┆ 114 ┆ 0 ┆ 0 ┆ 0 ┆ up │ │ 327794 ┆ 3741 ┆ 0 ┆ 0 ┆ 0 ┆ 26 ┆ 0 ┆ 0 ┆ 26 ┆ 0 ┆ peer │ │ 33381 ┆ 54004 ┆ 0 ┆ 0 ┆ 28 ┆ 28 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ up │ │ 44398 ┆ 3292 ┆ 484 ┆ 484 ┆ 56 ┆ 56 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ up │ └────────┴───────┴───────────┴───────────┴─────────────┴─────────────┴────────────┴────────────┴────────────┴────────────┴──────────────┘ shape: (9, 12) ┌────────────┬─────────────┬─────────────┬─────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┐ │ describe ┆ from ┆ to ┆ import_ok ┆ export_ok ┆ import_ski ┆ export_ski ┆ import_meh ┆ export_meh ┆ import_err ┆ export_err ┆ relationsh │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ p ┆ p ┆ --- ┆ --- ┆ --- ┆ --- ┆ ip │ │ str ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ --- ┆ --- ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ --- │ │ ┆ ┆ ┆ ┆ ┆ f64 ┆ f64 ┆ ┆ ┆ ┆ ┆ str │ ╞════════════╪═════════════╪═════════════╪═════════════╪════════════╪════════════╪════════════╪════════════╪════════════╪════════════╪════════════╪════════════╡ │ count ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636.0 ┆ 176636 │ │ null_count ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0 │ │ mean ┆ 967749.3288 ┆ 298711.4719 ┆ 85.689474 ┆ 68.211276 ┆ 166.204607 ┆ 190.881638 ┆ 102.634655 ┆ 75.481261 ┆ 80.429459 ┆ 100.384021 ┆ null │ │ ┆ 68 ┆ 48 ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │ │ std ┆ 5.9992e7 ┆ 3.2992e7 ┆ 4939.789172 ┆ 2708.65629 ┆ 6110.24057 ┆ 5395.90282 ┆ 1401.39041 ┆ 1930.80482 ┆ 3890.24666 ┆ 6235.79519 ┆ null │ │ ┆ ┆ ┆ ┆ 9 ┆ 9 ┆ 1 ┆ 9 ┆ 5 ┆ 1 ┆ 5 ┆ │ │ min ┆ 1.0 ┆ 1.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ down │ │ 25% ┆ 26575.75 ┆ 5466.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ null │ │ 50% ┆ 52286.5 ┆ 12741.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ null │ │ 75% ┆ 202513.0 ┆ 37595.25 ┆ 0.0 ┆ 2.0 ┆ 26.0 ┆ 30.0 ┆ 27.0 ┆ 0.0 ┆ 0.0 ┆ 0.0 ┆ null │ │ max ┆ 4.2926e9 ┆ 4.2926e9 ┆ 1.533988e6 ┆ 749784.0 ┆ 1.794792e6 ┆ 1.533988e6 ┆ 177342.0 ┆ 518285.0 ┆ 816612.0 ┆ 1.794792e6 ┆ up │ └────────────┴─────────────┴─────────────┴─────────────┴────────────┴────────────┴────────────┴────────────┴────────────┴────────────┴────────────┴────────────┘ ```

as_pair_stats.csv

SichangHe commented 1 year ago

Analysis on AS pair stats

Here, only the number of pairs is considered, the number of successes/skips/errors in the routes are normed (collapsed to 1 for each pair).

The ASes with the most errors. ```python In [12]: df_from.sort_values(by='import_err', ascending=False).head(20) Out[12]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err from 6939 22 0 39 0 1 2 42 92 13335 19 0 126 269 104 0 24 0 174 24 0 31 0 0 0 23 76 1299 25 0 27 69 0 0 22 0 1239 5 0 10 34 0 0 20 0 20473 6 0 24 0 8 21 20 31 42 6 0 18 0 2 4 19 36 16509 2 0 25 0 4 13 19 37 21859 0 0 34 2 26 47 19 30 9009 7 3 18 3 6 11 19 29 6461 5 0 26 46 0 0 19 0 137409 0 0 9 30 3 0 18 0 54994 6 0 29 90 41 0 18 0 132203 2 0 19 51 14 0 18 0 4455 0 7 5 5 2 2 18 15 2906 1 0 28 50 3 0 18 0 714 7 2 17 0 5 14 17 29 7713 3 0 11 0 1 7 17 23 24482 1 0 5 0 1 2 17 21 57976 1 0 13 36 5 0 17 0 In [13]: df_from.sort_values(by='export_err', ascending=False).head(20) Out[13]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err from 6939 22 0 39 0 1 2 42 92 174 24 0 31 0 0 0 23 76 3356 19 19 37 0 0 0 17 54 2914 14 0 23 0 0 0 11 42 16509 2 0 25 0 4 13 19 37 42 6 0 18 0 2 4 19 36 15169 1 0 21 0 0 2 15 35 20940 17 1 86 2 40 107 12 33 32934 10 0 20 0 3 9 17 32 20473 6 0 24 0 8 21 20 31 21859 0 0 34 2 26 47 19 30 714 7 2 17 0 5 14 17 29 9009 7 3 18 3 6 11 19 29 58453 6 1 16 0 3 6 14 28 9498 6 0 16 0 3 10 16 27 1828 3 0 16 0 7 13 16 26 10310 8 0 18 0 5 11 13 26 30844 4 11 15 11 3 6 12 24 54825 2 0 13 0 8 14 16 23 9304 5 0 15 0 8 18 16 23 In [14]: df_to.sort_values(by='import_err', ascending=False).head(20) Out[14]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err to 6939 0 1651 0 3968 2133 764 7391 3832 57463 2 107 1 1573 0 4 4484 2852 34224 36 169 15 313 91 38 2054 1725 18106 4 74 0 514 19 7 1917 1394 12552 362 302 0 325 58 58 1197 1054 20764 204 166 67 151 95 128 772 677 37100 7 109 0 379 220 27 759 540 31133 488 453 64 226 134 194 750 568 8492 195 71 62 60 6 16 680 744 3303 521 281 311 219 9 24 608 732 3741 1 82 1 311 190 25 524 350 3216 816 591 142 182 64 226 495 471 22652 23 28 6 234 77 11 386 223 23673 1 4 0 159 2 0 342 184 3130 2 4 0 148 1 0 277 131 1403 5 3 0 101 0 0 247 150 20485 333 488 82 191 367 219 211 102 20912 94 29 10 19 3 2 127 142 17819 0 7 0 91 0 0 122 27 174 0 1817 0 3610 6266 1678 115 20 In [15]: df_to.sort_values(by='export_err', ascending=False).head(20) Out[15]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err to 6939 0 1651 0 3968 2133 764 7391 3832 57463 2 107 1 1573 0 4 4484 2852 34224 36 169 15 313 91 38 2054 1725 18106 4 74 0 514 19 7 1917 1394 12552 362 302 0 325 58 58 1197 1054 1239 0 74 1891 385 0 586 0 882 8492 195 71 62 60 6 16 680 744 3303 521 281 311 219 9 24 608 732 20764 204 166 67 151 95 128 772 677 31133 488 453 64 226 134 194 750 568 37100 7 109 0 379 220 27 759 540 3216 816 591 142 182 64 226 495 471 293 0 31 670 256 0 5 0 396 3741 1 82 1 311 190 25 524 350 22652 23 28 6 234 77 11 386 223 9002 1281 806 457 287 31 306 33 200 23673 1 4 0 159 2 0 342 184 1403 5 3 0 101 0 0 247 150 6461 0 273 2386 1639 0 469 0 144 20912 94 29 10 19 3 2 127 142 ```
Some ASes have "perfect" 50% import_err or export_err rate. Filtered by that, the ASes with the most errors. ```python In [24]: df_from[df_from['%import_err'] == 50.0].sort_values(by='import_err', ascending=False).head(20) Out[24]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err sum %import_ok %export_ok %import_skip %export_skip %import_meh %export_meh %import_err %export_err from 65000 0 0 0 6 0 0 6 0 12 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 37727 0 1 0 0 0 0 5 4 10 0.0 10.000000 0.0 0.0 0.0 0.0 50.0 40.000000 13094 0 1 0 0 0 0 4 3 8 0.0 12.500000 0.0 0.0 0.0 0.0 50.0 37.500000 35353 0 1 0 0 0 0 4 3 8 0.0 12.500000 0.0 0.0 0.0 0.0 50.0 37.500000 24990 0 0 0 0 0 0 4 4 8 0.0 0.000000 0.0 0.0 0.0 0.0 50.0 50.000000 63516 0 0 0 0 0 0 3 3 6 0.0 0.000000 0.0 0.0 0.0 0.0 50.0 50.000000 40633 0 0 0 3 0 0 3 0 6 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 394745 0 1 0 0 0 0 3 2 6 0.0 16.666667 0.0 0.0 0.0 0.0 50.0 33.333333 14812 0 0 0 3 0 0 3 0 6 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 43100 0 0 0 0 0 0 3 3 6 0.0 0.000000 0.0 0.0 0.0 0.0 50.0 50.000000 201376 0 0 0 3 0 0 3 0 6 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 24748 0 0 0 3 0 0 3 0 6 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 150220 0 0 0 0 0 0 3 3 6 0.0 0.000000 0.0 0.0 0.0 0.0 50.0 50.000000 50898 0 0 0 0 0 0 3 3 6 0.0 0.000000 0.0 0.0 0.0 0.0 50.0 50.000000 199399 0 0 0 0 0 0 3 3 6 0.0 0.000000 0.0 0.0 0.0 0.0 50.0 50.000000 65010 0 0 0 2 0 0 2 0 4 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 204310 0 1 0 0 0 0 2 1 4 0.0 25.000000 0.0 0.0 0.0 0.0 50.0 25.000000 328397 0 0 0 2 0 0 2 0 4 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 210168 0 2 0 0 0 0 2 0 4 0.0 50.000000 0.0 0.0 0.0 0.0 50.0 0.000000 140719 0 0 0 2 0 0 2 0 4 0.0 0.000000 0.0 50.0 0.0 0.0 50.0 0.000000 In [25]: df_from[df_from['%export_err'] == 50.0].sort_values(by='export_err', ascending=False).head(20) Out[25]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err sum %import_ok %export_ok %import_skip %export_skip %import_meh %export_meh %import_err %export_err from 196844 0 0 2 0 0 0 12 14 28 0.000000 0.0 7.142857 0.0 0.0 0.0 42.857143 50.0 137367 0 0 1 0 0 0 12 13 26 0.000000 0.0 3.846154 0.0 0.0 0.0 46.153846 50.0 35005 1 0 0 0 0 0 5 6 12 8.333333 0.0 0.000000 0.0 0.0 0.0 41.666667 50.0 197902 3 0 0 0 0 0 2 5 10 30.000000 0.0 0.000000 0.0 0.0 0.0 20.000000 50.0 201054 1 0 0 0 0 0 4 5 10 10.000000 0.0 0.000000 0.0 0.0 0.0 40.000000 50.0 50384 1 0 0 0 0 0 4 5 10 10.000000 0.0 0.000000 0.0 0.0 0.0 40.000000 50.0 24990 0 0 0 0 0 0 4 4 8 0.000000 0.0 0.000000 0.0 0.0 0.0 50.000000 50.0 58196 1 0 0 0 0 0 3 4 8 12.500000 0.0 0.000000 0.0 0.0 0.0 37.500000 50.0 150220 0 0 0 0 0 0 3 3 6 0.000000 0.0 0.000000 0.0 0.0 0.0 50.000000 50.0 23899 0 0 1 0 0 0 2 3 6 0.000000 0.0 16.666667 0.0 0.0 0.0 33.333333 50.0 210043 2 0 1 0 0 0 0 3 6 33.333333 0.0 16.666667 0.0 0.0 0.0 0.000000 50.0 199399 0 0 0 0 0 0 3 3 6 0.000000 0.0 0.000000 0.0 0.0 0.0 50.000000 50.0 43100 0 0 0 0 0 0 3 3 6 0.000000 0.0 0.000000 0.0 0.0 0.0 50.000000 50.0 34282 2 0 0 0 0 0 1 3 6 33.333333 0.0 0.000000 0.0 0.0 0.0 16.666667 50.0 50107 1 0 0 0 0 0 2 3 6 16.666667 0.0 0.000000 0.0 0.0 0.0 33.333333 50.0 50898 0 0 0 0 0 0 3 3 6 0.000000 0.0 0.000000 0.0 0.0 0.0 50.000000 50.0 270648 0 0 3 0 0 0 0 3 6 0.000000 0.0 50.000000 0.0 0.0 0.0 0.000000 50.0 58697 0 0 1 0 0 0 2 3 6 0.000000 0.0 16.666667 0.0 0.0 0.0 33.333333 50.0 64512 0 0 2 0 0 0 1 3 6 0.000000 0.0 33.333333 0.0 0.0 0.0 16.666667 50.0 63516 0 0 0 0 0 0 3 3 6 0.000000 0.0 0.000000 0.0 0.0 0.0 50.000000 50.0 In [26]: df_to[df_to['%import_err'] == 50.0].sort_values(by='import_err', ascending=False).head(20) Out[26]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err sum %import_ok %export_ok %import_skip %export_skip %import_meh %export_meh %import_err %export_err to 55674 0 0 0 1 0 0 8 7 16 0.0 0.0 0.0 6.250000 0.0 0.0 50.0 43.750000 64213 0 0 0 4 0 0 5 1 10 0.0 0.0 0.0 40.000000 0.0 0.0 50.0 10.000000 50482 0 0 0 5 0 0 5 0 10 0.0 0.0 0.0 50.000000 0.0 0.0 50.0 0.000000 206487 0 2 0 0 0 0 4 2 8 0.0 25.0 0.0 0.000000 0.0 0.0 50.0 25.000000 199354 0 0 0 2 0 0 4 2 8 0.0 0.0 0.0 25.000000 0.0 0.0 50.0 25.000000 51131 0 0 0 0 0 0 3 3 6 0.0 0.0 0.0 0.000000 0.0 0.0 50.0 50.000000 52580 0 0 0 2 0 0 3 1 6 0.0 0.0 0.0 33.333333 0.0 0.0 50.0 16.666667 140433 0 0 0 0 0 0 3 3 6 0.0 0.0 0.0 0.000000 0.0 0.0 50.0 50.000000 270868 0 0 0 1 0 0 3 2 6 0.0 0.0 0.0 16.666667 0.0 0.0 50.0 33.333333 65222 0 0 0 2 0 0 2 0 4 0.0 0.0 0.0 50.000000 0.0 0.0 50.0 0.000000 132651 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.000000 0.0 0.0 50.0 50.000000 16345 0 0 0 2 0 0 2 0 4 0.0 0.0 0.0 50.000000 0.0 0.0 50.0 0.000000 49023 0 0 0 1 0 0 2 1 4 0.0 0.0 0.0 25.000000 0.0 0.0 50.0 25.000000 44927 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.000000 0.0 0.0 50.0 50.000000 38946 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.000000 0.0 0.0 50.0 50.000000 38081 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.000000 0.0 0.0 50.0 50.000000 37990 0 0 0 2 0 0 2 0 4 0.0 0.0 0.0 50.000000 0.0 0.0 50.0 0.000000 20130 0 0 0 1 0 0 2 1 4 0.0 0.0 0.0 25.000000 0.0 0.0 50.0 25.000000 17971 0 0 0 2 0 0 2 0 4 0.0 0.0 0.0 50.000000 0.0 0.0 50.0 0.000000 2653 0 0 0 1 0 0 2 1 4 0.0 0.0 0.0 25.000000 0.0 0.0 50.0 25.000000 In [27]: df_to[df_to['%export_err'] == 50.0].sort_values(by='export_err', ascending=False).head(20) Out[27]: import_ok export_ok import_skip export_skip import_meh export_meh import_err export_err sum %import_ok %export_ok %import_skip %export_skip %import_meh %export_meh %import_err %export_err to 140433 0 0 0 0 0 0 3 3 6 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 51131 0 0 0 0 0 0 3 3 6 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 38946 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 38081 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 132651 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 65000 0 0 2 0 0 0 0 2 4 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 44927 0 0 0 0 0 0 2 2 4 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 40633 0 0 2 0 0 0 0 2 4 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 134972 0 0 2 0 0 0 0 2 4 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 150620 0 0 1 0 0 0 0 1 2 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 196742 1 0 0 0 0 0 0 1 2 50.0 0.0 0.0 0.0 0.0 0.0 0.0 50.0 169677 0 0 1 0 0 0 0 1 2 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 167001 0 0 1 0 0 0 0 1 2 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 147100 0 0 0 0 0 0 1 1 2 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 149320 0 0 0 0 0 0 1 1 2 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 142321 0 0 0 0 0 0 1 1 2 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 140770 0 0 0 0 0 0 1 1 2 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 140591 0 0 1 0 0 0 0 1 2 0.0 0.0 50.0 0.0 0.0 0.0 0.0 50.0 198424 0 0 0 0 0 0 1 1 2 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 199755 0 0 0 0 0 0 1 1 2 0.0 0.0 0.0 0.0 0.0 0.0 50.0 50.0 ```