diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index 85d2a3bc..43d60a38 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -1,7 +1,7 @@ /* * BIRD -- OSPF * - * (c) 1999 Ondrej Filip + * (c) 1999-2000 Ondrej Filip * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -16,19 +16,20 @@ ospf_dbdes_tx(struct ospf_neighbor *n) struct ospf_iface *ifa; u16 length; struct proto *p; + u16 i,j; + u8 *aa,*bb; ifa=n->ifa; p=(struct proto *)(ifa->proto); + pkt=(struct ospf_dbdes_packet *)(ifa->ip_sk->tbuf); + op=(struct ospf_packet *)pkt; switch(n->state) { case NEIGHBOR_EXSTART: /* Send empty packets */ - pkt=(struct ospf_dbdes_packet *)(ifa->ip_sk->tbuf); - op=(struct ospf_packet *)pkt; - fill_ospf_pkt_hdr(ifa, pkt, DBDES); - pkt->iface_mtu= ((struct iface *)ifa)->mtu; + pkt->iface_mtu=ifa->iface->mtu; pkt->options= ifa->options; pkt->imms=n->myimms; pkt->ddseq=n->dds; @@ -37,8 +38,67 @@ ospf_dbdes_tx(struct ospf_neighbor *n) ospf_pkt_finalize(ifa, op); sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO); debug("%s: DB_DES sent for %u.\n", p->name, n->rid); + break; + + case NEIGHBOR_EXCHANGE: + if(! ((IAMMASTER(n->myimms) && (n->dds==n->ddr+1)) || ((!IAMMASTER(n->myimms)) && (n->dds==n->ddr)))) + { + snode *sn; /* Send next */ + struct ospf_lsaheader *lsa; + + fill_ospf_pkt_hdr(ifa, pkt, DBDES); + pkt->iface_mtu= ifa->iface->mtu; + pkt->options= ifa->options; + pkt->ddseq=n->dds; + + sn=s_get(&(n->dbsi)); + j=i=(pkt->iface_mtu-sizeof(struct ospf_dbdes_packet))/sizeof(struct ospf_lsaheader); /* Number of lsaheaders */ + lsa=(n->ldbdes+sizeof(struct ospf_dbdes_packet)); + + for(;i>0;i--) + { + struct top_hash_entry *en; + + en=(struct top_hash_entry *)sn; + lsa->lsage=htons(en->lsage); + lsa->options=htons(en->options); + lsa->lstype=htons(en->lsa_type); + lsa->lsid=htons(en->lsa_id); + lsa->advr=htons(en->rtr_id); + lsa->lssn=htons(en->lsseqno); + lsa->length=htons(en->length); + lsa->checksum=htons(en->checksum); + if(sn->next==NULL) + { + break; /* Should set some flag? */ + } + sn=sn->next; + } + s_put(&(n->dbsi),sn); + + if(sn->next==NULL) + { + n->myimms=(n->myimms-DBDES_M); /* Unset more bit */ + } + + pkt->imms=n->myimms; + + length=j*sizeof(struct ospf_lsaheader)+sizeof(struct ospf_dbdes_packet); + op->length=htons(length); + ospf_pkt_finalize(ifa, op); + sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO); + } + + aa=ifa->ip_sk->tbuf; + bb=n->ldbdes; + length=ntohs(op->length); + + for(i=0; iiface->mtu; i++) + { + *(aa+i)=*(bb+i); /* Copy last sent packet again */ + } + sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO); - /*case NEIGHBOR_EXCHANGE: */ default: /* Ignore it */ break; } diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index 61868075..e3b81683 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -103,6 +103,7 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, n->options=ps->options; n->ifa=ifa; n->adj=0; + n->ldbdes=mb_alloc(p->pool, ifa->iface->mtu); neigh_chstate(n,NEIGHBOR_DOWN); install_inactim(n); } diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index cd8b035d..e2aaa7ad 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -233,7 +233,8 @@ ospf_iface_default(struct ospf_iface *ifa) { u8 i; - ifa->area=0; /* FIXME: Read from config */ + ifa->oa=NULL; + ifa->an=0; /* FIXME This should respect config */ ifa->cost=COST_D; ifa->rxmtint=RXMTINT_D; ifa->iftransdelay=IFTRANSDELAY_D; diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index e4277f77..1470b83a 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -204,7 +204,10 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) if(n->state==NEIGHBOR_EXSTART) { neigh_chstate(n,NEIGHBOR_EXCHANGE); - /* FIXME Go on... */ + s_init_list(&(n->lsrql)); + s_init_list(&(n->lsrtl)); + s_init(&(n->dbsi), &(n->ifa->oa->lsal)); + ospf_dbdes_tx(n); } break; case INM_EXDONE: diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index c161deaa..18db001d 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -21,6 +21,7 @@ #include "lib/checksum.h" #include "lib/ip.h" #include "lib/lists.h" +#include "lib/slists.h" #include "lib/socket.h" #include "lib/timer.h" #include "lib/resource.h" @@ -60,10 +61,11 @@ struct ospf_iface { node n; struct proto_ospf *proto; struct iface *iface; /* Nest's iface */ + struct ospf_area *oa; + u32 an; /* Area number */ sock *hello_sk; /* Hello socket */ sock *ip_sk; /* IP socket (for DD ...) */ list neigh_list; /* List of neigbours */ - u32 area; /* OSPF Area */ u16 cost; /* Cost of iface */ u16 rxmtint; /* number of seconds between LSA retransmissions */ u16 iftransdelay; /* The estimated number of seconds it takes to @@ -183,6 +185,12 @@ struct ospf_neighbor u32 dr; /* Neigbour's idea of DR */ u32 bdr; /* Neigbour's idea of BDR */ u8 adj; /* built adjacency? */ + siterator dbsi; /* Database summary list iterator */ + slist lsrql; /* Link state request */ /* FIXME add top_gr hashing? */ + siterator lsrqi; + slist lsrtl; /* Link state retransmission list */ + siterator lsrti; + void *ldbdes; /* Last database description packet */ }; /* Definitions for interface state machine */ @@ -213,6 +221,7 @@ struct ospf_area { struct ospf_area *next; u32 areaid; struct top_graph *gr; /* LSA graph */ + slist lsal; /* List of all LSA's */ struct top_hash_entry *rt; /* My own router LSA */ slab *rtlinks; }; diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 1e9706a5..b0ab477f 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -23,7 +23,7 @@ fill_ospf_pkt_hdr(struct ospf_iface *ifa, void *buf, u8 h_type) pkt->type=h_type; pkt->routerid=htonl(p->cf->global->router_id); - pkt->areaid=htonl(ifa->area); + pkt->areaid=htonl(ifa->an); pkt->autype=htons(ifa->autype); pkt->checksum=0; } @@ -101,7 +101,7 @@ ospf_rx_hook(sock *sk, int size) /* FIXME: Do authetification */ - if(ps->areaid!=ifa->area) + if(ps->areaid!=ifa->an) { log("%s: Bad OSPF packet received: other area %ld", p->name, ps->areaid); log("%s: Discarding",p->name); diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 1f86014a..ad88f013 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -38,9 +38,11 @@ addifa_rtlsa(struct ospf_iface *ifa) while(oa!=NULL) { - if(oa->areaid==ifa->area) break; + if(oa->areaid==ifa->an) break; oa=oa->next; } + + ifa->oa=oa; if(oa==NULL) /* New area */ { @@ -48,12 +50,13 @@ addifa_rtlsa(struct ospf_iface *ifa) po->firstarea=mb_alloc(po->proto.pool, sizeof(struct ospf_area)); po->firstarea->next=oa; oa=po->firstarea; - oa->areaid=ifa->area; + oa->areaid=ifa->an; oa->gr=ospf_top_new(po); + s_init_list(&(oa->lsal)); oa->rtlinks=sl_new(po->proto.pool, sizeof(struct top_graph_rtlsa_link)); oa->rt=ospf_hash_get(oa->gr, rtid, rtid, LSA_T_RT); - DBG("XXXXXX %x XXXXXXX\n", oa->rt); + s_add_head(&(oa->lsal), (snode *)oa->rt); rt=mb_alloc(po->proto.pool, sizeof(struct top_graph_rtlsa)); oa->rt->vertex=(void *)rt; oa->rt->lsage=0; @@ -61,7 +64,7 @@ addifa_rtlsa(struct ospf_iface *ifa) rt->Vbit=0; rt->Ebit= (po->areano++ ? 0 : 1); /* If it's 1st area set 0 */ rt->Bbit=0; /* FIXME Could read config */ - DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->area); + DBG("%s: New OSPF area \"%d\" added.\n", po->proto.name, ifa->an); if(po->areano==2) /* We are attached to more than 2 areas! */ { diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index e2021b00..6a1aad5e 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -10,6 +10,7 @@ #define _BIRD_OSPF_TOPOLOGY_H_ struct top_hash_entry { /* Index for fast mapping (type,rtrid,LSid)->vertex */ + snode n; struct top_hash_entry *next; /* Next in hash chain */ struct top_vertex *vertex; u32 lsa_id, rtr_id; @@ -25,6 +26,7 @@ struct top_hash_entry { /* Index for fast mapping (type,rtrid,LSid)->vertex */ #define LSA_CHECKAGE 300 /* 5 minutes */ #define LSA_MAXAGEDIFF 900 /* 15 minutes */ u32 lsseqno; + u16 length, checksum; #define LSA_INITSEQNO 0x80000001 #define LSA_MAXSEQNO 0x7fffffff };