diff options
Diffstat (limited to 'proto/ospf')
-rw-r--r-- | proto/ospf/iface.c | 660 | ||||
-rw-r--r-- | proto/ospf/iface.h | 19 | ||||
-rw-r--r-- | proto/ospf/neighbor.c | 10 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 10 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 1 | ||||
-rw-r--r-- | proto/ospf/topology.c | 584 | ||||
-rw-r--r-- | proto/ospf/topology.h | 44 |
7 files changed, 669 insertions, 659 deletions
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 30887464..b2052646 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -8,42 +8,41 @@ #include "ospf.h" -char *ospf_is[]={ "down", "loop", "waiting", "point-to-point", "drother", - "backup", "dr" }; +char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother", + "backup", "dr" +}; -char *ospf_ism[]={ "interface up", "wait timer fired", "backup seen", - "neighbor change", "loop indicated", "unloop indicated", "interface down"}; +char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen", + "neighbor change", "loop indicated", "unloop indicated", "interface down" +}; -char *ospf_it[]={ "broadcast", "nbma", "point-to-point", "virtual link" }; +char *ospf_it[] = { "broadcast", "nbma", "point-to-point", "virtual link" }; static void -poll_timer_hook(timer *timer) +poll_timer_hook(timer * timer) { ospf_hello_send(timer, 1, NULL); } static void -hello_timer_hook(timer *timer) +hello_timer_hook(timer * timer) { ospf_hello_send(timer, 0, NULL); } static void -wait_timer_hook(timer *timer) +wait_timer_hook(timer * timer) { - struct ospf_iface *ifa; - struct proto *p; + struct ospf_iface *ifa = (struct ospf_iface *) timer->data; + struct proto *p = (struct proto *) (ifa->proto); - ifa=(struct ospf_iface *)timer->data; - p=(struct proto *)(ifa->proto); - OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", - ifa->iface->name); - ospf_int_sm(ifa, ISM_WAITF); + OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", ifa->iface->name); + ospf_iface_sm(ifa, ISM_WAITF); } /** - * iface_chstate - handle changes of interface state + * ospf_iface_chstate - handle changes of interface state * @ifa: OSPF interface * @state: new state * @@ -52,72 +51,74 @@ wait_timer_hook(timer *timer) * %ALLDROUTERS have to be opened, etc. */ void -iface_chstate(struct ospf_iface *ifa, u8 state) +ospf_iface_chstate(struct ospf_iface *ifa, u8 state) { - struct proto_ospf *po=ifa->proto; - struct proto *p=&po->proto; + struct proto_ospf *po = ifa->proto; + struct proto *p = &po->proto; u8 oldstate; - if(ifa->state!=state) + if (ifa->state != state) { - OSPF_TRACE(D_EVENTS, "Changing state of iface: %s from \"%s\" into \"%s\".", - ifa->iface->name, ospf_is[ifa->state], ospf_is[state]); - oldstate=ifa->state; - ifa->state=state; - if(ifa->iface->flags & IF_MULTICAST) + OSPF_TRACE(D_EVENTS, + "Changing state of iface: %s from \"%s\" into \"%s\".", + ifa->iface->name, ospf_is[ifa->state], ospf_is[state]); + oldstate = ifa->state; + ifa->state = state; + if (ifa->iface->flags & IF_MULTICAST) { - if((state==OSPF_IS_BACKUP)||(state==OSPF_IS_DR)) + if ((state == OSPF_IS_BACKUP) || (state == OSPF_IS_DR)) { - if((ifa->dr_sk==NULL)&&(ifa->type!=OSPF_IT_NBMA)) - { - DBG("%s: Adding new multicast socket for (B)DR\n", p->name); - ifa->dr_sk=sk_new(p->pool); - ifa->dr_sk->type=SK_IP_MC; - ifa->dr_sk->sport=0; - ifa->dr_sk->dport=OSPF_PROTO; - ifa->dr_sk->saddr=AllDRouters; - ifa->dr_sk->daddr=AllDRouters; - ifa->dr_sk->tos=IP_PREC_INTERNET_CONTROL; - ifa->dr_sk->ttl=1; - ifa->dr_sk->rx_hook=ospf_rx_hook; - ifa->dr_sk->tx_hook=ospf_tx_hook; - ifa->dr_sk->err_hook=ospf_err_hook; - ifa->dr_sk->iface=ifa->iface; - ifa->dr_sk->rbsize=ifa->iface->mtu; - ifa->dr_sk->tbsize=ifa->iface->mtu; - ifa->dr_sk->data=(void *)ifa; - if(sk_open(ifa->dr_sk)!=0) + if ((ifa->dr_sk == NULL) && (ifa->type != OSPF_IT_NBMA)) + { + DBG("%s: Adding new multicast socket for (B)DR\n", p->name); + ifa->dr_sk = sk_new(p->pool); + ifa->dr_sk->type = SK_IP_MC; + ifa->dr_sk->sport = 0; + ifa->dr_sk->dport = OSPF_PROTO; + ifa->dr_sk->saddr = AllDRouters; + ifa->dr_sk->daddr = AllDRouters; + ifa->dr_sk->tos = IP_PREC_INTERNET_CONTROL; + ifa->dr_sk->ttl = 1; + ifa->dr_sk->rx_hook = ospf_rx_hook; + ifa->dr_sk->tx_hook = ospf_tx_hook; + ifa->dr_sk->err_hook = ospf_err_hook; + ifa->dr_sk->iface = ifa->iface; + ifa->dr_sk->rbsize = ifa->iface->mtu; + ifa->dr_sk->tbsize = ifa->iface->mtu; + ifa->dr_sk->data = (void *) ifa; + if (sk_open(ifa->dr_sk) != 0) { DBG("%s: SK_OPEN: new? mc open failed.\n", p->name); } - } + } } else { rfree(ifa->dr_sk); - ifa->dr_sk=NULL; + ifa->dr_sk = NULL; } - if((oldstate==OSPF_IS_DR)&&(ifa->nlsa!=NULL)) + if ((oldstate == OSPF_IS_DR) && (ifa->nlsa != NULL)) { - ifa->nlsa->lsa.age=LSA_MAXAGE; - if(state>=OSPF_IS_WAITING) + ifa->nlsa->lsa.age = LSA_MAXAGE; + if (state >= OSPF_IS_WAITING) { - ospf_lsupd_flush_nlsa(ifa->nlsa,ifa->oa); + ospf_lsupd_flush_nlsa(ifa->nlsa, ifa->oa); } - if(can_flush_lsa(ifa->oa)) flush_lsa(ifa->nlsa,ifa->oa); - ifa->nlsa=NULL; + if (can_flush_lsa(ifa->oa)) + flush_lsa(ifa->nlsa, ifa->oa); + ifa->nlsa = NULL; } } } } -void -downint(struct ospf_iface *ifa) +static void +ospf_iface_down(struct ospf_iface *ifa) { - struct ospf_neighbor *n,*nx; - struct proto *p=&ifa->proto->proto; + struct ospf_neighbor *n, *nx; + struct proto *p = &ifa->proto->proto; - WALK_LIST_DELSAFE(n,nx,ifa->neigh_list) + WALK_LIST_DELSAFE(n, nx, ifa->neigh_list) { OSPF_TRACE(D_EVENTS, "Removing neighbor %I", n->ip); ospf_neigh_remove(n); @@ -137,7 +138,7 @@ downint(struct ospf_iface *ifa) } /** - * ospf_int_sm - OSPF interface state machine + * ospf_iface_sm - OSPF interface state machine * @ifa: OSPF interface * @event: event comming to state machine * @@ -145,317 +146,357 @@ downint(struct ospf_iface *ifa) * interface. */ void -ospf_int_sm(struct ospf_iface *ifa, int event) +ospf_iface_sm(struct ospf_iface *ifa, int event) { - struct proto *p=(struct proto *)(ifa->proto); - struct ospf_area *oa=ifa->oa; + struct ospf_area *oa = ifa->oa; - OSPF_TRACE(D_EVENTS, "SM on iface %s. Event is \"%s\".", - ifa->iface->name, ospf_ism[event]); + DBG("SM on iface %s. Event is \"%s\".", + ifa->iface->name, ospf_ism[event]); - switch(event) + switch (event) { - case ISM_UP: - if(ifa->state==OSPF_IS_DOWN) - { - /* Now, nothing should be adjacent */ - tm_start(ifa->hello_timer,ifa->helloint); - - if(ifa->poll_timer) - tm_start(ifa->poll_timer,ifa->pollint); - - if((ifa->type==OSPF_IT_PTP) || (ifa->type==OSPF_IT_VLINK)) - { - iface_chstate(ifa, OSPF_IS_PTP); - } - else - { - if(ifa->priority==0) - { - iface_chstate(ifa, OSPF_IS_DROTHER); - } - else - { - iface_chstate(ifa, OSPF_IS_WAITING); - tm_start(ifa->wait_timer,ifa->waitint); - } - } - } - schedule_rt_lsa(ifa->oa); - break; - case ISM_BACKS: - case ISM_WAITF: - if(ifa->state==OSPF_IS_WAITING) - { - bdr_election(ifa); - } - break; - case ISM_NEICH: - if((ifa->state==OSPF_IS_DROTHER) || (ifa->state==OSPF_IS_DR) || - (ifa->state==OSPF_IS_BACKUP)) + case ISM_UP: + if (ifa->state == OSPF_IS_DOWN) + { + /* Now, nothing should be adjacent */ + tm_start(ifa->hello_timer, ifa->helloint); + + if (ifa->poll_timer) + tm_start(ifa->poll_timer, ifa->pollint); + + if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_VLINK)) + ospf_iface_chstate(ifa, OSPF_IS_PTP); + else { - bdr_election(ifa); - schedule_rt_lsa(ifa->oa); + if (ifa->priority == 0) + ospf_iface_chstate(ifa, OSPF_IS_DROTHER); + else + { + ospf_iface_chstate(ifa, OSPF_IS_WAITING); + tm_start(ifa->wait_timer, ifa->waitint); + } } - break; - case ISM_DOWN: - iface_chstate(ifa, OSPF_IS_DOWN); - downint(ifa); - schedule_rt_lsa(oa); - break; - case ISM_LOOP: /* Useless? */ - iface_chstate(ifa, OSPF_IS_LOOP); - downint(ifa); - schedule_rt_lsa(ifa->oa); - break; - case ISM_UNLOOP: - iface_chstate(ifa, OSPF_IS_DOWN); + } + schedule_rt_lsa(ifa->oa); + break; + case ISM_BACKS: + case ISM_WAITF: + if (ifa->state == OSPF_IS_WAITING) + { + bdr_election(ifa); + } + break; + case ISM_NEICH: + if ((ifa->state == OSPF_IS_DROTHER) || (ifa->state == OSPF_IS_DR) || + (ifa->state == OSPF_IS_BACKUP)) + { + bdr_election(ifa); schedule_rt_lsa(ifa->oa); - break; - default: - bug("%s: ISM - Unknown event?",p->name); - break; + } + break; + case ISM_DOWN: + ospf_iface_chstate(ifa, OSPF_IS_DOWN); + ospf_iface_down(ifa); + schedule_rt_lsa(oa); + break; + case ISM_LOOP: /* Useless? */ + ospf_iface_chstate(ifa, OSPF_IS_LOOP); + ospf_iface_down(ifa); + schedule_rt_lsa(ifa->oa); + break; + case ISM_UNLOOP: + ospf_iface_chstate(ifa, OSPF_IS_DOWN); + schedule_rt_lsa(ifa->oa); + break; + default: + bug("OSPF_I_SM - Unknown event?"); + break; } - + } -sock * +static sock * ospf_open_mc_socket(struct ospf_iface *ifa) { sock *mcsk; struct proto *p; - p=(struct proto *)(ifa->proto); - - mcsk=sk_new(p->pool); - mcsk->type=SK_IP_MC; - mcsk->sport=0; - mcsk->dport=OSPF_PROTO; - mcsk->saddr=AllSPFRouters; - mcsk->daddr=AllSPFRouters; - mcsk->tos=IP_PREC_INTERNET_CONTROL; - mcsk->ttl=1; - mcsk->rx_hook=ospf_rx_hook; - mcsk->tx_hook=ospf_tx_hook; - mcsk->err_hook=ospf_err_hook; - mcsk->iface=ifa->iface; - mcsk->rbsize=ifa->iface->mtu; - mcsk->tbsize=ifa->iface->mtu; - mcsk->data=(void *)ifa; - if(sk_open(mcsk)!=0) + p = (struct proto *) (ifa->proto); + + mcsk = sk_new(p->pool); + mcsk->type = SK_IP_MC; + mcsk->sport = 0; + mcsk->dport = OSPF_PROTO; + mcsk->saddr = AllSPFRouters; + mcsk->daddr = AllSPFRouters; + mcsk->tos = IP_PREC_INTERNET_CONTROL; + mcsk->ttl = 1; + mcsk->rx_hook = ospf_rx_hook; + mcsk->tx_hook = ospf_tx_hook; + mcsk->err_hook = ospf_err_hook; + mcsk->iface = ifa->iface; + mcsk->rbsize = ifa->iface->mtu; + mcsk->tbsize = ifa->iface->mtu; + mcsk->data = (void *) ifa; + if (sk_open(mcsk) != 0) { - DBG("%s: SK_OPEN: mc open failed.\n",p->name); - return(NULL); + DBG("%s: SK_OPEN: mc open failed.\n", p->name); + return (NULL); } - DBG("%s: SK_OPEN: mc opened.\n",p->name); - return(mcsk); + DBG("%s: SK_OPEN: mc opened.\n", p->name); + return (mcsk); } -sock * -ospf_open_ip_socket(struct ospf_iface *ifa) +static sock * +ospf_open_ip_socket(struct ospf_iface * ifa) { sock *ipsk; struct proto *p; - p=(struct proto *)(ifa->proto); - - ipsk=sk_new(p->pool); - ipsk->type=SK_IP; - ipsk->dport=OSPF_PROTO; - ipsk->saddr=ifa->iface->addr->ip; - ipsk->tos=IP_PREC_INTERNET_CONTROL; - ipsk->ttl=1; - ipsk->rx_hook=ospf_rx_hook; - ipsk->tx_hook=ospf_tx_hook; - ipsk->err_hook=ospf_err_hook; - ipsk->iface=ifa->iface; - ipsk->rbsize=ifa->iface->mtu; - ipsk->tbsize=ifa->iface->mtu; - ipsk->data=(void *)ifa; - if(sk_open(ipsk)!=0) + p = (struct proto *) (ifa->proto); + + ipsk = sk_new(p->pool); + ipsk->type = SK_IP; + ipsk->dport = OSPF_PROTO; + ipsk->saddr = ifa->iface->addr->ip; + ipsk->tos = IP_PREC_INTERNET_CONTROL; + ipsk->ttl = 1; + ipsk->rx_hook = ospf_rx_hook; + ipsk->tx_hook = ospf_tx_hook; + ipsk->err_hook = ospf_err_hook; + ipsk->iface = ifa->iface; + ipsk->rbsize = ifa->iface->mtu; + ipsk->tbsize = ifa->iface->mtu; + ipsk->data = (void *) ifa; + if (sk_open(ipsk) != 0) { - DBG("%s: SK_OPEN: ip open failed.\n",p->name); - return(NULL); + DBG("%s: SK_OPEN: ip open failed.\n", p->name); + return (NULL); } - DBG("%s: SK_OPEN: ip opened.\n",p->name); - return(ipsk); + DBG("%s: SK_OPEN: ip opened.\n", p->name); + return (ipsk); } u8 -ospf_iface_clasify(struct iface *ifa, struct proto *p) +ospf_iface_clasify(struct iface *ifa) { - DBG("%s: Iface flags=%x.\n", p->name, ifa->flags); - if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))== - (IF_MULTIACCESS|IF_MULTICAST)) - { - DBG("%s: Clasifying BCAST.\n", p->name); - return OSPF_IT_BCAST; - } - if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))== - IF_MULTIACCESS) - { - DBG("%s: Clasifying NBMA.\n", p->name); + if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) == + (IF_MULTIACCESS | IF_MULTICAST)) + return OSPF_IT_BCAST; + + if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) == IF_MULTIACCESS) return OSPF_IT_NBMA; - } - DBG("%s: Clasifying P-T-P.\n", p->name); + return OSPF_IT_PTP; } -struct ospf_iface* -find_iface(struct proto_ospf *p, struct iface *what) +struct ospf_iface * +ospf_iface_find(struct proto_ospf *p, struct iface *what) { struct ospf_iface *i; - WALK_LIST (i, p->iface_list) - if ((i)->iface == what) - return i; + WALK_LIST(i, p->iface_list) if ((i)->iface == what) + return i; return NULL; } +static void +ospf_iface_add(struct object_lock *lock) +{ + struct ospf_iface *ifa = lock->data; + struct proto_ospf *po = ifa->proto; + struct iface *iface = lock->iface; + struct proto *p = &po->proto; + + ifa->ioprob = OSPF_I_OK; + + 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); + log("%s: Declaring as stub.", p->name); + ifa->stub = 1; + ifa->ioprob += OSPF_I_MC; + } + 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); + log("%s: Declaring as stub.", p->name); + ifa->stub = 1; + ifa->ioprob += OSPF_I_IP; + } + ifa->lock = lock; + + ifa->state = OSPF_IS_DOWN; + ospf_iface_sm(ifa, ISM_UP); +} + void -ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface) +ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface) { - struct proto_ospf *po=(struct proto_ospf *)p; - struct ospf_config *c=(struct ospf_config *)(p->cf); + struct proto_ospf *po = (struct proto_ospf *) p; + struct ospf_config *c = (struct ospf_config *) (p->cf); struct ospf_area_config *ac; - struct ospf_iface_patt *ip=NULL; + struct ospf_iface_patt *ip = NULL; struct ospf_iface *ifa; struct object_lock *lock; - struct nbma_node *nbma,*nb; + struct nbma_node *nbma, *nb; + struct ospf_area *oa; DBG("%s: If notify called\n", p->name); if (iface->flags & IF_IGNORE) return; - if(flags & IF_CHANGE_UP) + if (flags & IF_CHANGE_UP) { WALK_LIST(ac, c->area_list) { - if(ip=(struct ospf_iface_patt *) - iface_patt_match(&ac->patt_list, iface)) break; + if (ip = (struct ospf_iface_patt *) + iface_patt_match(&ac->patt_list, iface)) + break; } - if(ip) + if (ip) { OSPF_TRACE(D_EVENTS, "Using interface %s.", iface->name); - ifa=mb_allocz(p->pool, sizeof(struct ospf_iface)); - ifa->proto=po; - ifa->iface=iface; - - ifa->an=ac->areaid; - ifa->cost=ip->cost; - ifa->rxmtint=ip->rxmtint; - ifa->inftransdelay=ip->inftransdelay; - ifa->priority=ip->priority; - ifa->helloint=ip->helloint; - ifa->pollint=ip->pollint; - ifa->strictnbma=ip->strictnbma; - ifa->waitint=ip->waitint; - ifa->deadc=ip->deadc; - ifa->stub=ip->stub; - ifa->autype=ip->autype; - memcpy(ifa->aukey,ip->password,8); - 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; + ifa = mb_allocz(p->pool, sizeof(struct ospf_iface)); + ifa->proto = po; + ifa->iface = iface; + + ifa->an = ac->areaid; + ifa->cost = ip->cost; + ifa->rxmtint = ip->rxmtint; + ifa->inftransdelay = ip->inftransdelay; + ifa->priority = ip->priority; + ifa->helloint = ip->helloint; + ifa->pollint = ip->pollint; + ifa->strictnbma = ip->strictnbma; + ifa->waitint = ip->waitint; + ifa->deadc = ip->deadc; + ifa->stub = ip->stub; + ifa->autype = ip->autype; + memcpy(ifa->aukey, ip->password, 8); + ifa->options = 2; /* FIXME what options? */ + + if (ip->type == OSPF_IT_UNDEF) + ifa->type = + ospf_iface_clasify(ifa->iface); + else + ifa->type = ip->type; init_list(&ifa->neigh_list); init_list(&ifa->nbma_list); - WALK_LIST(nb,ip->nbma_list) + WALK_LIST(nb, ip->nbma_list) { - nbma=mb_alloc(p->pool,sizeof(struct nbma_node)); - nbma->ip=nb->ip; - nbma->eligible=nb->eligible; - add_tail(&ifa->nbma_list, NODE nbma); + nbma = mb_alloc(p->pool, sizeof(struct nbma_node)); + nbma->ip = nb->ip; + nbma->eligible = nb->eligible; + add_tail(&ifa->nbma_list, NODE nbma); } - + /* 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; + 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); - - if(ifa->type==OSPF_IT_NBMA) + + if (ifa->type == OSPF_IT_NBMA) { - ifa->poll_timer=tm_new(p->pool); - ifa->poll_timer->data=ifa; - ifa->poll_timer->randomize=0; - ifa->poll_timer->hook=poll_timer_hook; - ifa->poll_timer->recurrent=ifa->pollint; - DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint); + ifa->poll_timer = tm_new(p->pool); + ifa->poll_timer->data = ifa; + ifa->poll_timer->randomize = 0; + ifa->poll_timer->hook = poll_timer_hook; + ifa->poll_timer->recurrent = ifa->pollint; + DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint); } - else ifa->poll_timer=NULL; - - 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; + else + ifa->poll_timer = NULL; + + 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; + add_tail(&((struct proto_ospf *) p)->iface_list, NODE ifa); + ifa->state = OSPF_IS_DOWN; - lock = olock_new( p->pool ); + lock = olock_new(p->pool); lock->addr = AllSPFRouters; lock->type = OBJLOCK_IP; lock->port = OSPF_PROTO; lock->iface = iface; lock->data = ifa; - lock->hook = ospf_ifa_add; - addifa_rtlsa(ifa); + lock->hook = ospf_iface_add; + + WALK_LIST(NODE oa, po->area_list) + { + if (oa->areaid == ifa->an) + break; + } + + if (EMPTY_LIST(po->area_list) || (oa->areaid != ifa->an)) /* New area */ + bug("Cannot add any area to accepted Interface"); + else + ifa->oa = oa; + olock_acquire(lock); } } - if(flags & IF_CHANGE_DOWN) + if (flags & IF_CHANGE_DOWN) { - if((ifa=find_iface((struct proto_ospf *)p, iface))!=NULL) + if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL) { OSPF_TRACE(D_EVENTS, "Killing interface %s.", iface->name); - ospf_int_sm(ifa, ISM_DOWN); + ospf_iface_sm(ifa, ISM_DOWN); } } - if(flags & IF_CHANGE_MTU) + if (flags & IF_CHANGE_MTU) { - if((ifa=find_iface((struct proto_ospf *)p, iface))!=NULL) + if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL) { struct ospf_packet *op; struct ospf_neighbor *n; OSPF_TRACE(D_EVENTS, "Changing MTU on interface %s.", iface->name); if (ifa->hello_sk) { - ifa->hello_sk->rbsize = ifa->iface->mtu; - ifa->hello_sk->tbsize = ifa->iface->mtu; + ifa->hello_sk->rbsize = ifa->iface->mtu; + ifa->hello_sk->tbsize = ifa->iface->mtu; sk_reallocate(ifa->hello_sk); } if (ifa->dr_sk) { - ifa->dr_sk->rbsize = ifa->iface->mtu; - ifa->dr_sk->tbsize = ifa->iface->mtu; + ifa->dr_sk->rbsize = ifa->iface->mtu; + ifa->dr_sk->tbsize = ifa->iface->mtu; sk_reallocate(ifa->dr_sk); } if (ifa->ip_sk) { - ifa->ip_sk->rbsize = ifa->iface->mtu; - ifa->ip_sk->tbsize = ifa->iface->mtu; + ifa->ip_sk->rbsize = ifa->iface->mtu; + ifa->ip_sk->tbsize = ifa->iface->mtu; sk_reallocate(ifa->ip_sk); } - WALK_LIST(n,ifa->neigh_list) + WALK_LIST(n, ifa->neigh_list) { - op = (struct ospf_packet *)n->ldbdes; - n->ldbdes = mb_allocz(n->pool, iface->mtu); + op = (struct ospf_packet *) n->ldbdes; + n->ldbdes = mb_allocz(n->pool, iface->mtu); - if(ntohs(op->length) <= iface->mtu) /* If the packet in old buffer is bigger, let it filled by zeros */ - memcpy(n->ldbdes, op, iface->mtu); /* If the packet is old is same or smaller, copy it */ + if (ntohs(op->length) <= iface->mtu) /* If the packet in old buffer is bigger, let it filled by zeros */ + memcpy(n->ldbdes, op, iface->mtu); /* If the packet is old is same or smaller, copy it */ - rfree(op); + rfree(op); } } } @@ -464,74 +505,32 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface) void ospf_iface_info(struct ospf_iface *ifa) { - char *strict="(strict)"; - - if((ifa->type!=OSPF_IT_NBMA)||(ifa->strictnbma==0)) strict=""; - cli_msg(-1015,"Interface \"%s\":", ifa->iface->name); - cli_msg(-1015,"\tArea: %I (%u)", ifa->oa->areaid, ifa->oa->areaid); - cli_msg(-1015,"\tType: %s %s", ospf_it[ifa->type], strict); - cli_msg(-1015,"\tState: %s %s", ospf_is[ifa->state], - ifa->stub ? "(stub)" : ""); - cli_msg(-1015,"\tPriority: %u", ifa->priority); - cli_msg(-1015,"\tCost: %u", ifa->cost); - cli_msg(-1015,"\tHello timer: %u", ifa->helloint); - if(ifa->type==OSPF_IT_NBMA) - { - cli_msg(-1015,"\tPoll timer: %u", ifa->pollint); - } - cli_msg(-1015,"\tWait timer: %u", ifa->waitint); - cli_msg(-1015,"\tDead timer: %u", ifa->deadc*ifa->helloint); - cli_msg(-1015,"\tRetransmit timer: %u", ifa->rxmtint); - if((ifa->type==OSPF_IT_BCAST)||(ifa->type==OSPF_IT_NBMA)) - { - cli_msg(-1015,"\tDesigned router (ID): %I", ifa->drid); - cli_msg(-1015,"\tDesigned router (IP): %I", ifa->drip); - cli_msg(-1015,"\tBackup designed router (ID): %I", ifa->bdrid); - cli_msg(-1015,"\tBackup designed router (IP): %I", ifa->bdrip); - } -} - -void -ospf_ifa_add(struct object_lock *lock) -{ - struct ospf_iface *ifa=lock->data; - struct proto_ospf *po=ifa->proto; - struct iface *iface=lock->iface; - struct proto *p=&po->proto; - - ifa->ioprob=OSPF_I_OK; - - if(ifa->type!=OSPF_IT_NBMA) + char *strict = "(strict)"; + + if ((ifa->type != OSPF_IT_NBMA) || (ifa->strictnbma == 0)) + strict = ""; + cli_msg(-1015, "Interface \"%s\":", ifa->iface->name); + cli_msg(-1015, "\tArea: %I (%u)", ifa->oa->areaid, ifa->oa->areaid); + cli_msg(-1015, "\tType: %s %s", ospf_it[ifa->type], strict); + cli_msg(-1015, "\tState: %s %s", ospf_is[ifa->state], + ifa->stub ? "(stub)" : ""); + cli_msg(-1015, "\tPriority: %u", ifa->priority); + cli_msg(-1015, "\tCost: %u", ifa->cost); + cli_msg(-1015, "\tHello timer: %u", ifa->helloint); + 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); - log("%s: Declaring as stub.", p->name); - ifa->stub=1; - ifa->ioprob += OSPF_I_MC; - } - ifa->dr_sk=NULL; + cli_msg(-1015, "\tPoll timer: %u", ifa->pollint); } - - if((ifa->ip_sk=ospf_open_ip_socket(ifa))==NULL) + cli_msg(-1015, "\tWait timer: %u", ifa->waitint); + cli_msg(-1015, "\tDead timer: %u", ifa->deadc * ifa->helloint); + cli_msg(-1015, "\tRetransmit timer: %u", ifa->rxmtint); + if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA)) { - log("%s: Huh? could not open ip socket on interface %s?", p->name, - iface->name); - log("%s: Declaring as stub.", p->name); - ifa->stub=1; - ifa->ioprob += OSPF_I_IP; + cli_msg(-1015, "\tDesigned router (ID): %I", ifa->drid); + cli_msg(-1015, "\tDesigned router (IP): %I", ifa->drip); + cli_msg(-1015, "\tBackup designed router (ID): %I", ifa->bdrid); + cli_msg(-1015, "\tBackup designed router (IP): %I", ifa->bdrip); } - ifa->lock = lock; - - ifa->state=OSPF_IS_DOWN; - ospf_int_sm(ifa, ISM_UP); -} - -void -schedule_net_lsa(struct ospf_iface *ifa) -{ - ifa->orignet=1; } void @@ -540,4 +539,3 @@ ospf_iface_shutdown(struct ospf_iface *ifa) init_list(&ifa->neigh_list); hello_timer_hook(ifa->hello_timer); } - diff --git a/proto/ospf/iface.h b/proto/ospf/iface.h index e78a1f8d..2c03d2a7 100644 --- a/proto/ospf/iface.h +++ b/proto/ospf/iface.h @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. * @@ -10,20 +10,11 @@ #ifndef _BIRD_OSPF_IFACE_H_ #define _BIRD_OSPF_IFACE_H_ -void iface_chstate(struct ospf_iface *ifa, u8 state); -void downint(struct ospf_iface *ifa); -void ospf_int_sm(struct ospf_iface *ifa, int event); -sock *ospf_open_mc_socket(struct ospf_iface *ifa); -sock *ospf_open_ip_socket(struct ospf_iface *ifa); -u8 is_good_iface(struct proto *p, struct iface *iface); -u8 ospf_iface_clasify(struct iface *ifa, struct proto *p); -void ospf_add_timers(struct ospf_iface *ifa, pool *pool); -void ospf_iface_default(struct ospf_iface *ifa); -struct ospf_iface *find_iface(struct proto_ospf *p, struct iface *what); -void ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface); +void ospf_iface_chstate(struct ospf_iface *ifa, u8 state); +void ospf_iface_sm(struct ospf_iface *ifa, int event); +struct ospf_iface *ospf_iface_find(struct proto_ospf *p, struct iface *what); +void ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface); void ospf_iface_info(struct ospf_iface *ifa); void ospf_iface_shutdown(struct ospf_iface *ifa); -void ospf_ifa_add(struct object_lock *lock); -void schedule_net_lsa(struct ospf_iface *ifa); #endif /* _BIRD_OSPF_IFACE_H_ */ diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index 3337aab6..b32e4620 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -103,9 +103,9 @@ neigh_chstate(struct ospf_neighbor *n, u8 state) n->ip, ospf_ns[oldstate], ospf_ns[state]); if((state==NEIGHBOR_2WAY) && (oldstate<NEIGHBOR_2WAY)) - ospf_int_sm(ifa, ISM_NEICH); + ospf_iface_sm(ifa, ISM_NEICH); if((state<NEIGHBOR_2WAY) && (oldstate>=NEIGHBOR_2WAY)) - ospf_int_sm(ifa, ISM_NEICH); + ospf_iface_sm(ifa, ISM_NEICH); if(oldstate==NEIGHBOR_FULL) /* Decrease number of adjacencies */ { @@ -448,11 +448,11 @@ bdr_election(struct ospf_iface *ifa) DBG("DR=%I, BDR=%I\n", ifa->drid, ifa->bdrid); - if(myid==ifa->drid) iface_chstate(ifa, OSPF_IS_DR); + if(myid==ifa->drid) ospf_iface_chstate(ifa, OSPF_IS_DR); else { - if(myid==ifa->bdrid) iface_chstate(ifa, OSPF_IS_BACKUP); - else iface_chstate(ifa, OSPF_IS_DROTHER); + if(myid==ifa->bdrid) ospf_iface_chstate(ifa, OSPF_IS_BACKUP); + else ospf_iface_chstate(ifa, OSPF_IS_DROTHER); } rem_node(NODE &me); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 02bfd465..79564ed8 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -109,7 +109,7 @@ ospf_start(struct proto *p) oa->disp_timer->randomize=0; oa->disp_timer->hook=area_disp; oa->disp_timer->recurrent=oa->tick; - tm_start(oa->disp_timer,oa->tick); + tm_start(oa->disp_timer, 1); oa->calcrt=0; oa->origrt=0; init_list(&oa->net_list); @@ -168,7 +168,7 @@ ospf_init(struct proto_config *c) p->make_tmp_attrs = ospf_make_tmp_attrs; p->store_tmp_attrs = ospf_store_tmp_attrs; p->rt_notify = ospf_rt_notify; - p->if_notify = ospf_if_notify; + p->if_notify = ospf_iface_notify; p->rte_better = ospf_rte_better; p->rte_same = ospf_rte_same; @@ -245,6 +245,12 @@ ospf_build_attrs(ea_list *next, struct linpool *pool, u32 m1, u32 m2, u32 tag) } void +schedule_net_lsa(struct ospf_iface *ifa) +{ + ifa->orignet = 1; +} + +void schedule_rt_lsa(struct ospf_area *oa) { struct proto_ospf *po=oa->po; diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 56471b68..4b573f8b 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -444,6 +444,7 @@ void ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old,ea_list *attrs); void area_disp(timer *timer); void schedule_rt_lsa(struct ospf_area *oa); void schedule_rtcalc(struct ospf_area *oa); +void schedule_net_lsa(struct ospf_iface *ifa); void ospf_sh_neigh(struct proto *p, char *iff); void ospf_sh(struct proto *p); void ospf_sh_iface(struct proto *p, char *iff); diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 73d2ddd2..a80ca3d6 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -21,151 +21,140 @@ #define HASH_LO_MIN 8 static void * -originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p) +originate_rt_lsa_body(struct ospf_area *oa, u16 * length) { + struct proto_ospf *po = oa->po; struct ospf_iface *ifa; - int j=0,k=0,v=0; - u16 i=0; + int j = 0, k = 0, v = 0; + u16 i = 0; struct ospf_lsa_rt *rt; struct ospf_lsa_rt_link *ln; struct ospf_neighbor *neigh; DBG("%s: Originating RT_lsa body for area \"%I\".\n", po->proto.name, - oa->areaid); + oa->areaid); - WALK_LIST (ifa, p->iface_list) + WALK_LIST(ifa, po->iface_list) { - if((ifa->an==oa->areaid) && (ifa->state!=OSPF_IS_DOWN)) + if ((ifa->an == oa->areaid) && (ifa->state != OSPF_IS_DOWN)) { i++; - if(ifa->type==OSPF_IT_VLINK) v=1; + if (ifa->type == OSPF_IT_VLINK) + v = 1; } } - rt=mb_allocz(p->proto.pool, sizeof(struct ospf_lsa_rt)+ - i*sizeof(struct ospf_lsa_rt_link)); - if(p->areano>1) rt->veb.bit.b=1; - if((p->ebit)&&(!oa->stub)) rt->veb.bit.e=1; - rt->veb.bit.v=v; - ln=(struct ospf_lsa_rt_link *)(rt+1); - - WALK_LIST (ifa, p->iface_list) + rt = mb_allocz(po->proto.pool, sizeof(struct ospf_lsa_rt) + + i * sizeof(struct ospf_lsa_rt_link)); + if (po->areano > 1) + rt->veb.bit.b = 1; + if ((po->ebit) && (!oa->stub)) + rt->veb.bit.e = 1; + rt->veb.bit.v = v; + ln = (struct ospf_lsa_rt_link *) (rt + 1); + + WALK_LIST(ifa, po->iface_list) { - if((ifa->an!=oa->areaid) || (ifa->state==OSPF_IS_DOWN)) continue; + 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; + 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) + 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) - { - 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 - { - 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; + 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) + { + 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 + { + 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; } } - if(ifa->type==OSPF_IT_VLINK) v=1; - ln=(ln+1); + if (ifa->type == OSPF_IT_VLINK) + v = 1; + ln = (ln + 1); } - rt->links=i; - *length=i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt)+ + rt->links = i; + *length = i * sizeof(struct ospf_lsa_rt_link) + sizeof(struct ospf_lsa_rt) + sizeof(struct ospf_lsa_header); return rt; } -void -addifa_rtlsa(struct ospf_iface *ifa) -{ - struct ospf_area *oa; - struct proto_ospf *po=ifa->proto; - - WALK_LIST(NODE oa,po->area_list) - { - if(oa->areaid==ifa->an) break; - } - - if(EMPTY_LIST(po->area_list) || (oa->areaid!=ifa->an)) /* New area */ - { - bug("Cannot add any area to accepted Interface"); - } - else ifa->oa=oa; -} - /** * originate_rt_lsa - build new instance of router LSA * @oa: ospf_area which is LSA built to @@ -179,68 +168,69 @@ void originate_rt_lsa(struct ospf_area *oa) { struct ospf_lsa_header lsa; - struct proto_ospf *po=oa->po; - struct proto *p=&po->proto; - u32 rtid=po->proto.cf->global->router_id; + struct proto_ospf *po = oa->po; + struct proto *p = &po->proto; + u32 rtid = po->proto.cf->global->router_id; struct top_hash_entry *en; void *body; - if((oa->rt)&&((oa->rt->inst_t+MINLSINTERVAL))>now) return; - /* - * Tick is probably set to very low value. We cannot - * originate new LSA before MINLSINTERVAL. We will - * try to do it next tick. - */ - - OSPF_TRACE(D_EVENTS, "Originating RT_lsa for area \"%I\".",oa->areaid); - - lsa.age=0; - lsa.id=rtid; - lsa.type=LSA_T_RT; - lsa.rt=rtid; - lsa.options=0; - if(oa->rt==NULL) + if ((oa->rt) && ((oa->rt->inst_t + MINLSINTERVAL)) > now) + return; + /* + * Tick is probably set to very low value. We cannot + * originate new LSA before MINLSINTERVAL. We will + * try to do it next tick. + */ + + OSPF_TRACE(D_EVENTS, "Originating RT_lsa for area \"%I\".", oa->areaid); + + lsa.age = 0; + lsa.id = rtid; + lsa.type = LSA_T_RT; + lsa.rt = rtid; + lsa.options = 0; + if (oa->rt == NULL) { - lsa.sn=LSA_INITSEQNO; + lsa.sn = LSA_INITSEQNO; } else { - lsa.sn=oa->rt->lsa.sn+1; + lsa.sn = oa->rt->lsa.sn + 1; } - body=originate_rt_lsa_body(oa, &lsa.length, po); - lsasum_calculate(&lsa,body,po); - en=lsa_install_new(&lsa, body, oa); - oa->rt=en; - ospf_lsupd_flood(NULL,NULL,&oa->rt->lsa,NULL,oa,1); + body = originate_rt_lsa_body(oa, &lsa.length); + lsasum_calculate(&lsa, body, po); + en = lsa_install_new(&lsa, body, oa); + oa->rt = en; + ospf_lsupd_flood(NULL, NULL, &oa->rt->lsa, NULL, oa, 1); schedule_rtcalc(oa); - oa->origrt=0; + oa->origrt = 0; } static void * -originate_net_lsa_body(struct ospf_iface *ifa, u16 *length, - struct proto_ospf *po) +originate_net_lsa_body(struct ospf_iface *ifa, u16 * length, + struct proto_ospf *po) { - u16 i=1; + u16 i = 1; struct ospf_neighbor *n; u32 *body; struct ospf_lsa_net *net; - net=mb_alloc(po->proto.pool,sizeof(u32)*(ifa->fadj+1)+ - sizeof(struct ospf_lsa_net)); - net->netmask=ipa_mkmask(ifa->iface->addr->pxlen); + net = mb_alloc(po->proto.pool, sizeof(u32) * (ifa->fadj + 1) + + sizeof(struct ospf_lsa_net)); + net->netmask = ipa_mkmask(ifa->iface->addr->pxlen); - body=(u32 *)(net+1); - i=1; - *body=po->proto.cf->global->router_id; - WALK_LIST(n,ifa->neigh_list) + body = (u32 *) (net + 1); + i = 1; + *body = po->proto.cf->global->router_id; + WALK_LIST(n, ifa->neigh_list) { - if(n->state==NEIGHBOR_FULL) + if (n->state == NEIGHBOR_FULL) { - *(body+i)=n->rid; + *(body + i) = n->rid; i++; } } - *length=i*sizeof(u32)+sizeof(struct ospf_lsa_header)+ + *length = i * sizeof(u32) + sizeof(struct ospf_lsa_header) + sizeof(struct ospf_lsa_net); return net; } @@ -257,96 +247,103 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length, void originate_net_lsa(struct ospf_iface *ifa) { - struct proto_ospf *po=ifa->proto; + struct proto_ospf *po = ifa->proto; struct ospf_lsa_header lsa; - u32 rtid=po->proto.cf->global->router_id; - struct proto *p=&po->proto; + u32 rtid = po->proto.cf->global->router_id; + struct proto *p = &po->proto; void *body; - if(ifa->nlsa&&((ifa->nlsa->inst_t+MINLSINTERVAL)>now)) return; + if (ifa->nlsa && ((ifa->nlsa->inst_t + MINLSINTERVAL) > now)) + return; /* * It's too early to originate new network LSA. We will * try to do it next tick */ - if((ifa->state!=OSPF_IS_DR)||(ifa->fadj==0)) + if ((ifa->state != OSPF_IS_DR) || (ifa->fadj == 0)) { - if(ifa->nlsa==NULL) return; + if (ifa->nlsa == NULL) + return; OSPF_TRACE(D_EVENTS, "Deleting Net lsa for iface \"%s\".", - ifa->iface->name); - ifa->nlsa->lsa.sn+=1; - ifa->nlsa->lsa.age=LSA_MAXAGE; - ospf_lsupd_flood(NULL,NULL,&ifa->nlsa->lsa,NULL,ifa->oa,0); + ifa->iface->name); + ifa->nlsa->lsa.sn += 1; + ifa->nlsa->lsa.age = LSA_MAXAGE; + ospf_lsupd_flood(NULL, NULL, &ifa->nlsa->lsa, NULL, ifa->oa, 0); s_rem_node(SNODE ifa->nlsa); - if(ifa->nlsa->lsa_body!=NULL) mb_free(ifa->nlsa->lsa_body); - ifa->nlsa->lsa_body=NULL; + if (ifa->nlsa->lsa_body != NULL) + mb_free(ifa->nlsa->lsa_body); + ifa->nlsa->lsa_body = NULL; ospf_hash_delete(ifa->oa->gr, ifa->nlsa); schedule_rtcalc(ifa->oa); - ifa->nlsa=NULL; - return ; + ifa->nlsa = NULL; + return; } OSPF_TRACE(D_EVENTS, "Originating Net lsa for iface \"%s\".", - ifa->iface->name); - - lsa.age=0; - lsa.id=ipa_to_u32(ifa->iface->addr->ip); - lsa.type=LSA_T_NET; - lsa.rt=rtid; - lsa.options=0; - if(ifa->nlsa==NULL) + ifa->iface->name); + + lsa.age = 0; + lsa.id = ipa_to_u32(ifa->iface->addr->ip); + lsa.type = LSA_T_NET; + lsa.rt = rtid; + lsa.options = 0; + if (ifa->nlsa == NULL) { - lsa.sn=LSA_INITSEQNO; + lsa.sn = LSA_INITSEQNO; } else { - lsa.sn=ifa->nlsa->lsa.sn+1; + lsa.sn = ifa->nlsa->lsa.sn + 1; } - body=originate_net_lsa_body(ifa, &lsa.length, po); - lsasum_calculate(&lsa,body,po); - ifa->nlsa=lsa_install_new(&lsa, body, ifa->oa); - ospf_lsupd_flood(NULL,NULL,&ifa->nlsa->lsa,NULL,ifa->oa,1); - ifa->orignet=0; + body = originate_net_lsa_body(ifa, &lsa.length, po); + lsasum_calculate(&lsa, body, po); + ifa->nlsa = lsa_install_new(&lsa, body, ifa->oa); + ospf_lsupd_flood(NULL, NULL, &ifa->nlsa->lsa, NULL, ifa->oa, 1); + ifa->orignet = 0; } static void * -originate_ext_lsa_body(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs) +originate_ext_lsa_body(net * n, rte * e, struct proto_ospf *po, + struct ea_list *attrs) { - struct proto *p=&po->proto; + struct proto *p = &po->proto; struct ospf_lsa_ext *ext; struct ospf_lsa_ext_tos *et; u32 m1 = ea_get_int(attrs, EA_OSPF_METRIC1, LSINFINITY); u32 m2 = ea_get_int(attrs, EA_OSPF_METRIC2, 10000); u32 tag = ea_get_int(attrs, EA_OSPF_TAG, 0); - int inas=0; + int inas = 0; - ext=mb_alloc(p->pool,sizeof(struct ospf_lsa_ext)+ - sizeof(struct ospf_lsa_ext_tos)); - ext->netmask=ipa_mkmask(n->n.pxlen); + ext = mb_alloc(p->pool, sizeof(struct ospf_lsa_ext) + + sizeof(struct ospf_lsa_ext_tos)); + ext->netmask = ipa_mkmask(n->n.pxlen); - et=(struct ospf_lsa_ext_tos *)(ext+1); + et = (struct ospf_lsa_ext_tos *) (ext + 1); - if(m1!=LSINFINITY) + if (m1 != LSINFINITY) { - et->etos=0; - et->metric=m1; + et->etos = 0; + et->metric = m1; } else { - et->etos=0x80; - et->metric=m2; + et->etos = 0x80; + et->metric = m2; } - et->padding=0; - et->tag=tag; - if(ipa_compare(e->attrs->gw,ipa_from_u32(0))!=0) + et->padding = 0; + et->tag = tag; + if (ipa_compare(e->attrs->gw, ipa_from_u32(0)) != 0) { - if(find_iface((struct proto_ospf *)p, e->attrs->iface)!=NULL) inas=1; + if (ospf_iface_find((struct proto_ospf *) p, e->attrs->iface) != NULL) + inas = 1; } - - if(!inas) et->fwaddr= ipa_from_u32(0); - else et->fwaddr=e->attrs->gw; + + if (!inas) + et->fwaddr = ipa_from_u32(0); + else + et->fwaddr = e->attrs->gw; return ext; } @@ -367,8 +364,8 @@ int max_ext_lsa(unsigned pxlen) { int i; - for(i=1;pxlen<BITS_PER_IP_ADDRESS;pxlen++,i<<=1) - if(i>=MAXNETS) + for (i = 1; pxlen < BITS_PER_IP_ADDRESS; pxlen++, i <<= 1) + if (i >= MAXNETS) return MAXNETS; return i; } @@ -389,64 +386,68 @@ max_ext_lsa(unsigned pxlen) * origination is necessary. */ void -originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs) +originate_ext_lsa(net * n, rte * e, struct proto_ospf *po, + struct ea_list *attrs) { struct ospf_lsa_header lsa; - u32 rtid=po->proto.cf->global->router_id; - struct top_hash_entry *en=NULL; - void *body=NULL; - struct proto *p=&po->proto; + u32 rtid = po->proto.cf->global->router_id; + struct top_hash_entry *en = NULL; + void *body = NULL; + struct proto *p = &po->proto; struct ospf_area *oa; - struct ospf_lsa_ext *ext1,*ext2; + struct ospf_lsa_ext *ext1, *ext2; int i; int max; OSPF_TRACE(D_EVENTS, "Originating Ext lsa for %I/%d.", n->n.prefix, - n->n.pxlen); - - lsa.age=0; - lsa.id=ipa_to_u32(n->n.prefix); - lsa.type=LSA_T_EXT; - lsa.rt=rtid; - lsa.sn=LSA_INITSEQNO; - body=originate_ext_lsa_body(n, e, po, attrs); - lsa.length=sizeof(struct ospf_lsa_ext)+sizeof(struct ospf_lsa_ext_tos)+ + n->n.pxlen); + + lsa.age = 0; + lsa.id = ipa_to_u32(n->n.prefix); + lsa.type = LSA_T_EXT; + lsa.rt = rtid; + lsa.sn = LSA_INITSEQNO; + body = originate_ext_lsa_body(n, e, po, attrs); + lsa.length = sizeof(struct ospf_lsa_ext) + sizeof(struct ospf_lsa_ext_tos) + sizeof(struct ospf_lsa_header); - ext1=body; - max=max_ext_lsa(n->n.pxlen); + ext1 = body; + max = max_ext_lsa(n->n.pxlen); - oa=HEAD(po->area_list); + oa = HEAD(po->area_list); - for(i=0;i<max;i++) + for (i = 0; i < max; i++) { - if((en=ospf_hash_find_header(oa->gr, &lsa))!=NULL) + if ((en = ospf_hash_find_header(oa->gr, &lsa)) != NULL) { - ext2=en->lsa_body; - if(ipa_compare(ext1->netmask,ext2->netmask)!=0) lsa.id++; - else break; + ext2 = en->lsa_body; + if (ipa_compare(ext1->netmask, ext2->netmask) != 0) + lsa.id++; + else + break; } - else break; + else + break; } - if(i==max) + if (i == max) { - log("%s: got more routes for one /%d network then %d, ignoring",p->name, - n->n.pxlen,max); + log("%s: got more routes for one /%d network then %d, ignoring", p->name, + n->n.pxlen, max); mb_free(body); return; } - lsasum_calculate(&lsa,body,po); + lsasum_calculate(&lsa, body, po); WALK_LIST(oa, po->area_list) { - en=lsa_install_new(&lsa, body, oa); - ospf_lsupd_flood(NULL,NULL,&en->lsa,NULL,oa,1); - body=originate_ext_lsa_body(n, e, po, attrs); + en = lsa_install_new(&lsa, body, oa); + ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1); + body = originate_ext_lsa_body(n, e, po, attrs); } mb_free(body); - if(po->ebit==0) + if (po->ebit == 0) { - po->ebit=1; + po->ebit = 1; WALK_LIST(oa, po->area_list) { schedule_rt_lsa(oa); @@ -470,7 +471,8 @@ ospf_top_ht_alloc(struct top_graph *f) f->hash_entries_min = f->hash_size HASH_LO_MARK; DBG("Allocating OSPF hash of order %d: %d hash_entries, %d low, %d high\n", f->hash_order, f->hash_size, f->hash_entries_min, f->hash_entries_max); - f->hash_table = mb_alloc(f->pool, f->hash_size * sizeof(struct top_hash_entry *)); + f->hash_table = + mb_alloc(f->pool, f->hash_size * sizeof(struct top_hash_entry *)); bzero(f->hash_table, f->hash_size * sizeof(struct top_hash_entry *)); } @@ -492,10 +494,14 @@ ospf_top_hash_u32(u32 a) static inline unsigned ospf_top_hash(struct top_graph *f, u32 lsaid, u32 rtrid, u32 type) { -#if 1 /* Dirty patch to make rt table calculation work. */ -return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32((type==LSA_T_NET) ? lsaid : rtrid) + type) & f->hash_mask; +#if 1 /* Dirty patch to make rt table calculation work. */ + return (ospf_top_hash_u32(lsaid) + + ospf_top_hash_u32((type == + LSA_T_NET) ? lsaid : rtrid) + + type) & f->hash_mask; #else - return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32(rtrid) + type) & f->hash_mask; + return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32(rtrid) + + type) & f->hash_mask; #endif } @@ -507,7 +513,7 @@ return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32((type==LSA_T_NET) ? lsaid : * its used in @ospf_area structure. */ struct top_graph * -ospf_top_new(pool *pool, struct proto_ospf *p) +ospf_top_new(pool * pool, struct proto_ospf *p) { struct top_graph *f; @@ -537,36 +543,37 @@ ospf_top_rehash(struct top_graph *f, int step) oldn = f->hash_size; oldt = f->hash_table; - DBG("Re-hashing topology hash from order %d to %d\n", f->hash_order, f->hash_order+step); + DBG("Re-hashing topology hash from order %d to %d\n", f->hash_order, + f->hash_order + step); f->hash_order += step; ospf_top_ht_alloc(f); newt = f->hash_table; - for(oldh=0; oldh < oldn; oldh++) + for (oldh = 0; oldh < oldn; oldh++) + { + e = oldt[oldh]; + while (e) { - e = oldt[oldh]; - while (e) - { - x = e->next; - n = newt + ospf_top_hash(f, e->lsa.id, e->lsa.rt, e->lsa.type); - e->next = *n; - *n = e; - e = x; - } + x = e->next; + n = newt + ospf_top_hash(f, e->lsa.id, e->lsa.rt, e->lsa.type); + e->next = *n; + *n = e; + e = x; } + } ospf_top_ht_free(oldt); } struct top_hash_entry * ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h) { - return ospf_hash_find(f,h->id,h->rt,h->type); + return ospf_hash_find(f, h->id, h->rt, h->type); } struct top_hash_entry * ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h) { - return ospf_hash_get(f,h->id,h->rt,h->type); + return ospf_hash_get(f, h->id, h->rt, h->type); } struct top_hash_entry * @@ -574,16 +581,16 @@ ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type) { struct top_hash_entry *e = f->hash_table[ospf_top_hash(f, lsa, rtr, type)]; -#if 1 /* Dirty patch to make rt table calculation work. */ - if(type==LSA_T_NET) +#if 1 /* Dirty patch to make rt table calculation work. */ + if (type == LSA_T_NET) { - while (e && (e->lsa.id != lsa || e->lsa.type != LSA_T_NET )) - e = e->next; + while (e && (e->lsa.id != lsa || e->lsa.type != LSA_T_NET)) + e = e->next; } else { - while (e && (e->lsa.id != lsa || e->lsa.type != type || e->lsa.rt != rtr)) - e = e->next; + while (e && (e->lsa.id != lsa || e->lsa.type != type || e->lsa.rt != rtr)) + e = e->next; } #else while (e && (e->lsa.id != lsa || e->lsa.rt != rtr || e->lsa.type != type)) @@ -595,7 +602,8 @@ ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type) struct top_hash_entry * ospf_hash_get(struct top_graph *f, u32 lsa, u32 rtr, u32 type) { - struct top_hash_entry **ee = f->hash_table + ospf_top_hash(f, lsa, rtr, type); + struct top_hash_entry **ee = + f->hash_table + ospf_top_hash(f, lsa, rtr, type); struct top_hash_entry *e = *ee; while (e && (e->lsa.id != lsa || e->lsa.rt != rtr || e->lsa.type != type)) @@ -607,9 +615,9 @@ ospf_hash_get(struct top_graph *f, u32 lsa, u32 rtr, u32 type) e->lsa.rt = rtr; e->lsa.type = type; e->lsa_body = NULL; - e->nhi=NULL; - e->next=*ee; /* MJ you forgot this :-) */ - *ee=e; + e->nhi = NULL; + e->next = *ee; /* MJ you forgot this :-) */ + *ee = e; if (f->hash_entries++ > f->hash_entries_max) ospf_top_rehash(f, HASH_HI_STEP); return e; @@ -622,17 +630,17 @@ ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e) struct top_hash_entry **ee = f->hash_table + h; while (*ee) + { + if (*ee == e) { - if (*ee == e) - { - *ee = e->next; - sl_free(f->hash_slab, e); - if (f->hash_entries-- < f->hash_entries_min) - ospf_top_rehash(f, -HASH_LO_STEP); - return; - } - ee = &((*ee)->next); + *ee = e->next; + sl_free(f->hash_slab, e); + if (f->hash_entries-- < f->hash_entries_min) + ospf_top_rehash(f, -HASH_LO_STEP); + return; } + ee = &((*ee)->next); + } bug("ospf_hash_delete() called for invalid node"); } @@ -642,17 +650,16 @@ ospf_top_dump(struct top_graph *f, struct proto *p) unsigned int i; OSPF_TRACE(D_EVENTS, "Hash entries: %d", f->hash_entries); - for(i=0; i<f->hash_size; i++) + for (i = 0; i < f->hash_size; i++) + { + struct top_hash_entry *e = f->hash_table[i]; + while (e) { - struct top_hash_entry *e = f->hash_table[i]; - while (e) - { - OSPF_TRACE(D_EVENTS, "\t%1x %-1I %-1I %4u 0x%08x", - e->lsa.type, e->lsa.id, - e->lsa.rt, e->lsa.age, e->lsa.sn); - e = e->next; - } + OSPF_TRACE(D_EVENTS, "\t%1x %-1I %-1I %4u 0x%08x", + e->lsa.type, e->lsa.id, e->lsa.rt, e->lsa.age, e->lsa.sn); + e = e->next; } + } } /* This is very inefficient, please don't call it often */ @@ -670,15 +677,16 @@ can_flush_lsa(struct ospf_area *oa) WALK_LIST(ifa, iface_list) { - if(ifa->oa==oa) + if (ifa->oa == oa) { WALK_LIST(n, ifa->neigh_list) { - if((n->state==NEIGHBOR_EXCHANGE)||(n->state==NEIGHBOR_LOADING)) + if ((n->state == NEIGHBOR_EXCHANGE) || (n->state == NEIGHBOR_LOADING)) { return 0; } } + break; } } diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index a3558371..5baa0c9e 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 - 2000 Ondrej Filip <feela@network.cz> + * (c) 1999 - 2004 Ondrej Filip <feela@network.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -9,19 +9,20 @@ #ifndef _BIRD_OSPF_TOPOLOGY_H_ #define _BIRD_OSPF_TOPOLOGY_H_ -struct top_hash_entry { /* Index for fast mapping (type,rtrid,LSid)->vertex */ +struct top_hash_entry +{ /* Index for fast mapping (type,rtrid,LSid)->vertex */ snode n; - node cn; /* For adding into list of candidates - * in intra-area routing table - * calculation - */ - struct top_hash_entry *next; /* Next in hash chain */ + node cn; /* For adding into list of candidates + * in intra-area routing table + * calculation + */ + struct top_hash_entry *next; /* Next in hash chain */ struct ospf_lsa_header lsa; void *lsa_body; - bird_clock_t inst_t; /* Time of installation into DB */ - ip_addr nh; /* Next hop */ + bird_clock_t inst_t; /* Time of installation into DB */ + ip_addr nh; /* Next hop */ struct iface *nhi; - u16 dist; /* Distance from the root */ + u16 dist; /* Distance from the root */ u16 ini_age; u8 color; #define OUTSPF 0 @@ -31,9 +32,10 @@ struct top_hash_entry { /* Index for fast mapping (type,rtrid,LSid)->vertex */ u16 padding2; }; -struct top_graph { - pool *pool; /* Pool we allocate from */ - slab *hash_slab; /* Slab for hash entries */ +struct top_graph +{ + pool *pool; /* Pool we allocate from */ + slab *hash_slab; /* Slab for hash entries */ struct top_hash_entry **hash_table; /* Hashing (modelled a`la fib) */ unsigned int hash_size; unsigned int hash_order; @@ -45,16 +47,20 @@ struct top_graph { struct top_graph *ospf_top_new(pool *, struct proto_ospf *); void ospf_top_free(struct top_graph *); void ospf_top_dump(struct top_graph *, struct proto *); -struct top_hash_entry *ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h); -struct top_hash_entry *ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h); -struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 lsa, u32 rtr, u32 type); -struct top_hash_entry *ospf_hash_get(struct top_graph *, u32 lsa, u32 rtr, u32 type); +struct top_hash_entry *ospf_hash_find_header(struct top_graph *f, + struct ospf_lsa_header *h); +struct top_hash_entry *ospf_hash_get_header(struct top_graph *f, + struct ospf_lsa_header *h); +struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 lsa, u32 rtr, + u32 type); +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); void originate_rt_lsa(struct ospf_area *oa); void originate_net_lsa(struct ospf_iface *ifa); int can_flush_lsa(struct ospf_area *oa); int max_ext_lsa(unsigned pxlen); -void originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs); +void originate_ext_lsa(net * n, rte * e, struct proto_ospf *po, + struct ea_list *attrs); #endif /* _BIRD_OSPF_TOPOLOGY_H_ */ |