Example #1
0
    def test_addr_assignment(self):
        """Test correct assignment of Docker host addresses to border router interfaces."""
        net = HostNetwork("host_network", ipaddress.ip_network("10.0.0.0/24"))
        hosts = [LocalHost(), LocalHost()]
        asys = [AS(host, False) for host in hosts]

        net.set_host_ip(hosts[0], ipaddress.ip_address("10.0.0.10"))
        net.set_host_ip(hosts[1], ipaddress.ip_address("10.0.0.11"))

        with self.assertRaises(errors.NotAvailable):
            net.assign_br_address(ISD_AS("1-ff00:0:000"),
                                  asys[0],
                                  IfId(1),
                                  pref_ip=ipaddress.ip_address("10.0.0.2"))

        ip, port = net.assign_br_address(ISD_AS("1-ff00:0:000"), asys[0],
                                         IfId(1))
        self.assertEqual(ip, ipaddress.ip_address("10.0.0.10"))
        self.assertEqual(port, L4Port(50000))

        ip, port = net.assign_br_address(ISD_AS("1-ff00:0:001"), asys[1],
                                         IfId(1))
        self.assertEqual(ip, ipaddress.ip_address("10.0.0.11"))
        self.assertEqual(port, L4Port(50000))

        ip, port = net.assign_br_address(ISD_AS("1-ff00:0:001"), asys[1],
                                         IfId(2))
        self.assertEqual(ip, ipaddress.ip_address("10.0.0.11"))
        self.assertEqual(port, L4Port(50001))
Example #2
0
    def test_ifid_assignment(self):
        self.assertEqual(self.asys.get_unused_ifid(), 1)
        self.asys.border_routers[1].links[IfId(1)] = Link(
            LinkEp("1-ff00:0:110-br2#1"), LinkEp("1-ff00:0:112#1"), LinkType.CHILD)

        self.assertEqual(self.asys.get_unused_ifid(), 3)
        self.asys.border_routers[1].links[IfId(3)] = Link(
            LinkEp("1-ff00:0:110-br2#1"), LinkEp("1-ff00:0:113#1"), LinkType.CHILD)

        self.assertEqual(self.asys.get_unused_ifid(), 6)
Example #3
0
 def setUp(self):
     asys = AS(LocalHost(), True)
     asys.border_routers = [
         BorderRouter(1),
         BorderRouter(2)
     ]
     asys.border_routers[0].links[IfId(2)] = Link(LinkEp("1-ff00:0:110-br1#2"), LinkEp("2-ff00:0:210#1"), LinkType.CORE)
     asys.border_routers[0].links[IfId(4)] = Link(LinkEp("1-ff00:0:110-br1#4"), LinkEp("2-ff00:0:211#1"), LinkType.CORE)
     asys.border_routers[1].links[IfId(5)] = Link(LinkEp("1-ff00:0:110-br2#5"), LinkEp("1-ff00:0:111#1"), LinkType.CHILD)
     self.asys = asys
Example #4
0
def pick_unused_ifid(ifids: List[IfId]) -> IfId:
    """Returns the smallest interface ID not in `ifids`.

    :param ifids: List of ifids in ascending order.
    """
    if len(ifids) == 0:
        return IfId(FIRST_IFID)
    else:

        for i, ifid in enumerate(ifids):
            if (i + FIRST_IFID) != ifid:
                return IfId(i + FIRST_IFID)
        else:
            return IfId(ifids[-1] + 1)
Example #5
0
    def __init__(self, topo_file: MutableMapping[str, Any]):
        """Initializes used interface identifier sets from the given topology file."""
        self.used_ifids: DefaultDict[ISD_AS, List[IfId]] = defaultdict(list)
        for link in topo_file['links']:
            for ep in [LinkEp(link['a']), LinkEp(link['b'])]:
                if ep.ifid:
                    self.used_ifids[ep].append(IfId(ep.ifid))

        for ifids in self.used_ifids.values():
            ifids.sort()
Example #6
0
    def test_br_addr_assignment(self):
        """Test assignment of (IP, port) tuples to border router interfaces."""
        br = DockerBridge("test", LocalHost(),
                          ipaddress.IPv4Network("10.0.0.0/29"))
        asys = AS(LocalHost(), False)

        # Assign BR interface addresses
        for _ in range(2):  # Multiple calls must return the same addresses
            for ifid in range(1, 3):
                for as_id in range(1, 6):
                    ip, port = br.assign_br_address(ISD_AS(as_id), asys,
                                                    IfId(ifid))
                    self.assertEqual(
                        ip, ipaddress.IPv4Address(0x0A000000 + as_id + 1))
                    self.assertEqual(port, 50000 + ifid - 1)

        with self.assertRaises(errors.OutOfResources):
            br.assign_br_address(ISD_AS(8), asys, IfId(1))

        # AS IP assignment
        for as_id in range(1, 6):
            isd_as = ISD_AS(as_id)
            self.assertEqual(br.get_ip_address(isd_as),
                             br.assign_ip_address(isd_as))

        # Retrieve BR interface underlay addresses
        for ifid in range(1, 3):
            for asys in range(1, 6):
                ip, port = unwrap(br.get_br_address(ISD_AS(asys), IfId(ifid)))
                self.assertEqual(ip,
                                 ipaddress.IPv4Address(0x0A000000 + asys + 1))
                self.assertEqual(port, 50000 + ifid - 1)

        # Free BR interfaces
        for asys in range(1, 6):
            for ifid in range(1, 3):
                self.assertEqual(br.free_br_address(ISD_AS(asys), IfId(ifid)),
                                 3 - ifid)

        # Check whether IPs are still bound
        for asys in range(1, 6):
            ip = br.get_ip_address(ISD_AS(asys))
            self.assertEqual(ip, ipaddress.IPv4Address(0x0A000000 + asys + 1))
Example #7
0
    def add_link_ep(self, link_ep: LinkEp, link: Link) -> None:
        """Assign the given link to a `BorderRouter` object identified by `link_ep`.

        This function assigns IDs to border routers in the same way as the SCION topology generator
        does: IDs are assigned consecutively starting from 1. Border routers, which have not been
        given a name in the topology file have a single interface, i.e., a new BR is created with
        the next available ID for every link added to the AS.
        Border routers that have a name can have multiple interfaces, and are given an ID the first
        time they are encountered.

        Border routers are named in the topology definition by inserting a name between the ISD-AS
        identifer and the interface ID. For example, "1-ff00:0:110-test#1" names interface "1" of a
        BR called "test" in ASff00:0:110.
        """
        unnamed_brs, named_brs = self._border_routers[link_ep]
        nextId = len(unnamed_brs) + len(named_brs) + 1
        br_name = link_ep.br_name()
        if br_name:
            if br_name not in named_brs:
                named_brs[br_name] = BorderRouter(nextId)
            named_brs[br_name].links[IfId(link_ep.ifid)] = link
        else:
            unnamed_brs.append(BorderRouter(nextId))
            unnamed_brs[-1].links[IfId(link_ep.ifid)] = link
Example #8
0
def _update_underlay_addresses(topo_file: Mapping[str, Any], isd_as: ISD_AS, asys: AS):
    """Update the underlay addresses of the border router interfaces to match the given AS object.

    :param topo_file: Parsed topology.json file to modify.
    :param isd_as: AS the topology file belongs to.
    :param asys: AS the topology file belongs to.
    """
    for br in asys.border_routers:
        br_name = br.get_name(isd_as)
        interfaces = topo_file['BorderRouters'][br_name]['Interfaces']
        for ifid, iface in interfaces.items():
            local, remote = br.links[IfId(int(ifid))].get_underlay_addresses(isd_as)
            iface['PublicOverlay']['Addr'] = str(local.ip)
            iface['PublicOverlay']['OverlayPort'] = int(local.port)
            iface['RemoteOverlay']['Addr'] = str(remote.ip)
            iface['RemoteOverlay']['OverlayPort'] = int(remote.port)
Example #9
0
    def test(self):
        """Test successful address assignment."""
        topo = self.topo
        assign_underlay_addresses(topo)

        self.assertEqual(len(topo.bridges), 4)

        # link 1
        net = topo.get_bridge_subnet(ipaddress.ip_network("10.0.10.0/29"))
        self.assertIsInstance(net, DockerBridge)
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:110"), IfId(1)),
            UnderlayAddress(ipaddress.ip_address("10.0.10.2"), L4Port(50000)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:111"), IfId(1)),
            UnderlayAddress(ipaddress.ip_address("10.0.10.3"), L4Port(50000)))

        # link 2
        net = topo.get_bridge_subnet(ipaddress.ip_network("10.0.11.0/29"))
        self.assertIsInstance(net, DockerBridge)
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:110"), IfId(2)),
            UnderlayAddress(ipaddress.ip_address("10.0.11.2"), L4Port(50000)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:112"), IfId(1)),
            UnderlayAddress(ipaddress.ip_address("10.0.11.3"), L4Port(50000)))

        # links 3 to 5
        net = topo.get_bridge_subnet(ipaddress.ip_network("10.0.20.0/24"))
        self.assertIsInstance(net, OvsBridge)
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:111"), IfId(2)),
            UnderlayAddress(ipaddress.ip_address("10.0.20.2"), L4Port(50000)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:111"), IfId(3)),
            UnderlayAddress(ipaddress.ip_address("10.0.20.2"), L4Port(50001)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:112"), IfId(2)),
            UnderlayAddress(ipaddress.ip_address("10.0.20.3"), L4Port(50000)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:112"), IfId(3)),
            UnderlayAddress(ipaddress.ip_address("10.0.20.3"), L4Port(50001)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:113"), IfId(1)),
            UnderlayAddress(ipaddress.ip_address("10.0.20.4"), L4Port(50000)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:113"), IfId(2)),
            UnderlayAddress(ipaddress.ip_address("10.0.20.4"), L4Port(50001)))

        # link 6
        net = topo.get_bridge_subnet(ipaddress.ip_network("10.0.21.0/24"))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:112"), IfId(4)),
            UnderlayAddress(ipaddress.ip_address("10.0.21.9"), L4Port(50000)))
        self.assertEqual(
            net.get_br_address(ISD_AS("1-ff00:0:113"), IfId(3)),
            UnderlayAddress(ipaddress.ip_address("10.0.21.10"), L4Port(50000)))
    def test(self):
        """Test successful parse."""
        topo_file = yaml.safe_load(TEST_TOPO)
        topo = extract_topo_info(topo_file)
        ASES = [
            ISD_AS("1-ff00:0:110"),
            ISD_AS("1-ff00:0:111"),
            ISD_AS("1-ff00:0:112")
        ]

        self.assertIsNone(topo.coordinator)
        self.assertEqual(len(topo.additional_services), 0)

        # IPv6
        self.assertFalse(topo.ipv6_enabled)

        # Default link subnet
        self.assertEqual(topo.default_link_subnet,
                         ipaddress.ip_network("10.0.10.0/24"))

        # ASes
        self.assertEqual(len(topo.ases), 3)
        for asys in ASES:
            self.assertIn(asys, topo.ases)

        # IXPs
        self.assertIn("ixp1", topo.ixps)
        ixp = topo.ixps["ixp1"]
        for isd_as in [ISD_AS("1-ff00:0:111"), ISD_AS("1-ff00:0:112")]:
            self.assertIn(isd_as, ixp.ases)
            self.assertIs(ixp.ases[isd_as], topo.ases[isd_as])

        # Networks
        self.assertEqual(len(topo.bridges), 2)
        ip_net = ipaddress.ip_network("10.0.11.0/29")
        self.assertIsInstance(topo.get_bridge_subnet(ip_net), DockerBridge)
        ip_net = ipaddress.ip_network("10.0.20.0/24")
        self.assertIsInstance(topo.get_bridge_subnet(ip_net), OvsBridge)

        # Links
        self.assertEqual(len(topo.links), 3)
        self.assertEqual(topo.links[0].ep_a, LinkEp("1-ff00:0:110#1"))
        self.assertEqual(topo.links[0].ep_b, LinkEp("1-ff00:0:111#1"))
        self.assertIsNone(topo.links[0].bridge)
        self.assertEqual(topo.links[1].ep_a, LinkEp("1-ff00:0:110#2"))
        self.assertEqual(topo.links[1].ep_b, LinkEp("1-ff00:0:112#1"))
        self.assertEqual(
            topo.links[1].bridge,
            topo.get_bridge_subnet(ipaddress.ip_network("10.0.11.0/29")))
        self.assertEqual(topo.links[2].ep_a, LinkEp("1-ff00:0:111#2"))
        self.assertEqual(topo.links[2].ep_b, LinkEp("1-ff00:0:112#2"))
        self.assertEqual(
            topo.links[2].bridge,
            topo.get_bridge_subnet(ipaddress.ip_network("10.0.20.0/24")))

        # BRs
        self.assertEqual(len(topo.ases[ASES[0]].border_routers), 2)
        self.assertEqual(len(topo.ases[ASES[1]].border_routers), 2)
        self.assertEqual(len(topo.ases[ASES[2]].border_routers), 1)

        # br1-ff00_0_110-1
        br = topo.ases[ASES[0]].border_routers[0]
        self.assertEqual(br.id, 1)
        self.assertEqual(br.get_name(ASES[0]), "br1-ff00_0_110-1")
        self.assertEqual(len(br.links), 1)
        self.assertIs(br.links[IfId(1)], topo.links[0])

        # br1-ff00_0_110-2
        br = topo.ases[ASES[0]].border_routers[1]
        self.assertEqual(br.id, 2)
        self.assertEqual(br.get_name(ASES[0]), "br1-ff00_0_110-2")
        self.assertEqual(len(br.links), 1)
        self.assertIs(br.links[IfId(2)], topo.links[1])

        # br1-ff00_0_111-1
        br = topo.ases[ASES[1]].border_routers[0]
        self.assertEqual(br.id, 1)
        self.assertEqual(br.get_name(ASES[1]), "br1-ff00_0_111-1")
        self.assertEqual(len(br.links), 1)
        self.assertIs(br.links[IfId(1)], topo.links[0])

        # br1-ff00_0_111-2
        br = topo.ases[ASES[1]].border_routers[1]
        self.assertEqual(br.id, 2)
        self.assertEqual(br.get_name(ASES[1]), "br1-ff00_0_111-2")
        self.assertEqual(len(br.links), 1)
        self.assertIs(br.links[IfId(2)], topo.links[2])

        # br1-ff00_0_112-1
        br = topo.ases[ASES[2]].border_routers[0]
        self.assertEqual(br.id, 1)
        self.assertEqual(br.get_name(ASES[2]), "br1-ff00_0_112-1")
        self.assertEqual(len(br.links), 2)
        self.assertIs(br.links[IfId(1)], topo.links[1])
        self.assertIs(br.links[IfId(2)], topo.links[2])

        # topo_file
        self.assertNotIn("link_subnet", topo_file['defaults'])
        self.assertNotIn("IXPs", topo_file)
        for link in topo_file['links']:
            self.assertNotIn('network', link)
Example #11
0
    def test(self):
        """Test successful parse of a topology with multiple hosts and a coordinator."""
        topo_file = yaml.safe_load(TEST_TOPO)
        topo = extract_topo_info(topo_file)
        assign_underlay_addresses(topo)

        # IPv6
        self.assertFalse(topo.ipv6_enabled)

        # Default link subnet
        self.assertEqual(topo.default_link_subnet,
                         ipaddress.ip_network("10.0.10.0/24"))

        # Hosts
        self.assertEqual(len(topo.hosts), 2)
        self.assertIsInstance(topo.hosts['localhost'], LocalHost)
        self.assertIsInstance(topo.hosts['host1'], RemoteHost)

        host = cast(RemoteHost, topo.hosts['host1'])
        self.assertEqual(host.name, 'host1')
        self.assertEqual(host.ssh_host, ipaddress.ip_address("192.168.244.3"))
        self.assertEqual(host._ssh_port, 22)
        self.assertEqual(host._username, "scion")
        self.assertEqual(host._identity_file, ".ssh/id_rsa")

        # Networks
        self.assertEqual(len(topo.bridges), 8)

        bridge = topo.get_bridge_subnet(ipaddress.ip_network("10.0.20.0/24"))
        self.assertIsInstance(bridge, DockerBridge)
        self.assertEqual(bridge.name, "bridge1")
        self.assertEqual(
            cast(DockerBridge, bridge)._host, topo.hosts['localhost'])

        bridge = topo.get_bridge_subnet(ipaddress.ip_network("10.0.21.0/24"))
        self.assertIsInstance(bridge, OvsBridge)
        self.assertEqual(bridge.name, "ovs_bridge1")
        self.assertEqual(
            cast(OvsBridge, bridge)._host, topo.hosts['localhost'])

        bridge = topo.get_bridge_subnet(ipaddress.ip_network("10.0.22.0/24"))
        self.assertIsInstance(bridge, OverlayNetwork)
        self.assertEqual(bridge.name, "overlay_bridge1")
        self.assertEqual(
            cast(OverlayNetwork, bridge)._host, topo.hosts['host1'])
        self.assertEqual(cast(OverlayNetwork, bridge).encrypted, True)
        bridge = topo.get_bridge_subnet(ipaddress.ip_network("10.0.23.0/24"))

        self.assertIsInstance(bridge, HostNetwork)
        self.assertEqual(bridge.name, "physical_network1")

        # Coordinator
        self.assertIs(topo.coordinator.bridge,
                      topo.get_bridge_name("overlay_bridge1"))
        self.assertIs(topo.coordinator.host, topo.hosts['localhost'])
        self.assertFalse(topo.coordinator.cpu_affinity.is_unrestricted())
        self.assertEqual(str(topo.coordinator.cpu_affinity), "0")
        expected = UnderlayAddress(ipaddress.ip_address("192.168.244.2"),
                                   L4Port(8000))
        self.assertEqual(topo.coordinator.exposed_at, expected)

        self.assertEqual(len(topo.coordinator.users), 3)

        user = topo.coordinator.users['admin']
        self.assertEqual(user.email, "*****@*****.**")
        self.assertEqual(user.password, "admin")
        self.assertTrue(user.is_admin)

        user = topo.coordinator.users['user1']
        self.assertEqual(user.email, "*****@*****.**")
        self.assertEqual(user.password, "user1")
        self.assertFalse(user.is_admin)

        user = topo.coordinator.users['user2']
        self.assertEqual(user.email, "*****@*****.**")
        self.assertEqual(user.password, "user2")
        self.assertFalse(user.is_admin)

        # Prometheus
        self.assertEqual(len(topo.additional_services), 1)
        prom = cast(Prometheus, topo.additional_services[0])
        self.assertIs(prom.bridge, topo.get_bridge_name("overlay_bridge1"))
        self.assertEqual(prom.host, topo.hosts['localhost'])
        self.assertFalse(prom.cpu_affinity.is_unrestricted())
        self.assertEqual(str(prom.cpu_affinity), "1")
        expected = UnderlayAddress(ipaddress.ip_address("192.168.244.2"),
                                   L4Port(9090))
        self.assertEqual(prom.exposed_at, expected)

        self.assertEqual(prom.scrape_interval, "5s")
        self.assertIn(ISD_AS("1-ff00:0:110"), prom.targets)
        self.assertIn(ISD_AS("1-ff00:0:111"), prom.targets)
        self.assertIn(ISD_AS("1-ff00:0:112"), prom.targets)

        # ASes
        self.assertEqual(len(topo.ases), 8)

        asys = topo.ases[ISD_AS("1-ff00:0:110")]
        self.assertTrue(asys.is_core)
        self.assertFalse(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['localhost'])
        self.assertTrue(asys.cpu_affinity.is_unrestricted())
        self.assertIsNone(asys.owner)

        asys = topo.ases[ISD_AS("1-ff00:0:111")]
        self.assertFalse(asys.is_core)
        self.assertTrue(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['localhost'])
        self.assertTrue(asys.cpu_affinity.is_unrestricted())
        self.assertIsNone(asys.owner)

        asys = topo.ases[ISD_AS("1-ff00:0:112")]
        self.assertFalse(asys.is_core)
        self.assertFalse(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['localhost'])
        self.assertFalse(asys.cpu_affinity.is_unrestricted())
        self.assertEqual(str(asys.cpu_affinity), "0,1,2,3")
        self.assertEqual(asys.owner, "user1")

        asys = topo.ases[ISD_AS("1-ff00:0:113")]
        self.assertFalse(asys.is_core)
        self.assertFalse(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['localhost'])
        self.assertFalse(asys.cpu_affinity.is_unrestricted())
        self.assertEqual(str(asys.cpu_affinity), "2,3,5")
        self.assertEqual(asys.owner, "user1")

        asys = topo.ases[ISD_AS("2-ff00:0:210")]
        self.assertTrue(asys.is_core)
        self.assertFalse(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['localhost'])
        self.assertIsNone(asys.owner)

        asys = topo.ases[ISD_AS("2-ff00:0:211")]
        self.assertFalse(asys.is_core)
        self.assertTrue(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['localhost'])
        self.assertIsNone(asys.owner)

        asys = topo.ases[ISD_AS("2-ff00:0:212")]
        self.assertFalse(asys.is_core)
        self.assertFalse(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['host1'])
        self.assertEqual(asys.owner, "user2")

        asys = topo.ases[ISD_AS("2-ff00:0:213")]
        self.assertFalse(asys.is_core)
        self.assertFalse(asys.is_attachment_point)
        self.assertIs(asys.host, topo.hosts['host1'])
        self.assertEqual(asys.owner, "user2")

        # IXPs
        self.assertIn("ixp1", topo.ixps)
        ixp = topo.ixps["ixp1"]
        expected_ases = [ISD_AS("1-ff00:0:112"), ISD_AS("1-ff00:0:113")]
        for isd_as in expected_ases:
            self.assertIn(isd_as, ixp.ases)
            self.assertIs(ixp.ases[isd_as], topo.ases[isd_as])
        self.assertIsInstance(ixp.bridge, DockerBridge)
        self.assertEqual(ixp.bridge.ip_network,
                         ipaddress.ip_network("10.0.12.0/24"))

        self.assertIn("ixp2", topo.ixps)
        ixp = topo.ixps["ixp2"]
        expected_ases = [
            ISD_AS("1-ff00:0:112"),
            ISD_AS("1-ff00:0:113"),
            ISD_AS("2-ff00:0:212"),
            ISD_AS("2-ff00:0:213")
        ]
        for isd_as in expected_ases:
            self.assertIn(isd_as, ixp.ases)
            self.assertIs(ixp.ases[isd_as], topo.ases[isd_as])
        self.assertIsInstance(ixp.bridge, HostNetwork)
        self.assertIs(ixp.bridge, topo.get_bridge_name("physical_network1"))

        # Links
        self.assertEqual(len(topo.links), 13)

        interfaces = dict(topo.ases[ISD_AS("1-ff00:0:110")].links())
        link = interfaces[IfId(1)]
        subnet = ipaddress.ip_network("10.0.13.0/24")
        self.assertIs(link.bridge, topo.get_bridge_subnet(subnet))

        interfaces = dict(topo.ases[ISD_AS("1-ff00:0:111")].links())
        link = interfaces[IfId(1)]
        self.assertTrue(
            link.bridge.ip_network.overlaps(topo.default_link_subnet))
        link = interfaces[IfId(2)]
        self.assertTrue(
            link.bridge.ip_network.overlaps(topo.default_link_subnet))

        interfaces = dict(topo.ases[ISD_AS("2-ff00:0:211")].links())
        link = interfaces[IfId(1)]
        self.assertIs(link.bridge, topo.get_bridge_name("overlay_bridge1"))
        link = interfaces[IfId(2)]
        self.assertIs(link.bridge, topo.get_bridge_name("overlay_bridge1"))

        null = LinkEp()
        dummy_link_count = 0
        for link in topo.links:
            if link.type == LinkType.UNSET:
                dummy_link_count += 1
                self.assertEqual(link.ep_b, null)
            elif link.ep_b == null:
                self.assertEqual(link.type, LinkType.UNSET)
            self.assertNotEqual(link.ep_a, null)
        self.assertEqual(dummy_link_count, 6)

        # topo_file
        self.assertNotIn("link_subnet", topo_file['defaults'])
        self.assertNotIn("hosts", topo_file)
        self.assertNotIn("networks", topo_file)
        self.assertNotIn("coordinator", topo_file)
        self.assertNotIn("IXPs", topo_file)
        for link in topo_file['links']:
            self.assertNotIn('network', link)