Indentation.
This commit is contained in:
parent
66261211a9
commit
2e10a170fe
14 changed files with 1629 additions and 1481 deletions
|
@ -117,9 +117,9 @@ ospf_dbdes_send(struct ospf_neighbor *n)
|
||||||
|
|
||||||
case NEIGHBOR_LOADING:
|
case NEIGHBOR_LOADING:
|
||||||
case NEIGHBOR_FULL:
|
case NEIGHBOR_FULL:
|
||||||
length = ntohs(((struct ospf_packet *)n->ldbdes)->length);
|
length = ntohs(((struct ospf_packet *) n->ldbdes)->length);
|
||||||
|
|
||||||
if(!length)
|
if (!length)
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_PACKETS, "No packet in my buffer for repeating");
|
OSPF_TRACE(D_PACKETS, "No packet in my buffer for repeating");
|
||||||
ospf_neigh_sm(n, INM_KILLNBR);
|
ospf_neigh_sm(n, INM_KILLNBR);
|
||||||
|
|
|
@ -36,13 +36,15 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
|
||||||
|
|
||||||
if (ntohs(ps->helloint) != ifa->helloint)
|
if (ntohs(ps->helloint) != ifa->helloint)
|
||||||
{
|
{
|
||||||
log(L_WARN "%s%I%shello interval mismatch (%d).", beg, faddr, rec, ntohs(ps->helloint));
|
log(L_WARN "%s%I%shello interval mismatch (%d).", beg, faddr, rec,
|
||||||
|
ntohs(ps->helloint));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntohl(ps->deadint) != ifa->helloint * ifa->deadc)
|
if (ntohl(ps->deadint) != ifa->helloint * ifa->deadc)
|
||||||
{
|
{
|
||||||
log(L_ERR "%s%I%sdead interval mismatch (%d).", beg, faddr, rec, ntohl(ps->deadint));
|
log(L_ERR "%s%I%sdead interval mismatch (%d).", beg, faddr, rec,
|
||||||
|
ntohl(ps->deadint));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,8 +150,7 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
|
||||||
{
|
{
|
||||||
struct ospf_area *oa = ifa->oa;
|
struct ospf_area *oa = ifa->oa;
|
||||||
|
|
||||||
DBG("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)
|
||||||
{
|
{
|
||||||
|
@ -248,7 +247,7 @@ ospf_open_mc_socket(struct ospf_iface *ifa)
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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;
|
||||||
|
@ -278,7 +277,7 @@ ospf_open_ip_socket(struct ospf_iface * ifa)
|
||||||
}
|
}
|
||||||
|
|
||||||
u8
|
u8
|
||||||
ospf_iface_clasify(struct iface *ifa)
|
ospf_iface_clasify(struct iface * ifa)
|
||||||
{
|
{
|
||||||
if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
|
if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
|
||||||
(IF_MULTIACCESS | IF_MULTICAST))
|
(IF_MULTIACCESS | IF_MULTICAST))
|
||||||
|
@ -386,8 +385,7 @@ ospf_iface_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 =
|
ifa->type = ospf_iface_clasify(ifa->iface);
|
||||||
ospf_iface_clasify(ifa->iface);
|
|
||||||
else
|
else
|
||||||
ifa->type = ip->type;
|
ifa->type = ip->type;
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,15 @@
|
||||||
void
|
void
|
||||||
flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
|
flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
struct proto *p=&oa->po->proto;
|
struct proto *p = &oa->po->proto;
|
||||||
OSPF_TRACE(D_EVENTS, "Going to remove node Type: %u, Id: %I, Rt: %I, Age: %u",
|
OSPF_TRACE(D_EVENTS,
|
||||||
|
"Going to remove node Type: %u, Id: %I, Rt: %I, Age: %u",
|
||||||
en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.age);
|
en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.age);
|
||||||
s_rem_node(SNODE en);
|
s_rem_node(SNODE en);
|
||||||
if(en->lsa_body!=NULL) mb_free(en->lsa_body);
|
if (en->lsa_body != NULL)
|
||||||
en->lsa_body=NULL;
|
mb_free(en->lsa_body);
|
||||||
ospf_hash_delete(oa->gr,en);
|
en->lsa_body = NULL;
|
||||||
|
ospf_hash_delete(oa->gr, en);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,49 +40,52 @@ flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
|
||||||
void
|
void
|
||||||
ospf_age(struct ospf_area *oa)
|
ospf_age(struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
struct proto *p=&oa->po->proto;
|
struct proto *p = &oa->po->proto;
|
||||||
struct proto_ospf *po=(struct proto_ospf *)p;
|
struct proto_ospf *po = (struct proto_ospf *) p;
|
||||||
struct top_hash_entry *en,*nxt;
|
struct top_hash_entry *en, *nxt;
|
||||||
int flush=can_flush_lsa(oa);
|
int flush = can_flush_lsa(oa);
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS, "Running ospf_age");
|
OSPF_TRACE(D_EVENTS, "Running ospf_age");
|
||||||
|
|
||||||
WALK_SLIST_DELSAFE(en,nxt,oa->lsal)
|
WALK_SLIST_DELSAFE(en, nxt, oa->lsal)
|
||||||
{
|
{
|
||||||
if(oa->calcrt)
|
if (oa->calcrt)
|
||||||
{
|
{
|
||||||
en->color=OUTSPF;
|
en->color = OUTSPF;
|
||||||
en->dist=LSINFINITY;
|
en->dist = LSINFINITY;
|
||||||
en->nhi=NULL;
|
en->nhi = NULL;
|
||||||
en->nh=ipa_from_u32(0);
|
en->nh = ipa_from_u32(0);
|
||||||
DBG("Infinitying Type: %u, Id: %I, Rt: %I\n", en->lsa.type, en->lsa.id,
|
DBG("Infinitying Type: %u, Id: %I, Rt: %I\n", en->lsa.type, en->lsa.id,
|
||||||
en->lsa.rt);
|
en->lsa.rt);
|
||||||
}
|
}
|
||||||
if(en->lsa.age==LSA_MAXAGE)
|
if (en->lsa.age == LSA_MAXAGE)
|
||||||
{
|
{
|
||||||
if(flush) flush_lsa(en,oa);
|
if (flush)
|
||||||
|
flush_lsa(en, oa);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if((en->lsa.rt==p->cf->global->router_id)&&(en->lsa.age>=LSREFRESHTIME))
|
if ((en->lsa.rt == p->cf->global->router_id) &&(en->lsa.age >=
|
||||||
|
LSREFRESHTIME))
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_EVENTS, "Refreshing my LSA: Type: %u, Id: %I, Rt: %I",
|
OSPF_TRACE(D_EVENTS, "Refreshing my LSA: Type: %u, Id: %I, Rt: %I",
|
||||||
en->lsa.type, en->lsa.id, en->lsa.rt);
|
en->lsa.type, en->lsa.id, en->lsa.rt);
|
||||||
en->lsa.sn++;
|
en->lsa.sn++;
|
||||||
en->lsa.age=0;
|
en->lsa.age = 0;
|
||||||
en->inst_t=now;
|
en->inst_t = now;
|
||||||
en->ini_age=0;
|
en->ini_age = 0;
|
||||||
lsasum_calculate(&en->lsa,en->lsa_body,po);
|
lsasum_calculate(&en->lsa, en->lsa_body, po);
|
||||||
ospf_lsupd_flood(NULL,NULL,&en->lsa,NULL,oa,1);
|
ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if((en->lsa.age=(en->ini_age+(now-en->inst_t)))>=LSA_MAXAGE)
|
if ((en->lsa.age = (en->ini_age + (now - en->inst_t))) >= LSA_MAXAGE)
|
||||||
{
|
{
|
||||||
if(flush)
|
if (flush)
|
||||||
{
|
{
|
||||||
flush_lsa(en,oa);
|
flush_lsa(en, oa);
|
||||||
schedule_rtcalc(oa);
|
schedule_rtcalc(oa);
|
||||||
}
|
}
|
||||||
else en->lsa.age=LSA_MAXAGE;
|
else
|
||||||
|
en->lsa.age = LSA_MAXAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,70 +93,70 @@ ospf_age(struct ospf_area *oa)
|
||||||
void
|
void
|
||||||
htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
|
htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
|
||||||
{
|
{
|
||||||
n->age=htons(h->age);
|
n->age = htons(h->age);
|
||||||
n->options=h->options;
|
n->options = h->options;
|
||||||
n->type=h->type;
|
n->type = h->type;
|
||||||
n->id=htonl(h->id);
|
n->id = htonl(h->id);
|
||||||
n->rt=htonl(h->rt);
|
n->rt = htonl(h->rt);
|
||||||
n->sn=htonl(h->sn);
|
n->sn = htonl(h->sn);
|
||||||
n->checksum=htons(h->checksum);
|
n->checksum = htons(h->checksum);
|
||||||
n->length=htons(h->length);
|
n->length = htons(h->length);
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
|
ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
|
||||||
{
|
{
|
||||||
h->age=ntohs(n->age);
|
h->age = ntohs(n->age);
|
||||||
h->options=n->options;
|
h->options = n->options;
|
||||||
h->type=n->type;
|
h->type = n->type;
|
||||||
h->id=ntohl(n->id);
|
h->id = ntohl(n->id);
|
||||||
h->rt=ntohl(n->rt);
|
h->rt = ntohl(n->rt);
|
||||||
h->sn=ntohl(n->sn);
|
h->sn = ntohl(n->sn);
|
||||||
h->checksum=ntohs(n->checksum);
|
h->checksum = ntohs(n->checksum);
|
||||||
h->length=ntohs(n->length);
|
h->length = ntohs(n->length);
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
htonlsab(void *h, void *n, u8 type, u16 len)
|
htonlsab(void *h, void *n, u8 type, u16 len)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
switch(type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case LSA_T_RT:
|
case LSA_T_RT:
|
||||||
{
|
{
|
||||||
struct ospf_lsa_rt *hrt, *nrt;
|
struct ospf_lsa_rt *hrt, *nrt;
|
||||||
struct ospf_lsa_rt_link *hrtl,*nrtl;
|
struct ospf_lsa_rt_link *hrtl, *nrtl;
|
||||||
u16 links;
|
u16 links;
|
||||||
|
|
||||||
nrt=n;
|
nrt = n;
|
||||||
hrt=h;
|
hrt = h;
|
||||||
links=hrt->links;
|
links = hrt->links;
|
||||||
|
|
||||||
nrt->veb.byte=hrt->veb.byte;
|
nrt->veb.byte = hrt->veb.byte;
|
||||||
nrt->padding=0;
|
nrt->padding = 0;
|
||||||
nrt->links=htons(hrt->links);
|
nrt->links = htons(hrt->links);
|
||||||
nrtl=(struct ospf_lsa_rt_link *)(nrt+1);
|
nrtl = (struct ospf_lsa_rt_link *) (nrt + 1);
|
||||||
hrtl=(struct ospf_lsa_rt_link *)(hrt+1);
|
hrtl = (struct ospf_lsa_rt_link *) (hrt + 1);
|
||||||
for(i=0;i<links;i++)
|
for (i = 0; i < links; i++)
|
||||||
{
|
{
|
||||||
(nrtl+i)->id=htonl((hrtl+i)->id);
|
(nrtl + i)->id = htonl((hrtl + i)->id);
|
||||||
(nrtl+i)->data=htonl((hrtl+i)->data);
|
(nrtl + i)->data = htonl((hrtl + i)->data);
|
||||||
(nrtl+i)->type=(hrtl+i)->type;
|
(nrtl + i)->type = (hrtl + i)->type;
|
||||||
(nrtl+i)->notos=(hrtl+i)->notos;
|
(nrtl + i)->notos = (hrtl + i)->notos;
|
||||||
(nrtl+i)->metric=htons((hrtl+i)->metric);
|
(nrtl + i)->metric = htons((hrtl + i)->metric);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LSA_T_NET:
|
case LSA_T_NET:
|
||||||
{
|
{
|
||||||
u32 *hid,*nid;
|
u32 *hid, *nid;
|
||||||
|
|
||||||
nid=n;
|
nid = n;
|
||||||
hid=h;
|
hid = h;
|
||||||
|
|
||||||
for(i=0;i<(len/sizeof(u32));i++)
|
for (i = 0; i < (len / sizeof(u32)); i++)
|
||||||
{
|
{
|
||||||
*(nid+i)=htonl(*(hid+i));
|
*(nid + i) = htonl(*(hid + i));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -161,21 +166,21 @@ htonlsab(void *h, void *n, u8 type, u16 len)
|
||||||
struct ospf_lsa_summ *hs, *ns;
|
struct ospf_lsa_summ *hs, *ns;
|
||||||
struct ospf_lsa_summ_net *hn, *nn;
|
struct ospf_lsa_summ_net *hn, *nn;
|
||||||
|
|
||||||
hs=h;
|
hs = h;
|
||||||
ns=n;
|
ns = n;
|
||||||
|
|
||||||
ns->netmask=hs->netmask;
|
ns->netmask = hs->netmask;
|
||||||
ipa_hton(ns->netmask);
|
ipa_hton(ns->netmask);
|
||||||
|
|
||||||
hn=(struct ospf_lsa_summ_net *)(hs+1);
|
hn = (struct ospf_lsa_summ_net *) (hs + 1);
|
||||||
nn=(struct ospf_lsa_summ_net *)(ns+1);
|
nn = (struct ospf_lsa_summ_net *) (ns + 1);
|
||||||
|
|
||||||
for(i=0;i<((len-sizeof(struct ospf_lsa_summ))/
|
for (i = 0; i < ((len - sizeof(struct ospf_lsa_summ)) /
|
||||||
sizeof(struct ospf_lsa_summ_net));i++)
|
sizeof(struct ospf_lsa_summ_net)); i++)
|
||||||
{
|
{
|
||||||
(nn+i)->tos=(hn+i)->tos;
|
(nn + i)->tos = (hn + i)->tos;
|
||||||
(nn+i)->metric=htons((hn+i)->metric);
|
(nn + i)->metric = htons((hn + i)->metric);
|
||||||
(nn+i)->padding=0;
|
(nn + i)->padding = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -184,28 +189,29 @@ htonlsab(void *h, void *n, u8 type, u16 len)
|
||||||
struct ospf_lsa_ext *he, *ne;
|
struct ospf_lsa_ext *he, *ne;
|
||||||
struct ospf_lsa_ext_tos *ht, *nt;
|
struct ospf_lsa_ext_tos *ht, *nt;
|
||||||
|
|
||||||
he=h;
|
he = h;
|
||||||
ne=n;
|
ne = n;
|
||||||
|
|
||||||
ne->netmask=he->netmask;
|
ne->netmask = he->netmask;
|
||||||
ipa_hton(ne->netmask);
|
ipa_hton(ne->netmask);
|
||||||
|
|
||||||
ht=(struct ospf_lsa_ext_tos *)(he+1);
|
ht = (struct ospf_lsa_ext_tos *) (he + 1);
|
||||||
nt=(struct ospf_lsa_ext_tos *)(ne+1);
|
nt = (struct ospf_lsa_ext_tos *) (ne + 1);
|
||||||
|
|
||||||
for(i=0;i<((len-sizeof(struct ospf_lsa_ext))/
|
for (i = 0; i < ((len - sizeof(struct ospf_lsa_ext)) /
|
||||||
sizeof(struct ospf_lsa_ext_tos));i++)
|
sizeof(struct ospf_lsa_ext_tos)); i++)
|
||||||
{
|
{
|
||||||
(nt+i)->etos=(ht+i)->etos;
|
(nt + i)->etos = (ht + i)->etos;
|
||||||
(nt+i)->padding=0;
|
(nt + i)->padding = 0;
|
||||||
(nt+i)->metric=htons((ht+i)->metric);
|
(nt + i)->metric = htons((ht + i)->metric);
|
||||||
(nt+i)->fwaddr=(ht+i)->fwaddr;
|
(nt + i)->fwaddr = (ht + i)->fwaddr;
|
||||||
ipa_hton((nt+i)->fwaddr);
|
ipa_hton((nt + i)->fwaddr);
|
||||||
(nt+i)->tag=htonl((ht+i)->tag);
|
(nt + i)->tag = htonl((ht + i)->tag);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: bug("(hton): Unknown LSA");
|
default:
|
||||||
|
bug("(hton): Unknown LSA");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,42 +219,42 @@ void
|
||||||
ntohlsab(void *n, void *h, u8 type, u16 len)
|
ntohlsab(void *n, void *h, u8 type, u16 len)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
switch(type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case LSA_T_RT:
|
case LSA_T_RT:
|
||||||
{
|
{
|
||||||
struct ospf_lsa_rt *hrt, *nrt;
|
struct ospf_lsa_rt *hrt, *nrt;
|
||||||
struct ospf_lsa_rt_link *hrtl,*nrtl;
|
struct ospf_lsa_rt_link *hrtl, *nrtl;
|
||||||
u16 links;
|
u16 links;
|
||||||
|
|
||||||
nrt=n;
|
nrt = n;
|
||||||
hrt=h;
|
hrt = h;
|
||||||
|
|
||||||
hrt->veb.byte=nrt->veb.byte;
|
hrt->veb.byte = nrt->veb.byte;
|
||||||
hrt->padding=0;
|
hrt->padding = 0;
|
||||||
links=hrt->links=ntohs(nrt->links);
|
links = hrt->links = ntohs(nrt->links);
|
||||||
nrtl=(struct ospf_lsa_rt_link *)(nrt+1);
|
nrtl = (struct ospf_lsa_rt_link *) (nrt + 1);
|
||||||
hrtl=(struct ospf_lsa_rt_link *)(hrt+1);
|
hrtl = (struct ospf_lsa_rt_link *) (hrt + 1);
|
||||||
for(i=0;i<links;i++)
|
for (i = 0; i < links; i++)
|
||||||
{
|
{
|
||||||
(hrtl+i)->id=ntohl((nrtl+i)->id);
|
(hrtl + i)->id = ntohl((nrtl + i)->id);
|
||||||
(hrtl+i)->data=ntohl((nrtl+i)->data);
|
(hrtl + i)->data = ntohl((nrtl + i)->data);
|
||||||
(hrtl+i)->type=(nrtl+i)->type;
|
(hrtl + i)->type = (nrtl + i)->type;
|
||||||
(hrtl+i)->notos=(nrtl+i)->notos;
|
(hrtl + i)->notos = (nrtl + i)->notos;
|
||||||
(hrtl+i)->metric=ntohs((nrtl+i)->metric);
|
(hrtl + i)->metric = ntohs((nrtl + i)->metric);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LSA_T_NET:
|
case LSA_T_NET:
|
||||||
{
|
{
|
||||||
u32 *hid,*nid;
|
u32 *hid, *nid;
|
||||||
|
|
||||||
hid=h;
|
hid = h;
|
||||||
nid=n;
|
nid = n;
|
||||||
|
|
||||||
for(i=0;i<(len/sizeof(u32));i++)
|
for (i = 0; i < (len / sizeof(u32)); i++)
|
||||||
{
|
{
|
||||||
*(hid+i)=ntohl(*(nid+i));
|
*(hid + i) = ntohl(*(nid + i));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -258,21 +264,21 @@ ntohlsab(void *n, void *h, u8 type, u16 len)
|
||||||
struct ospf_lsa_summ *hs, *ns;
|
struct ospf_lsa_summ *hs, *ns;
|
||||||
struct ospf_lsa_summ_net *hn, *nn;
|
struct ospf_lsa_summ_net *hn, *nn;
|
||||||
|
|
||||||
hs=h;
|
hs = h;
|
||||||
ns=n;
|
ns = n;
|
||||||
|
|
||||||
hs->netmask=ns->netmask;
|
hs->netmask = ns->netmask;
|
||||||
ipa_ntoh(hs->netmask);
|
ipa_ntoh(hs->netmask);
|
||||||
|
|
||||||
hn=(struct ospf_lsa_summ_net *)(hs+1);
|
hn = (struct ospf_lsa_summ_net *) (hs + 1);
|
||||||
nn=(struct ospf_lsa_summ_net *)(ns+1);
|
nn = (struct ospf_lsa_summ_net *) (ns + 1);
|
||||||
|
|
||||||
for(i=0;i<((len-sizeof(struct ospf_lsa_summ))/
|
for (i = 0; i < ((len - sizeof(struct ospf_lsa_summ)) /
|
||||||
sizeof(struct ospf_lsa_summ_net));i++)
|
sizeof(struct ospf_lsa_summ_net)); i++)
|
||||||
{
|
{
|
||||||
(hn+i)->tos=(nn+i)->tos;
|
(hn + i)->tos = (nn + i)->tos;
|
||||||
(hn+i)->metric=ntohs((nn+i)->metric);
|
(hn + i)->metric = ntohs((nn + i)->metric);
|
||||||
(hn+i)->padding=0;
|
(hn + i)->padding = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -281,28 +287,29 @@ ntohlsab(void *n, void *h, u8 type, u16 len)
|
||||||
struct ospf_lsa_ext *he, *ne;
|
struct ospf_lsa_ext *he, *ne;
|
||||||
struct ospf_lsa_ext_tos *ht, *nt;
|
struct ospf_lsa_ext_tos *ht, *nt;
|
||||||
|
|
||||||
he=h;
|
he = h;
|
||||||
ne=n;
|
ne = n;
|
||||||
|
|
||||||
he->netmask=ne->netmask;
|
he->netmask = ne->netmask;
|
||||||
ipa_ntoh(he->netmask);
|
ipa_ntoh(he->netmask);
|
||||||
|
|
||||||
ht=(struct ospf_lsa_ext_tos *)(he+1);
|
ht = (struct ospf_lsa_ext_tos *) (he + 1);
|
||||||
nt=(struct ospf_lsa_ext_tos *)(ne+1);
|
nt = (struct ospf_lsa_ext_tos *) (ne + 1);
|
||||||
|
|
||||||
for(i=0;i<((len-sizeof(struct ospf_lsa_ext))/
|
for (i = 0; i < ((len - sizeof(struct ospf_lsa_ext)) /
|
||||||
sizeof(struct ospf_lsa_ext_tos));i++)
|
sizeof(struct ospf_lsa_ext_tos)); i++)
|
||||||
{
|
{
|
||||||
(ht+i)->etos=(nt+i)->etos;
|
(ht + i)->etos = (nt + i)->etos;
|
||||||
(ht+i)->padding=0;
|
(ht + i)->padding = 0;
|
||||||
(ht+i)->metric=ntohs((nt+i)->metric);
|
(ht + i)->metric = ntohs((nt + i)->metric);
|
||||||
(ht+i)->fwaddr=(nt+i)->fwaddr;
|
(ht + i)->fwaddr = (nt + i)->fwaddr;
|
||||||
ipa_ntoh((ht+i)->fwaddr);
|
ipa_ntoh((ht + i)->fwaddr);
|
||||||
(ht+i)->tag=ntohl((nt+i)->tag);
|
(ht + i)->tag = ntohl((nt + i)->tag);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: bug("(ntoh): Unknown LSA");
|
default:
|
||||||
|
bug("(ntoh): Unknown LSA");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -314,19 +321,19 @@ ntohlsab(void *n, void *h, u8 type, u16 len)
|
||||||
|
|
||||||
/* FIXME This is VERY uneficient, I have huge endianity problems */
|
/* FIXME This is VERY uneficient, I have huge endianity problems */
|
||||||
void
|
void
|
||||||
lsasum_calculate(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
|
lsasum_calculate(struct ospf_lsa_header *h, void *body, struct proto_ospf *po)
|
||||||
{
|
{
|
||||||
u16 length;
|
u16 length;
|
||||||
|
|
||||||
length=h->length;
|
length = h->length;
|
||||||
|
|
||||||
htonlsah(h,h);
|
htonlsah(h, h);
|
||||||
htonlsab(body,body,h->type,length-sizeof(struct ospf_lsa_header));
|
htonlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
|
||||||
|
|
||||||
(void)lsasum_check(h,body,po);
|
(void) lsasum_check(h, body, po);
|
||||||
|
|
||||||
ntohlsah(h,h);
|
ntohlsah(h, h);
|
||||||
ntohlsab(body,body,h->type,length-sizeof(struct ospf_lsa_header));
|
ntohlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -334,7 +341,7 @@ lsasum_calculate(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
|
||||||
* It also returns value in big endian
|
* It also returns value in big endian
|
||||||
*/
|
*/
|
||||||
u16
|
u16
|
||||||
lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
|
lsasum_check(struct ospf_lsa_header *h, void *body, struct proto_ospf *po)
|
||||||
{
|
{
|
||||||
u8 *sp, *ep, *p, *q, *b;
|
u8 *sp, *ep, *p, *q, *b;
|
||||||
int c0 = 0, c1 = 0;
|
int c0 = 0, c1 = 0;
|
||||||
|
@ -343,13 +350,14 @@ lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
|
||||||
|
|
||||||
b = body;
|
b = body;
|
||||||
sp = (char *) &h->options;
|
sp = (char *) &h->options;
|
||||||
length = ntohs(h->length)-2;
|
length = ntohs(h->length) - 2;
|
||||||
h->checksum = 0;
|
h->checksum = 0;
|
||||||
|
|
||||||
for (ep = sp + length; sp < ep; sp = q)
|
for (ep = sp + length; sp < ep; sp = q)
|
||||||
{ /* Actually MODX is very large, do we need the for-cyclus? */
|
{ /* Actually MODX is very large, do we need the for-cyclus? */
|
||||||
q = sp + MODX;
|
q = sp + MODX;
|
||||||
if (q > ep) q = ep;
|
if (q > ep)
|
||||||
|
q = ep;
|
||||||
for (p = sp; p < q; p++)
|
for (p = sp; p < q; p++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -358,13 +366,13 @@ lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
|
||||||
* (probably checksum in update receiving) and I go on
|
* (probably checksum in update receiving) and I go on
|
||||||
* after header
|
* after header
|
||||||
*/
|
*/
|
||||||
if((b==NULL) || (p<(u8 *)(h+1)))
|
if ((b == NULL) || (p < (u8 *) (h + 1)))
|
||||||
{
|
{
|
||||||
c0 += *p;
|
c0 += *p;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c0 += *(b+(p-sp)-sizeof(struct ospf_lsa_header)+2);
|
c0 += *(b + (p - sp) - sizeof(struct ospf_lsa_header) + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
c1 += c0;
|
c1 += c0;
|
||||||
|
@ -374,12 +382,14 @@ lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po)
|
||||||
}
|
}
|
||||||
|
|
||||||
x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
|
x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
|
||||||
if (x <= 0) x += 255;
|
if (x <= 0)
|
||||||
|
x += 255;
|
||||||
y = 510 - c0 - x;
|
y = 510 - c0 - x;
|
||||||
if (y > 255) y -= 255;
|
if (y > 255)
|
||||||
|
y -= 255;
|
||||||
|
|
||||||
((u8*)&h->checksum)[0] = x;
|
((u8 *) & h->checksum)[0] = x;
|
||||||
((u8*)&h->checksum)[1] = y;
|
((u8 *) & h->checksum)[1] = y;
|
||||||
return h->checksum;
|
return h->checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,22 +397,26 @@ int
|
||||||
lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
|
lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
|
||||||
/* Return codes from point of view of l1 */
|
/* Return codes from point of view of l1 */
|
||||||
{
|
{
|
||||||
u32 sn1,sn2;
|
u32 sn1, sn2;
|
||||||
|
|
||||||
sn1=l1->sn-LSA_INITSEQNO+1;
|
sn1 = l1->sn - LSA_INITSEQNO + 1;
|
||||||
sn2=l2->sn-LSA_INITSEQNO+1;
|
sn2 = l2->sn - LSA_INITSEQNO + 1;
|
||||||
|
|
||||||
if(sn1>sn2) return CMP_NEWER;
|
if (sn1 > sn2)
|
||||||
if(sn1<sn2) return CMP_OLDER;
|
return CMP_NEWER;
|
||||||
|
if (sn1 < sn2)
|
||||||
|
return CMP_OLDER;
|
||||||
|
|
||||||
if(l1->checksum!=l2->checksum)
|
if (l1->checksum != l2->checksum)
|
||||||
return l1->checksum<l2->checksum ? CMP_OLDER : CMP_NEWER;
|
return l1->checksum < l2->checksum ? CMP_OLDER : CMP_NEWER;
|
||||||
|
|
||||||
if((l1->age==LSA_MAXAGE)&&(l2->age!=LSA_MAXAGE)) return CMP_NEWER;
|
if ((l1->age == LSA_MAXAGE) && (l2->age != LSA_MAXAGE))
|
||||||
if((l2->age==LSA_MAXAGE)&&(l1->age!=LSA_MAXAGE)) return CMP_OLDER;
|
return CMP_NEWER;
|
||||||
|
if ((l2->age == LSA_MAXAGE) && (l1->age != LSA_MAXAGE))
|
||||||
|
return CMP_OLDER;
|
||||||
|
|
||||||
if(ABS(l1->age-l2->age)>LSA_MAXAGEDIFF)
|
if (ABS(l1->age - l2->age) > LSA_MAXAGEDIFF)
|
||||||
return l1->age<l2->age ? CMP_NEWER : CMP_OLDER;
|
return l1->age < l2->age ? CMP_NEWER : CMP_OLDER;
|
||||||
|
|
||||||
return CMP_SAME;
|
return CMP_SAME;
|
||||||
}
|
}
|
||||||
|
@ -421,27 +435,28 @@ struct top_hash_entry *
|
||||||
lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
|
lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
/* LSA can be temporarrily, but body must be mb_allocated. */
|
/* LSA can be temporarrily, but body must be mb_allocated. */
|
||||||
int change=0;
|
int change = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
struct top_hash_entry *en;
|
struct top_hash_entry *en;
|
||||||
|
|
||||||
if((en=ospf_hash_find_header(oa->gr,lsa))==NULL)
|
if ((en = ospf_hash_find_header(oa->gr, lsa)) == NULL)
|
||||||
{
|
{
|
||||||
en=ospf_hash_get_header(oa->gr,lsa);
|
en = ospf_hash_get_header(oa->gr, lsa);
|
||||||
change=1;
|
change = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((en->lsa.length!=lsa->length)||(en->lsa.options!=lsa->options)||
|
if ((en->lsa.length != lsa->length) || (en->lsa.options != lsa->options)
|
||||||
((en->lsa.age==LSA_MAXAGE)||(lsa->age==LSA_MAXAGE))) change=1;
|
|| ((en->lsa.age == LSA_MAXAGE) || (lsa->age == LSA_MAXAGE)))
|
||||||
|
change = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u8 *k=en->lsa_body,*l=body;
|
u8 *k = en->lsa_body, *l = body;
|
||||||
for(i=0;i<(lsa->length-sizeof(struct ospf_lsa_header));i++)
|
for (i = 0; i < (lsa->length - sizeof(struct ospf_lsa_header)); i++)
|
||||||
{
|
{
|
||||||
if(*(k+i)!=*(l+i))
|
if (*(k + i) != *(l + i))
|
||||||
{
|
{
|
||||||
change=1;
|
change = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,13 +468,14 @@ lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
|
||||||
lsa->id, lsa->rt, lsa->type, lsa->age, lsa->checksum, lsa->sn);
|
lsa->id, lsa->rt, lsa->type, lsa->age, lsa->checksum, lsa->sn);
|
||||||
|
|
||||||
s_add_tail(&oa->lsal, SNODE en);
|
s_add_tail(&oa->lsal, SNODE en);
|
||||||
en->inst_t=now;
|
en->inst_t = now;
|
||||||
if(en->lsa_body!=NULL) mb_free(en->lsa_body);
|
if (en->lsa_body != NULL)
|
||||||
en->lsa_body=body;
|
mb_free(en->lsa_body);
|
||||||
memcpy(&en->lsa,lsa,sizeof(struct ospf_lsa_header));
|
en->lsa_body = body;
|
||||||
en->ini_age=en->lsa.age;
|
memcpy(&en->lsa, lsa, sizeof(struct ospf_lsa_header));
|
||||||
|
en->ini_age = en->lsa.age;
|
||||||
|
|
||||||
if(change)
|
if (change)
|
||||||
{
|
{
|
||||||
schedule_rtcalc(oa);
|
schedule_rtcalc(oa);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,14 @@ void htonlsab(void *h, void *n, u8 type, u16 len);
|
||||||
void ntohlsab(void *n, void *h, u8 type, u16 len);
|
void ntohlsab(void *n, void *h, u8 type, u16 len);
|
||||||
void lsasum_calculate(struct ospf_lsa_header *header, void *body,
|
void lsasum_calculate(struct ospf_lsa_header *header, void *body,
|
||||||
struct proto_ospf *p);
|
struct proto_ospf *p);
|
||||||
u16 lsasum_check(struct ospf_lsa_header *h,void *body,struct proto_ospf *po);
|
u16 lsasum_check(struct ospf_lsa_header *h, void *body,
|
||||||
|
struct proto_ospf *po);
|
||||||
#define CMP_NEWER 1
|
#define CMP_NEWER 1
|
||||||
#define CMP_SAME 0
|
#define CMP_SAME 0
|
||||||
#define CMP_OLDER -1
|
#define CMP_OLDER -1
|
||||||
int lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2);
|
int lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2);
|
||||||
struct top_hash_entry *lsa_install_new(struct ospf_lsa_header *lsa, void *body,
|
struct top_hash_entry *lsa_install_new(struct ospf_lsa_header *lsa,
|
||||||
struct ospf_area *oa);
|
void *body, struct ospf_area *oa);
|
||||||
void ospf_age(struct ospf_area *oa);
|
void ospf_age(struct ospf_area *oa);
|
||||||
void flush_lsa(struct top_hash_entry *en, struct ospf_area *oa);
|
void flush_lsa(struct top_hash_entry *en, struct ospf_area *oa);
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,8 @@ ospf_lsreq_receive(struct ospf_lsreq_packet *ps,
|
||||||
if (ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
|
if (ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
|
||||||
llsh->lsh.type) == NULL)
|
llsh->lsh.type) == NULL)
|
||||||
{
|
{
|
||||||
log(L_WARN "Received bad LS req from: %I looking: RT: %I, ID: %I, Type: %u",
|
log(L_WARN
|
||||||
|
"Received bad LS req from: %I looking: RT: %I, ID: %I, Type: %u",
|
||||||
n->ip, lsh->rt, lsh->id, lsh->type);
|
n->ip, lsh->rt, lsh->id, lsh->type);
|
||||||
ospf_neigh_sm(n, INM_BADLSREQ);
|
ospf_neigh_sm(n, INM_BADLSREQ);
|
||||||
rfree(upslab);
|
rfree(upslab);
|
||||||
|
|
|
@ -8,29 +8,32 @@
|
||||||
|
|
||||||
#include "ospf.h"
|
#include "ospf.h"
|
||||||
|
|
||||||
char *ospf_ns[]={" down",
|
char *ospf_ns[] = { " down",
|
||||||
" attempt",
|
" attempt",
|
||||||
" init",
|
" init",
|
||||||
" 2way",
|
" 2way",
|
||||||
" exstart",
|
" exstart",
|
||||||
"exchange",
|
"exchange",
|
||||||
" loading",
|
" loading",
|
||||||
" full"};
|
" full"
|
||||||
|
};
|
||||||
|
|
||||||
const char *ospf_inm[]={ "hello received", "neighbor start", "2-way received",
|
const char *ospf_inm[] =
|
||||||
|
{ "hello received", "neighbor start", "2-way received",
|
||||||
"negotiation done", "exstart done", "bad ls request", "load done",
|
"negotiation done", "exstart done", "bad ls request", "load done",
|
||||||
"adjacency ok?", "sequence mismatch", "1-way received", "kill neighbor",
|
"adjacency ok?", "sequence mismatch", "1-way received", "kill neighbor",
|
||||||
"inactivity timer", "line down" };
|
"inactivity timer", "line down"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void neighbor_timer_hook(timer *timer);
|
void neighbor_timer_hook(timer * timer);
|
||||||
void rxmt_timer_hook(timer *timer);
|
void rxmt_timer_hook(timer * timer);
|
||||||
void ackd_timer_hook(timer *t);
|
void ackd_timer_hook(timer * t);
|
||||||
|
|
||||||
struct ospf_neighbor *
|
struct ospf_neighbor *
|
||||||
ospf_neighbor_new(struct ospf_iface *ifa)
|
ospf_neighbor_new(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
struct proto *p = (struct proto *)(ifa->proto);
|
struct proto *p = (struct proto *) (ifa->proto);
|
||||||
struct pool *pool = rp_new(p->pool, "OSPF Neighbor");
|
struct pool *pool = rp_new(p->pool, "OSPF Neighbor");
|
||||||
struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor));
|
struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor));
|
||||||
|
|
||||||
|
@ -38,8 +41,8 @@ ospf_neighbor_new(struct ospf_iface *ifa)
|
||||||
n->ifa = ifa;
|
n->ifa = ifa;
|
||||||
add_tail(&ifa->neigh_list, NODE n);
|
add_tail(&ifa->neigh_list, NODE n);
|
||||||
n->adj = 0;
|
n->adj = 0;
|
||||||
n->ldbdes=mb_allocz(pool, ifa->iface->mtu);
|
n->ldbdes = mb_allocz(pool, ifa->iface->mtu);
|
||||||
n->state=NEIGHBOR_DOWN;
|
n->state = NEIGHBOR_DOWN;
|
||||||
|
|
||||||
n->inactim = tm_new(pool);
|
n->inactim = tm_new(pool);
|
||||||
n->inactim->data = n;
|
n->inactim->data = n;
|
||||||
|
@ -59,20 +62,20 @@ ospf_neighbor_new(struct ospf_iface *ifa)
|
||||||
n->lsrth = ospf_top_new(pool, n->ifa->proto);
|
n->lsrth = ospf_top_new(pool, n->ifa->proto);
|
||||||
s_init(&(n->lsrqi), &(n->lsrql));
|
s_init(&(n->lsrqi), &(n->lsrql));
|
||||||
s_init(&(n->lsrti), &(n->lsrtl));
|
s_init(&(n->lsrti), &(n->lsrtl));
|
||||||
tm_start(n->rxmt_timer,n->ifa->rxmtint);
|
tm_start(n->rxmt_timer, n->ifa->rxmtint);
|
||||||
DBG("%s: Installing rxmt timer.\n", p->name);
|
DBG("%s: Installing rxmt timer.\n", p->name);
|
||||||
|
|
||||||
n->ackd_timer = tm_new(pool);
|
n->ackd_timer = tm_new(pool);
|
||||||
n->ackd_timer->data = n;
|
n->ackd_timer->data = n;
|
||||||
n->ackd_timer->randomize = 0;
|
n->ackd_timer->randomize = 0;
|
||||||
n->ackd_timer->hook = ackd_timer_hook;
|
n->ackd_timer->hook = ackd_timer_hook;
|
||||||
n->ackd_timer->recurrent = ifa->rxmtint/2;
|
n->ackd_timer->recurrent = ifa->rxmtint / 2;
|
||||||
init_list(&n->ackl[ACKL_DIRECT]);
|
init_list(&n->ackl[ACKL_DIRECT]);
|
||||||
init_list(&n->ackl[ACKL_DELAY]);
|
init_list(&n->ackl[ACKL_DELAY]);
|
||||||
tm_start(n->ackd_timer,n->ifa->rxmtint/2);
|
tm_start(n->ackd_timer, n->ifa->rxmtint / 2);
|
||||||
DBG("%s: Installing ackd timer.\n", p->name);
|
DBG("%s: Installing ackd timer.\n", p->name);
|
||||||
|
|
||||||
return(n);
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,125 +92,133 @@ neigh_chstate(struct ospf_neighbor *n, u8 state)
|
||||||
{
|
{
|
||||||
u8 oldstate;
|
u8 oldstate;
|
||||||
|
|
||||||
oldstate=n->state;
|
oldstate = n->state;
|
||||||
|
|
||||||
if(oldstate!=state)
|
if (oldstate != state)
|
||||||
{
|
{
|
||||||
struct ospf_iface *ifa=n->ifa;
|
struct ospf_iface *ifa = n->ifa;
|
||||||
struct proto_ospf *po=ifa->oa->po;
|
struct proto_ospf *po = ifa->oa->po;
|
||||||
struct proto *p=&po->proto;
|
struct proto *p = &po->proto;
|
||||||
|
|
||||||
n->state=state;
|
n->state = state;
|
||||||
|
|
||||||
OSPF_TRACE( D_EVENTS, "Neighbor %I changes state from \"%s\" to \"%s\".",
|
OSPF_TRACE(D_EVENTS, "Neighbor %I changes state from \"%s\" to \"%s\".",
|
||||||
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_iface_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_iface_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 */
|
||||||
{
|
{
|
||||||
ifa->fadj--;
|
ifa->fadj--;
|
||||||
schedule_rt_lsa(ifa->oa);
|
schedule_rt_lsa(ifa->oa);
|
||||||
schedule_net_lsa(ifa);
|
schedule_net_lsa(ifa);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state==NEIGHBOR_FULL) /* Increase number of adjacencies */
|
if (state == NEIGHBOR_FULL) /* Increase number of adjacencies */
|
||||||
{
|
{
|
||||||
ifa->fadj++;
|
ifa->fadj++;
|
||||||
schedule_rt_lsa(ifa->oa);
|
schedule_rt_lsa(ifa->oa);
|
||||||
schedule_net_lsa(ifa);
|
schedule_net_lsa(ifa);
|
||||||
}
|
}
|
||||||
if(state==NEIGHBOR_EXSTART)
|
if (state == NEIGHBOR_EXSTART)
|
||||||
{
|
{
|
||||||
if(n->adj==0) /* First time adjacency */
|
if (n->adj == 0) /* First time adjacency */
|
||||||
{
|
{
|
||||||
n->dds=random_u32();
|
n->dds = random_u32();
|
||||||
}
|
}
|
||||||
n->dds++;
|
n->dds++;
|
||||||
n->myimms.byte=0;
|
n->myimms.byte = 0;
|
||||||
n->myimms.bit.ms=1;
|
n->myimms.bit.ms = 1;
|
||||||
n->myimms.bit.m=1;
|
n->myimms.bit.m = 1;
|
||||||
n->myimms.bit.i=1;
|
n->myimms.bit.i = 1;
|
||||||
}
|
}
|
||||||
if(state>NEIGHBOR_EXSTART) n->myimms.bit.i=0;
|
if (state > NEIGHBOR_EXSTART)
|
||||||
|
n->myimms.bit.i = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ospf_neighbor *
|
struct ospf_neighbor *
|
||||||
electbdr(list nl)
|
electbdr(list nl)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *neigh,*n1,*n2;
|
struct ospf_neighbor *neigh, *n1, *n2;
|
||||||
|
|
||||||
n1=NULL;
|
n1 = NULL;
|
||||||
n2=NULL;
|
n2 = NULL;
|
||||||
WALK_LIST (neigh, nl) /* First try those decl. themselves */
|
WALK_LIST(neigh, nl) /* First try those decl. themselves */
|
||||||
{
|
{
|
||||||
if(neigh->state>=NEIGHBOR_2WAY) /* Higher than 2WAY */
|
if (neigh->state >= NEIGHBOR_2WAY) /* Higher than 2WAY */
|
||||||
if(neigh->priority>0) /* Eligible */
|
if (neigh->priority > 0) /* Eligible */
|
||||||
if(ipa_compare(neigh->ip,neigh->dr)!=0) /* And not decl. itself DR */
|
if (ipa_compare(neigh->ip, neigh->dr) != 0) /* And not decl. itself DR */
|
||||||
{
|
{
|
||||||
if(ipa_compare(neigh->ip,neigh->bdr)==0) /* Declaring BDR */
|
if (ipa_compare(neigh->ip, neigh->bdr) == 0) /* Declaring BDR */
|
||||||
{
|
{
|
||||||
if(n1!=NULL)
|
if (n1 != NULL)
|
||||||
{
|
{
|
||||||
if(neigh->priority>n1->priority) n1=neigh;
|
if (neigh->priority > n1->priority)
|
||||||
else if(neigh->priority==n1->priority)
|
n1 = neigh;
|
||||||
if(neigh->rid>n1->rid) n1=neigh;
|
else if (neigh->priority == n1->priority)
|
||||||
|
if (neigh->rid > n1->rid)
|
||||||
|
n1 = neigh;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n1=neigh;
|
n1 = neigh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* And NOT declaring BDR */
|
else /* And NOT declaring BDR */
|
||||||
{
|
{
|
||||||
if(n2!=NULL)
|
if (n2 != NULL)
|
||||||
{
|
{
|
||||||
if(neigh->priority>n2->priority) n2=neigh;
|
if (neigh->priority > n2->priority)
|
||||||
else if(neigh->priority==n2->priority)
|
n2 = neigh;
|
||||||
if(neigh->rid>n2->rid) n2=neigh;
|
else if (neigh->priority == n2->priority)
|
||||||
|
if (neigh->rid > n2->rid)
|
||||||
|
n2 = neigh;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n2=neigh;
|
n2 = neigh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(n1==NULL) n1=n2;
|
if (n1 == NULL)
|
||||||
|
n1 = n2;
|
||||||
|
|
||||||
return(n1);
|
return (n1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ospf_neighbor *
|
struct ospf_neighbor *
|
||||||
electdr(list nl)
|
electdr(list nl)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *neigh,*n;
|
struct ospf_neighbor *neigh, *n;
|
||||||
|
|
||||||
n=NULL;
|
n = NULL;
|
||||||
WALK_LIST (neigh, nl) /* And now DR */
|
WALK_LIST(neigh, nl) /* And now DR */
|
||||||
{
|
{
|
||||||
if(neigh->state>=NEIGHBOR_2WAY) /* Higher than 2WAY */
|
if (neigh->state >= NEIGHBOR_2WAY) /* Higher than 2WAY */
|
||||||
if(neigh->priority>0) /* Eligible */
|
if (neigh->priority > 0) /* Eligible */
|
||||||
if(ipa_compare(neigh->ip,neigh->dr)==0) /* And declaring itself DR */
|
if (ipa_compare(neigh->ip, neigh->dr) == 0) /* And declaring itself DR */
|
||||||
{
|
{
|
||||||
if(n!=NULL)
|
if (n != NULL)
|
||||||
{
|
{
|
||||||
if(neigh->priority>n->priority) n=neigh;
|
if (neigh->priority > n->priority)
|
||||||
else if(neigh->priority==n->priority)
|
n = neigh;
|
||||||
if(neigh->rid>n->rid) n=neigh;
|
else if (neigh->priority == n->priority)
|
||||||
|
if (neigh->rid > n->rid)
|
||||||
|
n = neigh;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n=neigh;
|
n = neigh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(n);
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -217,45 +228,47 @@ can_do_adj(struct ospf_neighbor *n)
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ifa=n->ifa;
|
ifa = n->ifa;
|
||||||
p=(struct proto *)(ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
i=0;
|
i = 0;
|
||||||
|
|
||||||
switch(ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
case OSPF_IT_PTP:
|
case OSPF_IT_PTP:
|
||||||
case OSPF_IT_VLINK:
|
case OSPF_IT_VLINK:
|
||||||
i=1;
|
i = 1;
|
||||||
break;
|
break;
|
||||||
case OSPF_IT_BCAST:
|
case OSPF_IT_BCAST:
|
||||||
case OSPF_IT_NBMA:
|
case OSPF_IT_NBMA:
|
||||||
switch(ifa->state)
|
switch (ifa->state)
|
||||||
{
|
{
|
||||||
case OSPF_IS_DOWN:
|
case OSPF_IS_DOWN:
|
||||||
bug("%s: Iface %s in down state?", p->name, ifa->iface->name);
|
bug("%s: Iface %s in down state?", p->name, ifa->iface->name);
|
||||||
break;
|
break;
|
||||||
case OSPF_IS_WAITING:
|
case OSPF_IS_WAITING:
|
||||||
DBG("%s: Neighbor? on iface %s\n",p->name, ifa->iface->name);
|
DBG("%s: Neighbor? on iface %s\n", p->name, ifa->iface->name);
|
||||||
break;
|
break;
|
||||||
case OSPF_IS_DROTHER:
|
case OSPF_IS_DROTHER:
|
||||||
if(((n->rid==ifa->drid) || (n->rid==ifa->bdrid))
|
if (((n->rid == ifa->drid) || (n->rid == ifa->bdrid))
|
||||||
&& (n->state>=NEIGHBOR_2WAY)) i=1;
|
&& (n->state >= NEIGHBOR_2WAY))
|
||||||
|
i = 1;
|
||||||
break;
|
break;
|
||||||
case OSPF_IS_PTP:
|
case OSPF_IS_PTP:
|
||||||
case OSPF_IS_BACKUP:
|
case OSPF_IS_BACKUP:
|
||||||
case OSPF_IS_DR:
|
case OSPF_IS_DR:
|
||||||
if(n->state>=NEIGHBOR_2WAY) i=1;
|
if (n->state >= NEIGHBOR_2WAY)
|
||||||
|
i = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bug("%s: Iface %s in unknown state?",p->name, ifa->iface->name);
|
bug("%s: Iface %s in unknown state?", p->name, ifa->iface->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bug("%s: Iface %s is unknown type?",p->name, ifa->iface->name);
|
bug("%s: Iface %s is unknown type?", p->name, ifa->iface->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DBG("%s: Iface %s can_do_adj=%d\n",p->name, ifa->iface->name,i);
|
DBG("%s: Iface %s can_do_adj=%d\n", p->name, ifa->iface->name, i);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,91 +287,94 @@ can_do_adj(struct ospf_neighbor *n)
|
||||||
void
|
void
|
||||||
ospf_neigh_sm(struct ospf_neighbor *n, int event)
|
ospf_neigh_sm(struct ospf_neighbor *n, int event)
|
||||||
{
|
{
|
||||||
struct proto_ospf *po=n->ifa->proto;
|
struct proto_ospf *po = n->ifa->proto;
|
||||||
struct proto *p=(struct proto *)po;
|
struct proto *p = (struct proto *) po;
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS, "Neighbor state machine for neighbor %I, event \"%s\".",
|
OSPF_TRACE(D_EVENTS,
|
||||||
n->ip, ospf_inm[event]);
|
"Neighbor state machine for neighbor %I, event \"%s\".", n->ip,
|
||||||
|
ospf_inm[event]);
|
||||||
|
|
||||||
switch(event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case INM_START:
|
case INM_START:
|
||||||
neigh_chstate(n,NEIGHBOR_ATTEMPT);
|
neigh_chstate(n, NEIGHBOR_ATTEMPT);
|
||||||
/* NBMA are used different way */
|
/* NBMA are used different way */
|
||||||
break;
|
break;
|
||||||
case INM_HELLOREC:
|
case INM_HELLOREC:
|
||||||
switch(n->state)
|
switch (n->state)
|
||||||
{
|
{
|
||||||
case NEIGHBOR_ATTEMPT:
|
case NEIGHBOR_ATTEMPT:
|
||||||
case NEIGHBOR_DOWN:
|
case NEIGHBOR_DOWN:
|
||||||
neigh_chstate(n, NEIGHBOR_INIT);
|
neigh_chstate(n, NEIGHBOR_INIT);
|
||||||
default:
|
default:
|
||||||
tm_start(n->inactim, n->ifa->deadc*n->ifa->helloint); /* Restart inactivity timer */
|
tm_start(n->inactim, n->ifa->deadc * n->ifa->helloint); /* Restart inactivity timer */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INM_2WAYREC:
|
case INM_2WAYREC:
|
||||||
if(n->state<NEIGHBOR_2WAY) neigh_chstate(n,NEIGHBOR_2WAY);
|
if (n->state < NEIGHBOR_2WAY)
|
||||||
if((n->state==NEIGHBOR_2WAY) && can_do_adj(n))
|
neigh_chstate(n, NEIGHBOR_2WAY);
|
||||||
neigh_chstate(n,NEIGHBOR_EXSTART);
|
if ((n->state == NEIGHBOR_2WAY) && can_do_adj(n))
|
||||||
|
neigh_chstate(n, NEIGHBOR_EXSTART);
|
||||||
break;
|
break;
|
||||||
case INM_NEGDONE:
|
case INM_NEGDONE:
|
||||||
if(n->state==NEIGHBOR_EXSTART)
|
if (n->state == NEIGHBOR_EXSTART)
|
||||||
{
|
{
|
||||||
neigh_chstate(n,NEIGHBOR_EXCHANGE);
|
neigh_chstate(n, NEIGHBOR_EXCHANGE);
|
||||||
s_init(&(n->dbsi), &(n->ifa->oa->lsal));
|
s_init(&(n->dbsi), &(n->ifa->oa->lsal));
|
||||||
while(!EMPTY_LIST(n->ackl[ACKL_DELAY]))
|
while (!EMPTY_LIST(n->ackl[ACKL_DELAY]))
|
||||||
{
|
{
|
||||||
struct lsah_n *no;
|
struct lsah_n *no;
|
||||||
no=(struct lsah_n *)HEAD(n->ackl[ACKL_DELAY]);
|
no = (struct lsah_n *) HEAD(n->ackl[ACKL_DELAY]);
|
||||||
rem_node(NODE no);
|
rem_node(NODE no);
|
||||||
mb_free(no);
|
mb_free(no);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else bug("NEGDONE and I'm not in EXSTART?");
|
else
|
||||||
|
bug("NEGDONE and I'm not in EXSTART?");
|
||||||
break;
|
break;
|
||||||
case INM_EXDONE:
|
case INM_EXDONE:
|
||||||
neigh_chstate(n,NEIGHBOR_LOADING);
|
neigh_chstate(n, NEIGHBOR_LOADING);
|
||||||
break;
|
break;
|
||||||
case INM_LOADDONE:
|
case INM_LOADDONE:
|
||||||
neigh_chstate(n,NEIGHBOR_FULL);
|
neigh_chstate(n, NEIGHBOR_FULL);
|
||||||
break;
|
break;
|
||||||
case INM_ADJOK:
|
case INM_ADJOK:
|
||||||
switch(n->state)
|
switch (n->state)
|
||||||
{
|
{
|
||||||
case NEIGHBOR_2WAY:
|
case NEIGHBOR_2WAY:
|
||||||
/* Can In build adjacency? */
|
/* Can In build adjacency? */
|
||||||
if(can_do_adj(n))
|
if (can_do_adj(n))
|
||||||
{
|
{
|
||||||
neigh_chstate(n,NEIGHBOR_EXSTART);
|
neigh_chstate(n, NEIGHBOR_EXSTART);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(n->state>=NEIGHBOR_EXSTART)
|
if (n->state >= NEIGHBOR_EXSTART)
|
||||||
if(!can_do_adj(n))
|
if (!can_do_adj(n))
|
||||||
{
|
{
|
||||||
neigh_chstate(n,NEIGHBOR_2WAY);
|
neigh_chstate(n, NEIGHBOR_2WAY);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INM_SEQMIS:
|
case INM_SEQMIS:
|
||||||
case INM_BADLSREQ:
|
case INM_BADLSREQ:
|
||||||
if(n->state>=NEIGHBOR_EXCHANGE)
|
if (n->state >= NEIGHBOR_EXCHANGE)
|
||||||
{
|
{
|
||||||
neigh_chstate(n,NEIGHBOR_EXSTART);
|
neigh_chstate(n, NEIGHBOR_EXSTART);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INM_KILLNBR:
|
case INM_KILLNBR:
|
||||||
case INM_LLDOWN:
|
case INM_LLDOWN:
|
||||||
case INM_INACTTIM:
|
case INM_INACTTIM:
|
||||||
neigh_chstate(n,NEIGHBOR_DOWN);
|
neigh_chstate(n, NEIGHBOR_DOWN);
|
||||||
break;
|
break;
|
||||||
case INM_1WAYREC:
|
case INM_1WAYREC:
|
||||||
neigh_chstate(n,NEIGHBOR_INIT);
|
neigh_chstate(n, NEIGHBOR_INIT);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bug("%s: INM - Unknown event?",p->name);
|
bug("%s: INM - Unknown event?", p->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,91 +391,104 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
|
||||||
void
|
void
|
||||||
bdr_election(struct ospf_iface *ifa)
|
bdr_election(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *neigh,*ndr,*nbdr,me;
|
struct ospf_neighbor *neigh, *ndr, *nbdr, me;
|
||||||
u32 myid;
|
u32 myid;
|
||||||
ip_addr ndrip, nbdrip;
|
ip_addr ndrip, nbdrip;
|
||||||
int doadj;
|
int doadj;
|
||||||
struct proto *p=&ifa->proto->proto;
|
struct proto *p = &ifa->proto->proto;
|
||||||
|
|
||||||
DBG("(B)DR election.\n");
|
DBG("(B)DR election.\n");
|
||||||
|
|
||||||
myid=p->cf->global->router_id;
|
myid = p->cf->global->router_id;
|
||||||
|
|
||||||
me.state=NEIGHBOR_2WAY;
|
me.state = NEIGHBOR_2WAY;
|
||||||
me.rid=myid;
|
me.rid = myid;
|
||||||
me.priority=ifa->priority;
|
me.priority = ifa->priority;
|
||||||
me.dr=ifa->drip;
|
me.dr = ifa->drip;
|
||||||
me.bdr=ifa->bdrip;
|
me.bdr = ifa->bdrip;
|
||||||
me.ip=ifa->iface->addr->ip;
|
me.ip = ifa->iface->addr->ip;
|
||||||
|
|
||||||
add_tail(&ifa->neigh_list, NODE &me);
|
add_tail(&ifa->neigh_list, NODE & me);
|
||||||
|
|
||||||
nbdr=electbdr(ifa->neigh_list);
|
nbdr = electbdr(ifa->neigh_list);
|
||||||
ndr=electdr(ifa->neigh_list);
|
ndr = electdr(ifa->neigh_list);
|
||||||
|
|
||||||
if(ndr==NULL) ndr=nbdr;
|
if (ndr == NULL)
|
||||||
|
ndr = nbdr;
|
||||||
|
|
||||||
if(((ifa->drid==myid) && (ndr!=&me))
|
if (((ifa->drid == myid) && (ndr != &me))
|
||||||
|| ((ifa->drid!=myid) && (ndr==&me))
|
|| ((ifa->drid != myid) && (ndr == &me))
|
||||||
|| ((ifa->bdrid==myid) && (nbdr!=&me))
|
|| ((ifa->bdrid == myid) && (nbdr != &me))
|
||||||
|| ((ifa->bdrid!=myid) && (nbdr==&me)))
|
|| ((ifa->bdrid != myid) && (nbdr == &me)))
|
||||||
{
|
{
|
||||||
if(ndr==NULL) ifa->drip=me.dr=ipa_from_u32(0);
|
if (ndr == NULL)
|
||||||
else ifa->drip=me.dr=ndr->ip;
|
ifa->drip = me.dr = ipa_from_u32(0);
|
||||||
|
else
|
||||||
|
ifa->drip = me.dr = ndr->ip;
|
||||||
|
|
||||||
if(nbdr==NULL) ifa->bdrip=me.bdr=ipa_from_u32(0);
|
if (nbdr == NULL)
|
||||||
else ifa->bdrip=me.bdr=nbdr->ip;
|
ifa->bdrip = me.bdr = ipa_from_u32(0);
|
||||||
|
else
|
||||||
|
ifa->bdrip = me.bdr = nbdr->ip;
|
||||||
|
|
||||||
nbdr=electbdr(ifa->neigh_list);
|
nbdr = electbdr(ifa->neigh_list);
|
||||||
ndr=electdr(ifa->neigh_list);
|
ndr = electdr(ifa->neigh_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ndr==NULL) ndrip=ipa_from_u32(0);
|
if (ndr == NULL)
|
||||||
else ndrip=ndr->ip;
|
ndrip = ipa_from_u32(0);
|
||||||
|
else
|
||||||
|
ndrip = ndr->ip;
|
||||||
|
|
||||||
if(nbdr==NULL) nbdrip=ipa_from_u32(0);
|
if (nbdr == NULL)
|
||||||
else nbdrip=nbdr->ip;
|
nbdrip = ipa_from_u32(0);
|
||||||
|
else
|
||||||
|
nbdrip = nbdr->ip;
|
||||||
|
|
||||||
doadj=0;
|
doadj = 0;
|
||||||
if((ipa_compare(ifa->drip,ndrip)!=0) || (ipa_compare(ifa->bdrip,nbdrip)!=0))
|
if ((ipa_compare(ifa->drip, ndrip) != 0)
|
||||||
doadj=1;
|
|| (ipa_compare(ifa->bdrip, nbdrip) != 0))
|
||||||
|
doadj = 1;
|
||||||
|
|
||||||
if(ndr==NULL)
|
if (ndr == NULL)
|
||||||
{
|
{
|
||||||
ifa->drid=0;
|
ifa->drid = 0;
|
||||||
ifa->drip=ipa_from_u32(0);
|
ifa->drip = ipa_from_u32(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ifa->drid=ndr->rid;
|
ifa->drid = ndr->rid;
|
||||||
ifa->drip=ndr->ip;
|
ifa->drip = ndr->ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nbdr==NULL)
|
if (nbdr == NULL)
|
||||||
{
|
{
|
||||||
ifa->bdrid=0;
|
ifa->bdrid = 0;
|
||||||
ifa->bdrip=ipa_from_u32(0);
|
ifa->bdrip = ipa_from_u32(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ifa->bdrid=nbdr->rid;
|
ifa->bdrid = nbdr->rid;
|
||||||
ifa->bdrip=nbdr->ip;
|
ifa->bdrip = nbdr->ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("DR=%I, BDR=%I\n", ifa->drid, ifa->bdrid);
|
DBG("DR=%I, BDR=%I\n", ifa->drid, ifa->bdrid);
|
||||||
|
|
||||||
if(myid==ifa->drid) ospf_iface_chstate(ifa, OSPF_IS_DR);
|
if (myid == ifa->drid)
|
||||||
|
ospf_iface_chstate(ifa, OSPF_IS_DR);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(myid==ifa->bdrid) ospf_iface_chstate(ifa, OSPF_IS_BACKUP);
|
if (myid == ifa->bdrid)
|
||||||
else ospf_iface_chstate(ifa, OSPF_IS_DROTHER);
|
ospf_iface_chstate(ifa, OSPF_IS_BACKUP);
|
||||||
|
else
|
||||||
|
ospf_iface_chstate(ifa, OSPF_IS_DROTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
rem_node(NODE &me);
|
rem_node(NODE & me);
|
||||||
|
|
||||||
if(doadj)
|
if (doadj)
|
||||||
{
|
{
|
||||||
WALK_LIST (neigh, ifa->neigh_list)
|
WALK_LIST(neigh, ifa->neigh_list)
|
||||||
{
|
{
|
||||||
ospf_neigh_sm(neigh, INM_ADJOK);
|
ospf_neigh_sm(neigh, INM_ADJOK);
|
||||||
}
|
}
|
||||||
|
@ -471,8 +500,7 @@ find_neigh(struct ospf_iface *ifa, u32 rid)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
|
|
||||||
WALK_LIST (n, ifa->neigh_list)
|
WALK_LIST(n, ifa->neigh_list) if (n->rid == rid)
|
||||||
if(n->rid == rid)
|
|
||||||
return n;
|
return n;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -482,17 +510,17 @@ find_neigh(struct ospf_iface *ifa, u32 rid)
|
||||||
struct ospf_neighbor *
|
struct ospf_neighbor *
|
||||||
find_neigh_noifa(struct proto_ospf *po, u32 rid)
|
find_neigh_noifa(struct proto_ospf *po, u32 rid)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n=NULL,*m;
|
struct ospf_neighbor *n = NULL, *m;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
|
|
||||||
WALK_LIST (ifa, po->iface_list)
|
WALK_LIST(ifa, po->iface_list) if ((m = find_neigh(ifa, rid)) != NULL)
|
||||||
if((m=find_neigh(ifa, rid))!=NULL)
|
|
||||||
{
|
{
|
||||||
if(m->state>=NEIGHBOR_2WAY)
|
if (m->state >= NEIGHBOR_2WAY)
|
||||||
{
|
{
|
||||||
if(n==NULL) n=m;
|
if (n == NULL)
|
||||||
else
|
n = m;
|
||||||
if(m->ifa->cost < n->ifa->cost) n=m;
|
else if (m->ifa->cost < n->ifa->cost)
|
||||||
|
n = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
@ -502,23 +530,25 @@ struct ospf_area *
|
||||||
ospf_find_area(struct proto_ospf *po, u32 aid)
|
ospf_find_area(struct proto_ospf *po, u32 aid)
|
||||||
{
|
{
|
||||||
struct ospf_area *oa;
|
struct ospf_area *oa;
|
||||||
WALK_LIST(NODE oa,po->area_list)
|
WALK_LIST(NODE oa, po->area_list)
|
||||||
if(((struct ospf_area *)oa)->areaid==aid) return oa;
|
if (((struct ospf_area *) oa)->areaid == aid)
|
||||||
|
return oa;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Neighbor is inactive for a long time. Remove it. */
|
/* Neighbor is inactive for a long time. Remove it. */
|
||||||
void
|
void
|
||||||
neighbor_timer_hook(timer *timer)
|
neighbor_timer_hook(timer * timer)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
|
||||||
n=(struct ospf_neighbor *)timer->data;
|
n = (struct ospf_neighbor *) timer->data;
|
||||||
ifa=n->ifa;
|
ifa = n->ifa;
|
||||||
p=(struct proto *)(ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
OSPF_TRACE(D_EVENTS,"Inactivity timer fired on interface %s for neighbor %I.",
|
OSPF_TRACE(D_EVENTS,
|
||||||
|
"Inactivity timer fired on interface %s for neighbor %I.",
|
||||||
ifa->iface->name, n->ip);
|
ifa->iface->name, n->ip);
|
||||||
ospf_neigh_remove(n);
|
ospf_neigh_remove(n);
|
||||||
}
|
}
|
||||||
|
@ -529,8 +559,8 @@ ospf_neigh_remove(struct ospf_neighbor *n)
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
|
||||||
ifa=n->ifa;
|
ifa = n->ifa;
|
||||||
p=(struct proto *)(ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
neigh_chstate(n, NEIGHBOR_DOWN);
|
neigh_chstate(n, NEIGHBOR_DOWN);
|
||||||
rem_node(NODE n);
|
rem_node(NODE n);
|
||||||
rfree(n->pool);
|
rfree(n->pool);
|
||||||
|
@ -540,60 +570,66 @@ ospf_neigh_remove(struct ospf_neighbor *n)
|
||||||
void
|
void
|
||||||
ospf_sh_neigh_info(struct ospf_neighbor *n)
|
ospf_sh_neigh_info(struct ospf_neighbor *n)
|
||||||
{
|
{
|
||||||
struct ospf_iface *ifa=n->ifa;
|
struct ospf_iface *ifa = n->ifa;
|
||||||
char *pos="other";
|
char *pos = "other";
|
||||||
char etime[6];
|
char etime[6];
|
||||||
int exp,sec,min;
|
int exp, sec, min;
|
||||||
|
|
||||||
exp=n->inactim->expires-now;
|
exp = n->inactim->expires - now;
|
||||||
sec=exp-(exp/60);
|
sec = exp - (exp / 60);
|
||||||
min=(exp-sec)/60;
|
min = (exp - sec) / 60;
|
||||||
if(min>59)
|
if (min > 59)
|
||||||
{
|
{
|
||||||
bsprintf(etime,"-Inf-");
|
bsprintf(etime, "-Inf-");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bsprintf(etime,"%02u:%02u", min, sec);
|
bsprintf(etime, "%02u:%02u", min, sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->rid==ifa->drid) pos="dr ";
|
if (n->rid == ifa->drid)
|
||||||
if(n->rid==ifa->bdrid) pos="bdr ";
|
pos = "dr ";
|
||||||
if(n->ifa->type==OSPF_IT_PTP) pos="ptp ";
|
if (n->rid == ifa->bdrid)
|
||||||
|
pos = "bdr ";
|
||||||
|
if (n->ifa->type == OSPF_IT_PTP)
|
||||||
|
pos = "ptp ";
|
||||||
|
|
||||||
cli_msg(-1013,"%-1I\t%3u\t%s/%s\t%-5s\t%-1I\t%-10s",n->rid, n->priority,
|
cli_msg(-1013, "%-1I\t%3u\t%s/%s\t%-5s\t%-1I\t%-10s", n->rid, n->priority,
|
||||||
ospf_ns[n->state], pos, etime, n->ip,ifa->iface->name);
|
ospf_ns[n->state], pos, etime, n->ip, ifa->iface->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rxmt_timer_hook(timer *timer)
|
rxmt_timer_hook(timer * timer)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n = (struct ospf_neighbor *)timer->data;
|
struct ospf_neighbor *n = (struct ospf_neighbor *) timer->data;
|
||||||
struct top_hash_entry *en;
|
struct top_hash_entry *en;
|
||||||
|
|
||||||
DBG("%s: RXMT timer fired on interface %s for neigh: %I.\n",
|
DBG("%s: RXMT timer fired on interface %s for neigh: %I.\n",
|
||||||
p->name, ifa->iface->name, n->ip);
|
p->name, ifa->iface->name, n->ip);
|
||||||
if (n->state < NEIGHBOR_LOADING) ospf_dbdes_send(n);
|
if (n->state < NEIGHBOR_LOADING)
|
||||||
|
ospf_dbdes_send(n);
|
||||||
|
|
||||||
if(n->state < NEIGHBOR_FULL) ospf_lsreq_send(n);
|
if (n->state < NEIGHBOR_FULL)
|
||||||
|
ospf_lsreq_send(n);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!EMPTY_SLIST(n->lsrtl))
|
if (!EMPTY_SLIST(n->lsrtl))
|
||||||
{
|
{
|
||||||
list uplist;
|
list uplist;
|
||||||
slab *upslab;
|
slab *upslab;
|
||||||
struct l_lsr_head *llsh;
|
struct l_lsr_head *llsh;
|
||||||
|
|
||||||
init_list(&uplist);
|
init_list(&uplist);
|
||||||
upslab=sl_new(n->pool,sizeof(struct l_lsr_head));
|
upslab = sl_new(n->pool, sizeof(struct l_lsr_head));
|
||||||
|
|
||||||
WALK_SLIST(SNODE en,n->lsrtl)
|
WALK_SLIST(SNODE en, n->lsrtl)
|
||||||
{
|
{
|
||||||
if((SNODE en)->next==(SNODE en)) bug("RTList is cycled");
|
if ((SNODE en)->next == (SNODE en))
|
||||||
llsh=sl_alloc(upslab);
|
bug("RTList is cycled");
|
||||||
llsh->lsh.id=en->lsa.id;
|
llsh = sl_alloc(upslab);
|
||||||
llsh->lsh.rt=en->lsa.rt;
|
llsh->lsh.id = en->lsa.id;
|
||||||
llsh->lsh.type=en->lsa.type;
|
llsh->lsh.rt = en->lsa.rt;
|
||||||
|
llsh->lsh.type = en->lsa.type;
|
||||||
DBG("Working on ID: %I, RT: %I, Type: %u\n",
|
DBG("Working on ID: %I, RT: %I, Type: %u\n",
|
||||||
en->lsa.id, en->lsa.rt, en->lsa.type);
|
en->lsa.id, en->lsa.rt, en->lsa.type);
|
||||||
add_tail(&uplist, NODE llsh);
|
add_tail(&uplist, NODE llsh);
|
||||||
|
@ -605,9 +641,8 @@ rxmt_timer_hook(timer *timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ackd_timer_hook(timer *t)
|
ackd_timer_hook(timer * t)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n=t->data;
|
struct ospf_neighbor *n = t->data;
|
||||||
ospf_lsack_send(n, ACKL_DELAY);
|
ospf_lsack_send(n, ACKL_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -53,19 +53,22 @@
|
||||||
#define LSINFINITY 0xffff /* RFC says 0xffffff ??? */
|
#define LSINFINITY 0xffff /* RFC says 0xffffff ??? */
|
||||||
#define DISPTICK 7
|
#define DISPTICK 7
|
||||||
|
|
||||||
struct ospf_config {
|
struct ospf_config
|
||||||
|
{
|
||||||
struct proto_config c;
|
struct proto_config c;
|
||||||
int rfc1583;
|
int rfc1583;
|
||||||
list area_list;
|
list area_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nbma_node {
|
struct nbma_node
|
||||||
|
{
|
||||||
node n;
|
node n;
|
||||||
ip_addr ip;
|
ip_addr ip;
|
||||||
int eligible;
|
int eligible;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct area_net {
|
struct area_net
|
||||||
|
{
|
||||||
node n;
|
node n;
|
||||||
struct prefix px;
|
struct prefix px;
|
||||||
int hidden;
|
int hidden;
|
||||||
|
@ -73,7 +76,8 @@ struct area_net {
|
||||||
int oldactive;
|
int oldactive;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_area_config {
|
struct ospf_area_config
|
||||||
|
{
|
||||||
node n;
|
node n;
|
||||||
u32 areaid;
|
u32 areaid;
|
||||||
int stub;
|
int stub;
|
||||||
|
@ -82,7 +86,8 @@ struct ospf_area_config {
|
||||||
list net_list;
|
list net_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_iface {
|
struct ospf_iface
|
||||||
|
{
|
||||||
node n;
|
node n;
|
||||||
struct proto_ospf *proto;
|
struct proto_ospf *proto;
|
||||||
struct iface *iface; /* Nest's iface */
|
struct iface *iface; /* Nest's iface */
|
||||||
|
@ -150,7 +155,8 @@ struct ospf_iface {
|
||||||
list nbma_list;
|
list nbma_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_packet {
|
struct ospf_packet
|
||||||
|
{
|
||||||
u8 version;
|
u8 version;
|
||||||
u8 type;
|
u8 type;
|
||||||
#define HELLO_P 1 /* Hello */
|
#define HELLO_P 1 /* Hello */
|
||||||
|
@ -167,7 +173,8 @@ struct ospf_packet {
|
||||||
u8 authetication[8];
|
u8 authetication[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_hello_packet {
|
struct ospf_hello_packet
|
||||||
|
{
|
||||||
struct ospf_packet ospf_packet;
|
struct ospf_packet ospf_packet;
|
||||||
ip_addr netmask;
|
ip_addr netmask;
|
||||||
u16 helloint;
|
u16 helloint;
|
||||||
|
@ -178,7 +185,8 @@ struct ospf_hello_packet {
|
||||||
ip_addr bdr;
|
ip_addr bdr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct immsb {
|
struct immsb
|
||||||
|
{
|
||||||
#ifdef _BIG_ENDIAN
|
#ifdef _BIG_ENDIAN
|
||||||
u8 padding:5;
|
u8 padding:5;
|
||||||
u8 i:1;
|
u8 i:1;
|
||||||
|
@ -192,12 +200,14 @@ struct immsb {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
union imms {
|
union imms
|
||||||
|
{
|
||||||
u8 byte;
|
u8 byte;
|
||||||
struct immsb bit;
|
struct immsb bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_dbdes_packet {
|
struct ospf_dbdes_packet
|
||||||
|
{
|
||||||
struct ospf_packet ospf_packet;
|
struct ospf_packet ospf_packet;
|
||||||
u16 iface_mtu;
|
u16 iface_mtu;
|
||||||
u8 options;
|
u8 options;
|
||||||
|
@ -209,7 +219,8 @@ struct ospf_dbdes_packet {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ospf_lsa_header {
|
struct ospf_lsa_header
|
||||||
|
{
|
||||||
u16 age; /* LS Age */
|
u16 age; /* LS Age */
|
||||||
#define LSA_MAXAGE 3600 /* 1 hour */
|
#define LSA_MAXAGE 3600 /* 1 hour */
|
||||||
#define LSA_CHECKAGE 300 /* 5 minutes */
|
#define LSA_CHECKAGE 300 /* 5 minutes */
|
||||||
|
@ -230,19 +241,22 @@ struct ospf_lsa_header {
|
||||||
u16 length;
|
u16 length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vebb {
|
struct vebb
|
||||||
|
{
|
||||||
u8 b:1;
|
u8 b:1;
|
||||||
u8 e:1;
|
u8 e:1;
|
||||||
u8 v:1;
|
u8 v:1;
|
||||||
u8 padding:5;
|
u8 padding:5;
|
||||||
};
|
};
|
||||||
|
|
||||||
union veb {
|
union veb
|
||||||
|
{
|
||||||
u8 byte;
|
u8 byte;
|
||||||
struct vebb bit;
|
struct vebb bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_rt {
|
struct ospf_lsa_rt
|
||||||
|
{
|
||||||
union veb veb;
|
union veb veb;
|
||||||
#define LSA_RT_V 5
|
#define LSA_RT_V 5
|
||||||
#define LSA_RT_E 6
|
#define LSA_RT_E 6
|
||||||
|
@ -251,7 +265,8 @@ struct ospf_lsa_rt {
|
||||||
u16 links;
|
u16 links;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_rt_link {
|
struct ospf_lsa_rt_link
|
||||||
|
{
|
||||||
u32 id;
|
u32 id;
|
||||||
u32 data;
|
u32 data;
|
||||||
u8 type;
|
u8 type;
|
||||||
|
@ -263,31 +278,37 @@ struct ospf_lsa_rt_link {
|
||||||
u16 metric;
|
u16 metric;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_rt_link_tos { /* Actually we ignore TOS. This is useless */
|
struct ospf_lsa_rt_link_tos
|
||||||
|
{ /* Actually we ignore TOS. This is useless */
|
||||||
u8 tos;
|
u8 tos;
|
||||||
u8 padding;
|
u8 padding;
|
||||||
u16 metric;
|
u16 metric;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_net {
|
struct ospf_lsa_net
|
||||||
|
{
|
||||||
ip_addr netmask;
|
ip_addr netmask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_summ {
|
struct ospf_lsa_summ
|
||||||
|
{
|
||||||
ip_addr netmask;
|
ip_addr netmask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_summ_net {
|
struct ospf_lsa_summ_net
|
||||||
|
{
|
||||||
u8 tos;
|
u8 tos;
|
||||||
u8 padding;
|
u8 padding;
|
||||||
u16 metric;
|
u16 metric;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_ext {
|
struct ospf_lsa_ext
|
||||||
|
{
|
||||||
ip_addr netmask;
|
ip_addr netmask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsa_ext_tos {
|
struct ospf_lsa_ext_tos
|
||||||
|
{
|
||||||
u8 etos;
|
u8 etos;
|
||||||
u8 padding;
|
u8 padding;
|
||||||
u16 metric;
|
u16 metric;
|
||||||
|
@ -295,11 +316,13 @@ struct ospf_lsa_ext_tos {
|
||||||
u32 tag;
|
u32 tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsreq_packet {
|
struct ospf_lsreq_packet
|
||||||
|
{
|
||||||
struct ospf_packet ospf_packet;
|
struct ospf_packet ospf_packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsreq_header {
|
struct ospf_lsreq_header
|
||||||
|
{
|
||||||
u16 padd1;
|
u16 padd1;
|
||||||
u8 padd2;
|
u8 padd2;
|
||||||
u8 type;
|
u8 type;
|
||||||
|
@ -307,17 +330,20 @@ struct ospf_lsreq_header {
|
||||||
u32 rt; /* Advertising router */
|
u32 rt; /* Advertising router */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct l_lsr_head {
|
struct l_lsr_head
|
||||||
|
{
|
||||||
node n;
|
node n;
|
||||||
struct ospf_lsreq_header lsh;
|
struct ospf_lsreq_header lsh;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsupd_packet {
|
struct ospf_lsupd_packet
|
||||||
|
{
|
||||||
struct ospf_packet ospf_packet;
|
struct ospf_packet ospf_packet;
|
||||||
u32 lsano; /* Number of LSA's */
|
u32 lsano; /* Number of LSA's */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_lsack_packet {
|
struct ospf_lsack_packet
|
||||||
|
{
|
||||||
struct ospf_packet ospf_packet;
|
struct ospf_packet ospf_packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -387,7 +413,8 @@ struct ospf_neighbor
|
||||||
#define INM_INACTTIM 11 /* Inactivity timer */
|
#define INM_INACTTIM 11 /* Inactivity timer */
|
||||||
#define INM_LLDOWN 12 /* Line down */
|
#define INM_LLDOWN 12 /* Line down */
|
||||||
|
|
||||||
struct ospf_area {
|
struct ospf_area
|
||||||
|
{
|
||||||
node n;
|
node n;
|
||||||
u32 areaid;
|
u32 areaid;
|
||||||
timer *disp_timer; /* Area's dispatcher hear beat */
|
timer *disp_timer; /* Area's dispatcher hear beat */
|
||||||
|
@ -405,7 +432,8 @@ struct ospf_area {
|
||||||
unsigned tick;
|
unsigned tick;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proto_ospf {
|
struct proto_ospf
|
||||||
|
{
|
||||||
struct proto proto;
|
struct proto proto;
|
||||||
list iface_list; /* Interfaces we really use */
|
list iface_list; /* Interfaces we really use */
|
||||||
list area_list;
|
list area_list;
|
||||||
|
@ -415,7 +443,8 @@ struct proto_ospf {
|
||||||
int ebit; /* Did I originate any ext lsa? */
|
int ebit; /* Did I originate any ext lsa? */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_iface_patt {
|
struct ospf_iface_patt
|
||||||
|
{
|
||||||
struct iface_patt i;
|
struct iface_patt i;
|
||||||
int cost;
|
int cost;
|
||||||
int helloint;
|
int helloint;
|
||||||
|
@ -437,12 +466,13 @@ struct ospf_iface_patt {
|
||||||
list nbma_list;
|
list nbma_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
int ospf_import_control(struct proto *p, rte **new, ea_list **attrs,
|
int ospf_import_control(struct proto *p, rte ** new, ea_list ** attrs,
|
||||||
struct linpool *pool);
|
struct linpool *pool);
|
||||||
struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
|
struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
|
||||||
void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs);
|
void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs);
|
||||||
void ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old,ea_list *attrs);
|
void ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old,
|
||||||
void area_disp(timer *timer);
|
ea_list * attrs);
|
||||||
|
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 schedule_net_lsa(struct ospf_iface *ifa);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "ospf.h"
|
#include "ospf.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
fill_ospf_pkt_hdr (struct ospf_iface *ifa, void *buf, u8 h_type)
|
fill_ospf_pkt_hdr(struct ospf_iface *ifa, void *buf, u8 h_type)
|
||||||
{
|
{
|
||||||
struct ospf_packet *pkt;
|
struct ospf_packet *pkt;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
@ -22,25 +22,25 @@ fill_ospf_pkt_hdr (struct ospf_iface *ifa, void *buf, u8 h_type)
|
||||||
|
|
||||||
pkt->type = h_type;
|
pkt->type = h_type;
|
||||||
|
|
||||||
pkt->routerid = htonl (p->cf->global->router_id);
|
pkt->routerid = htonl(p->cf->global->router_id);
|
||||||
pkt->areaid = htonl (ifa->an);
|
pkt->areaid = htonl(ifa->an);
|
||||||
pkt->autype = htons (ifa->autype);
|
pkt->autype = htons(ifa->autype);
|
||||||
pkt->checksum = 0;
|
pkt->checksum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_tx_authenticate (struct ospf_iface *ifa, struct ospf_packet *pkt)
|
ospf_tx_authenticate(struct ospf_iface *ifa, struct ospf_packet *pkt)
|
||||||
{
|
{
|
||||||
pkt->autype = htons (ifa->autype);
|
pkt->autype = htons(ifa->autype);
|
||||||
memcpy (pkt->authetication, ifa->aukey, 8);
|
memcpy(pkt->authetication, ifa->aukey, 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ospf_rx_authenticate (struct ospf_iface *ifa, struct ospf_packet *pkt)
|
ospf_rx_authenticate(struct ospf_iface *ifa, struct ospf_packet *pkt)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (pkt->autype != htons (ifa->autype))
|
if (pkt->autype != htons(ifa->autype))
|
||||||
return 0;
|
return 0;
|
||||||
if (ifa->autype == AU_NONE)
|
if (ifa->autype == AU_NONE)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -57,16 +57,16 @@ ospf_rx_authenticate (struct ospf_iface *ifa, struct ospf_packet *pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_pkt_finalize (struct ospf_iface *ifa, struct ospf_packet *pkt)
|
ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt)
|
||||||
{
|
{
|
||||||
|
|
||||||
ospf_tx_authenticate (ifa, pkt);
|
ospf_tx_authenticate(ifa, pkt);
|
||||||
|
|
||||||
/* Count checksum */
|
/* Count checksum */
|
||||||
pkt->checksum = ipsum_calculate (pkt, sizeof (struct ospf_packet) - 8,
|
pkt->checksum = ipsum_calculate(pkt, sizeof(struct ospf_packet) - 8,
|
||||||
(pkt + 1),
|
(pkt + 1),
|
||||||
ntohs (pkt->length) -
|
ntohs(pkt->length) -
|
||||||
sizeof (struct ospf_packet), NULL);
|
sizeof(struct ospf_packet), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +79,7 @@ ospf_pkt_finalize (struct ospf_iface *ifa, struct ospf_packet *pkt)
|
||||||
* non generic functions.
|
* non generic functions.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ospf_rx_hook (sock *sk, int size)
|
ospf_rx_hook(sock * sk, int size)
|
||||||
{
|
{
|
||||||
#ifndef IPV6
|
#ifndef IPV6
|
||||||
struct ospf_packet *ps;
|
struct ospf_packet *ps;
|
||||||
|
@ -89,74 +89,69 @@ ospf_rx_hook (sock *sk, int size)
|
||||||
if (ifa->stub)
|
if (ifa->stub)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
DBG ("%s: RX_Hook called on interface %s.\n", p->name, sk->iface->name);
|
DBG("%s: RX_Hook called on interface %s.\n", p->name, sk->iface->name);
|
||||||
|
|
||||||
ps = (struct ospf_packet *) ipv4_skip_header (sk->rbuf, &size);
|
ps = (struct ospf_packet *) ipv4_skip_header(sk->rbuf, &size);
|
||||||
if (ps == NULL)
|
if (ps == NULL)
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: bad IP header", p->name);
|
log("%s: Bad OSPF packet received: bad IP header", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
log("%s: Discarding", p->name);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((unsigned) size < sizeof (struct ospf_packet))
|
if ((unsigned) size < sizeof(struct ospf_packet))
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: too short (%u bytes)", p->name,
|
log("%s: Bad OSPF packet received: too short (%u bytes)", p->name, size);
|
||||||
size);
|
log("%s: Discarding", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ntohs (ps->length) != size) || (size != (4 * (size / 4))))
|
if ((ntohs(ps->length) != size) || (size != (4 * (size / 4))))
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: size field does not match",
|
log("%s: Bad OSPF packet received: size field does not match", p->name);
|
||||||
p->name);
|
log("%s: Discarding", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->version != OSPF_VERSION)
|
if (ps->version != OSPF_VERSION)
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: version %u", p->name, ps->version);
|
log("%s: Bad OSPF packet received: version %u", p->name, ps->version);
|
||||||
log ("%s: Discarding", p->name);
|
log("%s: Discarding", p->name);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ipsum_verify (ps, 16, (void *) ps + sizeof (struct ospf_packet),
|
if (!ipsum_verify(ps, 16, (void *) ps + sizeof(struct ospf_packet),
|
||||||
ntohs (ps->length) - sizeof (struct ospf_packet), NULL))
|
ntohs(ps->length) - sizeof(struct ospf_packet), NULL))
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: bad checksum", p->name);
|
log("%s: Bad OSPF packet received: bad checksum", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
log("%s: Discarding", p->name);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ospf_rx_authenticate (ifa, ps))
|
if (!ospf_rx_authenticate(ifa, ps))
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: bad password", p->name);
|
log("%s: Bad OSPF packet received: bad password", p->name);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntohl (ps->areaid) != ifa->an)
|
if (ntohl(ps->areaid) != ifa->an)
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: other area %ld", p->name,
|
log("%s: Bad OSPF packet received: other area %ld", p->name, ps->areaid);
|
||||||
ps->areaid);
|
log("%s: Discarding", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntohl (ps->routerid) == p->cf->global->router_id)
|
if (ntohl(ps->routerid) == p->cf->global->router_id)
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: received my own router ID!",
|
log("%s: Bad OSPF packet received: received my own router ID!", p->name);
|
||||||
p->name);
|
log("%s: Discarding", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntohl (ps->routerid) == 0)
|
if (ntohl(ps->routerid) == 0)
|
||||||
{
|
{
|
||||||
log ("%s: Bad OSPF packet received: Id 0.0.0.0 is not allowed.",
|
log("%s: Bad OSPF packet received: Id 0.0.0.0 is not allowed.", p->name);
|
||||||
p->name);
|
log("%s: Discarding", p->name);
|
||||||
log ("%s: Discarding", p->name);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,29 +166,28 @@ ospf_rx_hook (sock *sk, int size)
|
||||||
switch (ps->type)
|
switch (ps->type)
|
||||||
{
|
{
|
||||||
case HELLO_P:
|
case HELLO_P:
|
||||||
DBG ("%s: Hello received.\n", p->name);
|
DBG("%s: Hello received.\n", p->name);
|
||||||
ospf_hello_receive((struct ospf_hello_packet *) ps, ifa, size,
|
ospf_hello_receive((struct ospf_hello_packet *) ps, ifa, size, sk->faddr);
|
||||||
sk->faddr);
|
|
||||||
break;
|
break;
|
||||||
case DBDES_P:
|
case DBDES_P:
|
||||||
DBG ("%s: Database description received.\n", p->name);
|
DBG("%s: Database description received.\n", p->name);
|
||||||
ospf_dbdes_receive ((struct ospf_dbdes_packet *) ps, ifa, size);
|
ospf_dbdes_receive((struct ospf_dbdes_packet *) ps, ifa, size);
|
||||||
break;
|
break;
|
||||||
case LSREQ_P:
|
case LSREQ_P:
|
||||||
DBG ("%s: Link state request received.\n", p->name);
|
DBG("%s: Link state request received.\n", p->name);
|
||||||
ospf_lsreq_receive((struct ospf_lsreq_packet *) ps, ifa, size);
|
ospf_lsreq_receive((struct ospf_lsreq_packet *) ps, ifa, size);
|
||||||
break;
|
break;
|
||||||
case LSUPD_P:
|
case LSUPD_P:
|
||||||
DBG ("%s: Link state update received.\n", p->name);
|
DBG("%s: Link state update received.\n", p->name);
|
||||||
ospf_lsupd_receive((struct ospf_lsupd_packet *) ps, ifa, size);
|
ospf_lsupd_receive((struct ospf_lsupd_packet *) ps, ifa, size);
|
||||||
break;
|
break;
|
||||||
case LSACK_P:
|
case LSACK_P:
|
||||||
DBG ("%s: Link state ack received.\n", p->name);
|
DBG("%s: Link state ack received.\n", p->name);
|
||||||
ospf_lsack_receive((struct ospf_lsack_packet *) ps, ifa, size);
|
ospf_lsack_receive((struct ospf_lsack_packet *) ps, ifa, size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log ("%s: Bad packet received: wrong type %u", p->name, ps->type);
|
log("%s: Bad packet received: wrong type %u", p->name, ps->type);
|
||||||
log ("%s: Discarding\n", p->name);
|
log("%s: Discarding\n", p->name);
|
||||||
return (1);
|
return (1);
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
|
@ -203,7 +197,7 @@ ospf_rx_hook (sock *sk, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_tx_hook (sock * sk)
|
ospf_tx_hook(sock * sk)
|
||||||
{
|
{
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
@ -211,11 +205,11 @@ ospf_tx_hook (sock * sk)
|
||||||
ifa = (struct ospf_iface *) (sk->data);
|
ifa = (struct ospf_iface *) (sk->data);
|
||||||
|
|
||||||
p = (struct proto *) (ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
DBG ("%s: TX_Hook called on interface %s\n", p->name, sk->iface->name);
|
DBG("%s: TX_Hook called on interface %s\n", p->name, sk->iface->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_err_hook (sock * sk, int err UNUSED)
|
ospf_err_hook(sock * sk, int err UNUSED)
|
||||||
{
|
{
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
@ -223,23 +217,23 @@ ospf_err_hook (sock * sk, int err UNUSED)
|
||||||
ifa = (struct ospf_iface *) (sk->data);
|
ifa = (struct ospf_iface *) (sk->data);
|
||||||
|
|
||||||
p = (struct proto *) (ifa->proto);
|
p = (struct proto *) (ifa->proto);
|
||||||
DBG ("%s: Err_Hook called on interface %s\n", p->name, sk->iface->name);
|
DBG("%s: Err_Hook called on interface %s\n", p->name, sk->iface->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sk_send_to_agt (sock * sk, u16 len, struct ospf_iface *ifa, u8 state)
|
sk_send_to_agt(sock * sk, u16 len, struct ospf_iface *ifa, u8 state)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
|
|
||||||
WALK_LIST (NODE n, ifa->neigh_list) if (n->state >= state)
|
WALK_LIST(NODE n, ifa->neigh_list) if (n->state >= state)
|
||||||
sk_send_to (sk, len, n->ip, OSPF_PROTO);
|
sk_send_to(sk, len, n->ip, OSPF_PROTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sk_send_to_bdr (sock * sk, u16 len, struct ospf_iface *ifa)
|
sk_send_to_bdr(sock * sk, u16 len, struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
if (ipa_compare (ifa->drip, ipa_from_u32 (0)) != 0)
|
if (ipa_compare(ifa->drip, ipa_from_u32(0)) != 0)
|
||||||
sk_send_to (sk, len, ifa->drip, OSPF_PROTO);
|
sk_send_to(sk, len, ifa->drip, OSPF_PROTO);
|
||||||
if (ipa_compare (ifa->bdrip, ipa_from_u32 (0)) != 0)
|
if (ipa_compare(ifa->bdrip, ipa_from_u32(0)) != 0)
|
||||||
sk_send_to (sk, len, ifa->bdrip, OSPF_PROTO);
|
sk_send_to(sk, len, ifa->bdrip, OSPF_PROTO);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
void fill_ospf_pkt_hdr(struct ospf_iface *ifa, void *buf, u8 h_type);
|
void fill_ospf_pkt_hdr(struct ospf_iface *ifa, void *buf, u8 h_type);
|
||||||
void ospf_tx_authenticate(struct ospf_iface *ifa, struct ospf_packet *pkt);
|
void ospf_tx_authenticate(struct ospf_iface *ifa, struct ospf_packet *pkt);
|
||||||
void ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt);
|
void ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt);
|
||||||
int ospf_rx_hook(sock *sk, int size);
|
int ospf_rx_hook(sock * sk, int size);
|
||||||
void ospf_tx_hook(sock *sk);
|
void ospf_tx_hook(sock * sk);
|
||||||
void ospf_err_hook(sock *sk, int err);
|
void ospf_err_hook(sock * sk, int err);
|
||||||
void sk_send_to_agt(sock *sk, u16 len, struct ospf_iface *ifa, u8 state);
|
void sk_send_to_agt(sock * sk, u16 len, struct ospf_iface *ifa, u8 state);
|
||||||
void sk_send_to_bdr(sock *sk, u16 len, struct ospf_iface *ifa);
|
void sk_send_to_bdr(sock * sk, u16 len, struct ospf_iface *ifa);
|
||||||
|
|
||||||
#endif /* _BIRD_OSPF_PACKET_H_ */
|
#endif /* _BIRD_OSPF_PACKET_H_ */
|
||||||
|
|
601
proto/ospf/rt.c
601
proto/ospf/rt.c
|
@ -11,26 +11,26 @@
|
||||||
void
|
void
|
||||||
init_infib(struct fib_node *fn)
|
init_infib(struct fib_node *fn)
|
||||||
{
|
{
|
||||||
struct infib *f=(struct infib *)fn;
|
struct infib *f = (struct infib *) fn;
|
||||||
|
|
||||||
f->metric=LSINFINITY;
|
f->metric = LSINFINITY;
|
||||||
f->oldmetric=LSINFINITY;
|
f->oldmetric = LSINFINITY;
|
||||||
f->en=NULL;
|
f->en = NULL;
|
||||||
f->olden=NULL;
|
f->olden = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
init_efib(struct fib_node *fn)
|
init_efib(struct fib_node *fn)
|
||||||
{
|
{
|
||||||
struct extfib *f=(struct extfib *)fn;
|
struct extfib *f = (struct extfib *) fn;
|
||||||
|
|
||||||
f->metric=LSINFINITY;
|
f->metric = LSINFINITY;
|
||||||
f->metric2=LSINFINITY;
|
f->metric2 = LSINFINITY;
|
||||||
f->nh=ipa_from_u32(0);
|
f->nh = ipa_from_u32(0);
|
||||||
f->nhi=NULL;
|
f->nhi = NULL;
|
||||||
f->oldmetric=LSINFINITY;
|
f->oldmetric = LSINFINITY;
|
||||||
f->oldmetric2=LSINFINITY;
|
f->oldmetric2 = LSINFINITY;
|
||||||
f->oldnh=ipa_from_u32(0);
|
f->oldnh = ipa_from_u32(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,148 +46,158 @@ init_efib(struct fib_node *fn)
|
||||||
void
|
void
|
||||||
ospf_rt_spfa(struct ospf_area *oa)
|
ospf_rt_spfa(struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
u32 i,*rts;
|
u32 i, *rts;
|
||||||
struct ospf_lsa_rt *rt;
|
struct ospf_lsa_rt *rt;
|
||||||
struct ospf_lsa_rt_link *rtl,*rr;
|
struct ospf_lsa_rt_link *rtl, *rr;
|
||||||
struct fib *in=&oa->infib;
|
struct fib *in = &oa->infib;
|
||||||
struct infib *nf;
|
struct infib *nf;
|
||||||
struct fib_iterator fit;
|
struct fib_iterator fit;
|
||||||
struct proto *p=&oa->po->proto;
|
struct proto *p = &oa->po->proto;
|
||||||
struct proto_ospf *po=oa->po;
|
struct proto_ospf *po = oa->po;
|
||||||
ip_addr ip;
|
ip_addr ip;
|
||||||
struct ospf_lsa_net *ln;
|
struct ospf_lsa_net *ln;
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS, "Starting routing table calculation for area %I",
|
OSPF_TRACE(D_EVENTS, "Starting routing table calculation for area %I",
|
||||||
oa->areaid);
|
oa->areaid);
|
||||||
|
|
||||||
if(oa->rt==NULL) return;
|
if (oa->rt == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
FIB_WALK(in,nftmp)
|
FIB_WALK(in, nftmp)
|
||||||
{
|
{
|
||||||
nf=(struct infib *)nftmp;
|
nf = (struct infib *) nftmp;
|
||||||
nf->metric=LSINFINITY;
|
nf->metric = LSINFINITY;
|
||||||
nf->en=NULL;
|
nf->en = NULL;
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
|
|
||||||
init_list(&oa->cand); /* Empty list of candidates */
|
init_list(&oa->cand); /* Empty list of candidates */
|
||||||
oa->trcap=0;
|
oa->trcap = 0;
|
||||||
|
|
||||||
DBG("LSA db prepared, adding me into candidate list.\n");
|
DBG("LSA db prepared, adding me into candidate list.\n");
|
||||||
|
|
||||||
oa->rt->dist=0;
|
oa->rt->dist = 0;
|
||||||
oa->rt->color=CANDIDATE;
|
oa->rt->color = CANDIDATE;
|
||||||
add_head(&oa->cand, &oa->rt->cn);
|
add_head(&oa->cand, &oa->rt->cn);
|
||||||
DBG("RT LSA: rt: %I, id: %I, type: %u\n",oa->rt->lsa.rt,
|
DBG("RT LSA: rt: %I, id: %I, type: %u\n", oa->rt->lsa.rt,
|
||||||
oa->rt->lsa.id,oa->rt->lsa.type);
|
oa->rt->lsa.id, oa->rt->lsa.type);
|
||||||
|
|
||||||
while(!EMPTY_LIST(oa->cand))
|
while (!EMPTY_LIST(oa->cand))
|
||||||
{
|
{
|
||||||
struct top_hash_entry *act,*tmp;
|
struct top_hash_entry *act, *tmp;
|
||||||
node *n;
|
node *n;
|
||||||
u16 met;
|
u16 met;
|
||||||
|
|
||||||
n=HEAD(oa->cand);
|
n = HEAD(oa->cand);
|
||||||
act=SKIP_BACK(struct top_hash_entry, cn, n);
|
act = SKIP_BACK(struct top_hash_entry, cn, n);
|
||||||
rem_node(n);
|
rem_node(n);
|
||||||
|
|
||||||
DBG("Working on LSA: rt: %I, id: %I, type: %u\n",act->lsa.rt,
|
DBG("Working on LSA: rt: %I, id: %I, type: %u\n", act->lsa.rt,
|
||||||
act->lsa.id,act->lsa.type);
|
act->lsa.id, act->lsa.type);
|
||||||
|
|
||||||
act->color=INSPF;
|
act->color = INSPF;
|
||||||
switch(act->lsa.type)
|
switch (act->lsa.type)
|
||||||
{
|
{
|
||||||
case LSA_T_RT:
|
case LSA_T_RT:
|
||||||
rt=(struct ospf_lsa_rt *)act->lsa_body;
|
rt = (struct ospf_lsa_rt *) act->lsa_body;
|
||||||
if(rt->veb.bit.v) oa->trcap=1;
|
if (rt->veb.bit.v)
|
||||||
rr=(struct ospf_lsa_rt_link *)(rt+1);
|
oa->trcap = 1;
|
||||||
DBG(" Number of links: %u\n",rt->links);
|
rr = (struct ospf_lsa_rt_link *) (rt + 1);
|
||||||
for(i=0;i<rt->links;i++)
|
DBG(" Number of links: %u\n", rt->links);
|
||||||
|
for (i = 0; i < rt->links; i++)
|
||||||
{
|
{
|
||||||
tmp=NULL;
|
tmp = NULL;
|
||||||
rtl=(rr+i);
|
rtl = (rr + i);
|
||||||
DBG(" Working on link: %I (type: %u) ",rtl->id,rtl->type);
|
DBG(" Working on link: %I (type: %u) ", rtl->id, rtl->type);
|
||||||
switch(rtl->type)
|
switch (rtl->type)
|
||||||
{
|
{
|
||||||
case LSART_STUB:
|
case LSART_STUB:
|
||||||
/* This violates rfc2328! but I hope it's also correct. */
|
/* This violates rfc2328! but I hope it's also correct. */
|
||||||
DBG("\n");
|
DBG("\n");
|
||||||
ip=ipa_from_u32(rtl->id);
|
ip = ipa_from_u32(rtl->id);
|
||||||
nf=fib_get(in,&ip, ipa_mklen(ipa_from_u32(rtl->data)));
|
nf = fib_get(in, &ip, ipa_mklen(ipa_from_u32(rtl->data)));
|
||||||
if(nf->metric>(met=act->dist+rtl->metric))
|
if (nf->metric > (met = act->dist + rtl->metric))
|
||||||
{
|
{
|
||||||
DBG(" Adding stub route....\n");
|
DBG(" Adding stub route....\n");
|
||||||
if(oa->rt==act) break;
|
if (oa->rt == act)
|
||||||
if(act->nhi==NULL) break;
|
break;
|
||||||
nf->metric=met;
|
if (act->nhi == NULL)
|
||||||
nf->en=act;
|
break;
|
||||||
DBG(" Adding stub route: %I\n",ip);
|
nf->metric = met;
|
||||||
DBG(" Next hop=%I\n",nf->en->nh);
|
nf->en = act;
|
||||||
|
DBG(" Adding stub route: %I\n", ip);
|
||||||
|
DBG(" Next hop=%I\n", nf->en->nh);
|
||||||
}
|
}
|
||||||
else DBG(" NOT adding stub route: %I\n",ip);
|
else
|
||||||
|
DBG(" NOT adding stub route: %I\n", ip);
|
||||||
break;
|
break;
|
||||||
case LSART_VLNK:
|
case LSART_VLNK:
|
||||||
DBG("Ignoring\n");
|
DBG("Ignoring\n");
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case LSART_NET:
|
case LSART_NET:
|
||||||
tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_NET);
|
tmp = ospf_hash_find(oa->gr, rtl->id, rtl->id, LSA_T_NET);
|
||||||
if(tmp==NULL) DBG("Not found!\n");
|
if (tmp == NULL)
|
||||||
else DBG("Found. :-)\n");
|
DBG("Not found!\n");
|
||||||
|
else
|
||||||
|
DBG("Found. :-)\n");
|
||||||
break;
|
break;
|
||||||
case LSART_PTP:
|
case LSART_PTP:
|
||||||
tmp=ospf_hash_find(oa->gr,rtl->id,rtl->id,LSA_T_RT);
|
tmp = ospf_hash_find(oa->gr, rtl->id, rtl->id, LSA_T_RT);
|
||||||
DBG("PTP found.\n");
|
DBG("PTP found.\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log("Unknown link type in router lsa.");
|
log("Unknown link type in router lsa.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(tmp) DBG("Going to add cand, Mydist: %u, Req: %u\n",
|
if (tmp)
|
||||||
tmp->dist, act->dist+rtl->metric);
|
DBG("Going to add cand, Mydist: %u, Req: %u\n",
|
||||||
add_cand(&oa->cand,tmp,act,act->dist+rtl->metric,oa);
|
tmp->dist, act->dist + rtl->metric);
|
||||||
|
add_cand(&oa->cand, tmp, act, act->dist + rtl->metric, oa);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LSA_T_NET:
|
case LSA_T_NET:
|
||||||
ln=act->lsa_body;
|
ln = act->lsa_body;
|
||||||
ip=ipa_and(ipa_from_u32(act->lsa.id),ln->netmask);
|
ip = ipa_and(ipa_from_u32(act->lsa.id), ln->netmask);
|
||||||
nf=fib_get(in,&ip, ipa_mklen(ln->netmask));
|
nf = fib_get(in, &ip, ipa_mklen(ln->netmask));
|
||||||
if(nf->metric>act->dist)
|
if (nf->metric > act->dist)
|
||||||
{
|
{
|
||||||
nf->metric=act->dist;
|
nf->metric = act->dist;
|
||||||
nf->en=act;
|
nf->en = act;
|
||||||
DBG(" Adding into routing table\n");
|
DBG(" Adding into routing table\n");
|
||||||
}
|
}
|
||||||
rts=(u32 *)(ln+1);
|
rts = (u32 *) (ln + 1);
|
||||||
for(i=0;i<(act->lsa.length-sizeof(struct ospf_lsa_header)-
|
for (i = 0; i < (act->lsa.length - sizeof(struct ospf_lsa_header) -
|
||||||
sizeof(struct ospf_lsa_net))/sizeof(u32);i++)
|
sizeof(struct ospf_lsa_net)) / sizeof(u32); i++)
|
||||||
{
|
{
|
||||||
DBG(" Working on router %I ", *(rts+i));
|
DBG(" Working on router %I ", *(rts + i));
|
||||||
tmp=ospf_hash_find(oa->gr, *(rts+i), *(rts+i), LSA_T_RT);
|
tmp = ospf_hash_find(oa->gr, *(rts + i), *(rts + i), LSA_T_RT);
|
||||||
if(tmp!=NULL) DBG("Found :-)\n");
|
if (tmp != NULL)
|
||||||
else DBG("Not found!\n");
|
DBG("Found :-)\n");
|
||||||
add_cand(&oa->cand,tmp,act,act->dist,oa);
|
else
|
||||||
|
DBG("Not found!\n");
|
||||||
|
add_cand(&oa->cand, tmp, act, act->dist, oa);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Now sync our fib with nest's */
|
/* Now sync our fib with nest's */
|
||||||
DBG("Now syncing my rt table with nest's\n");
|
DBG("Now syncing my rt table with nest's\n");
|
||||||
FIB_ITERATE_INIT(&fit,in);
|
FIB_ITERATE_INIT(&fit, in);
|
||||||
again:
|
again:
|
||||||
FIB_ITERATE_START(in,&fit,nftmp)
|
FIB_ITERATE_START(in, &fit, nftmp)
|
||||||
{
|
{
|
||||||
nf=(struct infib *)nftmp;
|
nf = (struct infib *) nftmp;
|
||||||
if(nf->metric==LSINFINITY)
|
if (nf->metric == LSINFINITY)
|
||||||
{
|
{
|
||||||
net *ne;
|
net *ne;
|
||||||
struct top_hash_entry *en=nf->en;
|
struct top_hash_entry *en = nf->en;
|
||||||
ln=en->lsa_body;
|
ln = en->lsa_body;
|
||||||
|
|
||||||
ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
ne = net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
||||||
if((en!=NULL)&&(en->nhi!=NULL))
|
if ((en != NULL) && (en->nhi != NULL))
|
||||||
DBG("Deleting rt entry %I\n (P: %x, GW: %I, Iface: %s)\n",
|
DBG("Deleting rt entry %I\n (P: %x, GW: %I, Iface: %s)\n",
|
||||||
nf->fn.prefix, en, en->nh,en->nhi->name);
|
nf->fn.prefix, en, en->nh, en->nhi->name);
|
||||||
rte_update(p->table, ne, p, NULL);
|
rte_update(p->table, ne, p, NULL);
|
||||||
|
|
||||||
/* Now delete my fib */
|
/* Now delete my fib */
|
||||||
|
@ -198,57 +208,59 @@ again:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Update routing table */
|
/* Update routing table */
|
||||||
if(ipa_equal(nf->en->nh,ipa_from_u32(0)))
|
if (ipa_equal(nf->en->nh, ipa_from_u32(0)))
|
||||||
{
|
{
|
||||||
struct top_hash_entry *en=nf->en;
|
struct top_hash_entry *en = nf->en;
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
neighbor *nn;
|
neighbor *nn;
|
||||||
|
|
||||||
if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL)
|
if ((neigh = find_neigh_noifa(po, en->lsa.rt)) == NULL)
|
||||||
{
|
{
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
nn=neigh_find(p,&neigh->ip,0);
|
nn = neigh_find(p, &neigh->ip, 0);
|
||||||
DBG(" Next hop calculated: %I\n", nn->addr);
|
DBG(" Next hop calculated: %I\n", nn->addr);
|
||||||
en->nh=nn->addr;
|
en->nh = nn->addr;
|
||||||
en->nhi=nn->iface;
|
en->nhi = nn->iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((nf->en!=nf->olden)||(nf->metric!=nf->oldmetric))
|
if ((nf->en != nf->olden) || (nf->metric != nf->oldmetric))
|
||||||
{
|
{
|
||||||
net *ne;
|
net *ne;
|
||||||
rta a0;
|
rta a0;
|
||||||
rte *e;
|
rte *e;
|
||||||
struct top_hash_entry *en=nf->en;
|
struct top_hash_entry *en = nf->en;
|
||||||
ln=en->lsa_body;
|
ln = en->lsa_body;
|
||||||
|
|
||||||
bzero(&a0, sizeof(a0));
|
bzero(&a0, sizeof(a0));
|
||||||
|
|
||||||
a0.proto=p;
|
a0.proto = p;
|
||||||
a0.source=RTS_OSPF;
|
a0.source = RTS_OSPF;
|
||||||
a0.scope=SCOPE_UNIVERSE;
|
a0.scope = SCOPE_UNIVERSE;
|
||||||
a0.cast=RTC_UNICAST;
|
a0.cast = RTC_UNICAST;
|
||||||
if(ipa_to_u32(en->nh)==0) a0.dest=RTD_DEVICE;
|
if (ipa_to_u32(en->nh) == 0)
|
||||||
else a0.dest=RTD_ROUTER;
|
a0.dest = RTD_DEVICE;
|
||||||
a0.flags=0;
|
else
|
||||||
a0.aflags=0;
|
a0.dest = RTD_ROUTER;
|
||||||
a0.iface=en->nhi;
|
a0.flags = 0;
|
||||||
a0.gw=en->nh;
|
a0.aflags = 0;
|
||||||
|
a0.iface = en->nhi;
|
||||||
|
a0.gw = en->nh;
|
||||||
|
|
||||||
ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
ne = net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
||||||
e=rte_get_temp(&a0);
|
e = rte_get_temp(&a0);
|
||||||
e->u.ospf.metric1=nf->metric;
|
e->u.ospf.metric1 = nf->metric;
|
||||||
e->u.ospf.metric2=LSINFINITY;
|
e->u.ospf.metric2 = LSINFINITY;
|
||||||
e->u.ospf.tag=0;
|
e->u.ospf.tag = 0;
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
e->net=ne;
|
e->net = ne;
|
||||||
e->pref = p->preference;
|
e->pref = p->preference;
|
||||||
DBG("Modifying rt entry %I\n (GW: %I, Iface: %s)\n",
|
DBG("Modifying rt entry %I\n (GW: %I, Iface: %s)\n",
|
||||||
nf->fn.prefix,en->nh,en->nhi->name);
|
nf->fn.prefix, en->nh, en->nhi->name);
|
||||||
rte_update(p->table, ne, p, e);
|
rte_update(p->table, ne, p, e);
|
||||||
|
|
||||||
nf->olden=nf->en;
|
nf->olden = nf->en;
|
||||||
nf->oldmetric=nf->metric;
|
nf->oldmetric = nf->metric;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,217 +281,229 @@ skip:
|
||||||
void
|
void
|
||||||
ospf_ext_spfa(struct proto_ospf *po) /* FIXME looking into inter-area */
|
ospf_ext_spfa(struct proto_ospf *po) /* FIXME looking into inter-area */
|
||||||
{
|
{
|
||||||
struct top_hash_entry *en,*etmp,*absr;
|
struct top_hash_entry *en, *etmp, *absr;
|
||||||
struct fib *ef=&po->efib;
|
struct fib *ef = &po->efib;
|
||||||
struct extfib *nf;
|
struct extfib *nf;
|
||||||
struct infib *inf;
|
struct infib *inf;
|
||||||
struct fib_iterator fit;
|
struct fib_iterator fit;
|
||||||
struct ospf_area *oa=NULL,*atmp,*absroa;
|
struct ospf_area *oa = NULL, *atmp, *absroa;
|
||||||
struct proto *p=&po->proto;
|
struct proto *p = &po->proto;
|
||||||
struct ospf_lsa_ext *le;
|
struct ospf_lsa_ext *le;
|
||||||
struct ospf_lsa_ext_tos *lt;
|
struct ospf_lsa_ext_tos *lt;
|
||||||
int mlen;
|
int mlen;
|
||||||
ip_addr ip,nnh;
|
ip_addr ip, nnh;
|
||||||
struct iface *nnhi=NULL;
|
struct iface *nnhi = NULL;
|
||||||
u16 met,met2;
|
u16 met, met2;
|
||||||
u32 tag;
|
u32 tag;
|
||||||
neighbor *nn;
|
neighbor *nn;
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS,"Starting routing table calculation for ext routes");
|
OSPF_TRACE(D_EVENTS, "Starting routing table calculation for ext routes");
|
||||||
|
|
||||||
FIB_WALK(ef,nftmp)
|
FIB_WALK(ef, nftmp)
|
||||||
{
|
{
|
||||||
nf=(struct extfib *)nftmp;
|
nf = (struct extfib *) nftmp;
|
||||||
nf->metric=LSINFINITY;
|
nf->metric = LSINFINITY;
|
||||||
nf->metric2=LSINFINITY;
|
nf->metric2 = LSINFINITY;
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
|
|
||||||
WALK_LIST(oa,po->area_list)
|
WALK_LIST(oa, po->area_list)
|
||||||
{
|
{
|
||||||
if(!oa->stub) break;
|
if (!oa->stub)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(oa==NULL) return;
|
if (oa == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
WALK_SLIST(en,oa->lsal)
|
WALK_SLIST(en, oa->lsal)
|
||||||
{
|
{
|
||||||
if(en->lsa.type!=LSA_T_EXT) continue;
|
if (en->lsa.type != LSA_T_EXT)
|
||||||
if(en->lsa.age==LSA_MAXAGE) continue;
|
continue;
|
||||||
if(en->lsa.rt==p->cf->global->router_id) continue;
|
if (en->lsa.age == LSA_MAXAGE)
|
||||||
|
continue;
|
||||||
|
if (en->lsa.rt == p->cf->global->router_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
le=en->lsa_body;
|
le = en->lsa_body;
|
||||||
lt=(struct ospf_lsa_ext_tos *)(le+1);
|
lt = (struct ospf_lsa_ext_tos *) (le + 1);
|
||||||
|
|
||||||
DBG("%s: Working on LSA. ID: %I, RT: %I, Type: %u, Mask %I\n",
|
DBG("%s: Working on LSA. ID: %I, RT: %I, Type: %u, Mask %I\n",
|
||||||
p->name,en->lsa.id,en->lsa.rt,en->lsa.type,le->netmask);
|
p->name, en->lsa.id, en->lsa.rt, en->lsa.type, le->netmask);
|
||||||
|
|
||||||
if(lt->metric==LSINFINITY) continue;
|
if (lt->metric == LSINFINITY)
|
||||||
ip=ipa_and(ipa_from_u32(en->lsa.id),le->netmask);
|
continue;
|
||||||
mlen=ipa_mklen(le->netmask);
|
ip = ipa_and(ipa_from_u32(en->lsa.id), le->netmask);
|
||||||
if((mlen<0)||(mlen>32))
|
mlen = ipa_mklen(le->netmask);
|
||||||
|
if ((mlen < 0) || (mlen > 32))
|
||||||
{
|
{
|
||||||
log("%s: Invalid mask in LSA. ID: %I, RT: %I, Type: %u, Mask %I",
|
log("%s: Invalid mask in LSA. ID: %I, RT: %I, Type: %u, Mask %I",
|
||||||
p->name,en->lsa.id,en->lsa.rt,en->lsa.type,le->netmask);
|
p->name, en->lsa.id, en->lsa.rt, en->lsa.type, le->netmask);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nf=NULL;
|
nf = NULL;
|
||||||
|
|
||||||
WALK_LIST(atmp,po->area_list)
|
WALK_LIST(atmp, po->area_list)
|
||||||
{
|
{
|
||||||
if((nf=fib_find(&atmp->infib,&ip, mlen))!=NULL) break;
|
if ((nf = fib_find(&atmp->infib, &ip, mlen)) != NULL)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nf!=NULL) continue; /* Some intra area path exists */
|
if (nf != NULL)
|
||||||
|
continue; /* Some intra area path exists */
|
||||||
|
|
||||||
absr=NULL;
|
absr = NULL;
|
||||||
absroa=NULL;
|
absroa = NULL;
|
||||||
nnhi=NULL;
|
nnhi = NULL;
|
||||||
nnh=IPA_NONE;
|
nnh = IPA_NONE;
|
||||||
|
|
||||||
met=0;met2=0;tag=0;
|
met = 0;
|
||||||
|
met2 = 0;
|
||||||
|
tag = 0;
|
||||||
|
|
||||||
WALK_LIST(atmp,po->area_list) /*
|
WALK_LIST(atmp, po->area_list) /*
|
||||||
* Find shortest path
|
* Find shortest path
|
||||||
* to advertising router
|
* to advertising router
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if((etmp=ospf_hash_find(atmp->gr,en->lsa.rt,en->lsa.rt,LSA_T_RT))!=NULL)
|
if ((etmp =
|
||||||
|
ospf_hash_find(atmp->gr, en->lsa.rt, en->lsa.rt,
|
||||||
|
LSA_T_RT)) != NULL)
|
||||||
{
|
{
|
||||||
if((absr==NULL) || (absr->dist>etmp->dist) ||
|
if ((absr == NULL) || (absr->dist > etmp->dist) ||
|
||||||
((etmp->dist==absr->dist) && (absroa->areaid<atmp->areaid)))
|
((etmp->dist == absr->dist) && (absroa->areaid < atmp->areaid)))
|
||||||
{
|
{
|
||||||
absr=etmp;
|
absr = etmp;
|
||||||
absroa=atmp;
|
absroa = atmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((absr==NULL)||(absr->dist==LSINFINITY)||
|
if ((absr == NULL) || (absr->dist == LSINFINITY) ||
|
||||||
(((struct ospf_lsa_rt *)(absr->lsa_body))->veb.bit.e==0))
|
(((struct ospf_lsa_rt *) (absr->lsa_body))->veb.bit.e == 0))
|
||||||
{
|
{
|
||||||
DBG("ASBR is null or its dist=INF\n");
|
DBG("ASBR is null or its dist=INF\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ipa_compare(lt->fwaddr,ipa_from_u32(0))==0)
|
if (ipa_compare(lt->fwaddr, ipa_from_u32(0)) == 0)
|
||||||
{
|
{
|
||||||
if(lt->etos>0) /* FW address == 0 */
|
if (lt->etos > 0) /* FW address == 0 */
|
||||||
{
|
{
|
||||||
met=absr->dist;
|
met = absr->dist;
|
||||||
met2=lt->metric;
|
met2 = lt->metric;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
met=absr->dist+lt->metric;
|
met = absr->dist + lt->metric;
|
||||||
met2=LSINFINITY;
|
met2 = LSINFINITY;
|
||||||
}
|
}
|
||||||
tag=lt->tag;
|
tag = lt->tag;
|
||||||
}
|
}
|
||||||
else /* FW address !=0 */
|
else /* FW address !=0 */
|
||||||
{
|
{
|
||||||
inf=NULL;
|
inf = NULL;
|
||||||
WALK_LIST(atmp,po->area_list)
|
WALK_LIST(atmp, po->area_list)
|
||||||
{
|
{
|
||||||
if((inf=fib_route(&atmp->infib,lt->fwaddr,32))!=NULL)
|
if ((inf = fib_route(&atmp->infib, lt->fwaddr, 32)) != NULL)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inf==NULL)
|
if (inf == NULL)
|
||||||
{
|
{
|
||||||
DBG("Cannot find network route (GW=%I)\n",lt->fwaddr);
|
DBG("Cannot find network route (GW=%I)\n", lt->fwaddr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lt->etos>0)
|
if (lt->etos > 0)
|
||||||
{
|
{
|
||||||
met=inf->metric;
|
met = inf->metric;
|
||||||
met2=lt->metric;
|
met2 = lt->metric;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
met=inf->metric+lt->metric;
|
met = inf->metric + lt->metric;
|
||||||
met2=LSINFINITY;
|
met2 = LSINFINITY;
|
||||||
}
|
}
|
||||||
tag=lt->tag;
|
tag = lt->tag;
|
||||||
|
|
||||||
if((nn=neigh_find(p,<->fwaddr,0))!=NULL)
|
if ((nn = neigh_find(p, <->fwaddr, 0)) != NULL)
|
||||||
{
|
{
|
||||||
nnh=lt->fwaddr;
|
nnh = lt->fwaddr;
|
||||||
nnhi=nn->iface;
|
nnhi = nn->iface;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nnh=inf->en->nh;
|
nnh = inf->en->nh;
|
||||||
nnhi=inf->en->nhi;
|
nnhi = inf->en->nhi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nf=fib_get(ef,&ip, mlen);
|
nf = fib_get(ef, &ip, mlen);
|
||||||
if((nf->metric==LSINFINITY) || /* nf is new */
|
if ((nf->metric == LSINFINITY) || /* nf is new */
|
||||||
((met<nf->metric)&&(nf->metric2==met2)) || /* both E1 or E2
|
((met < nf->metric) && (nf->metric2 == met2)) || /* both E1 or E2
|
||||||
* with same metric */
|
* with same metric */
|
||||||
((met2<nf->metric2)&&(nf->metric2!=LSINFINITY)) || /* E2 smaller and
|
((met2 < nf->metric2) && (nf->metric2 != LSINFINITY)) || /* E2 smaller and
|
||||||
* 1st is not E1 */
|
* 1st is not E1 */
|
||||||
((nf->metric2!=LSINFINITY)&&(met2==LSINFINITY))) /* 2nd is E1 and
|
((nf->metric2 != LSINFINITY) && (met2 == LSINFINITY))) /* 2nd is E1 and
|
||||||
* 1st is E2 */
|
* 1st is E2 */
|
||||||
{
|
{
|
||||||
if(nf->metric!=LSINFINITY)
|
if (nf->metric != LSINFINITY)
|
||||||
OSPF_TRACE(D_EVENTS,
|
OSPF_TRACE(D_EVENTS,
|
||||||
"Rewriting %I/%d met=%d, met2=%d, nmet=%d, nmet2=%d",
|
"Rewriting %I/%d met=%d, met2=%d, nmet=%d, nmet2=%d",
|
||||||
ip, mlen, nf->metric, nf->metric2, met, met2);
|
ip, mlen, nf->metric, nf->metric2, met, met2);
|
||||||
nf->metric=met;
|
nf->metric = met;
|
||||||
nf->metric2=met2;
|
nf->metric2 = met2;
|
||||||
nf->tag=tag;
|
nf->tag = tag;
|
||||||
|
|
||||||
if(nnhi!=NULL)
|
if (nnhi != NULL)
|
||||||
{
|
{
|
||||||
nf->nh=nnh;
|
nf->nh = nnh;
|
||||||
nf->nhi=nnhi;
|
nf->nhi = nnhi;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(ipa_compare(absr->nh,ipa_from_u32(0))==0)
|
if (ipa_compare(absr->nh, ipa_from_u32(0)) == 0)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
|
|
||||||
if((neigh=find_neigh_noifa(po,absr->lsa.rt))==NULL)
|
if ((neigh = find_neigh_noifa(po, absr->lsa.rt)) == NULL)
|
||||||
{
|
{
|
||||||
DBG("Cannot find neighbor\n");
|
DBG("Cannot find neighbor\n");
|
||||||
nf->metric=LSINFINITY; /* delete this route */
|
nf->metric = LSINFINITY; /* delete this route */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nn=neigh_find(p,&neigh->ip,0);
|
nn = neigh_find(p, &neigh->ip, 0);
|
||||||
DBG(" Next hop calculated: %I\n", nn->addr);
|
DBG(" Next hop calculated: %I\n", nn->addr);
|
||||||
nf->nh=nn->addr;
|
nf->nh = nn->addr;
|
||||||
nf->nhi=nn->iface;
|
nf->nhi = nn->iface;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nf->nh=absr->nh;
|
nf->nh = absr->nh;
|
||||||
nf->nhi=absr->nhi;
|
nf->nhi = absr->nhi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("Now syncing my rt table with nest's\n");
|
DBG("Now syncing my rt table with nest's\n");
|
||||||
FIB_ITERATE_INIT(&fit,ef);
|
FIB_ITERATE_INIT(&fit, ef);
|
||||||
noch:
|
noch:
|
||||||
FIB_ITERATE_START(ef,&fit,nftmp)
|
FIB_ITERATE_START(ef, &fit, nftmp)
|
||||||
{
|
{
|
||||||
nf=(struct extfib *)nftmp;
|
nf = (struct extfib *) nftmp;
|
||||||
if(nf->metric==LSINFINITY)
|
if (nf->metric == LSINFINITY)
|
||||||
{
|
{
|
||||||
net *ne;
|
net *ne;
|
||||||
|
|
||||||
ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
ne = net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
||||||
DBG("Deleting rt entry %I\n (IP: %I, GW: %I)\n",
|
DBG("Deleting rt entry %I\n (IP: %I, GW: %I)\n",
|
||||||
nf->fn.prefix,ip,nf->nh);
|
nf->fn.prefix, ip, nf->nh);
|
||||||
rte_update(p->table, ne, p, NULL);
|
rte_update(p->table, ne, p, NULL);
|
||||||
|
|
||||||
/* Now delete my fib */
|
/* Now delete my fib */
|
||||||
|
@ -488,8 +512,8 @@ noch:
|
||||||
goto noch;
|
goto noch;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if((nf->metric!=nf->oldmetric)||(nf->metric2!=nf->oldmetric2)||
|
if ((nf->metric != nf->oldmetric) || (nf->metric2 != nf->oldmetric2) ||
|
||||||
(!ipa_equal(nf->nh,nf->oldnh))||(nf->tag!=nf->oldtag))
|
(!ipa_equal(nf->nh, nf->oldnh)) || (nf->tag != nf->oldtag))
|
||||||
{
|
{
|
||||||
net *ne;
|
net *ne;
|
||||||
rta a0;
|
rta a0;
|
||||||
|
@ -497,31 +521,31 @@ noch:
|
||||||
|
|
||||||
bzero(&a0, sizeof(a0));
|
bzero(&a0, sizeof(a0));
|
||||||
|
|
||||||
a0.proto=p;
|
a0.proto = p;
|
||||||
a0.source=RTS_OSPF_EXT;
|
a0.source = RTS_OSPF_EXT;
|
||||||
a0.scope=SCOPE_UNIVERSE;
|
a0.scope = SCOPE_UNIVERSE;
|
||||||
a0.cast=RTC_UNICAST;
|
a0.cast = RTC_UNICAST;
|
||||||
a0.dest=RTD_ROUTER;
|
a0.dest = RTD_ROUTER;
|
||||||
a0.flags=0;
|
a0.flags = 0;
|
||||||
a0.aflags=0;
|
a0.aflags = 0;
|
||||||
a0.iface=nf->nhi;
|
a0.iface = nf->nhi;
|
||||||
a0.gw=nf->nh;
|
a0.gw = nf->nh;
|
||||||
ne=net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
ne = net_get(p->table, nf->fn.prefix, nf->fn.pxlen);
|
||||||
e=rte_get_temp(&a0);
|
e = rte_get_temp(&a0);
|
||||||
e->u.ospf.metric1=nf->metric;
|
e->u.ospf.metric1 = nf->metric;
|
||||||
e->u.ospf.metric2=nf->metric2;
|
e->u.ospf.metric2 = nf->metric2;
|
||||||
e->u.ospf.tag=nf->tag;
|
e->u.ospf.tag = nf->tag;
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
e->net=ne;
|
e->net = ne;
|
||||||
e->pref = p->preference;
|
e->pref = p->preference;
|
||||||
DBG("Modifying rt entry %I\n (IP: %I, GW: %I)\n",
|
DBG("Modifying rt entry %I\n (IP: %I, GW: %I)\n",
|
||||||
nf->fn.prefix,ip,nf->nh);
|
nf->fn.prefix, ip, nf->nh);
|
||||||
rte_update(p->table, ne, p, e);
|
rte_update(p->table, ne, p, e);
|
||||||
|
|
||||||
nf->oldmetric=nf->metric;
|
nf->oldmetric = nf->metric;
|
||||||
nf->oldmetric2=nf->metric2;
|
nf->oldmetric2 = nf->metric2;
|
||||||
nf->oldnh=nf->nh;
|
nf->oldnh = nf->nh;
|
||||||
nf->oldtag=nf->tag;
|
nf->oldtag = nf->tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FIB_ITERATE_END(nftmp);
|
FIB_ITERATE_END(nftmp);
|
||||||
|
@ -529,65 +553,73 @@ noch:
|
||||||
|
|
||||||
/* Add LSA into list of candidates in Dijkstra's algorithm */
|
/* Add LSA into list of candidates in Dijkstra's algorithm */
|
||||||
void
|
void
|
||||||
add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,
|
add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
u16 dist, struct ospf_area *oa)
|
u16 dist, struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
node *prev,*n;
|
node *prev, *n;
|
||||||
int added=0;
|
int added = 0;
|
||||||
struct top_hash_entry *act;
|
struct top_hash_entry *act;
|
||||||
|
|
||||||
if(en==NULL) return;
|
if (en == NULL)
|
||||||
if(en->lsa.age==LSA_MAXAGE) return;
|
return;
|
||||||
|
if (en->lsa.age == LSA_MAXAGE)
|
||||||
|
return;
|
||||||
/* FIXME Does it have link back? Test it! */
|
/* FIXME Does it have link back? Test it! */
|
||||||
if(en->color==INSPF) return;
|
if (en->color == INSPF)
|
||||||
|
return;
|
||||||
|
|
||||||
if(dist>=en->dist) return;
|
if (dist >= en->dist)
|
||||||
|
return;
|
||||||
/*
|
/*
|
||||||
* FIXME The line above is not a bug, but we don't support
|
* FIXME The line above is not a bug, but we don't support
|
||||||
* multiple next hops. I'll start as soon as nest will
|
* multiple next hops. I'll start as soon as nest will
|
||||||
*/
|
*/
|
||||||
DBG(" Adding candidate: rt: %I, id: %I, type: %u\n",en->lsa.rt,en->lsa.id,en->lsa.type);
|
DBG(" Adding candidate: rt: %I, id: %I, type: %u\n", en->lsa.rt,
|
||||||
|
en->lsa.id, en->lsa.type);
|
||||||
|
|
||||||
en->nhi=NULL;
|
en->nhi = NULL;
|
||||||
en->nh=IPA_NONE;
|
en->nh = IPA_NONE;
|
||||||
|
|
||||||
calc_next_hop(en, par, oa);
|
calc_next_hop(en, par, oa);
|
||||||
|
|
||||||
if(!en->nhi) return; /* We cannot find next hop, ignore it */
|
if (!en->nhi)
|
||||||
|
return; /* We cannot find next hop, ignore it */
|
||||||
|
|
||||||
if(en->color==CANDIDATE) /* We found a shorter path */
|
if (en->color == CANDIDATE) /* We found a shorter path */
|
||||||
{
|
{
|
||||||
rem_node(&en->cn);
|
rem_node(&en->cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
en->dist=dist;
|
en->dist = dist;
|
||||||
en->color=CANDIDATE;
|
en->color = CANDIDATE;
|
||||||
|
|
||||||
prev=NULL;
|
prev = NULL;
|
||||||
|
|
||||||
if(EMPTY_LIST(*l))
|
if (EMPTY_LIST(*l))
|
||||||
{
|
{
|
||||||
add_head(l,&en->cn);
|
add_head(l, &en->cn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WALK_LIST(n,*l)
|
WALK_LIST(n, *l)
|
||||||
{
|
{
|
||||||
act=SKIP_BACK(struct top_hash_entry, cn, n);
|
act = SKIP_BACK(struct top_hash_entry, cn, n);
|
||||||
if((act->dist>dist)||
|
if ((act->dist > dist) ||
|
||||||
((act->dist==dist)&&(act->lsa.type==LSA_T_NET)))
|
((act->dist == dist) && (act->lsa.type == LSA_T_NET)))
|
||||||
{
|
{
|
||||||
if(prev==NULL) add_head(l,&en->cn);
|
if (prev == NULL)
|
||||||
else insert_node(&en->cn,prev);
|
add_head(l, &en->cn);
|
||||||
added=1;
|
else
|
||||||
|
insert_node(&en->cn, prev);
|
||||||
|
added = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prev=n;
|
prev = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!added)
|
if (!added)
|
||||||
{
|
{
|
||||||
add_tail(l,&en->cn);
|
add_tail(l, &en->cn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* FIXME Some VLINK stuff should be here */
|
/* FIXME Some VLINK stuff should be here */
|
||||||
|
@ -598,28 +630,29 @@ calc_next_hop(struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
struct ospf_area *oa)
|
struct ospf_area *oa)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
struct proto *p=&oa->po->proto;
|
struct proto *p = &oa->po->proto;
|
||||||
struct proto_ospf *po=oa->po;
|
struct proto_ospf *po = oa->po;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
u32 myrid=p->cf->global->router_id;
|
u32 myrid = p->cf->global->router_id;
|
||||||
|
|
||||||
DBG(" Next hop called.\n");
|
DBG(" Next hop called.\n");
|
||||||
if(ipa_equal(par->nh,IPA_NONE))
|
if (ipa_equal(par->nh, IPA_NONE))
|
||||||
{
|
{
|
||||||
neighbor *nn;
|
neighbor *nn;
|
||||||
DBG(" Next hop calculating for id: %I rt: %I type: %u\n",
|
DBG(" Next hop calculating for id: %I rt: %I type: %u\n",
|
||||||
en->lsa.id,en->lsa.rt,en->lsa.type);
|
en->lsa.id, en->lsa.rt, en->lsa.type);
|
||||||
|
|
||||||
if(par==oa->rt)
|
if (par == oa->rt)
|
||||||
{
|
{
|
||||||
if(en->lsa.type==LSA_T_NET)
|
if (en->lsa.type == LSA_T_NET)
|
||||||
{
|
{
|
||||||
if(en->lsa.rt==myrid)
|
if (en->lsa.rt == myrid)
|
||||||
{
|
{
|
||||||
WALK_LIST(ifa,po->iface_list)
|
WALK_LIST(ifa, po->iface_list)
|
||||||
if(ipa_compare(ifa->iface->addr->ip,ipa_from_u32(en->lsa.id))==0)
|
if (ipa_compare(ifa->iface->addr->ip, ipa_from_u32(en->lsa.id)) ==
|
||||||
|
0)
|
||||||
{
|
{
|
||||||
en->nhi=ifa->iface;
|
en->nhi = ifa->iface;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log(L_ERR "I didn't find interface for my self originated LSA!\n");
|
log(L_ERR "I didn't find interface for my self originated LSA!\n");
|
||||||
|
@ -628,40 +661,44 @@ calc_next_hop(struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ip_addr ip=ipa_from_u32(en->lsa.id);
|
ip_addr ip = ipa_from_u32(en->lsa.id);
|
||||||
nn=neigh_find(p,&ip,0);
|
nn = neigh_find(p, &ip, 0);
|
||||||
if(nn) en->nhi=nn->iface;
|
if (nn)
|
||||||
|
en->nhi = nn->iface;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) return;
|
if ((neigh = find_neigh_noifa(po, en->lsa.rt)) == NULL)
|
||||||
en->nhi=neigh->ifa->iface;
|
return;
|
||||||
en->nh=neigh->ip; /* Yes, neighbor is it's own next hop */
|
en->nhi = neigh->ifa->iface;
|
||||||
|
en->nh = neigh->ip; /* Yes, neighbor is it's own next hop */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(par->lsa.type==LSA_T_NET)
|
if (par->lsa.type == LSA_T_NET)
|
||||||
{
|
{
|
||||||
if(en->lsa.type==LSA_T_NET) bug("Parent for net is net?");
|
if (en->lsa.type == LSA_T_NET)
|
||||||
if((en->nhi=par->nhi)==NULL)
|
bug("Parent for net is net?");
|
||||||
|
if ((en->nhi = par->nhi) == NULL)
|
||||||
bug("Did not find next hop interface for INSPF lsa!");
|
bug("Did not find next hop interface for INSPF lsa!");
|
||||||
if((neigh=find_neigh_noifa(po,en->lsa.rt))==NULL) return;
|
if ((neigh = find_neigh_noifa(po, en->lsa.rt)) == NULL)
|
||||||
en->nhi=neigh->ifa->iface;
|
return;
|
||||||
en->nh=neigh->ip; /* Yes, neighbor is it's own next hop */
|
en->nhi = neigh->ifa->iface;
|
||||||
|
en->nh = neigh->ip; /* Yes, neighbor is it's own next hop */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else /* Parent is some RT neighbor */
|
else /* Parent is some RT neighbor */
|
||||||
{
|
{
|
||||||
log(L_ERR "Router's parent has no next hop. (EN=%I, PAR=%I)", en->lsa.id, par->lsa.id);
|
log(L_ERR "Router's parent has no next hop. (EN=%I, PAR=%I)",
|
||||||
|
en->lsa.id, par->lsa.id);
|
||||||
/* I hoped this would never happen */
|
/* I hoped this would never happen */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
en->nh=par->nh;
|
en->nh = par->nh;
|
||||||
en->nhi=par->nhi;
|
en->nhi = par->nhi;
|
||||||
DBG(" Next hop calculated: %I.\n", en->nh);
|
DBG(" Next hop calculated: %I.\n", en->nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
#ifndef _BIRD_OSPF_RT_H_
|
#ifndef _BIRD_OSPF_RT_H_
|
||||||
#define _BIRD_OSPF_RT_H_
|
#define _BIRD_OSPF_RT_H_
|
||||||
|
|
||||||
struct infib {
|
struct infib
|
||||||
|
{
|
||||||
struct fib_node fn;
|
struct fib_node fn;
|
||||||
u16 metric;
|
u16 metric;
|
||||||
u16 oldmetric;
|
u16 oldmetric;
|
||||||
|
@ -18,7 +19,8 @@ struct infib {
|
||||||
struct top_hash_entry *olden;
|
struct top_hash_entry *olden;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct extfib {
|
struct extfib
|
||||||
|
{
|
||||||
struct fib_node fn;
|
struct fib_node fn;
|
||||||
u16 metric;
|
u16 metric;
|
||||||
u16 metric2;
|
u16 metric2;
|
||||||
|
@ -33,7 +35,7 @@ struct extfib {
|
||||||
|
|
||||||
void ospf_rt_spfa(struct ospf_area *oa);
|
void ospf_rt_spfa(struct ospf_area *oa);
|
||||||
void ospf_ext_spfa(struct proto_ospf *po);
|
void ospf_ext_spfa(struct proto_ospf *po);
|
||||||
void add_cand(list *l, struct top_hash_entry *en, struct top_hash_entry *par,
|
void add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par,
|
||||||
u16 dist, struct ospf_area *oa);
|
u16 dist, struct ospf_area *oa);
|
||||||
void calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
|
void calc_next_hop(struct top_hash_entry *par, struct top_hash_entry *en,
|
||||||
struct ospf_area *oa);
|
struct ospf_area *oa);
|
||||||
|
|
Loading…
Reference in a new issue