mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-17 16:48:43 +00:00
Cleanup in iface.c
This commit is contained in:
parent
a5918961f3
commit
b9ed99f738
@ -8,42 +8,41 @@
|
|||||||
|
|
||||||
#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" };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
poll_timer_hook(timer *timer)
|
poll_timer_hook(timer * timer)
|
||||||
{
|
{
|
||||||
ospf_hello_send(timer, 1, NULL);
|
ospf_hello_send(timer, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hello_timer_hook(timer *timer)
|
hello_timer_hook(timer * timer)
|
||||||
{
|
{
|
||||||
ospf_hello_send(timer, 0, NULL);
|
ospf_hello_send(timer, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
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,72 +51,74 @@ 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;
|
||||||
u8 oldstate;
|
u8 oldstate;
|
||||||
|
|
||||||
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,
|
||||||
ifa->iface->name, ospf_is[ifa->state], ospf_is[state]);
|
"Changing state of iface: %s from \"%s\" into \"%s\".",
|
||||||
oldstate=ifa->state;
|
ifa->iface->name, ospf_is[ifa->state], ospf_is[state]);
|
||||||
ifa->state=state;
|
oldstate = ifa->state;
|
||||||
if(ifa->iface->flags & IF_MULTICAST)
|
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))
|
if ((ifa->dr_sk == NULL) && (ifa->type != OSPF_IT_NBMA))
|
||||||
{
|
{
|
||||||
DBG("%s: Adding new multicast socket for (B)DR\n", p->name);
|
DBG("%s: Adding new multicast socket for (B)DR\n", p->name);
|
||||||
ifa->dr_sk=sk_new(p->pool);
|
ifa->dr_sk = sk_new(p->pool);
|
||||||
ifa->dr_sk->type=SK_IP_MC;
|
ifa->dr_sk->type = SK_IP_MC;
|
||||||
ifa->dr_sk->sport=0;
|
ifa->dr_sk->sport = 0;
|
||||||
ifa->dr_sk->dport=OSPF_PROTO;
|
ifa->dr_sk->dport = OSPF_PROTO;
|
||||||
ifa->dr_sk->saddr=AllDRouters;
|
ifa->dr_sk->saddr = AllDRouters;
|
||||||
ifa->dr_sk->daddr=AllDRouters;
|
ifa->dr_sk->daddr = AllDRouters;
|
||||||
ifa->dr_sk->tos=IP_PREC_INTERNET_CONTROL;
|
ifa->dr_sk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
ifa->dr_sk->ttl=1;
|
ifa->dr_sk->ttl = 1;
|
||||||
ifa->dr_sk->rx_hook=ospf_rx_hook;
|
ifa->dr_sk->rx_hook = ospf_rx_hook;
|
||||||
ifa->dr_sk->tx_hook=ospf_tx_hook;
|
ifa->dr_sk->tx_hook = ospf_tx_hook;
|
||||||
ifa->dr_sk->err_hook=ospf_err_hook;
|
ifa->dr_sk->err_hook = ospf_err_hook;
|
||||||
ifa->dr_sk->iface=ifa->iface;
|
ifa->dr_sk->iface = ifa->iface;
|
||||||
ifa->dr_sk->rbsize=ifa->iface->mtu;
|
ifa->dr_sk->rbsize = ifa->iface->mtu;
|
||||||
ifa->dr_sk->tbsize=ifa->iface->mtu;
|
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
||||||
ifa->dr_sk->data=(void *)ifa;
|
ifa->dr_sk->data = (void *) ifa;
|
||||||
if(sk_open(ifa->dr_sk)!=0)
|
if (sk_open(ifa->dr_sk) != 0)
|
||||||
{
|
{
|
||||||
DBG("%s: SK_OPEN: new? mc open failed.\n", p->name);
|
DBG("%s: SK_OPEN: new? mc open failed.\n", p->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rfree(ifa->dr_sk);
|
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;
|
ifa->nlsa->lsa.age = LSA_MAXAGE;
|
||||||
if(state>=OSPF_IS_WAITING)
|
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);
|
if (can_flush_lsa(ifa->oa))
|
||||||
ifa->nlsa=NULL;
|
flush_lsa(ifa->nlsa, ifa->oa);
|
||||||
|
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;
|
||||||
|
|
||||||
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_TRACE(D_EVENTS, "Removing neighbor %I", n->ip);
|
||||||
ospf_neigh_remove(n);
|
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
|
* @ifa: OSPF interface
|
||||||
* @event: event comming to state machine
|
* @event: event comming to state machine
|
||||||
*
|
*
|
||||||
@ -145,317 +146,357 @@ 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)
|
||||||
{
|
{
|
||||||
case ISM_UP:
|
case ISM_UP:
|
||||||
if(ifa->state==OSPF_IS_DOWN)
|
if (ifa->state == OSPF_IS_DOWN)
|
||||||
{
|
{
|
||||||
/* Now, nothing should be adjacent */
|
/* Now, nothing should be adjacent */
|
||||||
tm_start(ifa->hello_timer,ifa->helloint);
|
tm_start(ifa->hello_timer, ifa->helloint);
|
||||||
|
|
||||||
if(ifa->poll_timer)
|
if (ifa->poll_timer)
|
||||||
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)
|
|
||||||
{
|
|
||||||
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);
|
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_NEICH:
|
schedule_rt_lsa(ifa->oa);
|
||||||
if((ifa->state==OSPF_IS_DROTHER) || (ifa->state==OSPF_IS_DR) ||
|
break;
|
||||||
(ifa->state==OSPF_IS_BACKUP))
|
case ISM_BACKS:
|
||||||
{
|
case ISM_WAITF:
|
||||||
bdr_election(ifa);
|
if (ifa->state == OSPF_IS_WAITING)
|
||||||
schedule_rt_lsa(ifa->oa);
|
{
|
||||||
}
|
bdr_election(ifa);
|
||||||
break;
|
}
|
||||||
case ISM_DOWN:
|
break;
|
||||||
iface_chstate(ifa, OSPF_IS_DOWN);
|
case ISM_NEICH:
|
||||||
downint(ifa);
|
if ((ifa->state == OSPF_IS_DROTHER) || (ifa->state == OSPF_IS_DR) ||
|
||||||
schedule_rt_lsa(oa);
|
(ifa->state == OSPF_IS_BACKUP))
|
||||||
break;
|
{
|
||||||
case ISM_LOOP: /* Useless? */
|
bdr_election(ifa);
|
||||||
iface_chstate(ifa, OSPF_IS_LOOP);
|
|
||||||
downint(ifa);
|
|
||||||
schedule_rt_lsa(ifa->oa);
|
schedule_rt_lsa(ifa->oa);
|
||||||
break;
|
}
|
||||||
case ISM_UNLOOP:
|
break;
|
||||||
iface_chstate(ifa, OSPF_IS_DOWN);
|
case ISM_DOWN:
|
||||||
schedule_rt_lsa(ifa->oa);
|
ospf_iface_chstate(ifa, OSPF_IS_DOWN);
|
||||||
break;
|
ospf_iface_down(ifa);
|
||||||
default:
|
schedule_rt_lsa(oa);
|
||||||
bug("%s: ISM - Unknown event?",p->name);
|
break;
|
||||||
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)
|
ospf_open_mc_socket(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
sock *mcsk;
|
sock *mcsk;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
|
||||||
p=(struct proto *)(ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
|
|
||||||
mcsk=sk_new(p->pool);
|
mcsk = sk_new(p->pool);
|
||||||
mcsk->type=SK_IP_MC;
|
mcsk->type = SK_IP_MC;
|
||||||
mcsk->sport=0;
|
mcsk->sport = 0;
|
||||||
mcsk->dport=OSPF_PROTO;
|
mcsk->dport = OSPF_PROTO;
|
||||||
mcsk->saddr=AllSPFRouters;
|
mcsk->saddr = AllSPFRouters;
|
||||||
mcsk->daddr=AllSPFRouters;
|
mcsk->daddr = AllSPFRouters;
|
||||||
mcsk->tos=IP_PREC_INTERNET_CONTROL;
|
mcsk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
mcsk->ttl=1;
|
mcsk->ttl = 1;
|
||||||
mcsk->rx_hook=ospf_rx_hook;
|
mcsk->rx_hook = ospf_rx_hook;
|
||||||
mcsk->tx_hook=ospf_tx_hook;
|
mcsk->tx_hook = ospf_tx_hook;
|
||||||
mcsk->err_hook=ospf_err_hook;
|
mcsk->err_hook = ospf_err_hook;
|
||||||
mcsk->iface=ifa->iface;
|
mcsk->iface = ifa->iface;
|
||||||
mcsk->rbsize=ifa->iface->mtu;
|
mcsk->rbsize = ifa->iface->mtu;
|
||||||
mcsk->tbsize=ifa->iface->mtu;
|
mcsk->tbsize = ifa->iface->mtu;
|
||||||
mcsk->data=(void *)ifa;
|
mcsk->data = (void *) ifa;
|
||||||
if(sk_open(mcsk)!=0)
|
if (sk_open(mcsk) != 0)
|
||||||
{
|
{
|
||||||
DBG("%s: SK_OPEN: mc open failed.\n",p->name);
|
DBG("%s: SK_OPEN: mc open failed.\n", p->name);
|
||||||
return(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
DBG("%s: SK_OPEN: mc opened.\n",p->name);
|
DBG("%s: SK_OPEN: mc opened.\n", p->name);
|
||||||
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;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
|
||||||
p=(struct proto *)(ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
|
|
||||||
ipsk=sk_new(p->pool);
|
ipsk = sk_new(p->pool);
|
||||||
ipsk->type=SK_IP;
|
ipsk->type = SK_IP;
|
||||||
ipsk->dport=OSPF_PROTO;
|
ipsk->dport = OSPF_PROTO;
|
||||||
ipsk->saddr=ifa->iface->addr->ip;
|
ipsk->saddr = ifa->iface->addr->ip;
|
||||||
ipsk->tos=IP_PREC_INTERNET_CONTROL;
|
ipsk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
ipsk->ttl=1;
|
ipsk->ttl = 1;
|
||||||
ipsk->rx_hook=ospf_rx_hook;
|
ipsk->rx_hook = ospf_rx_hook;
|
||||||
ipsk->tx_hook=ospf_tx_hook;
|
ipsk->tx_hook = ospf_tx_hook;
|
||||||
ipsk->err_hook=ospf_err_hook;
|
ipsk->err_hook = ospf_err_hook;
|
||||||
ipsk->iface=ifa->iface;
|
ipsk->iface = ifa->iface;
|
||||||
ipsk->rbsize=ifa->iface->mtu;
|
ipsk->rbsize = ifa->iface->mtu;
|
||||||
ipsk->tbsize=ifa->iface->mtu;
|
ipsk->tbsize = ifa->iface->mtu;
|
||||||
ipsk->data=(void *)ifa;
|
ipsk->data = (void *) ifa;
|
||||||
if(sk_open(ipsk)!=0)
|
if (sk_open(ipsk) != 0)
|
||||||
{
|
{
|
||||||
DBG("%s: SK_OPEN: ip open failed.\n",p->name);
|
DBG("%s: SK_OPEN: ip open failed.\n", p->name);
|
||||||
return(NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
DBG("%s: SK_OPEN: ip opened.\n",p->name);
|
DBG("%s: SK_OPEN: ip opened.\n", p->name);
|
||||||
return(ipsk);
|
return (ipsk);
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
return OSPF_IT_BCAST;
|
||||||
{
|
|
||||||
DBG("%s: Clasifying BCAST.\n", p->name);
|
if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) == IF_MULTIACCESS)
|
||||||
return OSPF_IT_BCAST;
|
|
||||||
}
|
|
||||||
if((ifa->flags & (IF_MULTIACCESS|IF_MULTICAST))==
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
|
ospf_iface_add(struct object_lock *lock)
|
||||||
{
|
{
|
||||||
struct proto_ospf *po=(struct proto_ospf *)p;
|
struct ospf_iface *ifa = lock->data;
|
||||||
struct ospf_config *c=(struct ospf_config *)(p->cf);
|
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_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 ospf_area_config *ac;
|
struct ospf_area_config *ac;
|
||||||
struct ospf_iface_patt *ip=NULL;
|
struct ospf_iface_patt *ip = NULL;
|
||||||
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)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(flags & IF_CHANGE_UP)
|
if (flags & IF_CHANGE_UP)
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_EVENTS, "Using interface %s.", iface->name);
|
OSPF_TRACE(D_EVENTS, "Using interface %s.", iface->name);
|
||||||
|
|
||||||
ifa=mb_allocz(p->pool, sizeof(struct ospf_iface));
|
ifa = mb_allocz(p->pool, sizeof(struct ospf_iface));
|
||||||
ifa->proto=po;
|
ifa->proto = po;
|
||||||
ifa->iface=iface;
|
ifa->iface = iface;
|
||||||
|
|
||||||
ifa->an=ac->areaid;
|
ifa->an = ac->areaid;
|
||||||
ifa->cost=ip->cost;
|
ifa->cost = ip->cost;
|
||||||
ifa->rxmtint=ip->rxmtint;
|
ifa->rxmtint = ip->rxmtint;
|
||||||
ifa->inftransdelay=ip->inftransdelay;
|
ifa->inftransdelay = ip->inftransdelay;
|
||||||
ifa->priority=ip->priority;
|
ifa->priority = ip->priority;
|
||||||
ifa->helloint=ip->helloint;
|
ifa->helloint = ip->helloint;
|
||||||
ifa->pollint=ip->pollint;
|
ifa->pollint = ip->pollint;
|
||||||
ifa->strictnbma=ip->strictnbma;
|
ifa->strictnbma = ip->strictnbma;
|
||||||
ifa->waitint=ip->waitint;
|
ifa->waitint = ip->waitint;
|
||||||
ifa->deadc=ip->deadc;
|
ifa->deadc = ip->deadc;
|
||||||
ifa->stub=ip->stub;
|
ifa->stub = ip->stub;
|
||||||
ifa->autype=ip->autype;
|
ifa->autype = ip->autype;
|
||||||
memcpy(ifa->aukey,ip->password,8);
|
memcpy(ifa->aukey, ip->password, 8);
|
||||||
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);
|
||||||
WALK_LIST(nb,ip->nbma_list)
|
WALK_LIST(nb, ip->nbma_list)
|
||||||
{
|
{
|
||||||
nbma=mb_alloc(p->pool,sizeof(struct nbma_node));
|
nbma = mb_alloc(p->pool, sizeof(struct nbma_node));
|
||||||
nbma->ip=nb->ip;
|
nbma->ip = nb->ip;
|
||||||
nbma->eligible=nb->eligible;
|
nbma->eligible = nb->eligible;
|
||||||
add_tail(&ifa->nbma_list, NODE nbma);
|
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;
|
|
||||||
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
lock = olock_new( p->pool );
|
/* 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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
lock = olock_new(p->pool);
|
||||||
lock->addr = AllSPFRouters;
|
lock->addr = AllSPFRouters;
|
||||||
lock->type = OBJLOCK_IP;
|
lock->type = OBJLOCK_IP;
|
||||||
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;
|
||||||
OSPF_TRACE(D_EVENTS, "Changing MTU on interface %s.", iface->name);
|
OSPF_TRACE(D_EVENTS, "Changing MTU on interface %s.", iface->name);
|
||||||
if (ifa->hello_sk)
|
if (ifa->hello_sk)
|
||||||
{
|
{
|
||||||
ifa->hello_sk->rbsize = ifa->iface->mtu;
|
ifa->hello_sk->rbsize = ifa->iface->mtu;
|
||||||
ifa->hello_sk->tbsize = ifa->iface->mtu;
|
ifa->hello_sk->tbsize = ifa->iface->mtu;
|
||||||
sk_reallocate(ifa->hello_sk);
|
sk_reallocate(ifa->hello_sk);
|
||||||
}
|
}
|
||||||
if (ifa->dr_sk)
|
if (ifa->dr_sk)
|
||||||
{
|
{
|
||||||
ifa->dr_sk->rbsize = ifa->iface->mtu;
|
ifa->dr_sk->rbsize = ifa->iface->mtu;
|
||||||
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
ifa->dr_sk->tbsize = ifa->iface->mtu;
|
||||||
sk_reallocate(ifa->dr_sk);
|
sk_reallocate(ifa->dr_sk);
|
||||||
}
|
}
|
||||||
if (ifa->ip_sk)
|
if (ifa->ip_sk)
|
||||||
{
|
{
|
||||||
ifa->ip_sk->rbsize = ifa->iface->mtu;
|
ifa->ip_sk->rbsize = ifa->iface->mtu;
|
||||||
ifa->ip_sk->tbsize = ifa->iface->mtu;
|
ifa->ip_sk->tbsize = ifa->iface->mtu;
|
||||||
sk_reallocate(ifa->ip_sk);
|
sk_reallocate(ifa->ip_sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
WALK_LIST(n,ifa->neigh_list)
|
WALK_LIST(n, ifa->neigh_list)
|
||||||
{
|
{
|
||||||
op = (struct ospf_packet *)n->ldbdes;
|
op = (struct ospf_packet *) n->ldbdes;
|
||||||
n->ldbdes = mb_allocz(n->pool, iface->mtu);
|
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 */
|
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 */
|
memcpy(n->ldbdes, op, iface->mtu); /* If the packet is old is same or smaller, copy it */
|
||||||
|
|
||||||
rfree(op);
|
rfree(op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,80 +505,37 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
|
|||||||
void
|
void
|
||||||
ospf_iface_info(struct ospf_iface *ifa)
|
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))
|
||||||
cli_msg(-1015,"Interface \"%s\":", ifa->iface->name);
|
strict = "";
|
||||||
cli_msg(-1015,"\tArea: %I (%u)", ifa->oa->areaid, ifa->oa->areaid);
|
cli_msg(-1015, "Interface \"%s\":", ifa->iface->name);
|
||||||
cli_msg(-1015,"\tType: %s %s", ospf_it[ifa->type], strict);
|
cli_msg(-1015, "\tArea: %I (%u)", ifa->oa->areaid, ifa->oa->areaid);
|
||||||
cli_msg(-1015,"\tState: %s %s", ospf_is[ifa->state],
|
cli_msg(-1015, "\tType: %s %s", ospf_it[ifa->type], strict);
|
||||||
ifa->stub ? "(stub)" : "");
|
cli_msg(-1015, "\tState: %s %s", ospf_is[ifa->state],
|
||||||
cli_msg(-1015,"\tPriority: %u", ifa->priority);
|
ifa->stub ? "(stub)" : "");
|
||||||
cli_msg(-1015,"\tCost: %u", ifa->cost);
|
cli_msg(-1015, "\tPriority: %u", ifa->priority);
|
||||||
cli_msg(-1015,"\tHello timer: %u", ifa->helloint);
|
cli_msg(-1015, "\tCost: %u", ifa->cost);
|
||||||
if(ifa->type==OSPF_IT_NBMA)
|
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, "\tPoll timer: %u", ifa->pollint);
|
||||||
}
|
}
|
||||||
cli_msg(-1015,"\tWait timer: %u", ifa->waitint);
|
cli_msg(-1015, "\tWait timer: %u", ifa->waitint);
|
||||||
cli_msg(-1015,"\tDead timer: %u", ifa->deadc*ifa->helloint);
|
cli_msg(-1015, "\tDead timer: %u", ifa->deadc * ifa->helloint);
|
||||||
cli_msg(-1015,"\tRetransmit timer: %u", ifa->rxmtint);
|
cli_msg(-1015, "\tRetransmit timer: %u", ifa->rxmtint);
|
||||||
if((ifa->type==OSPF_IT_BCAST)||(ifa->type==OSPF_IT_NBMA))
|
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 (ID): %I", ifa->drid);
|
||||||
cli_msg(-1015,"\tDesigned router (IP): %I", ifa->drip);
|
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 (ID): %I", ifa->bdrid);
|
||||||
cli_msg(-1015,"\tBackup designed router (IP): %I", ifa->bdrip);
|
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)
|
|
||||||
{
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -21,151 +21,140 @@
|
|||||||
#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;
|
||||||
struct ospf_lsa_rt *rt;
|
struct ospf_lsa_rt *rt;
|
||||||
struct ospf_lsa_rt_link *ln;
|
struct ospf_lsa_rt_link *ln;
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
|
|
||||||
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;
|
||||||
rt->veb.bit.v=v;
|
if ((po->ebit) && (!oa->stub))
|
||||||
ln=(struct ospf_lsa_rt_link *)(rt+1);
|
rt->veb.bit.e = 1;
|
||||||
|
rt->veb.bit.v = v;
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
ln->type=3;
|
ln->type = 3;
|
||||||
ln->id=ipa_to_u32(ifa->iface->addr->ip);
|
ln->id = ipa_to_u32(ifa->iface->addr->ip);
|
||||||
ln->data=0xffffffff;
|
ln->data = 0xffffffff;
|
||||||
ln->metric=0;
|
ln->metric = 0;
|
||||||
ln->notos=0;
|
ln->notos = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch(ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
case OSPF_IT_PTP: /* rfc2328 - pg126 */
|
case OSPF_IT_PTP: /* rfc2328 - pg126 */
|
||||||
neigh=(struct ospf_neighbor *)HEAD(ifa->neigh_list);
|
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||||
if((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state==NEIGHBOR_FULL))
|
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
||||||
{
|
{
|
||||||
ln->type=LSART_PTP;
|
ln->type = LSART_PTP;
|
||||||
ln->id=neigh->rid;
|
ln->id = neigh->rid;
|
||||||
ln->metric=ifa->cost;
|
ln->metric = ifa->cost;
|
||||||
ln->notos=0;
|
ln->notos = 0;
|
||||||
if(ifa->iface->flags && IA_UNNUMBERED)
|
if (ifa->iface->flags && IA_UNNUMBERED)
|
||||||
{
|
{
|
||||||
ln->data=ifa->iface->index;
|
ln->data = ifa->iface->index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ln->id=ipa_to_u32(ifa->iface->addr->ip);
|
ln->id = ipa_to_u32(ifa->iface->addr->ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(ifa->state==OSPF_IS_PTP)
|
if (ifa->state == OSPF_IS_PTP)
|
||||||
{
|
{
|
||||||
ln->type=LSART_STUB;
|
ln->type = LSART_STUB;
|
||||||
ln->id=ln->id=ipa_to_u32(ifa->iface->addr->opposite);
|
ln->id = ln->id = ipa_to_u32(ifa->iface->addr->opposite);
|
||||||
ln->metric=ifa->cost;
|
ln->metric = ifa->cost;
|
||||||
ln->notos=0;
|
ln->notos = 0;
|
||||||
ln->data=0xffffffff;
|
ln->data = 0xffffffff;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i--; /* No link added */
|
i--; /* No link added */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSPF_IT_BCAST:
|
case OSPF_IT_BCAST:
|
||||||
case OSPF_IT_NBMA:
|
case OSPF_IT_NBMA:
|
||||||
if(ifa->state==OSPF_IS_WAITING)
|
if (ifa->state == OSPF_IS_WAITING)
|
||||||
{
|
{
|
||||||
ln->type=LSART_STUB;
|
ln->type = LSART_STUB;
|
||||||
ln->id=ipa_to_u32(ifa->iface->addr->prefix);
|
ln->id = ipa_to_u32(ifa->iface->addr->prefix);
|
||||||
ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
||||||
ln->metric=ifa->cost;
|
ln->metric = ifa->cost;
|
||||||
ln->notos=0;
|
ln->notos = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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))
|
||||||
ln->type=LSART_NET;
|
{
|
||||||
ln->id=ipa_to_u32(ifa->drip);
|
ln->type = LSART_NET;
|
||||||
ln->data=ipa_to_u32(ifa->iface->addr->ip);
|
ln->id = ipa_to_u32(ifa->drip);
|
||||||
ln->metric=ifa->cost;
|
ln->data = ipa_to_u32(ifa->iface->addr->ip);
|
||||||
ln->notos=0;
|
ln->metric = ifa->cost;
|
||||||
}
|
ln->notos = 0;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
ln->type=LSART_STUB;
|
{
|
||||||
ln->id=ipa_to_u32(ifa->iface->addr->prefix);
|
ln->type = LSART_STUB;
|
||||||
ln->data=ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
ln->id = ipa_to_u32(ifa->iface->addr->prefix);
|
||||||
ln->metric=ifa->cost;
|
ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
||||||
ln->notos=0;
|
ln->metric = ifa->cost;
|
||||||
}
|
ln->notos = 0;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case OSPF_IT_VLINK: /* FIXME Add virtual links! */
|
break;
|
||||||
i--;
|
case OSPF_IT_VLINK: /* FIXME Add virtual links! */
|
||||||
break;
|
i--;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ifa->type==OSPF_IT_VLINK) v=1;
|
if (ifa->type == OSPF_IT_VLINK)
|
||||||
ln=(ln+1);
|
v = 1;
|
||||||
|
ln = (ln + 1);
|
||||||
}
|
}
|
||||||
rt->links=i;
|
rt->links = i;
|
||||||
*length=i*sizeof(struct ospf_lsa_rt_link)+sizeof(struct ospf_lsa_rt)+
|
*length = i * sizeof(struct ospf_lsa_rt_link) + sizeof(struct ospf_lsa_rt) +
|
||||||
sizeof(struct ospf_lsa_header);
|
sizeof(struct ospf_lsa_header);
|
||||||
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
|
||||||
@ -179,68 +168,69 @@ void
|
|||||||
originate_rt_lsa(struct ospf_area *oa)
|
originate_rt_lsa(struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
struct ospf_lsa_header lsa;
|
struct ospf_lsa_header lsa;
|
||||||
struct proto_ospf *po=oa->po;
|
struct proto_ospf *po = oa->po;
|
||||||
struct proto *p=&po->proto;
|
struct proto *p = &po->proto;
|
||||||
u32 rtid=po->proto.cf->global->router_id;
|
u32 rtid = po->proto.cf->global->router_id;
|
||||||
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
|
/*
|
||||||
* originate new LSA before MINLSINTERVAL. We will
|
* Tick is probably set to very low value. We cannot
|
||||||
* try to do it next tick.
|
* 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);
|
OSPF_TRACE(D_EVENTS, "Originating RT_lsa for area \"%I\".", oa->areaid);
|
||||||
|
|
||||||
lsa.age=0;
|
lsa.age = 0;
|
||||||
lsa.id=rtid;
|
lsa.id = rtid;
|
||||||
lsa.type=LSA_T_RT;
|
lsa.type = LSA_T_RT;
|
||||||
lsa.rt=rtid;
|
lsa.rt = rtid;
|
||||||
lsa.options=0;
|
lsa.options = 0;
|
||||||
if(oa->rt==NULL)
|
if (oa->rt == NULL)
|
||||||
{
|
{
|
||||||
lsa.sn=LSA_INITSEQNO;
|
lsa.sn = LSA_INITSEQNO;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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;
|
||||||
ospf_lsupd_flood(NULL,NULL,&oa->rt->lsa,NULL,oa,1);
|
ospf_lsupd_flood(NULL, NULL, &oa->rt->lsa, NULL, oa, 1);
|
||||||
schedule_rtcalc(oa);
|
schedule_rtcalc(oa);
|
||||||
oa->origrt=0;
|
oa->origrt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
originate_net_lsa_body(struct ospf_iface *ifa, u16 *length,
|
originate_net_lsa_body(struct ospf_iface *ifa, u16 * length,
|
||||||
struct proto_ospf *po)
|
struct proto_ospf *po)
|
||||||
{
|
{
|
||||||
u16 i=1;
|
u16 i = 1;
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
u32 *body;
|
u32 *body;
|
||||||
struct ospf_lsa_net *net;
|
struct ospf_lsa_net *net;
|
||||||
|
|
||||||
net=mb_alloc(po->proto.pool,sizeof(u32)*(ifa->fadj+1)+
|
net = mb_alloc(po->proto.pool, sizeof(u32) * (ifa->fadj + 1) +
|
||||||
sizeof(struct ospf_lsa_net));
|
sizeof(struct ospf_lsa_net));
|
||||||
net->netmask=ipa_mkmask(ifa->iface->addr->pxlen);
|
net->netmask = ipa_mkmask(ifa->iface->addr->pxlen);
|
||||||
|
|
||||||
body=(u32 *)(net+1);
|
body = (u32 *) (net + 1);
|
||||||
i=1;
|
i = 1;
|
||||||
*body=po->proto.cf->global->router_id;
|
*body = po->proto.cf->global->router_id;
|
||||||
WALK_LIST(n,ifa->neigh_list)
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*length=i*sizeof(u32)+sizeof(struct ospf_lsa_header)+
|
*length = i * sizeof(u32) + sizeof(struct ospf_lsa_header) +
|
||||||
sizeof(struct ospf_lsa_net);
|
sizeof(struct ospf_lsa_net);
|
||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
@ -257,96 +247,103 @@ originate_net_lsa_body(struct ospf_iface *ifa, u16 *length,
|
|||||||
void
|
void
|
||||||
originate_net_lsa(struct ospf_iface *ifa)
|
originate_net_lsa(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
struct proto_ospf *po=ifa->proto;
|
struct proto_ospf *po = ifa->proto;
|
||||||
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;
|
||||||
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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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);
|
||||||
ifa->nlsa->lsa.sn+=1;
|
ifa->nlsa->lsa.sn += 1;
|
||||||
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)
|
||||||
ifa->nlsa->lsa_body=NULL;
|
mb_free(ifa->nlsa->lsa_body);
|
||||||
|
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);
|
||||||
ifa->nlsa=NULL;
|
ifa->nlsa = NULL;
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS, "Originating Net lsa for iface \"%s\".",
|
OSPF_TRACE(D_EVENTS, "Originating Net lsa for iface \"%s\".",
|
||||||
ifa->iface->name);
|
ifa->iface->name);
|
||||||
|
|
||||||
lsa.age=0;
|
lsa.age = 0;
|
||||||
lsa.id=ipa_to_u32(ifa->iface->addr->ip);
|
lsa.id = ipa_to_u32(ifa->iface->addr->ip);
|
||||||
lsa.type=LSA_T_NET;
|
lsa.type = LSA_T_NET;
|
||||||
lsa.rt=rtid;
|
lsa.rt = rtid;
|
||||||
lsa.options=0;
|
lsa.options = 0;
|
||||||
if(ifa->nlsa==NULL)
|
if (ifa->nlsa == NULL)
|
||||||
{
|
{
|
||||||
lsa.sn=LSA_INITSEQNO;
|
lsa.sn = LSA_INITSEQNO;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lsa.sn=ifa->nlsa->lsa.sn+1;
|
lsa.sn = ifa->nlsa->lsa.sn + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
body=originate_net_lsa_body(ifa, &lsa.length, po);
|
body = originate_net_lsa_body(ifa, &lsa.length, po);
|
||||||
lsasum_calculate(&lsa,body,po);
|
lsasum_calculate(&lsa, body, po);
|
||||||
ifa->nlsa=lsa_install_new(&lsa, body, ifa->oa);
|
ifa->nlsa = lsa_install_new(&lsa, body, ifa->oa);
|
||||||
ospf_lsupd_flood(NULL,NULL,&ifa->nlsa->lsa,NULL,ifa->oa,1);
|
ospf_lsupd_flood(NULL, NULL, &ifa->nlsa->lsa, NULL, ifa->oa, 1);
|
||||||
ifa->orignet=0;
|
ifa->orignet = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
struct ospf_lsa_ext_tos *et;
|
struct ospf_lsa_ext_tos *et;
|
||||||
u32 m1 = ea_get_int(attrs, EA_OSPF_METRIC1, LSINFINITY);
|
u32 m1 = ea_get_int(attrs, EA_OSPF_METRIC1, LSINFINITY);
|
||||||
u32 m2 = ea_get_int(attrs, EA_OSPF_METRIC2, 10000);
|
u32 m2 = ea_get_int(attrs, EA_OSPF_METRIC2, 10000);
|
||||||
u32 tag = ea_get_int(attrs, EA_OSPF_TAG, 0);
|
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)+
|
ext = mb_alloc(p->pool, sizeof(struct ospf_lsa_ext) +
|
||||||
sizeof(struct ospf_lsa_ext_tos));
|
sizeof(struct ospf_lsa_ext_tos));
|
||||||
ext->netmask=ipa_mkmask(n->n.pxlen);
|
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->etos = 0;
|
||||||
et->metric=m1;
|
et->metric = m1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
et->etos=0x80;
|
et->etos = 0x80;
|
||||||
et->metric=m2;
|
et->metric = m2;
|
||||||
}
|
}
|
||||||
et->padding=0;
|
et->padding = 0;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,8 +364,8 @@ int
|
|||||||
max_ext_lsa(unsigned pxlen)
|
max_ext_lsa(unsigned pxlen)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=1;pxlen<BITS_PER_IP_ADDRESS;pxlen++,i<<=1)
|
for (i = 1; pxlen < BITS_PER_IP_ADDRESS; pxlen++, i <<= 1)
|
||||||
if(i>=MAXNETS)
|
if (i >= MAXNETS)
|
||||||
return MAXNETS;
|
return MAXNETS;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -389,64 +386,68 @@ 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;
|
||||||
struct top_hash_entry *en=NULL;
|
struct top_hash_entry *en = NULL;
|
||||||
void *body=NULL;
|
void *body = NULL;
|
||||||
struct proto *p=&po->proto;
|
struct proto *p = &po->proto;
|
||||||
struct ospf_area *oa;
|
struct ospf_area *oa;
|
||||||
struct ospf_lsa_ext *ext1,*ext2;
|
struct ospf_lsa_ext *ext1, *ext2;
|
||||||
int i;
|
int i;
|
||||||
int max;
|
int max;
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS, "Originating Ext lsa for %I/%d.", n->n.prefix,
|
OSPF_TRACE(D_EVENTS, "Originating Ext lsa for %I/%d.", n->n.prefix,
|
||||||
n->n.pxlen);
|
n->n.pxlen);
|
||||||
|
|
||||||
lsa.age=0;
|
lsa.age = 0;
|
||||||
lsa.id=ipa_to_u32(n->n.prefix);
|
lsa.id = ipa_to_u32(n->n.prefix);
|
||||||
lsa.type=LSA_T_EXT;
|
lsa.type = LSA_T_EXT;
|
||||||
lsa.rt=rtid;
|
lsa.rt = rtid;
|
||||||
lsa.sn=LSA_INITSEQNO;
|
lsa.sn = LSA_INITSEQNO;
|
||||||
body=originate_ext_lsa_body(n, e, po, attrs);
|
body = originate_ext_lsa_body(n, e, po, attrs);
|
||||||
lsa.length=sizeof(struct ospf_lsa_ext)+sizeof(struct ospf_lsa_ext_tos)+
|
lsa.length = sizeof(struct ospf_lsa_ext) + sizeof(struct ospf_lsa_ext_tos) +
|
||||||
sizeof(struct ospf_lsa_header);
|
sizeof(struct ospf_lsa_header);
|
||||||
ext1=body;
|
ext1 = body;
|
||||||
max=max_ext_lsa(n->n.pxlen);
|
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;
|
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)
|
||||||
{
|
{
|
||||||
log("%s: got more routes for one /%d network then %d, ignoring",p->name,
|
log("%s: got more routes for one /%d network then %d, ignoring", p->name,
|
||||||
n->n.pxlen,max);
|
n->n.pxlen, max);
|
||||||
mb_free(body);
|
mb_free(body);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lsasum_calculate(&lsa,body,po);
|
lsasum_calculate(&lsa, body, po);
|
||||||
WALK_LIST(oa, po->area_list)
|
WALK_LIST(oa, po->area_list)
|
||||||
{
|
{
|
||||||
en=lsa_install_new(&lsa, body, oa);
|
en = lsa_install_new(&lsa, body, oa);
|
||||||
ospf_lsupd_flood(NULL,NULL,&en->lsa,NULL,oa,1);
|
ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1);
|
||||||
body=originate_ext_lsa_body(n, e, po, attrs);
|
body = originate_ext_lsa_body(n, e, po, attrs);
|
||||||
}
|
}
|
||||||
mb_free(body);
|
mb_free(body);
|
||||||
|
|
||||||
if(po->ebit==0)
|
if (po->ebit == 0)
|
||||||
{
|
{
|
||||||
po->ebit=1;
|
po->ebit = 1;
|
||||||
WALK_LIST(oa, po->area_list)
|
WALK_LIST(oa, po->area_list)
|
||||||
{
|
{
|
||||||
schedule_rt_lsa(oa);
|
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;
|
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 *));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,10 +494,14 @@ ospf_top_hash_u32(u32 a)
|
|||||||
static inline unsigned
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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.
|
* its used in @ospf_area structure.
|
||||||
*/
|
*/
|
||||||
struct top_graph *
|
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;
|
struct top_graph *f;
|
||||||
|
|
||||||
@ -537,36 +543,37 @@ 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;
|
||||||
|
|
||||||
for(oldh=0; oldh < oldn; oldh++)
|
for (oldh = 0; oldh < oldn; oldh++)
|
||||||
|
{
|
||||||
|
e = oldt[oldh];
|
||||||
|
while (e)
|
||||||
{
|
{
|
||||||
e = oldt[oldh];
|
x = e->next;
|
||||||
while (e)
|
n = newt + ospf_top_hash(f, e->lsa.id, e->lsa.rt, e->lsa.type);
|
||||||
{
|
e->next = *n;
|
||||||
x = e->next;
|
*n = e;
|
||||||
n = newt + ospf_top_hash(f, e->lsa.id, e->lsa.rt, e->lsa.type);
|
e = x;
|
||||||
e->next = *n;
|
|
||||||
*n = e;
|
|
||||||
e = x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ospf_top_ht_free(oldt);
|
ospf_top_ht_free(oldt);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct top_hash_entry *
|
struct top_hash_entry *
|
||||||
ospf_hash_find_header(struct top_graph *f, struct ospf_lsa_header *h)
|
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 *
|
struct top_hash_entry *
|
||||||
ospf_hash_get_header(struct top_graph *f, struct ospf_lsa_header *h)
|
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 *
|
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)];
|
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 1 /* Dirty patch to make rt table calculation work. */
|
||||||
if(type==LSA_T_NET)
|
if (type == LSA_T_NET)
|
||||||
{
|
{
|
||||||
while (e && (e->lsa.id != lsa || e->lsa.type != LSA_T_NET ))
|
while (e && (e->lsa.id != lsa || e->lsa.type != LSA_T_NET))
|
||||||
e = e->next;
|
e = e->next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (e && (e->lsa.id != lsa || e->lsa.type != type || e->lsa.rt != rtr))
|
while (e && (e->lsa.id != lsa || e->lsa.type != type || e->lsa.rt != rtr))
|
||||||
e = e->next;
|
e = e->next;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
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))
|
||||||
@ -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))
|
||||||
@ -607,9 +615,9 @@ ospf_hash_get(struct top_graph *f, u32 lsa, u32 rtr, u32 type)
|
|||||||
e->lsa.rt = rtr;
|
e->lsa.rt = rtr;
|
||||||
e->lsa.type = type;
|
e->lsa.type = type;
|
||||||
e->lsa_body = NULL;
|
e->lsa_body = NULL;
|
||||||
e->nhi=NULL;
|
e->nhi = NULL;
|
||||||
e->next=*ee; /* MJ you forgot this :-) */
|
e->next = *ee; /* MJ you forgot this :-) */
|
||||||
*ee=e;
|
*ee = e;
|
||||||
if (f->hash_entries++ > f->hash_entries_max)
|
if (f->hash_entries++ > f->hash_entries_max)
|
||||||
ospf_top_rehash(f, HASH_HI_STEP);
|
ospf_top_rehash(f, HASH_HI_STEP);
|
||||||
return e;
|
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;
|
struct top_hash_entry **ee = f->hash_table + h;
|
||||||
|
|
||||||
while (*ee)
|
while (*ee)
|
||||||
|
{
|
||||||
|
if (*ee == e)
|
||||||
{
|
{
|
||||||
if (*ee == e)
|
*ee = e->next;
|
||||||
{
|
sl_free(f->hash_slab, e);
|
||||||
*ee = e->next;
|
if (f->hash_entries-- < f->hash_entries_min)
|
||||||
sl_free(f->hash_slab, e);
|
ospf_top_rehash(f, -HASH_LO_STEP);
|
||||||
if (f->hash_entries-- < f->hash_entries_min)
|
return;
|
||||||
ospf_top_rehash(f, -HASH_LO_STEP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ee = &((*ee)->next);
|
|
||||||
}
|
}
|
||||||
|
ee = &((*ee)->next);
|
||||||
|
}
|
||||||
bug("ospf_hash_delete() called for invalid node");
|
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;
|
unsigned int i;
|
||||||
OSPF_TRACE(D_EVENTS, "Hash entries: %d", f->hash_entries);
|
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];
|
OSPF_TRACE(D_EVENTS, "\t%1x %-1I %-1I %4u 0x%08x",
|
||||||
while (e)
|
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 */
|
/* 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)
|
WALK_LIST(ifa, iface_list)
|
||||||
{
|
{
|
||||||
if(ifa->oa==oa)
|
if (ifa->oa == oa)
|
||||||
{
|
{
|
||||||
WALK_LIST(n, ifa->neigh_list)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,19 +9,20 @@
|
|||||||
#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
|
||||||
* calculation
|
* calculation
|
||||||
*/
|
*/
|
||||||
struct top_hash_entry *next; /* Next in hash chain */
|
struct top_hash_entry *next; /* Next in hash chain */
|
||||||
struct ospf_lsa_header lsa;
|
struct ospf_lsa_header lsa;
|
||||||
void *lsa_body;
|
void *lsa_body;
|
||||||
bird_clock_t inst_t; /* Time of installation into DB */
|
bird_clock_t inst_t; /* Time of installation into DB */
|
||||||
ip_addr nh; /* Next hop */
|
ip_addr nh; /* Next hop */
|
||||||
struct iface *nhi;
|
struct iface *nhi;
|
||||||
u16 dist; /* Distance from the root */
|
u16 dist; /* Distance from the root */
|
||||||
u16 ini_age;
|
u16 ini_age;
|
||||||
u8 color;
|
u8 color;
|
||||||
#define OUTSPF 0
|
#define OUTSPF 0
|
||||||
@ -31,9 +32,10 @@ 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 */
|
{
|
||||||
slab *hash_slab; /* Slab for hash entries */
|
pool *pool; /* Pool we allocate from */
|
||||||
|
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) */
|
||||||
unsigned int hash_size;
|
unsigned int hash_size;
|
||||||
unsigned int hash_order;
|
unsigned int hash_order;
|
||||||
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user