diff options
Diffstat (limited to 'proto/ospf/neighbor.c')
-rw-r--r-- | proto/ospf/neighbor.c | 115 |
1 files changed, 57 insertions, 58 deletions
diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index bb681c22..ba8d7b98 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -171,16 +171,23 @@ static struct ospf_neighbor * electbdr(list nl) { struct ospf_neighbor *neigh, *n1, *n2; + u32 nid; n1 = NULL; n2 = NULL; - WALK_LIST(neigh, nl) /* First try those decl. themselves */ + WALK_LIST(neigh, nl) /* First try those decl. themselves */ { +#ifdef OSPFv2 + nid = ipa_to_u32(neigh->ip); +#else /* OSPFv3 */ + nid = neigh->rid; +#endif + if (neigh->state >= NEIGHBOR_2WAY) /* Higher than 2WAY */ - if (neigh->priority > 0) /* Eligible */ - if (ipa_compare(neigh->ip, neigh->dr) != 0) /* And not decl. itself DR */ + if (neigh->priority > 0) /* Eligible */ + if (neigh->dr != nid) /* And not decl. itself DR */ { - if (ipa_compare(neigh->ip, neigh->bdr) == 0) /* Declaring BDR */ + if (neigh->bdr == nid) /* Declaring BDR */ { if (n1 != NULL) { @@ -222,13 +229,20 @@ static struct ospf_neighbor * electdr(list nl) { struct ospf_neighbor *neigh, *n; + u32 nid; n = NULL; - WALK_LIST(neigh, nl) /* And now DR */ + WALK_LIST(neigh, nl) /* And now DR */ { +#ifdef OSPFv2 + nid = ipa_to_u32(neigh->ip); +#else /* OSPFv3 */ + nid = neigh->rid; +#endif + if (neigh->state >= NEIGHBOR_2WAY) /* Higher than 2WAY */ - if (neigh->priority > 0) /* Eligible */ - if (ipa_compare(neigh->ip, neigh->dr) == 0) /* And declaring itself DR */ + if (neigh->priority > 0) /* Eligible */ + if (neigh->dr == nid) /* And declaring itself DR */ { if (n != NULL) { @@ -425,22 +439,28 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) void bdr_election(struct ospf_iface *ifa) { + struct proto_ospf *po = ifa->oa->po; + struct proto *p = &po->proto; + u32 myid = po->router_id; struct ospf_neighbor *neigh, *ndr, *nbdr, me; - u32 myid; - ip_addr ndrip, nbdrip; int doadj; - struct proto *p = &ifa->oa->po->proto; DBG("(B)DR election.\n"); - myid = p->cf->global->router_id; - me.state = NEIGHBOR_2WAY; me.rid = myid; me.priority = ifa->priority; - me.dr = ifa->drip; - me.bdr = ifa->bdrip; + +#ifdef OSPFv2 me.ip = ifa->iface->addr->ip; + me.dr = ipa_to_u32(ifa->drip); + me.bdr = ipa_to_u32(ifa->bdrip); +#else /* OSPFv3 */ + me.ip = ifa->lladdr; + me.dr = ifa->drid; + me.bdr = ifa->bdrid; + me.iface_id = ifa->iface->index; +#endif add_tail(&ifa->neigh_list, NODE & me); @@ -450,64 +470,43 @@ bdr_election(struct ospf_iface *ifa) if (ndr == NULL) ndr = nbdr; + /* 9.4. (4) */ if (((ifa->drid == myid) && (ndr != &me)) || ((ifa->drid != myid) && (ndr == &me)) || ((ifa->bdrid == myid) && (nbdr != &me)) || ((ifa->bdrid != myid) && (nbdr == &me))) { - if (ndr == NULL) - ifa->drip = me.dr = IPA_NONE; - else - ifa->drip = me.dr = ndr->ip; - - if (nbdr == NULL) - ifa->bdrip = me.bdr = IPA_NONE; - else - ifa->bdrip = me.bdr = nbdr->ip; +#ifdef OSPFv2 + me.dr = ndr ? ipa_to_u32(ndr->ip) : 0; + me.bdr = nbdr ? ipa_to_u32(nbdr->ip) : 0; +#else /* OSPFv3 */ + me.dr = ndr ? ndr->rid : 0; + me.bdr = nbdr ? nbdr->rid : 0; +#endif nbdr = electbdr(ifa->neigh_list); ndr = electdr(ifa->neigh_list); - } - if (ndr == NULL) - ndrip = IPA_NONE; - else - ndrip = ndr->ip; - - if (nbdr == NULL) - nbdrip = IPA_NONE; - else - nbdrip = nbdr->ip; - - doadj = 0; - if ((ipa_compare(ifa->drip, ndrip) != 0) - || (ipa_compare(ifa->bdrip, nbdrip) != 0)) - doadj = 1; - - if (ndr == NULL) - { - ifa->drid = 0; - ifa->drip = IPA_NONE; - } - else - { - ifa->drid = ndr->rid; - ifa->drip = ndr->ip; + if (ndr == NULL) + ndr = nbdr; } - if (nbdr == NULL) - { - ifa->bdrid = 0; - ifa->bdrip = IPA_NONE; - } - else - { - ifa->bdrid = nbdr->rid; - ifa->bdrip = nbdr->ip; - } + u32 odrid = ifa->drid; + u32 obdrid = ifa->bdrid; + + ifa->drid = ndr ? ndr->rid : 0; + ifa->drip = ndr ? ndr->ip : IPA_NONE; + ifa->bdrid = nbdr ? nbdr->rid : 0; + ifa->bdrip = nbdr ? nbdr->ip : IPA_NONE; + +#ifdef OSPFv3 + ifa->dr_iface_id = ndr ? ndr->iface_id : 0; +#endif DBG("DR=%R, BDR=%R\n", ifa->drid, ifa->bdrid); + doadj = ((ifa->drid != odrid) || (ifa->bdrid != obdrid)); + if (myid == ifa->drid) ospf_iface_chstate(ifa, OSPF_IS_DR); else |