diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index bce763e0..908ec587 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -356,6 +356,8 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface) ospf_add_timers(ifa,p->pool); add_tail(&((struct proto_ospf *)p)->iface_list, NODE ifa); ifa->state=OSPF_IS_DOWN; + ifa->nlsa=NULL; + ifa->fadj=0; ospf_int_sm(ifa, ISM_UP); } diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index 4a44b6b2..050a253d 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -25,11 +25,24 @@ neigh_chstate(struct ospf_neighbor *n, u8 state) if(n->state!=state) { ifa=n->ifa; + if(n->state==NEIGHBOR_FULL) + { + ifa->fadj++; + n->state=state; + originate_rt_lsa(ifa->oa,ifa->oa->po); + originate_net_lsa(ifa,ifa->oa->po); + } p=(struct proto *)(ifa->proto); debug("%s: Neigbor %I changes state from \"%s\" to \"%s\".\n", p->name, n->rid, ospf_ns[n->state], ospf_ns[state]); n->state=state; + if(state==NEIGHBOR_FULL) + { + ifa->fadj--; + originate_rt_lsa(n->ifa->oa,n->ifa->oa->po); + originate_net_lsa(ifa,ifa->oa->po); + } } } @@ -236,7 +249,6 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) break; case INM_LOADDONE: neigh_chstate(n,NEIGHBOR_FULL); - originate_rt_lsa(n->ifa->oa,po); break; case INM_ADJOK: switch(n->state) diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 7528921c..22064b96 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -102,7 +102,8 @@ struct ospf_iface { #define WAIT_DMH 3 /* Value of Wait timer - not found it in RFC * - using 3*HELLO */ - struct top_hash_entry *nlsa; + struct top_hash_entry *nlsa; /* Originated net lsa */ + int fadj; /* Number of full adjacent neigh */ }; struct ospf_packet { diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 0020b572..56228054 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -211,12 +211,12 @@ addifa_rtlsa(struct ospf_iface *ifa) ifa->oa=oa; - oa->rt=originate_rt_lsa(oa,po); + originate_rt_lsa(oa,po); DBG("RT LSA: rt: %I, id: %I, type: %u\n",oa->rt->lsa.rt,oa->rt->lsa.id,oa->rt->lsa.type); flood_lsa(NULL,NULL,&oa->rt->lsa,po,NULL,oa); } -struct top_hash_entry * +void originate_rt_lsa(struct ospf_area *oa, struct proto_ospf *po) { struct ospf_lsa_header lsa; @@ -241,7 +241,8 @@ originate_rt_lsa(struct ospf_area *oa, struct proto_ospf *po) body=originate_rt_lsa_body(oa, &lsa.length, po); lsasum_calculate(&lsa,body,po); en=lsa_install_new(&lsa, body, oa, &po->proto); - return en; + oa->rt=en; + flood_lsa(NULL,NULL,&oa->rt->lsa,po,NULL,oa); } void * @@ -252,11 +253,7 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length, struct ospf_neighbor *n; u32 *body; - WALK_LIST(n,ifa->neigh_list) - { - if(n->state==NEIGHBOR_FULL) i++; - } - body=mb_alloc(po->proto.pool,sizeof(u32)*i); + body=mb_alloc(po->proto.pool,sizeof(u32)*ifa->fadj); i=1; *body=po->proto.cf->global->router_id; WALK_LIST(n,ifa->neigh_list) @@ -271,7 +268,7 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length, return body; } -struct top_hash_entry * +void originate_net_lsa(struct ospf_iface *ifa, struct proto_ospf *po) { struct ospf_lsa_header lsa; @@ -281,6 +278,20 @@ originate_net_lsa(struct ospf_iface *ifa, struct proto_ospf *po) DBG("%s: Originating Net lsa for iface \"%s\".\n", po->proto.name, ifa->iface->name); + if(ifa->state!=OSPF_IS_DR) return; + + if(ifa->fadj==0) + { + if(ifa->nlsa==NULL) return; + + lsa.sn+=1; + lsa.age=LSA_MAXAGE; + flood_lsa(NULL,NULL,&ifa->nlsa->lsa,po,NULL,ifa->oa); + /* FIXME delete LSA */ + ifa->nlsa=NULL; + return ; + } + lsa.age=0; lsa.id=rtid; lsa.type=LSA_T_NET; @@ -291,17 +302,14 @@ originate_net_lsa(struct ospf_iface *ifa, struct proto_ospf *po) } else { - lsa.sn=ifa->nlsa->lsa.sn+1; + lsa.sn+=1; } body=originate_net_lsa_body(ifa, &lsa.length, po); lsasum_calculate(&lsa,body,po); en=lsa_install_new(&lsa, body, ifa->oa, &po->proto); - return en; + flood_lsa(NULL,NULL,&ifa->nlsa->lsa,po,NULL,ifa->oa); } - - - static void ospf_top_ht_alloc(struct top_graph *f) { diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index 5514f5e9..4181e05f 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -46,7 +46,7 @@ struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 lsa, u32 rtr, u32 struct top_hash_entry *ospf_hash_get(struct top_graph *, u32 lsa, u32 rtr, u32 type); void ospf_hash_delete(struct top_graph *, struct top_hash_entry *); void addifa_rtlsa(struct ospf_iface *ifa); -struct top_hash_entry *originate_rt_lsa(struct ospf_area *oa, - struct proto_ospf *po); +void originate_rt_lsa(struct ospf_area *oa,struct proto_ospf *po); +void originate_net_lsa(struct ospf_iface *ifa,struct proto_ospf *po); #endif /* _BIRD_OSPF_TOPOLOGY_H_ */