Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
d9753cf
fix typos
katyatitkova May 5, 2025
438a2b8
delete unused files
katyatitkova May 6, 2025
f9ea70e
delete redundant alias
katyatitkova May 6, 2025
b5b787a
fix typos
katyatitkova May 7, 2025
c0f5360
use ptr.To() instead of bool "constants"
katyatitkova May 7, 2025
59c3138
fix typos
katyatitkova May 7, 2025
55e3275
prototype (without tests)
katyatitkova May 8, 2025
276f77e
update policy test
katyatitkova May 8, 2025
644e499
example test for the new logic with lots of todos
katyatitkova May 8, 2025
decde95
clean up topology files and readme
katyatitkova May 12, 2025
0c29f97
delete magic numbers
katyatitkova May 12, 2025
ff8fc01
separate generated graph and graphupdater
katyatitkova May 12, 2025
134ba8e
intermediate generation with failing ling
katyatitkova May 12, 2025
dcc95a3
merge packages
katyatitkova May 12, 2025
f4dc2b6
fix copyright
katyatitkova May 12, 2025
cb8c79f
parameterize graph description name
katyatitkova May 12, 2025
456da16
extract links generation
katyatitkova May 13, 2025
b583038
add explanation
katyatitkova May 13, 2025
2a3838b
Merge branch 'master' into graphupdater
katyatitkova May 13, 2025
1b029f9
fix lint
katyatitkova May 13, 2025
90a09c3
Merge remote-tracking branch 'origin/graphupdater' into graphupdater
katyatitkova May 13, 2025
95f7f3b
fix links order
katyatitkova May 13, 2025
1dce9f4
generate real ifids.yaml for the graph
katyatitkova May 14, 2025
23b6607
generate proper json files
katyatitkova May 14, 2025
642d892
add test
katyatitkova May 14, 2025
d518841
fix lint
katyatitkova May 14, 2025
7115021
add readme
katyatitkova May 14, 2025
4f66621
add graph art
katyatitkova May 14, 2025
f27c4c6
fix graph art
katyatitkova May 14, 2025
42f0230
generate testdata properly
katyatitkova May 14, 2025
a9fc0ab
fix bash line reading
katyatitkova May 14, 2025
6673302
use safe ifIDs ranges
katyatitkova May 15, 2025
7abe30f
improve clarity
katyatitkova May 15, 2025
7e35f76
Merge branch 'master' into topogen
katyatitkova May 15, 2025
f0905e3
Merge branch 'topogen' into beaconing
katyatitkova May 15, 2025
27ec0d8
fix merge
katyatitkova May 15, 2025
e7305ee
delete outdated testdata
katyatitkova May 15, 2025
11e6bce
delete outdated testdata
katyatitkova May 15, 2025
4465a88
Revert "fix typos"
katyatitkova May 15, 2025
89b17f8
Revert "use ptr.To() instead of bool "constants""
katyatitkova May 15, 2025
351b0c6
Revert "fix typos"
katyatitkova May 15, 2025
79ae36d
Revert "delete redundant alias"
katyatitkova May 15, 2025
a9cb841
Revert "delete unused files"
katyatitkova May 15, 2025
03b6198
Revert "fix typos"
katyatitkova May 15, 2025
46b3067
Merge branch 'master' into beaconing
katyatitkova May 15, 2025
041a08e
Merge branch 'master' into beaconing
katyatitkova May 21, 2025
103e812
add base test
katyatitkova May 21, 2025
31bc9a4
fix filtering
katyatitkova May 21, 2025
861939e
Merge branch 'master' into beaconing
katyatitkova May 22, 2025
64581f0
add core beaconing tests
katyatitkova May 22, 2025
4b668e7
fix Times(0)
katyatitkova May 22, 2025
2f8f4bd
complete propagator_test.go
katyatitkova May 22, 2025
f96ee5b
Merge branch 'master' into beaconing
katyatitkova Jul 10, 2025
d3ec317
add partially working test
katyatitkova Jul 16, 2025
4a158dd
fix policy path
katyatitkova Aug 14, 2025
bb86f53
add a second test
katyatitkova Aug 18, 2025
1d06fef
test case where there's no path using peering link
katyatitkova Oct 9, 2025
9121ccd
fix
oncilla Dec 4, 2025
c2f193b
wip
oncilla Dec 4, 2025
5a22285
fix
oncilla Dec 4, 2025
437e8b5
wip
oncilla Dec 4, 2025
a887116
add one-hop segment
oncilla Jan 15, 2026
19c2bfd
update the graph
katyatitkova Jan 15, 2026
7cd00be
brainstorming session #2 artifacts
katyatitkova Jan 15, 2026
48e01a1
peering links fixed by Claude
katyatitkova Jan 28, 2026
f3d48f2
add forgotten golden files
katyatitkova Jan 28, 2026
680f729
add forgotten graph files
katyatitkova Jan 28, 2026
9441f3e
simplify splitter code
katyatitkova Jan 28, 2026
d8a9da8
simplify fetcher code
katyatitkova Jan 28, 2026
f5a32ad
simplify forwarder code
katyatitkova Jan 28, 2026
22f17e6
add topology picture
katyatitkova Jan 28, 2026
caf38d6
remove peering E2E test (not needed in this branch)
katyatitkova Feb 4, 2026
d475bb3
remove debugging leftovers
katyatitkova Feb 4, 2026
436b00c
remove debugging leftovers
katyatitkova Feb 4, 2026
cb92f87
remove debugging leftovers
katyatitkova Feb 4, 2026
b0dde07
use toWildCard() directly
katyatitkova Feb 4, 2026
77c7590
Merge branch 'master' into peering_test
katyatitkova Feb 19, 2026
9fd4d9a
delete generated text file
katyatitkova Feb 19, 2026
fd233d8
fix lint
katyatitkova Feb 19, 2026
8901905
Merge remote-tracking branch 'origin/master' into peering_test_v2
katyatitkova Mar 17, 2026
465fb2f
alternative approach to one-hop segments
katyatitkova Mar 17, 2026
ec2f663
Merge branch 'peering_test_v2' into beaconing_with_fixed_peering_links
katyatitkova Mar 19, 2026
9fc0df6
fix tests
katyatitkova Mar 24, 2026
4b1ec1b
fix tests
katyatitkova Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
523 changes: 517 additions & 6 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions acceptance/common/scion.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ def update_json(change_dict: Dict[str, Any], files: LocalPath):
with open(file, "w") as f:
json.dump(t, f, indent=2)

def write_file(contents: str, files: LocalPath):
""" Writes text into file(s).

Args:
contents: text to write into the file(s).
files: names of file or files to update.

Raises:
IOError / FileNotFoundError: File path is not valid
"""
for file in files:
with open(file, "w") as f:
f.write(contents)

def load_from_json(key: str, files: LocalPath) -> Any:
""" Reads the value associated with the given key from the given json files.
Expand Down
33 changes: 33 additions & 0 deletions acceptance/transit_traffic/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
load("//acceptance/common:topogen.bzl", "topogen_test")

py_library(
name = "transit_traffic_base",
srcs = ["transit_traffic_base.py"],
)

topogen_test(
name = "test_isd_1",
src = "test_isd_1.py",
topo = "//topology:testdata/big.topo",
deps = [
":transit_traffic_base",
],
)

topogen_test(
name = "test_isd_3",
src = "test_isd_3.py",
topo = "//topology:testdata/big.topo",
deps = [
":transit_traffic_base",
],
)

topogen_test(
name = "test_incomplete_config",
src = "test_incomplete_config.py",
topo = "//topology:testdata/big.topo",
deps = [
":transit_traffic_base",
],
)
71 changes: 71 additions & 0 deletions acceptance/transit_traffic/test_incomplete_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3

# Copyright 2026 SCION Association
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from acceptance.transit_traffic import transit_traffic_base

class Test(transit_traffic_base.Test):
"""
This test disallows transit traffic at only one of two core ASes in an ISD.
It demonstrates that an incomplete configuration (only AS 120 blocks transit,
while AS 110 does not) creates partial isolation: ISDs that both connect
through the blocking AS lose connectivity to each other, but can still reach
ISDs reachable through the non-blocking core AS.

The graph picture can be found here: topology/testdata/big.topo.png

Transit traffic is blocked only at AS 120.
"""

def setup_prepare(self):
super().setup_prepare("1", ["120"])

def _run(self):
# Since only AS 120 is blocking transit traffic, there's no propagation
# from ISDs 2 and 6 towards ISDs 3, 4 and 5. However, beacons from
# ISDs 3, 4 and 5 are not blocked by AS 120 since they are propagating
# to AS 110, which does not count as transit traffic. So there're
# no paths only in one direction.
self._assert_no_path("310", "210")
self._assert_path("210", "310")
self._assert_no_path("411", "211")
self._assert_path("211", "411")
self._assert_no_path("510", "210")
self._assert_path("210", "510")

# ISDs 3 and 4 cannot reach ISD 5: the only path goes through 120.
self._assert_no_path_in_both_directions("310", "510")
self._assert_no_path_in_both_directions("410", "510")
self._assert_no_path_in_both_directions("311", "510")
self._assert_no_path_in_both_directions("411", "510")

# Traffic originating or ending in AS 120 is allowed.
self._assert_bidirectional_path("120", "310")
self._assert_bidirectional_path("120", "510")
self._assert_bidirectional_path("120", "110")

# Traffic outside of ISD 1 is not affected.
self._assert_bidirectional_path("310", "410")
self._assert_bidirectional_path("311", "411")
self._assert_bidirectional_path("610", "210")
self._assert_bidirectional_path("410", "411")
self._assert_bidirectional_path("310", "311")
self._assert_bidirectional_path("110", "111")
self._assert_bidirectional_path("122", "123")
self._assert_bidirectional_path("610", "611")
self._assert_bidirectional_path("620", "621")

if __name__ == "__main__":
transit_traffic_base.main(Test)
72 changes: 72 additions & 0 deletions acceptance/transit_traffic/test_isd_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env python3

# Copyright 2026 SCION Association
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from acceptance.transit_traffic import transit_traffic_base

class Test(transit_traffic_base.Test):
"""
This test disallows transit traffic at all core ASes in ISD 1,
the central hub ISD. It differs from ISD 3 test since there are
no peering links between ISDs 1,2,4,5 and ISDs 2,6.

The graph picture can be found here: topology/testdata/big.topo.png

With transit blocked at both 110 and 120, ISD 1 becomes a wall:
each neighboring ISD can reach ISD 1 via 2-ISD origination beacons,
but no beacon transits through ISD 1 to connect two other ISDs.
Only ISDs with direct core links bypass ISD 1:
ISD 3 <-> ISD 4 (310-410) and ISD 2 <-> ISD 6 (210-610).
"""

def setup_prepare(self):
super().setup_prepare("1", ["110", "120"])

def _run(self):
# Traffic originating or ending in ISD 1 is allowed.
self._assert_bidirectional_path("210", "110")
self._assert_bidirectional_path("310", "120")
self._assert_bidirectional_path("410", "110")
self._assert_bidirectional_path("510", "120")
self._assert_bidirectional_path("610", "110")
self._assert_bidirectional_path("211", "111")
self._assert_bidirectional_path("311", "121")
self._assert_bidirectional_path("611", "111")
self._assert_bidirectional_path("110", "111")
self._assert_bidirectional_path("120", "122")

# Traffic outside of ISD 1 is not affected.
self._assert_bidirectional_path("310", "410")
self._assert_bidirectional_path("311", "411")
self._assert_bidirectional_path("210", "610")
self._assert_bidirectional_path("211", "611")
self._assert_bidirectional_path("310", "311")
self._assert_bidirectional_path("410", "411")
self._assert_bidirectional_path("610", "611")
self._assert_bidirectional_path("620", "621")

# Transit traffic via ISD 1 is not allowed.
self._assert_no_path_in_both_directions("210", "310")
self._assert_no_path_in_both_directions("210", "510")
self._assert_no_path_in_both_directions("310", "510")
self._assert_no_path_in_both_directions("310", "610")
self._assert_no_path_in_both_directions("410", "510")
self._assert_no_path_in_both_directions("410", "610")
self._assert_no_path_in_both_directions("510", "610")
self._assert_no_path_in_both_directions("211", "311")
self._assert_no_path_in_both_directions("411", "611")

if __name__ == "__main__":
transit_traffic_base.main(Test)
76 changes: 76 additions & 0 deletions acceptance/transit_traffic/test_isd_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python3

# Copyright 2026 SCION Association
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from acceptance.transit_traffic import transit_traffic_base

class Test(transit_traffic_base.Test):
"""
This test disallows transit traffic in all ASes of ISD 3 and checks the
resulting paths. It differs from ISD 1 test since there are
peering links between ISD 4 and ISD 1.

The graph picture can be found here: topology/testdata/big.topo.png

Transit traffic is blocked at all ASes in ISD 3 (310 and 311).
"""

def setup_prepare(self):
super().setup_prepare("3", ["310", "311"])

def _run(self):
# Traffic originating or ending in ISD 3 is allowed.
self._assert_bidirectional_path("310", "410")
self._assert_bidirectional_path("311", "410")
self._assert_bidirectional_path("310", "411")
self._assert_bidirectional_path("311", "411")
self._assert_bidirectional_path("310", "210")
self._assert_bidirectional_path("311", "123")
self._assert_bidirectional_path("310", "510")
self._assert_bidirectional_path("311", "111")
self._assert_bidirectional_path("310", "610")
self._assert_bidirectional_path("311", "611")

# Transit traffic via ISD 3 is not allowed,
# therefore beacons are not making it through ISD 3.
# Because of it, peering links info is not propagated.
# While the graph has peering links for all cases below,
# there's no path in such config.
self._assert_no_path_in_both_directions("410", "210")
self._assert_no_path_in_both_directions("411", "211")
self._assert_no_path_in_both_directions("411", "510")
self._assert_no_path_in_both_directions("410", "123")
self._assert_no_path_in_both_directions("411", "123")
self._assert_no_path_in_both_directions("410", "111")
self._assert_no_path_in_both_directions("410", "610")
self._assert_no_path_in_both_directions("411", "611")

# Traffic outside of ISD 3 is not affected.
self._assert_bidirectional_path("123", "510")
self._assert_bidirectional_path("123", "211")
self._assert_bidirectional_path("122", "111")
self._assert_bidirectional_path("120", "210")
self._assert_bidirectional_path("510", "211")
self._assert_bidirectional_path("111", "211")
self._assert_bidirectional_path("410", "411")
self._assert_bidirectional_path("610", "210")
self._assert_bidirectional_path("610", "110")
self._assert_bidirectional_path("610", "510")
self._assert_bidirectional_path("611", "211")
self._assert_bidirectional_path("610", "611")
self._assert_bidirectional_path("620", "621")

if __name__ == "__main__":
transit_traffic_base.main(Test)
98 changes: 98 additions & 0 deletions acceptance/transit_traffic/transit_traffic_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env python3

# Copyright 2026 SCION Association
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import time

from acceptance.common import base, scion
from tools.topology.scion_addr import ISD_AS

class Test(base.TestTopogen):
_ases = {
"110": "1-ff00:0:110",
"111": "1-ff00:0:111",
"120": "1-ff00:0:120",
"121": "1-ff00:0:121",
"122": "1-ff00:0:122",
"123": "1-ff00:0:123",
"210": "2-ff00:0:210",
"211": "2-ff00:0:211",
"310": "3-ff00:0:310",
"311": "3-ff00:0:311",
"410": "4-ff00:0:410",
"411": "4-ff00:0:411",
"510": "5-ff00:0:510",
"610": "6-ff00:0:610",
"611": "6-ff00:0:611",
"612": "6-ff00:0:612",
"620": "6-ff00:0:620",
"621": "6-ff00:0:621",
"622": "6-ff00:0:622",
}

def setup_prepare(self, no_transit_isd_number, no_transit_as_numbers):
super().setup_prepare()

for as_number in no_transit_as_numbers:
as_number_string = "ff00_0_%s" % as_number
as_relative_dir_path = "AS%s" % as_number_string
as_absolute_dir_path = self.artifacts / "gen" / as_relative_dir_path

cs_toml_path = (
as_absolute_dir_path
/ ("cs%s-%s-1.toml" % (no_transit_isd_number, as_number_string))
)
policy_path = as_absolute_dir_path / "policy.yaml"

scion.update_toml(
{"beaconing.policies.propagation": "/etc/scion/policy.yaml"},
[cs_toml_path])

scion.write_file("""Filter:
AllowTransitTraffic: False""", [policy_path])

def setup_start(self):
super().setup_start()
# since some paths are not available, self.await_connectivity() doesn't work well
time.sleep(15)

def _showpaths(self, source_as: str, destination_as: str):
print(self.execute_tester(ISD_AS(self._ases[source_as]),
"scion", "sp", self._ases[destination_as], "--timeout", "2s"))

def _assert_path(self, source_as: str, destination_as: str):
try:
self._showpaths(source_as, destination_as)
except Exception as e:
raise AssertionError(f"No path found: {source_as} -> {destination_as}") from e

def _assert_bidirectional_path(self, source_as: str, destination_as: str):
self._assert_path(source_as, destination_as)
self._assert_path(destination_as, source_as)

def _assert_no_path(self, source_as: str, destination_as: str):
try:
self._showpaths(source_as, destination_as)
except Exception as e:
print(e)
else:
raise AssertionError(f"Unexpected path: {source_as} -> {destination_as}")

def _assert_no_path_in_both_directions(self, source_as: str, destination_as: str):
self._assert_no_path(source_as, destination_as)
self._assert_no_path(destination_as, source_as)

def main(test_class):
base.main(test_class)
Loading
Loading