diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index ed509e97..c0d8770f 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -64,13 +64,13 @@ iface_chstate(struct ospf_iface *ifa, u8 state) ifa->dr_sk=NULL; } } - if(oldstate==OSPF_IS_DR) + if((oldstate==OSPF_IS_DR)&&(ifa->nlsa!=NULL)) { + ifa->nlsa->lsa.age=LSA_MAXAGE; if(state>=OSPF_IS_WAITING) { net_flush_lsa(ifa->nlsa,po,ifa->oa); } - ifa->nlsa->lsa.age=LSA_MAXAGE; if(can_flush_lsa(ifa->oa)) flush_lsa(ifa->nlsa,ifa->oa); ifa->nlsa=NULL; } @@ -250,25 +250,10 @@ ospf_open_ip_socket(struct ospf_iface *ifa) return(ipsk); } -/* - * This will later decide, wheter use iface for OSPF or not - * depending on config - */ -u8 -is_good_iface(struct proto *p, struct iface *iface) -{ - if(iface->flags & IF_UP) - { - if(!(iface->flags & IF_IGNORE)) return 1; - } - return 0; -} - /* Of course, it's NOT true now */ u8 ospf_iface_clasify(struct iface *ifa, struct proto *p) { - /* FIXME: Latter I'll use config - this is incorrect */ DBG("%s: Iface flags=%x.\n", p->name, ifa->flags); if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))== (IF_MULTIACCESS|IF_MULTICAST)) @@ -286,55 +271,6 @@ ospf_iface_clasify(struct iface *ifa, struct proto *p) return OSPF_IT_PTP; } -void -ospf_add_timers(struct ospf_iface *ifa, pool *pool) -{ - struct proto *p; - - p=(struct proto *)(ifa->proto); - /* Add hello timer */ - ifa->hello_timer=tm_new(pool); - ifa->hello_timer->data=ifa; - ifa->hello_timer->randomize=0; - if(ifa->helloint==0) ifa->helloint=HELLOINT_D; - ifa->hello_timer->hook=hello_timer_hook; - ifa->hello_timer->recurrent=ifa->helloint; - DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint); - - ifa->wait_timer=tm_new(pool); - ifa->wait_timer->data=ifa; - ifa->wait_timer->randomize=0; - ifa->wait_timer->hook=wait_timer_hook; - ifa->wait_timer->recurrent=0; - if(ifa->waitint==0) ifa->waitint= WAIT_DMH*ifa->helloint; - DBG("%s: Installing wait timer. (%u)\n", p->name, ifa->waitint); - - if(ifa->rxmtint==0) ifa->rxmtint=RXMTINT_D; -} - -void -ospf_iface_default(struct ospf_iface *ifa) -{ - u8 i; - - ifa->oa=NULL; - ifa->an=0; /* FIXME This should respect config */ - ifa->cost=COST_D; - ifa->rxmtint=RXMTINT_D; - ifa->inftransdelay=INFTRANSDELAY_D; - ifa->priority=PRIORITY_D; - ifa->helloint=HELLOINT_D; - ifa->deadc=DEADC_D; - ifa->autype=0; - for(i=0;i<8;i++) ifa->aukey[i]=0; - ifa->options=2; - ifa->drip=ipa_from_u32(0x00000000); - ifa->drid=0; - ifa->bdrip=ipa_from_u32(0x00000000); - ifa->bdrid=0; - ifa->type=ospf_iface_clasify(ifa->iface, (struct proto *)ifa->proto); -} - struct ospf_iface* find_iface(struct proto_ospf *p, struct iface *what) { @@ -351,54 +287,87 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface) { struct ospf_iface *ifa; sock *mcsk; - - struct ospf_config *c; - c=(struct ospf_config *)(p->cf); + struct ospf_config *c=(struct ospf_config *)(p->cf); + struct ospf_area_config *ac; + struct ospf_iface_patt *ip=NULL; + u8 i; DBG("%s: If notify called\n", p->name); if (iface->flags & IF_IGNORE) return; - if((flags & IF_CHANGE_UP) && is_good_iface(p, iface)) + if(flags & IF_CHANGE_UP) { debug("%s: using interface %s.\n", p->name, iface->name); - /* FIXME: Latter I'll use config - this is incorrect */ - ifa=mb_allocz(p->pool, sizeof(struct ospf_iface)); - ifa->proto=(struct proto_ospf *)p; - ifa->iface=iface; - ospf_iface_default(ifa); - if(ifa->type!=OSPF_IT_NBMA) + WALK_LIST(ac, c->area_list) { - if((ifa->hello_sk=ospf_open_mc_socket(ifa))==NULL) - { - log("%s: Huh? could not open mc socket on interface %s?", p->name, - iface->name); - mb_free(ifa); - log("%s: Ignoring this interface.", p->name); - return; - } - ifa->dr_sk=NULL; - - if((ifa->ip_sk=ospf_open_ip_socket(ifa))==NULL) - { - log("%s: Huh? could not open ip socket on interface %s?", p->name, - iface->name); - mb_free(ifa); - log("%s: Ignoring this interface", p->name); - return; - } - - init_list(&(ifa->neigh_list)); + if(ip=(struct ospf_iface_patt *) + iface_patt_match(&ac->patt_list, iface)) break; + } + + if(ip) + { + ifa=mb_allocz(p->pool, sizeof(struct ospf_iface)); + ifa->proto=(struct proto_ospf *)p; + ifa->iface=iface; + + ifa->an=ac->areaid; /* FIXME This should respect config */ + ifa->cost=ip->cost; + ifa->rxmtint=ip->rxmtint; + ifa->inftransdelay=ip->inftransdelay; + ifa->priority=ip->priority; + ifa->helloint=ip->helloint; + ifa->waitint=ip->waitint; + ifa->deadc=ip->deadc; + ifa->autype=0; /* FIXME add authentification */ + for(i=0;i<8;i++) ifa->aukey[i]=0; + ifa->options=2; /* FIXME what options? */ + + if(ip->type=OSPF_IT_UNDEF) + ifa->type=ospf_iface_clasify(ifa->iface, (struct proto *)ifa->proto); + else ifa->type=ip->type; + + if(ifa->type!=OSPF_IT_NBMA) + { + if((ifa->hello_sk=ospf_open_mc_socket(ifa))==NULL) + { + log("%s: Huh? could not open mc socket on interface %s?", p->name, + iface->name); + mb_free(ifa); + log("%s: Ignoring this interface.", p->name); + return; + } + ifa->dr_sk=NULL; + + if((ifa->ip_sk=ospf_open_ip_socket(ifa))==NULL) + { + log("%s: Huh? could not open ip socket on interface %s?", p->name, + iface->name); + mb_free(ifa); + log("%s: Ignoring this interface", p->name); + return; + } + + init_list(&(ifa->neigh_list)); + } + /* Add hello timer */ + ifa->hello_timer=tm_new(p->pool); + ifa->hello_timer->data=ifa; + ifa->hello_timer->randomize=0; + ifa->hello_timer->hook=hello_timer_hook; + ifa->hello_timer->recurrent=ifa->helloint; + DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint); + + ifa->wait_timer=tm_new(p->pool); + ifa->wait_timer->data=ifa; + ifa->wait_timer->randomize=0; + ifa->wait_timer->hook=wait_timer_hook; + ifa->wait_timer->recurrent=0; + DBG("%s: Installing wait timer. (%u)\n", p->name, ifa->waitint); + add_tail(&((struct proto_ospf *)p)->iface_list, NODE ifa); + ifa->state=OSPF_IS_DOWN; + ospf_int_sm(ifa, ISM_UP); } - /* FIXME: This should read config */ - ifa->helloint=0; - ifa->waitint=0; - 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); } if(flags & IF_CHANGE_DOWN) diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 9bb0388b..1fcd691a 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -75,14 +75,6 @@ ospf_init(struct proto_config *c) p->rte_same = ospf_rte_same; po->rfc1583=oc->rfc1583; - WALK_LIST(ac, oc->area_list) - { - debug("OSPF: area: %I, stub=%u tick=%u\n", ac->areaid, ac->stub, ac->tick); - WALK_LIST(patt, ac->patt_list) - debug("Patt cost=%d hello=%d ret=%d\n",patt->cost, patt->helloint, - patt->rxmtint); - } - return p; } @@ -425,10 +417,12 @@ ospf_sh(struct proto *p) if(n->state==NEIGHBOR_FULL) adjno++; } } - cli_msg(-1014,"\t\tNumber of interfaces: %u", ifano); - cli_msg(-1014,"\t\tNumber of LSAs: %u", oa->gr->hash_entries); - cli_msg(-1014,"\t\tNumber of neighbors: %u", nno); - cli_msg(-1014,"\t\tNumber of fully adjacent neighbors: %u", adjno); + cli_msg(-1014,"\t\tStub:\t%s", oa->stub ? "Yes" : "No"); + cli_msg(-1014,"\t\tRT scheduler tick:\t%u", oa->tick); + cli_msg(-1014,"\t\tNumber of interfaces:\t%u", ifano); + cli_msg(-1014,"\t\tNumber of LSAs in DB:\t%u", oa->gr->hash_entries); + cli_msg(-1014,"\t\tNumber of neighbors:\t%u", nno); + cli_msg(-1014,"\t\tNumber of adjacent neighbors:\t%u", adjno); } cli_msg(0,""); } diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index f25d7fa2..d44db95f 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -114,7 +114,6 @@ struct ospf_iface { */ struct top_hash_entry *nlsa; /* Originated net lsa */ int fadj; /* Number of full adjacent neigh */ - unsigned tick; }; struct ospf_packet { @@ -348,6 +347,7 @@ struct ospf_area { int trcap; /* Transit capability? */ struct proto_ospf *po; struct fib infib; /* FIB for intra-area routes */ + unsigned tick; }; struct proto_ospf { diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index aa6ef69b..04af6de9 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -51,97 +51,96 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p) WALK_LIST (ifa, p->iface_list) { - if((ifa->an==oa->areaid) && (ifa->state!=OSPF_IS_DOWN)) + if((ifa->an!=oa->areaid) || (ifa->state==OSPF_IS_DOWN)) continue; + + if(ifa->state==OSPF_IS_LOOP) { - if(ifa->state==OSPF_IS_LOOP) + ln->type=3; + ln->id=ipa_to_u32(ifa->iface->addr->ip); + ln->data=0xffffffff; + ln->metric=0; + ln->notos=0; + } + else + { + switch(ifa->type) { - ln->type=3; - ln->id=ipa_to_u32(ifa->iface->addr->ip); - ln->data=0xffffffff; - ln->metric=0; - ln->notos=0; - } - else - { - switch(ifa->type) - { - case OSPF_IT_PTP: /* rfc2328 - pg126 */ - neigh=(struct ospf_neighbor *)HEAD(ifa->neigh_list); - if((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state==NEIGHBOR_FULL)) - { - ln->type=LSART_PTP; - ln->id=neigh->rid; - ln->metric=ifa->cost; - ln->notos=0; - if(ifa->iface->flags && IA_UNNUMBERED) - { - ln->data=ifa->iface->index; - } - else - { - ln->id=ipa_to_u32(ifa->iface->addr->ip); - } - } - else - { - if(ifa->state==OSPF_IS_PTP) - { - ln->type=LSART_STUB; - ln->id=ln->id=ipa_to_u32(ifa->iface->addr->opposite); - ln->metric=ifa->cost; - ln->notos=0; - ln->data=0xffffffff; - } - else - { - i--; /* No link added */ - } - } - break; - case OSPF_IT_BCAST: - case OSPF_IT_NBMA: - if(ifa->state==OSPF_IS_WAITING) + case OSPF_IT_PTP: /* rfc2328 - pg126 */ + neigh=(struct ospf_neighbor *)HEAD(ifa->neigh_list); + if((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state==NEIGHBOR_FULL)) + { + ln->type=LSART_PTP; + ln->id=neigh->rid; + ln->metric=ifa->cost; + ln->notos=0; + if(ifa->iface->flags && IA_UNNUMBERED) + { + ln->data=ifa->iface->index; + } + else + { + ln->id=ipa_to_u32(ifa->iface->addr->ip); + } + } + else + { + if(ifa->state==OSPF_IS_PTP) { ln->type=LSART_STUB; - ln->id=ipa_to_u32(ifa->iface->addr->prefix); - ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen)); + ln->id=ln->id=ipa_to_u32(ifa->iface->addr->opposite); + ln->metric=ifa->cost; + ln->notos=0; + ln->data=0xffffffff; + } + else + { + i--; /* No link added */ + } + } + break; + case OSPF_IT_BCAST: + case OSPF_IT_NBMA: + if(ifa->state==OSPF_IS_WAITING) + { + ln->type=LSART_STUB; + ln->id=ipa_to_u32(ifa->iface->addr->prefix); + ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen)); + ln->metric=ifa->cost; + ln->notos=0; + } + else + { + j=0,k=0; + WALK_LIST(neigh, ifa->neigh_list) + { + if((neigh->rid==ifa->drid) && + (neigh->state==NEIGHBOR_FULL)) k=1; + if(neigh->state==NEIGHBOR_FULL) j=1; + } + if(((ifa->state==OSPF_IS_DR) && (j==1)) || (k==1)) + { + ln->type=LSART_NET; + ln->id=ipa_to_u32(ifa->drip); + ln->data=ipa_to_u32(ifa->iface->addr->ip); ln->metric=ifa->cost; ln->notos=0; } - else + else { - j=0,k=0; - WALK_LIST(neigh, ifa->neigh_list) - { - if((neigh->rid==ifa->drid) && - (neigh->state==NEIGHBOR_FULL)) k=1; - if(neigh->state==NEIGHBOR_FULL) j=1; - } - if(((ifa->state==OSPF_IS_DR) && (j==1)) || (k==1)) - { - ln->type=LSART_NET; - ln->id=ipa_to_u32(ifa->drip); - ln->data=ipa_to_u32(ifa->iface->addr->ip); - ln->metric=ifa->cost; - ln->notos=0; - } - else - { - ln->type=LSART_STUB; - ln->id=ipa_to_u32(ifa->iface->addr->prefix); - ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen)); - ln->metric=ifa->cost; - ln->notos=0; - } + ln->type=LSART_STUB; + ln->id=ipa_to_u32(ifa->iface->addr->prefix); + ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen)); + ln->metric=ifa->cost; + ln->notos=0; } - break; - case OSPF_IT_VLINK: /* FIXME Add virtual links! */ - i--; - break; - } + } + break; + case OSPF_IT_VLINK: /* FIXME Add virtual links! */ + i--; + break; } - if(ifa->type==OSPF_IT_VLINK) v=1; } + if(ifa->type==OSPF_IT_VLINK) v=1; ln=(ln+1); } rt->links=i; @@ -155,11 +154,13 @@ addifa_rtlsa(struct ospf_iface *ifa) { struct ospf_area *oa; struct proto_ospf *po=ifa->proto; + struct proto *p=&po->proto; u32 rtid; struct top_graph_rtlsa_link *li, *lih; + struct ospf_config *c=(struct ospf_config *)(p->cf); + struct ospf_area_config *ac=NULL,*a; rtid=po->proto.cf->global->router_id; - DBG("%s: New OSPF area \"%d\" adding.\n", po->proto.name, ifa->an); oa=NULL; @@ -171,29 +172,46 @@ addifa_rtlsa(struct ospf_iface *ifa) if(EMPTY_LIST(po->area_list) || (oa->areaid!=ifa->an)) /* New area */ { struct ospf_lsa_header *lsa; + DBG("%s: New OSPF area \"%d\" adding.\n", po->proto.name, ifa->an); + WALK_LIST(a,c->area_list) + { + if(a->areaid==ifa->an) + { + ac=a; + break; + } + } - oa=mb_allocz(po->proto.pool, sizeof(struct ospf_area)); - add_tail(&po->area_list,NODE oa); - oa->areaid=ifa->an; - oa->gr=ospf_top_new(po); - s_init_list(&(oa->lsal)); - oa->rt=NULL; - oa->po=po; - oa->disp_timer=tm_new(po->proto.pool); - oa->disp_timer->data=oa; - oa->disp_timer->randomize=0; - oa->disp_timer->hook=area_disp; - oa->disp_timer->recurrent=DISPTICK; - oa->lage=now; - tm_start(oa->disp_timer,DISPTICK); - oa->calcrt=1; - oa->origrt=0; - fib_init(&oa->infib,po->proto.pool,sizeof(struct infib),16,init_infib); - /* FIXME 16?? (Oh, sweet 16.... :-) */ - po->areano++; - DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an); - ifa->oa=oa; - schedule_rt_lsa(oa); + if(ac) + { + oa=mb_allocz(po->proto.pool, sizeof(struct ospf_area)); + add_tail(&po->area_list,NODE oa); + oa->areaid=ifa->an; + oa->stub=ac->stub; + oa->tick=ac->tick; + oa->gr=ospf_top_new(po); + s_init_list(&(oa->lsal)); + oa->rt=NULL; + oa->po=po; + oa->disp_timer=tm_new(po->proto.pool); + oa->disp_timer->data=oa; + oa->disp_timer->randomize=0; + oa->disp_timer->hook=area_disp; + oa->disp_timer->recurrent=oa->tick; + oa->lage=now; + tm_start(oa->disp_timer,oa->tick); + oa->calcrt=1; + oa->origrt=0; + fib_init(&oa->infib,po->proto.pool,sizeof(struct infib),16,init_infib); + po->areano++; + DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an); + ifa->oa=oa; + schedule_rt_lsa(oa); + } + else + { + bug("I didn't find area for interface.\n"); + } } else ifa->oa=oa; }