def update_topology_loop(self):
        hub.sleep(2)
        while True:
            if self.lsdb_updated_flag:
                self.lsdb_updated_flag = False
                ospftopo = {}

                for lsa in (l for l in self.lsdb.itervalues() if l.header.type_ == OSPF_ROUTER_LSA):
                    name = (lsa.header.type_, lsa.header.id_)

                    router = Router(name)
                    if lsa == self.myrouterlsa:
                        self.logger.debug("me: %s" % router)
                        self.me = router

                    ospftopo[name] = router

                    for l in lsa.links:
                        if l.type_ == 2:
                            # l.data is interface address
                            name = (2, l.data)
                            link = Link(name)
                            link.set_start(router, l.data)
                            link.metric = l.metric
                            link.tos = l.tos
                            link.nw = l.id_
                            router.add_link(link)
                            ospftopo[name] = link

                links = [l for l in ospftopo.itervalues() if isinstance(l, Link)]
                while len(links) > 0:
                    link = links.pop(0)
                    if not link.end:
                        el = [el for el in links if link.nw == el.nw]
                        if not len(el) == 1:
                            continue
                        el = el.pop(0)
                        link.set_end(el.start, el.startaddr)
                        el.set_end(link.start, link.startaddr)

                for lsa in (l for l in self.lsdb.itervalues() if l.header.type_ == OSPF_AS_EXTERNAL_LSA):
                    name = (lsa.header.type_, lsa.header.id_)
                    extnw = ExtNetwork(name)
                    ospftopo[name] = extnw
                    adv_r = (1, lsa.header.adv_router)
                    assert ospftopo.has_key(adv_r)

                    extnw.set_router(ospftopo[adv_r])
                    extnw.mask = lsa.extnws[0].mask
                    ospftopo[adv_r].add_extnw(extnw)
                self.ospftopo = ospftopo
                self.install_l3_rules()

            if self.labeldb_updated_flag:
                self.labeldb_updated_flag = False
                self.install_label_rules()

            hub.sleep(5)
def getTopology(addr):
    p = subprocess.Popen("/usr/local/sbin/ospfclient %s 0 0 0 0 0 2> /dev/null" % addr, shell=True, stdout = subprocess.PIPE)
    buf = p.stdout.readline()
    try:
        lsalist = json.loads(buf)
    except:
        print "failed to parse: %s" % buf
        return None

    topo = {}
    for lsa in [lsa for lsa in lsalist if lsa[u'type'] == 1]:
        lsa_type = lsa[u'type']
        name = (lsa_type, lsa[u'id'])

        router = Router(name)
        topo[name] = router

        for l in lsa[u'links']:
            if l[u'type'] == 2:
                name = (2, l[u'data'])
                link = Link(name)
                link.set_start(router, l[u'data'])
                link.metric = float(l[u'metric'])
                link.tos = float(l[u'tos'])
                link.nw = l[u'id']
                router.add_link(link)
                topo[name] = link

    links = [link for link in topo.values() if link.__class__ == Link]

    while len(links) > 0:
        link = links.pop(0)
        if not link.end:
            el = [el for el in links if link.nw == el.nw]
            assert len(el) == 1
            el = el.pop(0)
            link.set_end(el.start, el.startaddr)
            el.set_end(link.start, link.startaddr)

    for lsa in [lsa for lsa in lsalist if lsa[u'type'] == 5]:
        lsa_type = lsa[u'type']
        name = (lsa_type, lsa[u'id'])
        extnw = ExtNetwork(name)
        topo[name] = extnw
        adv_r = (1, lsa[u'adv_router'])
        assert topo.has_key(adv_r)
        extnw.set_router(topo[adv_r])
        extnw.mask=lsa[u'mask']
        topo[adv_r].add_extnw(extnw)

    return topo