Indentation.

This commit is contained in:
Ondrej Filip 2004-06-06 09:37:54 +00:00
parent 66261211a9
commit 2e10a170fe
14 changed files with 1629 additions and 1481 deletions

View file

@ -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);
@ -127,7 +127,7 @@ ospf_dbdes_send(struct ospf_neighbor *n)
} }
memcpy(ifa->ip_sk->tbuf, n->ldbdes, length); memcpy(ifa->ip_sk->tbuf, n->ldbdes, length);
/* Copy last sent packet again */ /* Copy last sent packet again */
sk_send_to(ifa->ip_sk, length, n->ip, OSPF_PROTO); sk_send_to(ifa->ip_sk, length, n->ip, OSPF_PROTO);
OSPF_TRACE(D_PACKETS, "DB_DES (M) sent to %I via %s.", n->ip, OSPF_TRACE(D_PACKETS, "DB_DES (M) sent to %I via %s.", n->ip,

View file

@ -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;
} }

View file

@ -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;

View file

@ -161,7 +161,7 @@ ospf_lsack_receive(struct ospf_lsack_packet *ps,
{ {
ntohlsah(plsa + i, &lsa); ntohlsah(plsa + i, &lsa);
if ((en = ospf_hash_find_header(n->lsrth, &lsa)) == NULL) if ((en = ospf_hash_find_header(n->lsrth, &lsa)) == NULL)
continue; /* pg 155 */ continue; /* pg 155 */
if (lsa_comp(&lsa, &en->lsa) != CMP_SAME) /* pg 156 */ if (lsa_comp(&lsa, &en->lsa) != CMP_SAME) /* pg 156 */
{ {

View file

@ -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,
en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.age); "Going to remove node Type: %u, Id: %I, Rt: %I, Age: %u",
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,124 +93,125 @@ 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;
} }
case LSA_T_SUM_NET: case LSA_T_SUM_NET:
case LSA_T_SUM_RT: case LSA_T_SUM_RT:
{ {
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;
} }
case LSA_T_EXT: case LSA_T_EXT:
{ {
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,96 +219,97 @@ 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;
} }
case LSA_T_SUM_NET: case LSA_T_SUM_NET:
case LSA_T_SUM_RT: case LSA_T_SUM_RT:
{ {
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;
} }
case LSA_T_EXT: case LSA_T_EXT:
{ {
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;
htonlsah(h,h); length = h->length;
htonlsab(body,body,h->type,length-sizeof(struct ospf_lsa_header));
(void)lsasum_check(h,body,po); htonlsah(h, h);
htonlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
ntohlsah(h,h);
ntohlsab(body,body,h->type,length-sizeof(struct ospf_lsa_header)); (void) lsasum_check(h, body, po);
ntohlsah(h, h);
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;
} }
} }
@ -450,19 +465,20 @@ lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
} }
DBG("Inst lsa: Id: %I, Rt: %I, Type: %u, Age: %u, Sum: %u, Sn: 0x%x\n", DBG("Inst lsa: Id: %I, Rt: %I, Type: %u, Age: %u, Sum: %u, Sn: 0x%x\n",
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);
} }
return en; return en;
} }

View file

@ -15,14 +15,15 @@ void ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h);
void htonlsab(void *h, void *n, u8 type, u16 len); 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);

View file

@ -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);

View file

@ -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;
case OSPF_IT_BCAST:
case OSPF_IT_NBMA:
switch (ifa->state)
{
case OSPF_IS_DOWN:
bug("%s: Iface %s in down state?", p->name, ifa->iface->name);
break; break;
case OSPF_IT_BCAST: case OSPF_IS_WAITING:
case OSPF_IT_NBMA: DBG("%s: Neighbor? on iface %s\n", p->name, ifa->iface->name);
switch(ifa->state) break;
{ case OSPF_IS_DROTHER:
case OSPF_IS_DOWN: if (((n->rid == ifa->drid) || (n->rid == ifa->bdrid))
bug("%s: Iface %s in down state?", p->name, ifa->iface->name); && (n->state >= NEIGHBOR_2WAY))
break; i = 1;
case OSPF_IS_WAITING: break;
DBG("%s: Neighbor? on iface %s\n",p->name, ifa->iface->name); case OSPF_IS_PTP:
break; case OSPF_IS_BACKUP:
case OSPF_IS_DROTHER: case OSPF_IS_DR:
if(((n->rid==ifa->drid) || (n->rid==ifa->bdrid)) if (n->state >= NEIGHBOR_2WAY)
&& (n->state>=NEIGHBOR_2WAY)) i=1; i = 1;
break;
case OSPF_IS_PTP:
case OSPF_IS_BACKUP:
case OSPF_IS_DR:
if(n->state>=NEIGHBOR_2WAY) i=1;
break;
default:
bug("%s: Iface %s in unknown state?",p->name, ifa->iface->name);
break;
}
break; break;
default: default:
bug("%s: Iface %s is unknown type?",p->name, ifa->iface->name); bug("%s: Iface %s in unknown state?", p->name, ifa->iface->name);
break; break;
}
break;
default:
bug("%s: Iface %s is unknown type?", p->name, ifa->iface->name);
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,92 +287,95 @@ 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;
case INM_HELLOREC:
switch (n->state)
{
case NEIGHBOR_ATTEMPT:
case NEIGHBOR_DOWN:
neigh_chstate(n, NEIGHBOR_INIT);
default:
tm_start(n->inactim, n->ifa->deadc * n->ifa->helloint); /* Restart inactivity timer */
break; break;
case INM_HELLOREC: }
switch(n->state) break;
case INM_2WAYREC:
if (n->state < NEIGHBOR_2WAY)
neigh_chstate(n, NEIGHBOR_2WAY);
if ((n->state == NEIGHBOR_2WAY) && can_do_adj(n))
neigh_chstate(n, NEIGHBOR_EXSTART);
break;
case INM_NEGDONE:
if (n->state == NEIGHBOR_EXSTART)
{
neigh_chstate(n, NEIGHBOR_EXCHANGE);
s_init(&(n->dbsi), &(n->ifa->oa->lsal));
while (!EMPTY_LIST(n->ackl[ACKL_DELAY]))
{ {
case NEIGHBOR_ATTEMPT: struct lsah_n *no;
case NEIGHBOR_DOWN: no = (struct lsah_n *) HEAD(n->ackl[ACKL_DELAY]);
neigh_chstate(n, NEIGHBOR_INIT); rem_node(NODE no);
default: mb_free(no);
tm_start(n->inactim, n->ifa->deadc*n->ifa->helloint); /* Restart inactivity timer */
break;
} }
break; }
case INM_2WAYREC: else
if(n->state<NEIGHBOR_2WAY) neigh_chstate(n,NEIGHBOR_2WAY); bug("NEGDONE and I'm not in EXSTART?");
if((n->state==NEIGHBOR_2WAY) && can_do_adj(n)) break;
neigh_chstate(n,NEIGHBOR_EXSTART); case INM_EXDONE:
break; neigh_chstate(n, NEIGHBOR_LOADING);
case INM_NEGDONE: break;
if(n->state==NEIGHBOR_EXSTART) case INM_LOADDONE:
neigh_chstate(n, NEIGHBOR_FULL);
break;
case INM_ADJOK:
switch (n->state)
{
case NEIGHBOR_2WAY:
/* Can In build adjacency? */
if (can_do_adj(n))
{ {
neigh_chstate(n,NEIGHBOR_EXCHANGE); neigh_chstate(n, NEIGHBOR_EXSTART);
s_init(&(n->dbsi), &(n->ifa->oa->lsal));
while(!EMPTY_LIST(n->ackl[ACKL_DELAY]))
{
struct lsah_n *no;
no=(struct lsah_n *)HEAD(n->ackl[ACKL_DELAY]);
rem_node(NODE no);
mb_free(no);
}
} }
else bug("NEGDONE and I'm not in EXSTART?");
break;
case INM_EXDONE:
neigh_chstate(n,NEIGHBOR_LOADING);
break;
case INM_LOADDONE:
neigh_chstate(n,NEIGHBOR_FULL);
break;
case INM_ADJOK:
switch(n->state)
{
case NEIGHBOR_2WAY:
/* Can In build adjacency? */
if(can_do_adj(n))
{
neigh_chstate(n,NEIGHBOR_EXSTART);
}
break;
default:
if(n->state>=NEIGHBOR_EXSTART)
if(!can_do_adj(n))
{
neigh_chstate(n,NEIGHBOR_2WAY);
}
break;
}
break;
case INM_SEQMIS:
case INM_BADLSREQ:
if(n->state>=NEIGHBOR_EXCHANGE)
{
neigh_chstate(n,NEIGHBOR_EXSTART);
}
break;
case INM_KILLNBR:
case INM_LLDOWN:
case INM_INACTTIM:
neigh_chstate(n,NEIGHBOR_DOWN);
break;
case INM_1WAYREC:
neigh_chstate(n,NEIGHBOR_INIT);
break; break;
default: default:
bug("%s: INM - Unknown event?",p->name); if (n->state >= NEIGHBOR_EXSTART)
if (!can_do_adj(n))
{
neigh_chstate(n, NEIGHBOR_2WAY);
}
break; break;
}
break;
case INM_SEQMIS:
case INM_BADLSREQ:
if (n->state >= NEIGHBOR_EXCHANGE)
{
neigh_chstate(n, NEIGHBOR_EXSTART);
}
break;
case INM_KILLNBR:
case INM_LLDOWN:
case INM_INACTTIM:
neigh_chstate(n, NEIGHBOR_DOWN);
break;
case INM_1WAYREC:
neigh_chstate(n, NEIGHBOR_INIT);
break;
default:
bug("%s: INM - Unknown event?", p->name);
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,9 +500,8 @@ 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,19 +510,19 @@ 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) n=m; else if (m->ifa->cost < n->ifa->cost)
else n = m;
if(m->ifa->cost < n->ifa->cost) n=m;
}
} }
}
return n; return n;
} }
@ -502,24 +530,26 @@ 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,
ifa->iface->name, n->ip); "Inactivity timer fired on interface %s for neighbor %I.",
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,63 +570,69 @@ 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->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, if (n->rid == ifa->drid)
ospf_ns[n->state], pos, etime, n->ip,ifa->iface->name); pos = "dr ";
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,
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);
} }
ospf_lsupd_send_list(n, &uplist); ospf_lsupd_send_list(n, &uplist);
rfree(upslab); rfree(upslab);
@ -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

View file

@ -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,47 +86,48 @@ 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 */
struct ospf_area *oa; struct ospf_area *oa;
struct object_lock *lock; struct object_lock *lock;
u32 an; /* Area number */ u32 an; /* Area number */
sock *hello_sk; /* Hello socket */ sock *hello_sk; /* Hello socket */
sock *dr_sk; /* For states DR or BACKUP */ sock *dr_sk; /* For states DR or BACKUP */
sock *ip_sk; /* IP socket (for DD ...) */ sock *ip_sk; /* IP socket (for DD ...) */
list neigh_list; /* List of neigbours */ list neigh_list; /* List of neigbours */
u16 cost; /* Cost of iface */ u16 cost; /* Cost of iface */
u16 rxmtint; /* number of seconds between LSA retransmissions */ u16 rxmtint; /* number of seconds between LSA retransmissions */
u16 inftransdelay; /* The estimated number of seconds it takes to u16 inftransdelay; /* The estimated number of seconds it takes to
transmit a Link State Update Packet over this transmit a Link State Update Packet over this
interface. LSAs contained in the update */ interface. LSAs contained in the update */
u8 priority; /* A router priority for DR election */ u8 priority; /* A router priority for DR election */
u16 helloint; /* number of seconds between hello sending */ u16 helloint; /* number of seconds between hello sending */
u16 waitint; /* number of sec before changing state from wait */ u16 waitint; /* number of sec before changing state from wait */
u16 pollint; /* Poll interval */ u16 pollint; /* Poll interval */
u32 deadc; /* after "deadint" missing hellos is router dead */ u32 deadc; /* after "deadint" missing hellos is router dead */
u16 autype; u16 autype;
u8 aukey[8]; u8 aukey[8];
u8 options; u8 options;
ip_addr drip; /* Designated router */ ip_addr drip; /* Designated router */
u32 drid; u32 drid;
ip_addr bdrip; /* Backup DR */ ip_addr bdrip; /* Backup DR */
u32 bdrid; u32 bdrid;
u8 type; /* OSPF view of type */ u8 type; /* OSPF view of type */
#define OSPF_IT_BCAST 0 #define OSPF_IT_BCAST 0
#define OSPF_IT_NBMA 1 #define OSPF_IT_NBMA 1
#define OSPF_IT_PTP 2 #define OSPF_IT_PTP 2
#define OSPF_IT_VLINK 3 #define OSPF_IT_VLINK 3
#define OSPF_IT_UNDEF 4 #define OSPF_IT_UNDEF 4
u8 strictnbma; /* Can I talk with unknown neighbors? */ u8 strictnbma; /* Can I talk with unknown neighbors? */
u8 stub; /* Inactive interface */ u8 stub; /* Inactive interface */
u8 ioprob; u8 ioprob;
#define OSPF_I_OK 0 /* Everything OK */ #define OSPF_I_OK 0 /* Everything OK */
#define OSPF_I_MC 1 /* I didn't open MC socket */ #define OSPF_I_MC 1 /* I didn't open MC socket */
#define OSPF_I_IP 2 /* I didn't open IP socet */ #define OSPF_I_IP 2 /* I didn't open IP socet */
u8 state; /* Interface state machine */ u8 state; /* Interface state machine */
#define OSPF_IS_DOWN 0 /* Not working */ #define OSPF_IS_DOWN 0 /* Not working */
#define OSPF_IS_LOOP 1 /* Should never happen */ #define OSPF_IS_LOOP 1 /* Should never happen */
#define OSPF_IS_WAITING 2 /* Waiting for Wait timer */ #define OSPF_IS_WAITING 2 /* Waiting for Wait timer */
@ -141,23 +146,24 @@ struct ospf_iface {
#define HELLOINT_D 10 #define HELLOINT_D 10
#define POLLINT_D 20 #define POLLINT_D 20
#define DEADC_D 4 #define DEADC_D 4
#define WAIT_DMH 4 /* Value of Wait timer - not found it in RFC #define WAIT_DMH 4 /* Value of Wait timer - not found it in RFC
* - using 4*HELLO * - using 4*HELLO
*/ */
struct top_hash_entry *nlsa; /* Originated net lsa */ struct top_hash_entry *nlsa; /* Originated net lsa */
int orignet; /* Schedule network LSA origination */ int orignet; /* Schedule network LSA origination */
int fadj; /* Number of full adjacent neigh */ int fadj; /* Number of full adjacent neigh */
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 */
#define DBDES_P 2 /* Database description */ #define DBDES_P 2 /* Database description */
#define LSREQ_P 3 /* Link state request */ #define LSREQ_P 3 /* Link state request */
#define LSUPD_P 4 /* Link state update */ #define LSUPD_P 4 /* Link state update */
#define LSACK_P 5 /* Link state acknowledgement */ #define LSACK_P 5 /* Link state acknowledgement */
u16 length; u16 length;
u32 routerid; u32 routerid;
u32 areaid; u32 areaid;
@ -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,11 +219,12 @@ struct ospf_dbdes_packet {
}; };
struct ospf_lsa_header { struct ospf_lsa_header
u16 age; /* LS Age */ {
#define LSA_MAXAGE 3600 /* 1 hour */ u16 age; /* LS Age */
#define LSA_CHECKAGE 300 /* 5 minutes */ #define LSA_MAXAGE 3600 /* 1 hour */
#define LSA_MAXAGEDIFF 900 /* 15 minutes */ #define LSA_CHECKAGE 300 /* 5 minutes */
#define LSA_MAXAGEDIFF 900 /* 15 minutes */
u8 options; u8 options;
u8 type; u8 type;
u32 id; u32 id;
@ -222,27 +233,30 @@ struct ospf_lsa_header {
#define LSA_T_SUM_NET 3 #define LSA_T_SUM_NET 3
#define LSA_T_SUM_RT 4 #define LSA_T_SUM_RT 4
#define LSA_T_EXT 5 #define LSA_T_EXT 5
u32 rt; /* Advertising router */ u32 rt; /* Advertising router */
s32 sn; /* LS Sequence number */ s32 sn; /* LS Sequence number */
#define LSA_INITSEQNO 0x80000001 #define LSA_INITSEQNO 0x80000001
#define LSA_MAXSEQNO 0x7fffffff #define LSA_MAXSEQNO 0x7fffffff
u16 checksum; u16 checksum;
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,29 +316,34 @@ 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;
u32 id; u32 id;
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;
}; };
@ -336,58 +362,59 @@ struct ospf_neighbor
#define NEIGHBOR_EXCHANGE 5 #define NEIGHBOR_EXCHANGE 5
#define NEIGHBOR_LOADING 6 #define NEIGHBOR_LOADING 6
#define NEIGHBOR_FULL 7 #define NEIGHBOR_FULL 7
timer *inactim; /* Inactivity timer */ timer *inactim; /* Inactivity timer */
union imms imms; /* I, M, Master/slave received */ union imms imms; /* I, M, Master/slave received */
u32 dds; /* DD Sequence number being sent */ u32 dds; /* DD Sequence number being sent */
u32 ddr; /* last Dat Des packet received */ u32 ddr; /* last Dat Des packet received */
union imms myimms; /* I, M Master/slave */ union imms myimms; /* I, M Master/slave */
u32 rid; /* Router ID */ u32 rid; /* Router ID */
ip_addr ip; /* IP of it's interface */ ip_addr ip; /* IP of it's interface */
u8 priority; /* Priority */ u8 priority; /* Priority */
u8 options; /* Options received */ u8 options; /* Options received */
ip_addr dr; /* Neigbour's idea of DR */ ip_addr dr; /* Neigbour's idea of DR */
ip_addr bdr; /* Neigbour's idea of BDR */ ip_addr bdr; /* Neigbour's idea of BDR */
u8 adj; /* built adjacency? */ u8 adj; /* built adjacency? */
siterator dbsi; /* Database summary list iterator */ siterator dbsi; /* Database summary list iterator */
slist lsrql; /* Link state request */ slist lsrql; /* Link state request */
struct top_graph *lsrqh; /* LSA graph */ struct top_graph *lsrqh; /* LSA graph */
siterator lsrqi; siterator lsrqi;
slist lsrtl; /* Link state retransmission list */ slist lsrtl; /* Link state retransmission list */
siterator lsrti; siterator lsrti;
struct top_graph *lsrth; struct top_graph *lsrth;
void *ldbdes; /* Last database description packet */ void *ldbdes; /* Last database description packet */
timer *rxmt_timer; /* RXMT timer */ timer *rxmt_timer; /* RXMT timer */
list ackl[2]; list ackl[2];
#define ACKL_DIRECT 0 #define ACKL_DIRECT 0
#define ACKL_DELAY 1 #define ACKL_DELAY 1
timer *ackd_timer; /* Delayed ack timer */ timer *ackd_timer; /* Delayed ack timer */
}; };
/* Definitions for interface state machine */ /* Definitions for interface state machine */
#define ISM_UP 0 /* Interface Up */ #define ISM_UP 0 /* Interface Up */
#define ISM_WAITF 1 /* Wait timer fired */ #define ISM_WAITF 1 /* Wait timer fired */
#define ISM_BACKS 2 /* Backup seen */ #define ISM_BACKS 2 /* Backup seen */
#define ISM_NEICH 3 /* Neighbor change */ #define ISM_NEICH 3 /* Neighbor change */
#define ISM_LOOP 4 /* Loop indicated */ #define ISM_LOOP 4 /* Loop indicated */
#define ISM_UNLOOP 5 /* Unloop indicated */ #define ISM_UNLOOP 5 /* Unloop indicated */
#define ISM_DOWN 6 /* Interface down */ #define ISM_DOWN 6 /* Interface down */
/* Definitions for neighbor state machine */ /* Definitions for neighbor state machine */
#define INM_HELLOREC 0 /* Hello Received */ #define INM_HELLOREC 0 /* Hello Received */
#define INM_START 1 /* Neighbor start - for NBMA */ #define INM_START 1 /* Neighbor start - for NBMA */
#define INM_2WAYREC 2 /* 2-Way received */ #define INM_2WAYREC 2 /* 2-Way received */
#define INM_NEGDONE 3 /* Negotiation done */ #define INM_NEGDONE 3 /* Negotiation done */
#define INM_EXDONE 4 /* Exchange done */ #define INM_EXDONE 4 /* Exchange done */
#define INM_BADLSREQ 5 /* Bad LS Request */ #define INM_BADLSREQ 5 /* Bad LS Request */
#define INM_LOADDONE 6 /* Load done */ #define INM_LOADDONE 6 /* Load done */
#define INM_ADJOK 7 /* AdjOK? */ #define INM_ADJOK 7 /* AdjOK? */
#define INM_SEQMIS 8 /* Sequence number mismatch */ #define INM_SEQMIS 8 /* Sequence number mismatch */
#define INM_1WAYREC 9 /* 1-Way */ #define INM_1WAYREC 9 /* 1-Way */
#define INM_KILLNBR 10 /* Kill Neighbor */ #define INM_KILLNBR 10 /* Kill 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,14 +443,15 @@ 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;
int rxmtint; int rxmtint;
int pollint; int pollint;
int inftransdelay; int inftransdelay;
int priority; int priority;
int waitint; int waitint;
int deadc; int deadc;
int type; int type;
@ -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);

View file

@ -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,51 +22,51 @@ 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;
if (ifa->autype == AU_SIMPLE) if (ifa->autype == AU_SIMPLE)
{
for (i = 0; i < 8; i++)
{ {
for (i = 0; i < 8; i++) if (pkt->authetication[i] != ifa->aukey[i])
{ return 0;
if (pkt->authetication[i] != ifa->aukey[i])
return 0;
}
return 1;
} }
return 1;
}
return 0; return 0;
} }
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,76 +89,71 @@ 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); }
}
/* Dump packet /* Dump packet
pu8=(u8 *)(sk->rbuf+5*4); pu8=(u8 *)(sk->rbuf+5*4);
@ -169,33 +164,32 @@ 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
#error RX_Hook does not work for IPv6 now. #error RX_Hook does not work for IPv6 now.
#endif #endif
@ -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);
} }

View file

@ -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_ */

File diff suppressed because it is too large Load diff

View file

@ -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,10 +35,10 @@ 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);
void init_infib(struct fib_node *fn); void init_infib(struct fib_node *fn);
void init_efib(struct fib_node *fn); void init_efib(struct fib_node *fn);