summaryrefslogtreecommitdiff
path: root/proto/ospf/rt.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf/rt.c')
-rw-r--r--proto/ospf/rt.c76
1 files changed, 40 insertions, 36 deletions
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index 4b512ff2..2ca1b36e 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -404,14 +404,15 @@ ospf_ext_spfa(struct proto_ospf *po) /* FIXME looking into inter-area */
nf->metric=met;
nf->metric2=met2;
nf->tag=tag;
- if(nnhi!=NULL)
+
+ if(ipa_compare(nnh,ipa_from_u32(0))!=0)
{
nf->nh=nnh;
nf->nhi=nnhi;
}
else
{
- if(absr->nhi==NULL)
+ if(ipa_compare(absr->nh,ipa_from_u32(0))==0)
{
struct ospf_neighbor *neigh;
@@ -559,59 +560,62 @@ calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
struct proto *p=&oa->po->proto;
struct proto_ospf *po=oa->po;
struct ospf_iface *ifa;
+ u32 myrid=p->cf->global->router_id;
+
DBG(" Next hop called\n");
if(ipa_to_u32(par->nh)==0)
{
neighbor *nn;
- DBG(" Next hop calculating for id: %I rt: %I type: %u\n",en->lsa.id,en->lsa.rt,en->lsa.type);
- if(par->lsa.type!=LSA_T_RT)
- {
- if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) return;
- nn=neigh_find(p,&neigh->ip,0);
- DBG(" Next hop calculated: %I.\n", nn->addr);
- en->nh=nn->addr;
- en->nhi=nn->iface;
- return;
- }
- else
+ DBG(" Next hop calculating for id: %I rt: %I type: %u\n",
+ en->lsa.id,en->lsa.rt,en->lsa.type);
+
+ if(par==oa->rt)
{
- if(par==oa->rt)
+ if(en->lsa.type==LSA_T_NET)
{
- if(en->lsa.type==LSA_T_NET)
+ if(en->lsa.rt==myrid)
{
- struct ospf_lsa_net *ne;
- ne=en->lsa_body;
-
- DBG("I'm parent (Net=%I)\n",(en->lsa.id & ipa_to_u32(ne->netmask)));
-
- WALK_LIST(ifa, oa->po->iface_list)
- {
- if(ipa_to_u32(ipa_and(ifa->iface->addr->ip,
- ipa_mkmask(ifa->iface->addr->pxlen))) ==
- (en->lsa.id & ipa_to_u32(ne->netmask)))
+ WALK_LIST(ifa,po->iface_list)
+ if(ipa_compare(ifa->iface->addr->ip,ipa_from_u32(en->lsa.id))==0)
{
en->nhi=ifa->iface;
- en->nh=ipa_from_u32(0);
- DBG("Ifa: %s\n",en->nhi->name);
return;
}
- }
+ bug("I didn't find interface for my self originated LSA!\n");
}
else
{
- if((neigh=find_neigh_noifa(po,par->lsa.rt))==NULL) return;
- nn=neigh_find(p,&neigh->ip,0);
- en->nh=ipa_from_u32(0);
- en->nhi=nn->iface;
+ ip_addr ip=ipa_from_u32(en->lsa.id);
+ nn=neigh_find(p,&ip,0);
+ if(nn) en->nhi=nn->iface;
+ return;
}
+ }
+ else
+ {
+ if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) return;
+ en->nhi=neigh->ifa->iface;
return;
}
-
+ }
+
+ if(par->lsa.type==LSA_T_NET)
+ {
+ if(en->lsa.type==LSA_T_NET) bug("Parent for net is net?");
+ en->nhi=par->nhi;
+ if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) return;
+ en->nh=neigh->ip;
+ return;
+ }
+ else
+ {
if((neigh=find_neigh_noifa(po,par->lsa.rt))==NULL) return;
nn=neigh_find(p,&neigh->ip,0);
- DBG(" Next hop calculated: %I\n", nn->addr);
- en->nh=nn->addr;
- en->nhi=nn->iface;
+ if(nn)
+ {
+ en->nhi=nn->iface;
+ en->nh=neigh->ip;
+ }
return;
}
}