Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion scionlab/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,19 +301,21 @@ class BorderRouterAdminForm(_CreateUpdateModelForm):
def create(self):
return BorderRouter.objects.create(
host=self.cleaned_data['host'],
is_hsr=self.cleaned_data['is_hsr'],
)

def update(self):
self.instance.update(
host=self.cleaned_data['host'],
is_hsr=self.cleaned_data['is_hsr'],
)


class BorderRouterInline(admin.TabularInline):
model = BorderRouter
extra = 0
form = BorderRouterAdminForm
fields = ('host',)
fields = ('host', 'is_hsr')

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "host":
Expand Down
20 changes: 20 additions & 0 deletions scionlab/fixtures/testdata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4525,101 +4525,121 @@
fields:
AS: 1
host: 1
is_hsr: false
- model: scionlab.borderrouter
pk: 2
fields:
AS: 3
host: 3
is_hsr: true
- model: scionlab.borderrouter
pk: 3
fields:
AS: 2
host: 2
is_hsr: true
- model: scionlab.borderrouter
pk: 4
fields:
AS: 4
host: 4
is_hsr: false
- model: scionlab.borderrouter
pk: 5
fields:
AS: 5
host: 5
is_hsr: false
- model: scionlab.borderrouter
pk: 6
fields:
AS: 6
host: 6
is_hsr: false
- model: scionlab.borderrouter
pk: 7
fields:
AS: 7
host: 7
is_hsr: false
- model: scionlab.borderrouter
pk: 8
fields:
AS: 8
host: 8
is_hsr: false
- model: scionlab.borderrouter
pk: 9
fields:
AS: 9
host: 9
is_hsr: false
- model: scionlab.borderrouter
pk: 10
fields:
AS: 10
host: 10
is_hsr: false
- model: scionlab.borderrouter
pk: 11
fields:
AS: 11
host: 11
is_hsr: false
- model: scionlab.borderrouter
pk: 12
fields:
AS: 12
host: 12
is_hsr: false
- model: scionlab.borderrouter
pk: 13
fields:
AS: 13
host: 13
is_hsr: false
- model: scionlab.borderrouter
pk: 14
fields:
AS: 14
host: 14
is_hsr: false
- model: scionlab.borderrouter
pk: 15
fields:
AS: 15
host: 15
is_hsr: false
- model: scionlab.borderrouter
pk: 16
fields:
AS: 16
host: 16
is_hsr: false
- model: scionlab.borderrouter
pk: 18
fields:
AS: 17
host: 17
is_hsr: false
- model: scionlab.borderrouter
pk: 20
fields:
AS: 18
host: 18
is_hsr: false
- model: scionlab.borderrouter
pk: 22
fields:
AS: 19
host: 19
is_hsr: false
- model: scionlab.borderrouter
pk: 24
fields:
AS: 20
host: 20
is_hsr: false
- model: scionlab.service
pk: 1
fields:
Expand Down
16 changes: 15 additions & 1 deletion scionlab/fixtures/testtopo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

from collections import namedtuple
from scionlab.models.core import ISD, AS, Link, Host, Service
from scionlab.models.core import ISD, AS, Link, Host, Service, BorderRouter
from scionlab.models.user_as import AttachmentPoint
from scionlab.models.vpn import VPN

Expand Down Expand Up @@ -110,6 +110,12 @@ def makeLinkDef(type, as_id_tail_a, as_id_tail_b):
(_expand_as_id(0x1301), Service.SIG),
]

# Router instances (AS ID, router instance ID) with high-speed router configuration
hsrs = [
(_expand_as_id(0x1102), 1),
(_expand_as_id(0x1103), 1),
]

# VPNs for APs, except 1303
vpns = [
VPNDef(_expand_as_id(0x1107), "10.0.8.1", 1194, "10.0.0.0/16"), # odd subnet, used in prod!
Expand All @@ -124,6 +130,7 @@ def create_testtopo():
create_links()
create_vpn()
create_extraservices()
setup_hsrs()


def create_isds():
Expand Down Expand Up @@ -156,6 +163,13 @@ def create_extraservices():
Service.objects.create(host=host, type=as_serv[1])


def setup_hsrs():
for as_id, brid in hsrs:
br = BorderRouter.objects.filter(AS__as_id=as_id)[brid-1]
br.is_hsr = True
br.save()


def _create_as(isd_id, as_id, label, public_ip, is_core=False, is_ap=False):
isd = ISD.objects.get(isd_id=isd_id)
as_ = AS.objects.create_with_default_services(
Expand Down
23 changes: 23 additions & 0 deletions scionlab/migrations/0002_hsr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2 on 2021-09-14 13:45

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('scionlab', '0001_squashed_0011_pullap'),
]

operations = [
migrations.AddField(
model_name='borderrouter',
name='is_hsr',
field=models.BooleanField(default=False, help_text='If true, this is a high-speed router instance with special configuration.'),
),
migrations.AlterField(
model_name='service',
name='type',
field=models.CharField(choices=[('CS', 'Control Service'), ('SIG', 'SCION IP Gateway'), ('BW', 'Bandwidth tester server'), ('PP', 'Pingpong server')], max_length=16),
),
]
26 changes: 20 additions & 6 deletions scionlab/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1009,26 +1009,29 @@ def get_interface_b(self):


class BorderRouterManager(models.Manager):
def create(self, host):
def create(self, host, is_hsr=False):
"""
Create a BorderRouter object.
:param Host host: the host, defines the AS
:param bool is_hsr: this is a high-speed router instance
:returns: BorderRouter
"""
host.AS.hosts.bump_config()

return super().create(
AS=host.AS,
host=host,
is_hsr=is_hsr,
)

def first_or_create(self, host):
def first_or_create(self, host, is_hsr=False):
"""
Get the first border router related to this host, or create a new one with default settings.
:param Host host: the host, defines the AS
:param bool is_hsr: this is a high-speed router instance
:returns: BorderRouter
"""
return host.border_routers.first() or self.create(host=host)
return host.border_routers.first() or self.create(host=host, is_hsr=is_hsr)

def iterator_non_empty(self):
"""
Expand All @@ -1053,6 +1056,10 @@ class BorderRouter(models.Model):
related_name='border_routers',
on_delete=models.CASCADE
)
is_hsr = models.BooleanField(
default=False,
help_text="If true, this is a high-speed router instance with special configuration."
)

objects = BorderRouterManager()

Expand Down Expand Up @@ -1094,12 +1101,14 @@ def internal_port(self):
def metrics_port(self):
return BR_METRICS_PORT_BASE + self.instance_id

def update(self, host=_placeholder):
def update(self, host=_placeholder, is_hsr=_placeholder):
"""
Update the given fields
:param Host host: optional, the host. Must be in current AS.
:param bool is_hsr: optional, this is a high-speed router instance
"""
prev_host = self.host
prev_is_hsr = self.is_hsr

if host is not _placeholder:
if host.AS != self.AS:
Expand All @@ -1108,10 +1117,15 @@ def update(self, host=_placeholder):
raise RuntimeError('BorderRouter.update cannot change AS')
self.host = host

if is_hsr is not _placeholder:
self.is_hsr = is_hsr

self.save()

if host != prev_host:
host.AS.hosts.bump_config()
if self.host != prev_host:
self.AS.hosts.bump_config()
elif self.is_hsr != prev_is_hsr:
self.host.bump_config()


class ServiceManager(models.Manager):
Expand Down
25 changes: 15 additions & 10 deletions scionlab/scion/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
SERVICES_TO_SYSTEMD_NAMES = {
Service.CS: 'scion-control-service',
Service.BW: 'scion-bwtestserver',
TYPE_BR: 'scion-border-router',
}

DEFAULT_ENV = ['TZ=UTC']
Expand Down Expand Up @@ -97,8 +96,9 @@ def _write_as_config(self, cb: '_ConfigBuilder'):
config_dir = cb.config_dir.lstrip('/') # don't use absolute paths in the archive

for router in self._routers():
self.archive.write_toml((config_dir, f'{router.instance_name}.toml'),
cb.build_br_conf(router))
if not router.is_hsr:
self.archive.write_toml((config_dir, f'{router.instance_name}.toml'),
cb.build_br_conf(router))

for service in self._control_services():
assert service.type == Service.CS
Expand Down Expand Up @@ -166,7 +166,11 @@ def generate(self):
# dispatcher and sciond config files are installed with the package

def systemd_units(self):
units = ["scion-border-router@%s.service" % router.instance_name
router_systemd_name = {
False: 'scion-border-router',
True: 'scion-hsr',
}
units = ["%s@%s.service" % (router_systemd_name[router.is_hsr], router.instance_name)
for router in self._routers()]
units += ["%s@%s.service" % (SERVICES_TO_SYSTEMD_NAMES[service.type], service.instance_name)
for service in self._control_services()]
Expand Down Expand Up @@ -205,12 +209,13 @@ def _cmd(binary_name, config_dir, config_file):
as_dir = self._as_dir()
config = configparser.ConfigParser()
for router in self._routers():
_add_supervisord_program_conf(
config,
router.instance_name,
_cmd(CMDS[TYPE_BR], as_dir, router.instance_name + '.toml'),
env=BORDER_ENV
)
if not router.is_hsr:
_add_supervisord_program_conf(
config,
router.instance_name,
_cmd(CMDS[TYPE_BR], as_dir, router.instance_name + '.toml'),
env=BORDER_ENV
)
for service in self._control_services():
_add_supervisord_program_conf(
config,
Expand Down
Loading