Cleanup in iface.c

This commit is contained in:
Ondrej Filip 2004-06-06 08:55:33 +00:00
parent a5918961f3
commit b9ed99f738
7 changed files with 665 additions and 655 deletions

View file

@ -9,10 +9,12 @@
#include "ospf.h" #include "ospf.h"
char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother", char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother",
"backup", "dr" }; "backup", "dr"
};
char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen", char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen",
"neighbor change", "loop indicated", "unloop indicated", "interface down"}; "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" };
@ -31,19 +33,16 @@ hello_timer_hook(timer *timer)
static void static void
wait_timer_hook(timer * timer) wait_timer_hook(timer * timer)
{ {
struct ospf_iface *ifa; struct ospf_iface *ifa = (struct ospf_iface *) timer->data;
struct proto *p; struct proto *p = (struct proto *) (ifa->proto);
ifa=(struct ospf_iface *)timer->data; OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", ifa->iface->name);
p=(struct proto *)(ifa->proto); ospf_iface_sm(ifa, ISM_WAITF);
OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.",
ifa->iface->name);
ospf_int_sm(ifa, ISM_WAITF);
} }
/** /**
* iface_chstate - handle changes of interface state * ospf_iface_chstate - handle changes of interface state
* @ifa: OSPF interface * @ifa: OSPF interface
* @state: new state * @state: new state
* *
@ -52,7 +51,7 @@ wait_timer_hook(timer *timer)
* %ALLDROUTERS have to be opened, etc. * %ALLDROUTERS have to be opened, etc.
*/ */
void 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_ospf *po = ifa->proto;
struct proto *p = &po->proto; struct proto *p = &po->proto;
@ -60,7 +59,8 @@ iface_chstate(struct ospf_iface *ifa, u8 state)
if (ifa->state != state) if (ifa->state != state)
{ {
OSPF_TRACE(D_EVENTS, "Changing state of iface: %s from \"%s\" into \"%s\".", OSPF_TRACE(D_EVENTS,
"Changing state of iface: %s from \"%s\" into \"%s\".",
ifa->iface->name, ospf_is[ifa->state], ospf_is[state]); ifa->iface->name, ospf_is[ifa->state], ospf_is[state]);
oldstate = ifa->state; oldstate = ifa->state;
ifa->state = state; ifa->state = state;
@ -104,15 +104,16 @@ iface_chstate(struct ospf_iface *ifa, u8 state)
{ {
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); if (can_flush_lsa(ifa->oa))
flush_lsa(ifa->nlsa, ifa->oa);
ifa->nlsa = NULL; ifa->nlsa = NULL;
} }
} }
} }
} }
void static void
downint(struct ospf_iface *ifa) ospf_iface_down(struct ospf_iface *ifa)
{ {
struct ospf_neighbor *n, *nx; struct ospf_neighbor *n, *nx;
struct proto *p = &ifa->proto->proto; struct proto *p = &ifa->proto->proto;
@ -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 * @ifa: OSPF interface
* @event: event comming to state machine * @event: event comming to state machine
* *
@ -145,12 +146,11 @@ downint(struct ospf_iface *ifa)
* interface. * interface.
*/ */
void 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\".", DBG("SM on iface %s. Event is \"%s\".",
ifa->iface->name, ospf_ism[event]); ifa->iface->name, ospf_ism[event]);
switch (event) switch (event)
@ -165,18 +165,14 @@ ospf_int_sm(struct ospf_iface *ifa, int event)
tm_start(ifa->poll_timer, ifa->pollint); tm_start(ifa->poll_timer, ifa->pollint);
if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_VLINK)) if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_VLINK))
{ ospf_iface_chstate(ifa, OSPF_IS_PTP);
iface_chstate(ifa, OSPF_IS_PTP);
}
else else
{ {
if (ifa->priority == 0) if (ifa->priority == 0)
{ ospf_iface_chstate(ifa, OSPF_IS_DROTHER);
iface_chstate(ifa, OSPF_IS_DROTHER);
}
else else
{ {
iface_chstate(ifa, OSPF_IS_WAITING); ospf_iface_chstate(ifa, OSPF_IS_WAITING);
tm_start(ifa->wait_timer, ifa->waitint); tm_start(ifa->wait_timer, ifa->waitint);
} }
} }
@ -199,27 +195,27 @@ ospf_int_sm(struct ospf_iface *ifa, int event)
} }
break; break;
case ISM_DOWN: case ISM_DOWN:
iface_chstate(ifa, OSPF_IS_DOWN); ospf_iface_chstate(ifa, OSPF_IS_DOWN);
downint(ifa); ospf_iface_down(ifa);
schedule_rt_lsa(oa); schedule_rt_lsa(oa);
break; break;
case ISM_LOOP: /* Useless? */ case ISM_LOOP: /* Useless? */
iface_chstate(ifa, OSPF_IS_LOOP); ospf_iface_chstate(ifa, OSPF_IS_LOOP);
downint(ifa); ospf_iface_down(ifa);
schedule_rt_lsa(ifa->oa); schedule_rt_lsa(ifa->oa);
break; break;
case ISM_UNLOOP: case ISM_UNLOOP:
iface_chstate(ifa, OSPF_IS_DOWN); ospf_iface_chstate(ifa, OSPF_IS_DOWN);
schedule_rt_lsa(ifa->oa); schedule_rt_lsa(ifa->oa);
break; break;
default: default:
bug("%s: ISM - Unknown event?",p->name); bug("OSPF_I_SM - Unknown event?");
break; break;
} }
} }
sock * static sock *
ospf_open_mc_socket(struct ospf_iface *ifa) ospf_open_mc_socket(struct ospf_iface *ifa)
{ {
sock *mcsk; sock *mcsk;
@ -251,7 +247,7 @@ ospf_open_mc_socket(struct ospf_iface *ifa)
return (mcsk); return (mcsk);
} }
sock * static sock *
ospf_open_ip_socket(struct ospf_iface * ifa) ospf_open_ip_socket(struct ospf_iface * ifa)
{ {
sock *ipsk; sock *ipsk;
@ -282,38 +278,67 @@ ospf_open_ip_socket(struct ospf_iface *ifa)
} }
u8 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 ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
(IF_MULTIACCESS | IF_MULTICAST)) (IF_MULTIACCESS | IF_MULTICAST))
{
DBG("%s: Clasifying BCAST.\n", p->name);
return OSPF_IT_BCAST; return OSPF_IT_BCAST;
}
if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))== if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) == IF_MULTIACCESS)
IF_MULTIACCESS)
{
DBG("%s: Clasifying NBMA.\n", p->name);
return OSPF_IT_NBMA; return OSPF_IT_NBMA;
}
DBG("%s: Clasifying P-T-P.\n", p->name);
return OSPF_IT_PTP; return OSPF_IT_PTP;
} }
struct ospf_iface * struct ospf_iface *
find_iface(struct proto_ospf *p, struct iface *what) ospf_iface_find(struct proto_ospf *p, struct iface *what)
{ {
struct ospf_iface *i; struct ospf_iface *i;
WALK_LIST (i, p->iface_list) WALK_LIST(i, p->iface_list) if ((i)->iface == what)
if ((i)->iface == what)
return i; return i;
return NULL; 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 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 proto_ospf *po = (struct proto_ospf *) p;
struct ospf_config *c = (struct ospf_config *) (p->cf); struct ospf_config *c = (struct ospf_config *) (p->cf);
@ -322,6 +347,7 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
struct ospf_iface *ifa; struct ospf_iface *ifa;
struct object_lock *lock; 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); DBG("%s: If notify called\n", p->name);
if (iface->flags & IF_IGNORE) if (iface->flags & IF_IGNORE)
@ -332,7 +358,8 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
WALK_LIST(ac, c->area_list) WALK_LIST(ac, c->area_list)
{ {
if (ip = (struct ospf_iface_patt *) if (ip = (struct ospf_iface_patt *)
iface_patt_match(&ac->patt_list, iface)) break; iface_patt_match(&ac->patt_list, iface))
break;
} }
if (ip) if (ip)
@ -359,8 +386,10 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
ifa->options = 2; /* FIXME what options? */ ifa->options = 2; /* FIXME what options? */
if (ip->type == OSPF_IT_UNDEF) if (ip->type == OSPF_IT_UNDEF)
ifa->type=ospf_iface_clasify(ifa->iface, (struct proto *)ifa->proto); ifa->type =
else ifa->type=ip->type; ospf_iface_clasify(ifa->iface);
else
ifa->type = ip->type;
init_list(&ifa->neigh_list); init_list(&ifa->neigh_list);
init_list(&ifa->nbma_list); init_list(&ifa->nbma_list);
@ -389,7 +418,8 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
ifa->poll_timer->recurrent = ifa->pollint; ifa->poll_timer->recurrent = ifa->pollint;
DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint); DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint);
} }
else ifa->poll_timer=NULL; else
ifa->poll_timer = NULL;
ifa->wait_timer = tm_new(p->pool); ifa->wait_timer = tm_new(p->pool);
ifa->wait_timer->data = ifa; ifa->wait_timer->data = ifa;
@ -406,24 +436,35 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
lock->port = OSPF_PROTO; lock->port = OSPF_PROTO;
lock->iface = iface; lock->iface = iface;
lock->data = ifa; lock->data = ifa;
lock->hook = ospf_ifa_add; lock->hook = ospf_iface_add;
addifa_rtlsa(ifa);
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); 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_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_packet *op;
struct ospf_neighbor *n; struct ospf_neighbor *n;
@ -466,7 +507,8 @@ ospf_iface_info(struct ospf_iface *ifa)
{ {
char *strict = "(strict)"; char *strict = "(strict)";
if((ifa->type!=OSPF_IT_NBMA)||(ifa->strictnbma==0)) strict=""; if ((ifa->type != OSPF_IT_NBMA) || (ifa->strictnbma == 0))
strict = "";
cli_msg(-1015, "Interface \"%s\":", ifa->iface->name); cli_msg(-1015, "Interface \"%s\":", ifa->iface->name);
cli_msg(-1015, "\tArea: %I (%u)", ifa->oa->areaid, ifa->oa->areaid); 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, "\tType: %s %s", ospf_it[ifa->type], strict);
@ -491,53 +533,9 @@ ospf_iface_info(struct ospf_iface *ifa)
} }
} }
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)
{
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_int_sm(ifa, ISM_UP);
}
void
schedule_net_lsa(struct ospf_iface *ifa)
{
ifa->orignet=1;
}
void void
ospf_iface_shutdown(struct ospf_iface *ifa) ospf_iface_shutdown(struct ospf_iface *ifa)
{ {
init_list(&ifa->neigh_list); init_list(&ifa->neigh_list);
hello_timer_hook(ifa->hello_timer); hello_timer_hook(ifa->hello_timer);
} }

View file

@ -1,7 +1,7 @@
/* /*
* BIRD -- OSPF * 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. * Can be freely distributed and used under the terms of the GNU GPL.
* *
@ -10,20 +10,11 @@
#ifndef _BIRD_OSPF_IFACE_H_ #ifndef _BIRD_OSPF_IFACE_H_
#define _BIRD_OSPF_IFACE_H_ #define _BIRD_OSPF_IFACE_H_
void iface_chstate(struct ospf_iface *ifa, u8 state); void ospf_iface_chstate(struct ospf_iface *ifa, u8 state);
void downint(struct ospf_iface *ifa); void ospf_iface_sm(struct ospf_iface *ifa, int event);
void ospf_int_sm(struct ospf_iface *ifa, int event); struct ospf_iface *ospf_iface_find(struct proto_ospf *p, struct iface *what);
sock *ospf_open_mc_socket(struct ospf_iface *ifa); void ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface);
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_info(struct ospf_iface *ifa); void ospf_iface_info(struct ospf_iface *ifa);
void ospf_iface_shutdown(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_ */ #endif /* _BIRD_OSPF_IFACE_H_ */

View file

@ -103,9 +103,9 @@ neigh_chstate(struct ospf_neighbor *n, u8 state)
n->ip, ospf_ns[oldstate], ospf_ns[state]); n->ip, ospf_ns[oldstate], ospf_ns[state]);
if((state==NEIGHBOR_2WAY) && (oldstate<NEIGHBOR_2WAY)) 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)) 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 */ 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); 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 else
{ {
if(myid==ifa->bdrid) iface_chstate(ifa, OSPF_IS_BACKUP); if(myid==ifa->bdrid) ospf_iface_chstate(ifa, OSPF_IS_BACKUP);
else iface_chstate(ifa, OSPF_IS_DROTHER); else ospf_iface_chstate(ifa, OSPF_IS_DROTHER);
} }
rem_node(NODE &me); rem_node(NODE &me);

View file

@ -109,7 +109,7 @@ ospf_start(struct proto *p)
oa->disp_timer->randomize=0; oa->disp_timer->randomize=0;
oa->disp_timer->hook=area_disp; oa->disp_timer->hook=area_disp;
oa->disp_timer->recurrent=oa->tick; oa->disp_timer->recurrent=oa->tick;
tm_start(oa->disp_timer,oa->tick); tm_start(oa->disp_timer, 1);
oa->calcrt=0; oa->calcrt=0;
oa->origrt=0; oa->origrt=0;
init_list(&oa->net_list); init_list(&oa->net_list);
@ -168,7 +168,7 @@ ospf_init(struct proto_config *c)
p->make_tmp_attrs = ospf_make_tmp_attrs; p->make_tmp_attrs = ospf_make_tmp_attrs;
p->store_tmp_attrs = ospf_store_tmp_attrs; p->store_tmp_attrs = ospf_store_tmp_attrs;
p->rt_notify = ospf_rt_notify; 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_better = ospf_rte_better;
p->rte_same = ospf_rte_same; p->rte_same = ospf_rte_same;
@ -244,6 +244,12 @@ ospf_build_attrs(ea_list *next, struct linpool *pool, u32 m1, u32 m2, u32 tag)
return l; return l;
} }
void
schedule_net_lsa(struct ospf_iface *ifa)
{
ifa->orignet = 1;
}
void void
schedule_rt_lsa(struct ospf_area *oa) schedule_rt_lsa(struct ospf_area *oa)
{ {

View file

@ -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 area_disp(timer *timer);
void schedule_rt_lsa(struct ospf_area *oa); void schedule_rt_lsa(struct ospf_area *oa);
void schedule_rtcalc(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_neigh(struct proto *p, char *iff);
void ospf_sh(struct proto *p); void ospf_sh(struct proto *p);
void ospf_sh_iface(struct proto *p, char *iff); void ospf_sh_iface(struct proto *p, char *iff);

View file

@ -21,8 +21,9 @@
#define HASH_LO_MIN 8 #define HASH_LO_MIN 8
static void * 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; struct ospf_iface *ifa;
int j = 0, k = 0, v = 0; int j = 0, k = 0, v = 0;
u16 i = 0; u16 i = 0;
@ -33,24 +34,28 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
DBG("%s: Originating RT_lsa body for area \"%I\".\n", po->proto.name, 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++; 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)+ rt = mb_allocz(po->proto.pool, sizeof(struct ospf_lsa_rt) +
i * sizeof(struct ospf_lsa_rt_link)); i * sizeof(struct ospf_lsa_rt_link));
if(p->areano>1) rt->veb.bit.b=1; if (po->areano > 1)
if((p->ebit)&&(!oa->stub)) rt->veb.bit.e=1; rt->veb.bit.b = 1;
if ((po->ebit) && (!oa->stub))
rt->veb.bit.e = 1;
rt->veb.bit.v = v; rt->veb.bit.v = v;
ln = (struct ospf_lsa_rt_link *) (rt + 1); ln = (struct ospf_lsa_rt_link *) (rt + 1);
WALK_LIST (ifa, p->iface_list) 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)
{ {
@ -112,9 +117,10 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
j = 0, k = 0; j = 0, k = 0;
WALK_LIST(neigh, ifa->neigh_list) WALK_LIST(neigh, ifa->neigh_list)
{ {
if((neigh->rid==ifa->drid) && if ((neigh->rid == ifa->drid) && (neigh->state == NEIGHBOR_FULL))
(neigh->state==NEIGHBOR_FULL)) k=1; k = 1;
if(neigh->state==NEIGHBOR_FULL) j=1; if (neigh->state == NEIGHBOR_FULL)
j = 1;
} }
if (((ifa->state == OSPF_IS_DR) && (j == 1)) || (k == 1)) if (((ifa->state == OSPF_IS_DR) && (j == 1)) || (k == 1))
{ {
@ -139,7 +145,8 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
break; break;
} }
} }
if(ifa->type==OSPF_IT_VLINK) v=1; if (ifa->type == OSPF_IT_VLINK)
v = 1;
ln = (ln + 1); ln = (ln + 1);
} }
rt->links = i; rt->links = i;
@ -148,24 +155,6 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length, struct proto_ospf *p)
return rt; 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 * originate_rt_lsa - build new instance of router LSA
* @oa: ospf_area which is LSA built to * @oa: ospf_area which is LSA built to
@ -185,7 +174,8 @@ originate_rt_lsa(struct ospf_area *oa)
struct top_hash_entry *en; struct top_hash_entry *en;
void *body; void *body;
if((oa->rt)&&((oa->rt->inst_t+MINLSINTERVAL))>now) return; if ((oa->rt) && ((oa->rt->inst_t + MINLSINTERVAL)) > now)
return;
/* /*
* Tick is probably set to very low value. We cannot * Tick is probably set to very low value. We cannot
* originate new LSA before MINLSINTERVAL. We will * originate new LSA before MINLSINTERVAL. We will
@ -207,7 +197,7 @@ originate_rt_lsa(struct ospf_area *oa)
{ {
lsa.sn = oa->rt->lsa.sn + 1; lsa.sn = oa->rt->lsa.sn + 1;
} }
body=originate_rt_lsa_body(oa, &lsa.length, po); body = originate_rt_lsa_body(oa, &lsa.length);
lsasum_calculate(&lsa, body, po); lsasum_calculate(&lsa, body, po);
en = lsa_install_new(&lsa, body, oa); en = lsa_install_new(&lsa, body, oa);
oa->rt = en; oa->rt = en;
@ -263,7 +253,8 @@ originate_net_lsa(struct ospf_iface *ifa)
struct proto *p = &po->proto; struct proto *p = &po->proto;
void *body; 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 * It's too early to originate new network LSA. We will
* try to do it next tick * try to do it next tick
@ -271,7 +262,8 @@ originate_net_lsa(struct ospf_iface *ifa)
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\".", OSPF_TRACE(D_EVENTS, "Deleting Net lsa for iface \"%s\".",
ifa->iface->name); ifa->iface->name);
@ -279,7 +271,8 @@ originate_net_lsa(struct ospf_iface *ifa)
ifa->nlsa->lsa.age = LSA_MAXAGE; ifa->nlsa->lsa.age = LSA_MAXAGE;
ospf_lsupd_flood(NULL, NULL, &ifa->nlsa->lsa, NULL, ifa->oa, 0); ospf_lsupd_flood(NULL, NULL, &ifa->nlsa->lsa, NULL, ifa->oa, 0);
s_rem_node(SNODE ifa->nlsa); s_rem_node(SNODE ifa->nlsa);
if(ifa->nlsa->lsa_body!=NULL) mb_free(ifa->nlsa->lsa_body); if (ifa->nlsa->lsa_body != NULL)
mb_free(ifa->nlsa->lsa_body);
ifa->nlsa->lsa_body = NULL; ifa->nlsa->lsa_body = NULL;
ospf_hash_delete(ifa->oa->gr, ifa->nlsa); ospf_hash_delete(ifa->oa->gr, ifa->nlsa);
schedule_rtcalc(ifa->oa); schedule_rtcalc(ifa->oa);
@ -312,7 +305,8 @@ originate_net_lsa(struct ospf_iface *ifa)
} }
static void * 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 *ext;
@ -342,11 +336,14 @@ originate_ext_lsa_body(net *n, rte *e, struct proto_ospf *po, struct ea_list *at
et->tag = tag; et->tag = tag;
if (ipa_compare(e->attrs->gw, ipa_from_u32(0)) != 0) 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); if (!inas)
else et->fwaddr=e->attrs->gw; et->fwaddr = ipa_from_u32(0);
else
et->fwaddr = e->attrs->gw;
return ext; return ext;
} }
@ -389,7 +386,8 @@ max_ext_lsa(unsigned pxlen)
* origination is necessary. * origination is necessary.
*/ */
void 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; struct ospf_lsa_header lsa;
u32 rtid = po->proto.cf->global->router_id; u32 rtid = po->proto.cf->global->router_id;
@ -422,10 +420,13 @@ originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs)
if ((en = ospf_hash_find_header(oa->gr, &lsa)) != NULL) if ((en = ospf_hash_find_header(oa->gr, &lsa)) != NULL)
{ {
ext2 = en->lsa_body; ext2 = en->lsa_body;
if(ipa_compare(ext1->netmask,ext2->netmask)!=0) lsa.id++; if (ipa_compare(ext1->netmask, ext2->netmask) != 0)
else break; lsa.id++;
else
break;
} }
else break; else
break;
} }
if (i == max) if (i == max)
@ -470,7 +471,8 @@ ospf_top_ht_alloc(struct top_graph *f)
f->hash_entries_min = f->hash_size HASH_LO_MARK; 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", 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_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 *)); bzero(f->hash_table, f->hash_size * sizeof(struct top_hash_entry *));
} }
@ -493,9 +495,13 @@ static inline unsigned
ospf_top_hash(struct top_graph *f, u32 lsaid, u32 rtrid, u32 type) ospf_top_hash(struct top_graph *f, u32 lsaid, u32 rtrid, u32 type)
{ {
#if 1 /* Dirty patch to make rt table calculation work. */ #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; return (ospf_top_hash_u32(lsaid) +
ospf_top_hash_u32((type ==
LSA_T_NET) ? lsaid : rtrid) +
type) & f->hash_mask;
#else #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 #endif
} }
@ -537,7 +543,8 @@ ospf_top_rehash(struct top_graph *f, int step)
oldn = f->hash_size; oldn = f->hash_size;
oldt = f->hash_table; 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; f->hash_order += step;
ospf_top_ht_alloc(f); ospf_top_ht_alloc(f);
newt = f->hash_table; newt = f->hash_table;
@ -595,7 +602,8 @@ ospf_hash_find(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
struct top_hash_entry * struct top_hash_entry *
ospf_hash_get(struct top_graph *f, u32 lsa, u32 rtr, u32 type) 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; struct top_hash_entry *e = *ee;
while (e && (e->lsa.id != lsa || e->lsa.rt != rtr || e->lsa.type != type)) while (e && (e->lsa.id != lsa || e->lsa.rt != rtr || e->lsa.type != type))
@ -648,8 +656,7 @@ ospf_top_dump(struct top_graph *f, struct proto *p)
while (e) while (e)
{ {
OSPF_TRACE(D_EVENTS, "\t%1x %-1I %-1I %4u 0x%08x", OSPF_TRACE(D_EVENTS, "\t%1x %-1I %-1I %4u 0x%08x",
e->lsa.type, e->lsa.id, e->lsa.type, e->lsa.id, e->lsa.rt, e->lsa.age, e->lsa.sn);
e->lsa.rt, e->lsa.age, e->lsa.sn);
e = e->next; e = e->next;
} }
} }
@ -679,6 +686,7 @@ can_flush_lsa(struct ospf_area *oa)
return 0; return 0;
} }
} }
break;
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
* BIRD -- OSPF * 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. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
@ -9,7 +9,8 @@
#ifndef _BIRD_OSPF_TOPOLOGY_H_ #ifndef _BIRD_OSPF_TOPOLOGY_H_
#define _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; snode n;
node cn; /* For adding into list of candidates node cn; /* For adding into list of candidates
* in intra-area routing table * in intra-area routing table
@ -31,7 +32,8 @@ struct top_hash_entry { /* Index for fast mapping (type,rtrid,LSid)->vertex */
u16 padding2; u16 padding2;
}; };
struct top_graph { struct top_graph
{
pool *pool; /* Pool we allocate from */ pool *pool; /* Pool we allocate from */
slab *hash_slab; /* Slab for hash entries */ slab *hash_slab; /* Slab for hash entries */
struct top_hash_entry **hash_table; /* Hashing (modelled a`la fib) */ struct top_hash_entry **hash_table; /* Hashing (modelled a`la fib) */
@ -45,16 +47,20 @@ struct top_graph {
struct top_graph *ospf_top_new(pool *, struct proto_ospf *); struct top_graph *ospf_top_new(pool *, struct proto_ospf *);
void ospf_top_free(struct top_graph *); void ospf_top_free(struct top_graph *);
void ospf_top_dump(struct top_graph *, struct proto *); 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_find_header(struct top_graph *f,
struct top_hash_entry *ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h); 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_header(struct top_graph *f,
struct top_hash_entry *ospf_hash_get(struct top_graph *, u32 lsa, u32 rtr, u32 type); 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 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_rt_lsa(struct ospf_area *oa);
void originate_net_lsa(struct ospf_iface *ifa); void originate_net_lsa(struct ospf_iface *ifa);
int can_flush_lsa(struct ospf_area *oa); int can_flush_lsa(struct ospf_area *oa);
int max_ext_lsa(unsigned pxlen); 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_ */ #endif /* _BIRD_OSPF_TOPOLOGY_H_ */