Skip to content

Commit

Permalink
rework SCION
Browse files Browse the repository at this point in the history
  • Loading branch information
amdfxlucas committed Feb 7, 2025
1 parent c60e7d5 commit 0260808
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 116 deletions.
12 changes: 12 additions & 0 deletions seedemu/core/Node.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,17 @@ def addHostName(self, name: str) -> Node:
self.__host_names.append(name)
return self



def getLocalIPAddress(self) -> str:
"""!
@brief Get the IP address of the local interface for this node.
"""
for iface in self.getInterfaces():
if iface.getNet().getType() == NetworkType.Local:
return iface.getAddress()
return ''

def getNameServers(self) -> List[str]:
"""!
@brief get configured recursive name servers on this node.
Expand Down Expand Up @@ -1030,6 +1041,7 @@ class Router(Node):

def __init__(self, name: str, role: NodeRole, asn: int, scope: str = None):
self.__is_border_router = False
self.__loopback_address=None
super().__init__( name,role,asn,scope)

def getRole(self) -> NodeRole:
Expand Down
16 changes: 5 additions & 11 deletions seedemu/core/ScionAutonomousSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class ScionAutonomousSystem(AutonomousSystem):
# Origination, propagation, and registration intervals
__beaconing_intervals: Tuple[Optional[str], Optional[str], Optional[str]]
__beaconing_policy: Dict[str, Dict]
__next_ifid: int # Next IFID assigned to a link
__note: str # optional free form parameter that contains interesting information about AS. This will be included in beacons if it is set
__generateStaticInfoConfig: bool

Expand All @@ -50,7 +49,6 @@ def __init__(self, asn: int, subnetTemplate: str = "10.{}.0.0/16"):
self.__mtu = None
self.__beaconing_intervals = (None, None, None)
self.__beaconing_policy = {}
self.__next_ifid = 1
self.__note = None
self.__generateStaticInfoConfig = False

Expand Down Expand Up @@ -84,13 +82,6 @@ def configure(self, emulator: Emulator):
base64.b64encode(os.urandom(16)).decode(),
base64.b64encode(os.urandom(16)).decode())

def getNextIfid(self) -> int:
"""!
@brief Get next unused IFID. Called during configuration.
"""
ifid = self.__next_ifid
self.__next_ifid += 1
return ifid

def getSecretKeys(self) -> Tuple[str, str]:
"""!
Expand Down Expand Up @@ -188,8 +179,11 @@ def getTopology(self, isd: int) -> Dict:
for router in self.getBorderRouters():
rnode: ScionRouter = self.getRouter( router.getName() )

border_routers[rnode.getName()] = {
"internal_addr": f"{rnode.getLoopbackAddress()}:30001",
listen_addr= rnode.getLocalIPAddress() if list([ ifn.getNet().isDirect() for ifn in rnode.getInterfaces() ]).count(True) ==1 else rnode.getLoopbackAddress()
#UDP address on which the router receives SCION packets
# from sibling routers and end hosts in this AS.
border_routers[rnode.getName()] = {
"internal_addr": f"{listen_addr }:30042",
"interfaces": rnode.getScionInterfaces()
}

Expand Down
98 changes: 50 additions & 48 deletions seedemu/layers/Routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class Routing(Layer):
protocols to use later and as router id.
"""

__loopback_assigner: IPv4Network
__loopback_pos: int
_loopback_assigner: IPv4Network
_loopback_pos: int

def __init__(self, loopback_range: str = '10.0.0.0/16'):
"""!
Expand All @@ -64,14 +64,14 @@ def __init__(self, loopback_range: str = '10.0.0.0/16'):
IP addresses.
"""
super().__init__()
self.__loopback_assigner = IPv4Network(loopback_range)
self.__loopback_pos = 1
self._loopback_assigner = IPv4Network(loopback_range)
self._loopback_pos = 1
self.addDependency('Base', False, False)

def getName(self) -> str:
return "Routing"

def __installBird(self, node: Node):
def _installBird(self, node: Node):
"""!
@brief Install bird on node, and handle the bug.
"""
Expand All @@ -84,68 +84,70 @@ def __installBird(self, node: Node):
if not BaseSystem.doesAContainB(base,BaseSystem.SEEDEMU_ROUTER) and base !=BaseSystem.SEEDEMU_ROUTER:
node.setBaseSystem(BaseSystem.SEEDEMU_ROUTER)

def configure(self, emulator: Emulator):
reg = emulator.getRegistry()
for ((scope, type, name), obj) in reg.getAll().items():
if type == 'rs':
rs_node: Node = obj
self.__installBird(rs_node)
rs_node.appendStartCommand('[ ! -d /run/bird ] && mkdir /run/bird')
rs_node.appendStartCommand('bird -d', True)
self._log("Bootstrapping bird.conf for RS {}...".format(name))
def _configure_rs(self, rs_node: Node):
rs_node.appendStartCommand('[ ! -d /run/bird ] && mkdir /run/bird')
rs_node.appendStartCommand('bird -d', True)
self._log("Bootstrapping bird.conf for RS {}...".format(rs_node.getName() ))

rs_ifaces = rs_node.getInterfaces()
assert len(rs_ifaces) == 1, "rs node {} has != 1 interfaces".format(rs_node.getName())
rs_ifaces = rs_node.getInterfaces()
assert len(rs_ifaces) == 1, "rs node {} has != 1 interfaces".format(rs_node.getName())

rs_iface = rs_ifaces[0]
rs_iface = rs_ifaces[0]

if not issubclass(rs_node.__class__, Router):
rs_node.__class__ = Router
rs_node.setBorderRouter(True)
rs_node.setFile("/etc/bird/bird.conf", RoutingFileTemplates["rs_bird"].format(
if not issubclass(rs_node.__class__, Router):
rs_node.__class__ = Router
rs_node.setBorderRouter(True)
rs_node.setFile("/etc/bird/bird.conf", RoutingFileTemplates["rs_bird"].format(
routerId = rs_iface.getAddress()
))
))

def _configure_bird_router(self, rnode: Router):
ifaces = ''
has_localnet = False
for iface in rnode.getInterfaces():
net = iface.getNet()
if net.isDirect():
has_localnet = True
ifaces += RoutingFileTemplates["rnode_bird_direct_interface"].format(
interfaceName = net.getName()
)
rnode.setFile("/etc/bird/bird.conf", RoutingFileTemplates["rnode_bird"].format(
routerId = rnode.getLoopbackAddress()
))
rnode.appendStartCommand('[ ! -d /run/bird ] && mkdir /run/bird')
rnode.appendStartCommand('bird -d', True)
if has_localnet: rnode.addProtocol('direct', 'local_nets', RoutingFileTemplates['rnode_bird_direct'].format(interfaces = ifaces))

def configure(self, emulator: Emulator):
reg = emulator.getRegistry()
for ((scope, type, name), obj) in reg.getAll().items():
if type == 'rs':
rs_node: Node = obj
self._installBird(rs_node)
self._configure_rs(rs_node)
if type == 'rnode':
rnode: Router = obj
if not issubclass(rnode.__class__, Router): rnode.__class__ = Router

self._log("Setting up loopback interface for AS{} Router {}...".format(scope, name))

lbaddr = self.__loopback_assigner[self.__loopback_pos]
if rnode.getLoopbackAddress()==None:
lbaddr = self._loopback_assigner[self._loopback_pos]

rnode.appendStartCommand('ip li add dummy0 type dummy')
rnode.appendStartCommand('ip li set dummy0 up')
rnode.appendStartCommand('ip addr add {}/32 dev dummy0'.format(lbaddr))
rnode.setLoopbackAddress(lbaddr)
self.__loopback_pos += 1
rnode.appendStartCommand('ip li add dummy0 type dummy')
rnode.appendStartCommand('ip li set dummy0 up')
rnode.appendStartCommand('ip addr add {}/32 dev dummy0'.format(lbaddr))
rnode.setLoopbackAddress(lbaddr)
self._loopback_pos += 1

self._log("Bootstrapping bird.conf for AS{} Router {}...".format(scope, name))

self.__installBird(rnode)
self._installBird(rnode)

r_ifaces = rnode.getInterfaces()
assert len(r_ifaces) > 0, "router node {}/{} has no interfaces".format(rnode.getAsn(), rnode.getName())

ifaces = ''
has_localnet = False

for iface in r_ifaces:
net = iface.getNet()
if net.isDirect():
has_localnet = True
ifaces += RoutingFileTemplates["rnode_bird_direct_interface"].format(
interfaceName = net.getName()
)

rnode.setFile("/etc/bird/bird.conf", RoutingFileTemplates["rnode_bird"].format(
routerId = rnode.getLoopbackAddress()
))

rnode.appendStartCommand('[ ! -d /run/bird ] && mkdir /run/bird')
rnode.appendStartCommand('bird -d', True)

if has_localnet: rnode.addProtocol('direct', 'local_nets', RoutingFileTemplates['rnode_bird_direct'].format(interfaces = ifaces))
self._configure_bird_router(rnode)

def render(self, emulator: Emulator):
reg = emulator.getRegistry()
Expand Down
Loading

0 comments on commit 0260808

Please sign in to comment.