From 291fb22eeb2469e364d1168d7ba5740f55406b32 Mon Sep 17 00:00:00 2001 From: mc36 Date: Wed, 17 Sep 2025 17:47:48 +0200 Subject: [PATCH] adding freertr to the suite --- README.md | 2 +- bgperf2.py | 14 +++++-- build_bgperf.sh | 2 +- freertr.py | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 freertr.py diff --git a/README.md b/README.md index 45ace83..e8b7d50 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ To change a target implementation, use `-t` option. Currently, `bgperf2` supports [BIRD](http://bird.network.cz/) and [FRRouting](https://frrouting.org/) (other than GoBGP. There is very intial support for[RustyBGP](https://github.com/osrg/rustybgp), partly because RustyBGP doesn't support all policy that Bgperf2 tries to use for policy testing. If you just want to -do routes and neighbors then RustyBGP works. +do routes and neighbors then RustyBGP works. Also there is some support for [freeRtr](http://freertr.org/) ```bash $ python3 bgperf2.py bench -t bird diff --git a/bgperf2.py b/bgperf2.py index 254e1b5..7914b1f 100755 --- a/bgperf2.py +++ b/bgperf2.py @@ -41,6 +41,7 @@ from frr import FRRouting, FRRoutingTarget from frr_compiled import FRRoutingCompiled, FRRoutingCompiledTarget from rustybgp import RustyBGP, RustyBGPTarget +from freertr import freertr, freertrTarget from openbgp import OpenBGP, OpenBGPTarget from flock import Flock, FlockTarget from srlinux import SRLinux, SRLinuxTarget @@ -96,7 +97,7 @@ def doctor(args): else: print('... not found. run `bgperf prepare`') - for name in ['gobgp', 'bird', 'frr_c', 'rustybgp', 'openbgp', 'flock', 'srlinux']: + for name in ['gobgp', 'bird', 'frr_c', 'rustybgp', 'freertr', 'openbgp', 'flock', 'srlinux']: print('{0} image'.format(name), end=' ') if img_exists('bgperf/{0}'.format(name)): print('... ok') @@ -113,6 +114,7 @@ def prepare(args): BIRD.build_image(args.force, nocache=args.no_cache) #FRRouting.build_image(args.force, nocache=args.no_cache) RustyBGP.build_image(args.force, nocache=args.no_cache) + freertr.build_image(args.force, nocache=args.no_cache) OpenBGP.build_image(args.force, nocache=args.no_cache) FRRoutingCompiled.build_image(args.force, nocache=args.no_cache) Bgpdump2.build_image(args.force, nocache=args.no_cache) @@ -133,6 +135,8 @@ def update(args): FRRouting.build_image(True, checkout=args.checkout, nocache=args.no_cache) if args.image == 'all' or args.image == 'rustybgp': RustyBGP.build_image(True, checkout=args.checkout, nocache=args.no_cache) + if args.image == 'all' or args.image == 'freertr': + freertr.build_image(True, checkout=args.checkout, nocache=args.no_cache) if args.image == 'all' or args.image == 'openbgp': OpenBGP.build_image(True, checkout=args.checkout, nocache=args.no_cache) if args.image == 'all' or args.image == 'flock': @@ -146,7 +150,7 @@ def update(args): def remove_target_containers(): for target_class in [BIRDTarget, GoBGPTarget, FRRoutingTarget, FRRoutingCompiledTarget, - RustyBGPTarget, OpenBGPTarget, FlockTarget, JunosTarget, SRLinuxTarget, EosTarget]: + RustyBGPTarget, freertrTarget, OpenBGPTarget, FlockTarget, JunosTarget, SRLinuxTarget, EosTarget]: if ctn_exists(target_class.CONTAINER_NAME): print('removing target container', target_class.CONTAINER_NAME) dckr.remove_container(target_class.CONTAINER_NAME, force=True) @@ -437,6 +441,8 @@ def bench(args): target_class = FRRoutingCompiledTarget elif args.target == 'rustybgp': target_class = RustyBGPTarget + elif args.target == 'freertr': + target_class = freertrTarget elif args.target == 'openbgp': target_class = OpenBGPTarget elif args.target == 'flock': @@ -1053,7 +1059,7 @@ def create_args_parser(main=True): parser_update = s.add_parser('update', help='rebuild bgp docker images') parser_update.add_argument('image', choices=['exabgp', 'exabgp_mrtparse', 'gobgp', 'bird', 'frr', 'frr_c', - 'rustybgp', 'openbgp', 'flock', 'bgpdump2', 'all']) + 'rustybgp', 'freertr', 'openbgp', 'flock', 'bgpdump2', 'all']) parser_update.add_argument('-c', '--checkout', default='HEAD') parser_update.add_argument('-n', '--no-cache', action='store_true') parser_update.set_defaults(func=update) @@ -1085,7 +1091,7 @@ def add_gen_conf_args(parser): parser.add_argument('--filter_test', choices=['transit', 'ixp'], default=None) parser_bench = s.add_parser('bench', help='run benchmarks') - parser_bench.add_argument('-t', '--target', choices=['gobgp', 'bird', 'frr_c', 'rustybgp', + parser_bench.add_argument('-t', '--target', choices=['gobgp', 'bird', 'frr_c', 'rustybgp', 'freertr', 'openbgp', 'flock', 'srlinux', 'junos', 'eos'], default='bird') parser_bench.add_argument('-i', '--image', help='specify custom docker image') parser_bench.add_argument('--mrt-file', type=str, diff --git a/build_bgperf.sh b/build_bgperf.sh index 2e085ec..8c6e526 100755 --- a/build_bgperf.sh +++ b/build_bgperf.sh @@ -1,3 +1,3 @@ python3 bgperf.py update exabgp & python3 bgperf.py update gobgp & python3 bgperf.py update bird & \ python3 bgperf.py update frr & python3 bgperf.py update frr_c & python3 bgperf.py update rustybgp & \ - python3 bgperf.py update bgpdump2 & python3 bgperf.py update openbgp & + python3 bgperf.py update freertr & python3 bgperf.py update bgpdump2 & python3 bgperf.py update openbgp & diff --git a/freertr.py b/freertr.py new file mode 100644 index 0000000..1fd26d2 --- /dev/null +++ b/freertr.py @@ -0,0 +1,106 @@ + +import toml +from base import * +from gobgp import GoBGPTarget + + +class freertr(Container): + CONTAINER_NAME = None + GUEST_DIR = '/root' + + def __init__(self, host_dir, conf, image='bgperf/freertr'): + super(freertr, self).__init__(self.CONTAINER_NAME, image, host_dir, self.GUEST_DIR, conf) + + @classmethod + def build_image(cls, force=False, tag='bgperf/freertr', checkout='', nocache=False): + + cls.dockerfile = ''' +FROM debian:latest +WORKDIR / +RUN apt-get update +RUN apt-get -y install iproute2 net-tools default-jdk-headless git zip telnet curl > /dev/null +RUN git clone https://github.com/mc36/freeRtr +WORKDIR freeRtr/src +RUN ./c.sh +'''.format(checkout) + super(freertr, cls).build_image(force, tag, nocache) + + +class freertrTarget(freertr, Target): + CONTAINER_NAME = 'bgperf_freertr_target' + CONFIG_FILE_NAME = 'rtr-sw.txt' + + def write_config(self): + neighbors = list(flatten(list(t.get('neighbors', {}).values()) for t in self.scenario_global_conf['testers'])) + [self.scenario_global_conf['monitor']] + + with open('{0}/{1}'.format(self.host_dir, self.CONFIG_FILE_NAME), 'w') as f: + + f.write(""" +hostname freertr +logging file debug /root/zzz.log +vrf definition test + exit +server http web + host * path /root/ + host * api exec + vrf test + exit +server telnet tel + security protocol telnet + vrf test + exit +interface loopback0 + vrf for test + ipv4 address {1} /0 + exit +router bgp4 1 + vrf test + router-id {1} + local-as {0} + distance 255 255 255 + no safe-ebgp +""".format(self.conf['as'], self.conf['router-id'])) + + for n in neighbors: + f.write(""" + neighbor {0} remote-as {1} + neighbor {0} connection-mode passive + neighbor {0} allow-as-out +""".format(n['local-address'], n['as'])) + + f.write(""" +exit +""") + + with open('{0}/rtr-hw.txt'.format(self.host_dir), 'w') as f: + f.write(""" +tcp2vrf 179 test 179 +tcp2vrf 23 test 23 +tcp2vrf 80 test 80 +""") + + def get_startup_cmd(self): + return '\n'.join( + ['#!/bin/bash', + 'cd /root/', + 'java -Xmx4096m -jar /freeRtr/src/rtr.jar routerc /root/rtr-'] + ).format( + guest_dir=self.guest_dir, + config_file_name=self.CONFIG_FILE_NAME, + debug_level='info') + + def get_version_cmd(self): + return "java -jar /freeRtr/src/rtr.jar show version number" + + def exec_version_cmd(self): + version = self.get_version_cmd() + i= dckr.exec_create(container=self.name, cmd=version, stderr=False) + return dckr.exec_start(i['Id'], stream=False, detach=False).decode('utf-8').strip() + + def get_neighbors_state(self): + result = {} + output = self.local("curl 127.0.0.1/.api./exec/show+ipv4+bgp+1+summary").splitlines() + for i in range(2,len(output)-1): + line = output[i].decode('ascii').split(";") + result[line[0]] = int(line[3]) + return result, result