From dd4da6f640fb581cbd7d1ca537bf382558492b8e Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Wed, 31 Oct 2012 17:14:35 +0100 Subject: [PATCH] Fixes another bug in OSPFv3 vlinks. --- proto/ospf/hello.c | 2 +- proto/ospf/iface.c | 2 ++ proto/ospf/lsupd.c | 2 +- proto/ospf/neighbor.c | 2 +- proto/ospf/ospf.c | 1 + proto/ospf/ospf.h | 4 +++- proto/ospf/topology.c | 18 +++++++++--------- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index f9ba28f6..6ec5c511 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -261,7 +261,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) pkt->priority = ifa->priority; #ifdef OSPFv3 - pkt->iface_id = htonl(ifa->iface->index); + pkt->iface_id = htonl(ifa->iface_id); pkt->options3 = ifa->oa->options >> 16; pkt->options2 = ifa->oa->options >> 8; diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index a6a0c6c1..aa7f7892 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -567,6 +567,8 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i log(L_WARN "%s: Cannot use interface %s as %s, forcing %s", p->name, iface->name, ospf_it[old_type], ospf_it[ifa->type]); + /* Assign iface ID, for vlinks, this is ugly hack */ + ifa->iface_id = (ifa->type != OSPF_IT_VLINK) ? iface->index : oa->po->last_vlink_id++; init_list(&ifa->neigh_list); init_list(&ifa->nbma_list); diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 633ed533..a5da4251 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -123,7 +123,7 @@ ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_i switch (scope) { case LSA_SCOPE_LINK: - return ifa->iface->index == domain; + return ifa->iface_id == domain; case LSA_SCOPE_AREA: return ifa->oa->areaid == domain; diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index 642365b3..26d81dce 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -459,7 +459,7 @@ bdr_election(struct ospf_iface *ifa) #else /* OSPFv3 */ me.dr = ifa->drid; me.bdr = ifa->bdrid; - me.iface_id = ifa->iface->index; + me.iface_id = ifa->iface_id; #endif add_tail(&ifa->neigh_list, NODE & me); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 5792453d..6654e107 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -232,6 +232,7 @@ ospf_start(struct proto *p) struct ospf_area_config *ac; po->router_id = proto_get_router_id(p->cf); + po->last_vlink_id = 0x80000000; po->rfc1583 = c->rfc1583; po->ebit = 0; po->ecmp = c->ecmp; diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 3bffaf91..7111a13d 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -189,7 +189,8 @@ struct ospf_iface u32 rxmtint; /* number of seconds between LSA retransmissions */ u32 pollint; /* Poll interval */ u32 deadint; /* after "deadint" missing hellos is router dead */ - u32 vid; /* Id of peer of virtual link */ + u32 iface_id; /* Interface ID (iface->index or new value for vlinks) */ + u32 vid; /* ID of peer of virtual link */ ip_addr vip; /* IP of peer of virtual link */ struct ospf_iface *vifa; /* OSPF iface which the vlink goes through */ struct ospf_area *voa; /* OSPF area which the vlink goes through */ @@ -776,6 +777,7 @@ struct proto_ospf int lsab_size, lsab_used; linpool *nhpool; /* Linpool used for next hops computed in SPF */ u32 router_id; + u32 last_vlink_id; /* Interface IDs for vlinks (starts at 0x80000000) */ }; struct ospf_iface_patt diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index a9be12ee..177cd53a 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -259,7 +259,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length) ln->type = LSART_PTP; ln->id = neigh->rid; ln->data = (ifa->addr->flags & IA_PEER) ? - ifa->iface->index : ipa_to_u32(ifa->addr->ip); + ifa->iface_id : ipa_to_u32(ifa->addr->ip); ln->metric = ifa->cost; ln->padding = 0; i++; @@ -368,7 +368,7 @@ add_lsa_rt_link(struct proto_ospf *po, struct ospf_iface *ifa, u8 type, u32 nif, ln->type = type; ln->padding = 0; ln->metric = ifa->cost; - ln->lif = ifa->iface->index; + ln->lif = ifa->iface_id; ln->nif = nif; ln->id = id; } @@ -546,7 +546,7 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length, if (n->state == NEIGHBOR_FULL) { #ifdef OSPFv3 - en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK); + en = ospf_hash_find(po->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK); if (en) options |= ((struct ospf_lsa_link *) en->lsa_body)->options; #endif @@ -596,7 +596,7 @@ originate_net_lsa(struct ospf_iface *ifa) lsa.options = ifa->oa->options; lsa.id = ipa_to_u32(ifa->addr->ip); #else /* OSPFv3 */ - lsa.id = ifa->iface->index; + lsa.id = ifa->iface_id; #endif lsa.rt = po->router_id; @@ -1207,10 +1207,10 @@ originate_link_lsa(struct ospf_iface *ifa) lsa.age = 0; lsa.type = LSA_T_LINK; - lsa.id = ifa->iface->index; + lsa.id = ifa->iface_id; lsa.rt = po->router_id; lsa.sn = get_seqnum(ifa->link_lsa); - u32 dom = ifa->iface->index; + u32 dom = ifa->iface_id; body = originate_link_lsa_body(ifa, &lsa.length); lsasum_calculate(&lsa, body); @@ -1471,7 +1471,7 @@ originate_prefix_net_lsa_body(struct ospf_iface *ifa, u16 *length) WALK_LIST(n, ifa->neigh_list) if ((n->state == NEIGHBOR_FULL) && - (en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK))) + (en = ospf_hash_find(po->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK))) add_link_lsa(po, en, offset, &pxc); lp = po->lsab; @@ -1493,7 +1493,7 @@ originate_prefix_net_lsa(struct ospf_iface *ifa) lsa.age = 0; lsa.type = LSA_T_PREFIX; - lsa.id = ifa->iface->index; + lsa.id = ifa->iface_id; lsa.rt = po->router_id; lsa.sn = get_seqnum(ifa->pxn_lsa); u32 dom = ifa->oa->areaid; @@ -1664,7 +1664,7 @@ ospf_lsa_domain(u32 type, struct ospf_iface *ifa) switch (type & LSA_SCOPE_MASK) { case LSA_SCOPE_LINK: - return ifa->iface->index; + return ifa->iface_id; case LSA_SCOPE_AREA: return ifa->oa->areaid;