Bug in next-hop calculation fixed. (For dual connected neighbors.)
This commit is contained in:
parent
ea31425a61
commit
e9d3c3aaea
2 changed files with 38 additions and 17 deletions
|
@ -432,16 +432,25 @@ find_neigh(struct ospf_iface *ifa, u32 rid)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Find a closest neighbor which is at leas 2-Way */
|
||||||
struct ospf_neighbor *
|
struct ospf_neighbor *
|
||||||
find_neigh_noifa(struct proto_ospf *po, u32 rid)
|
find_neigh_noifa(struct proto_ospf *po, u32 rid)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n=NULL,*m;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
|
|
||||||
WALK_LIST (ifa, po->iface_list)
|
WALK_LIST (ifa, po->iface_list)
|
||||||
if((n=find_neigh(ifa, rid))!=NULL)
|
if((m=find_neigh(ifa, rid))!=NULL)
|
||||||
return n;
|
{
|
||||||
return NULL;
|
if(m->state>=NEIGHBOR_2WAY)
|
||||||
|
{
|
||||||
|
if(n==NULL) n=m;
|
||||||
|
else
|
||||||
|
if(m->ifa->cost < n->ifa->cost) n=m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ospf_area *
|
struct ospf_area *
|
||||||
|
|
|
@ -107,6 +107,7 @@ ospf_rt_spfa(struct ospf_area *oa)
|
||||||
switch(rtl->type)
|
switch(rtl->type)
|
||||||
{
|
{
|
||||||
case LSART_STUB:
|
case LSART_STUB:
|
||||||
|
/* This violates rfc2328! but I hope it's also correct. */
|
||||||
DBG("\n");
|
DBG("\n");
|
||||||
ip=ipa_from_u32(rtl->id);
|
ip=ipa_from_u32(rtl->id);
|
||||||
nf=fib_get(in,&ip, ipa_mklen(ipa_from_u32(rtl->data)));
|
nf=fib_get(in,&ip, ipa_mklen(ipa_from_u32(rtl->data)));
|
||||||
|
@ -128,12 +129,12 @@ ospf_rt_spfa(struct ospf_area *oa)
|
||||||
break;
|
break;
|
||||||
case LSART_NET:
|
case LSART_NET:
|
||||||
tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_NET);
|
tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_NET);
|
||||||
if(tmp==NULL) DBG("Fuck!\n");
|
if(tmp==NULL) DBG("Not found!\n");
|
||||||
else DBG("Found. :-)\n");
|
else DBG("Found. :-)\n");
|
||||||
break;
|
break;
|
||||||
case LSART_PTP:
|
case LSART_PTP:
|
||||||
tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_RT);
|
tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_RT);
|
||||||
DBG("PTP searched.\n");
|
DBG("PTP found.\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log("Unknown link type in router lsa.");
|
log("Unknown link type in router lsa.");
|
||||||
|
@ -161,7 +162,7 @@ ospf_rt_spfa(struct ospf_area *oa)
|
||||||
DBG(" Working on router %I ", *(rts+i));
|
DBG(" Working on router %I ", *(rts+i));
|
||||||
tmp=ospf_hash_find(oa->gr, *(rts+i), *(rts+i), LSA_T_RT);
|
tmp=ospf_hash_find(oa->gr, *(rts+i), *(rts+i), LSA_T_RT);
|
||||||
if(tmp!=NULL) DBG("Found :-)\n");
|
if(tmp!=NULL) DBG("Found :-)\n");
|
||||||
else DBG("Fuck!\n");
|
else DBG("Not found!\n");
|
||||||
add_cand(&oa->cand,tmp,act,act->dist,oa);
|
add_cand(&oa->cand,tmp,act,act->dist,oa);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -512,6 +513,7 @@ let:
|
||||||
FIB_ITERATE_END(nftmp);
|
FIB_ITERATE_END(nftmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add LSA into list of candidates in Dijkstra alogithm */
|
||||||
void
|
void
|
||||||
add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,
|
add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
u16 dist, struct ospf_area *oa)
|
u16 dist, struct ospf_area *oa)
|
||||||
|
@ -535,7 +537,7 @@ add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
|
|
||||||
en->nhi=NULL;
|
en->nhi=NULL;
|
||||||
|
|
||||||
calc_next_hop(par,en,oa);
|
calc_next_hop(en, par, oa);
|
||||||
|
|
||||||
if(en->color==CANDIDATE) /* We found a shorter path */
|
if(en->color==CANDIDATE) /* We found a shorter path */
|
||||||
{
|
{
|
||||||
|
@ -572,11 +574,11 @@ add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
add_tail(l,&en->cn);
|
add_tail(l,&en->cn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* FIXME Some VLINK staff should be here */
|
/* FIXME Some VLINK stuff should be here */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
|
calc_next_hop(struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
struct ospf_area *oa)
|
struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
|
@ -585,13 +587,14 @@ calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
u32 myrid=p->cf->global->router_id;
|
u32 myrid=p->cf->global->router_id;
|
||||||
|
|
||||||
DBG(" Next hop called\n");
|
DBG(" Next hop called.\n");
|
||||||
if(ipa_to_u32(par->nh)==0)
|
if(ipa_to_u32(par->nh)==0)
|
||||||
{
|
{
|
||||||
neighbor *nn;
|
neighbor *nn;
|
||||||
DBG(" Next hop calculating for id: %I rt: %I type: %u\n",
|
DBG(" Next hop calculating for id: %I rt: %I type: %u\n",
|
||||||
en->lsa.id,en->lsa.rt,en->lsa.type);
|
en->lsa.id,en->lsa.rt,en->lsa.type);
|
||||||
|
|
||||||
|
/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */
|
||||||
if(par==oa->rt)
|
if(par==oa->rt)
|
||||||
{
|
{
|
||||||
if(en->lsa.type==LSA_T_NET)
|
if(en->lsa.type==LSA_T_NET)
|
||||||
|
@ -625,14 +628,23 @@ calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
|
||||||
if(par->lsa.type==LSA_T_NET)
|
if(par->lsa.type==LSA_T_NET)
|
||||||
{
|
{
|
||||||
if(en->lsa.type==LSA_T_NET) bug("Parent for net is net?");
|
if(en->lsa.type==LSA_T_NET) bug("Parent for net is net?");
|
||||||
en->nhi=par->nhi;
|
if((en->nhi=par->nhi)==NULL)
|
||||||
if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) return;
|
bug("Did not find next hop interface for INSPF lsa!");
|
||||||
en->nh=neigh->ip;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else /* Parent is some RT neighbor */
|
||||||
{
|
{
|
||||||
if((neigh=find_neigh_noifa(po,par->lsa.rt))==NULL) return;
|
/* FIXME: I should probably hold ospf_iface in top_hash_entry */
|
||||||
|
neigh=NULL;
|
||||||
|
WALK_LIST(ifa,po->iface_list)
|
||||||
|
{
|
||||||
|
if(ifa->iface==par->nhi)
|
||||||
|
{
|
||||||
|
if((neigh=find_neigh(ifa,par->lsa.rt))==NULL) return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(neigh==NULL) bug("I cannot find my neighbor.");
|
||||||
nn=neigh_find(p,&neigh->ip,0);
|
nn=neigh_find(p,&neigh->ip,0);
|
||||||
if(nn)
|
if(nn)
|
||||||
{
|
{
|
||||||
|
@ -644,6 +656,6 @@ calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
|
||||||
}
|
}
|
||||||
en->nh=par->nh;
|
en->nh=par->nh;
|
||||||
en->nhi=par->nhi;
|
en->nhi=par->nhi;
|
||||||
DBG(" Next hop calculated: %I..\n", en->nh);
|
DBG(" Next hop calculated: %I.\n", en->nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue