From 6d2b32114feadb283cb988daa7ed80142aa8c4d1 Mon Sep 17 00:00:00 2001 From: Ondrej Filip Date: Thu, 30 Mar 2000 00:18:59 +0000 Subject: [PATCH] LSreq initial work. --- proto/ospf/Makefile | 2 +- proto/ospf/dbdes.c | 16 +++++-- proto/ospf/hello.c | 6 +++ proto/ospf/lsreq.c | 104 ++++++++++++++++++++++++++++++++++++++++++ proto/ospf/lsreq.h | 18 ++++++++ proto/ospf/neighbor.c | 3 ++ proto/ospf/ospf.h | 20 +++++++- proto/ospf/packet.c | 1 + proto/ospf/topology.c | 1 + 9 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 proto/ospf/lsreq.c create mode 100644 proto/ospf/lsreq.h diff --git a/proto/ospf/Makefile b/proto/ospf/Makefile index 6b787c62..a7658f7f 100644 --- a/proto/ospf/Makefile +++ b/proto/ospf/Makefile @@ -1,4 +1,4 @@ -source=ospf.c topology.c packet.c hello.c neighbor.c iface.c dbdes.c +source=ospf.c topology.c packet.c hello.c neighbor.c iface.c dbdes.c lsreq.c root-rel=../../ dir-name=proto/ospf diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index c6dabc59..4e0f2a49 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -184,7 +184,7 @@ rxmt_timer_hook(timer *timer) n=(struct ospf_neighbor *)timer->data; ifa=n->ifa; p=(struct proto *)(ifa->proto); - debug("%s: RXMT timer fired on interface %s for nigh: %d.\n", + debug("%s: RXMT timer fired on interface %s for neigh: %u.\n", p->name, ifa->iface->name, n->rid); if(n->stateifa->oa->gr; + op=(struct ospf_packet *)ps; plsa=(void *)(ps+1); - ntohlsah(plsa, &lsa); + + j=(ntohs(op->length)-sizeof(struct ospf_dbdes_packet))/ + sizeof( struct ospf_lsa_header); + + for(i=0;ilsa))==1)) { sn=sl_alloc(gr->hash_slab); - ntohlsah(plsa, &(sn->lsa)); + ntohlsah(plsa+i, &(sn->lsa)); s_add_tail(&(n->lsrql), SNODE sn); } + } } void diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index e025ae47..77d114c7 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -112,6 +112,12 @@ ospf_hello_rx(struct ospf_hello_packet *ps, struct proto *p, n->rxmt_timer->hook=rxmt_timer_hook; n->rxmt_timer->recurrent=ifa->rxmtint; DBG("%s: Installing rxmt timer.\n", p->name); + n->lsrr_timer=tm_new(p->pool); + n->lsrr_timer->data=n; + n->lsrr_timer->randomize=0; + n->lsrr_timer->hook=lsrr_timer_hook; + n->lsrr_timer->recurrent=ifa->rxmtint; + DBG("%s: Installing lsrr timer.\n", p->name); } ospf_neigh_sm(n, INM_HELLOREC); diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c new file mode 100644 index 00000000..a0a86856 --- /dev/null +++ b/proto/ospf/lsreq.c @@ -0,0 +1,104 @@ +/* + * BIRD -- OSPF + * + * (c) 2000 Ondrej Filip + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include "ospf.h" + +void +ospf_lsreq_tx(struct ospf_neighbor *n) +{ + snode *sn; + struct top_hash_entry *en; + struct ospf_lsreq_packet *pk; + struct ospf_packet *op; + struct ospf_lsreq_header *lsh; + u16 length; + int i,j; + + pk=(struct ospf_lsreq_packet *)n->ifa->ip_sk->tbuf; + op=(struct ospf_packet *)n->ifa->ip_sk->tbuf; + + fill_ospf_pkt_hdr(n->ifa, pk, LSREQ); + + s_init(&(n->lsrqi), &(n->lsrql)); + sn=s_get(&(n->lsrqi)); + if(sn==NULL) return; + /* FIXME above I don't need iterator and slist */ + + i=j=(n->ifa->iface->mtu-SIPH-sizeof(struct ospf_lsreq_packet))/ + sizeof(struct ospf_lsreq_header); /* FIXME IP header! */ + lsh=(struct ospf_lsreq_header *)(pk+1); + + for(;i>0;i--) + { + en=(struct top_hash_entry *)sn; + lsh->padd1=0; lsh->padd2=0; + lsh->type=en->lsa.type; + lsh->rt=htonl(en->lsa.rt); + lsh->id=htonl(en->lsa.id); + lsh++; + DBG("Requesting %uth LSA: Type: %u, Id: %u, RT: %u\n",i, en->lsa.type, + en->lsa.id, en->lsa.rt); + if((sn=sn->next)==NULL) break; + } + + length=sizeof(struct ospf_lsreq_packet)+(j-i)*sizeof(struct ospf_lsreq_header); + op->length=htons(length); + ospf_pkt_finalize(n->ifa, op); + sk_send_to(n->ifa->ip_sk,length, n->ip, OSPF_PROTO); + DBG("Lsreq send to: %u\n", n->rid); +} + +void +lsrr_timer_hook(timer *timer) +{ + struct ospf_iface *ifa; + struct proto *p; + struct ospf_neighbor *n; + + n=(struct ospf_neighbor *)timer->data; + ifa=n->ifa; + p=(struct proto *)(ifa->proto); + debug("%s: LSRR timer fired on interface %s for neigh: %u.\n", + p->name, ifa->iface->name, n->rid); + ospf_lsreq_tx(n); +} + +void +ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p, + struct ospf_iface *ifa, u16 size) +{ + u32 nrid, myrid; + struct ospf_neighbor *n; + struct ospf_lsreq_header *lsh; + int length; + u8 i; + + nrid=ntohl(ps->ospf_packet.routerid); + + myrid=p->cf->global->router_id; + + if((n=find_neigh(ifa, nrid))==NULL) + { + debug("%s: Received dbdes from unknown neigbor! (%u)\n", p->name, + nrid); + return ; + } + if(n->statename); + + length=htons(ps->ospf_packet.length); + lsh=(void *)(ps+1); + for(i=0;i<(length-sizeof(struct ospf_lsreq_packet))/ + sizeof(struct ospf_lsreq_header);i++); + { + DBG("Processing LSA: ID=%u, Type=%u, Router=%u\n", lsh->id, lsh->type, + lsh->rt); + /* FIXME Go on */ + } + +} + diff --git a/proto/ospf/lsreq.h b/proto/ospf/lsreq.h new file mode 100644 index 00000000..46d5b928 --- /dev/null +++ b/proto/ospf/lsreq.h @@ -0,0 +1,18 @@ +/* + * BIRD -- OSPF + * + * (c) 2000 Ondrej Filip + * + * Can be freely distributed and used under the terms of the GNU GPL. + * + */ + +#ifndef _BIRD_OSPF_LSREQ_H_ +#define _BIRD_OSPF_LSREQ_H_ + +void ospf_lsreq_tx(struct ospf_neighbor *n); +void lsrr_timer_hook(timer *timer); +void ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p, + struct ospf_iface *ifa, u16 size); + +#endif /* _BIRD_OSPF_LSREQ_H_ */ diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index d08e58ce..0f4bbcf0 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -210,8 +210,11 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event) s_init_list(&(n->lsrql)); s_init_list(&(n->lsrtl)); s_init(&(n->dbsi), &(n->ifa->oa->lsal)); + s_init(&(n->lsrqi), &(n->lsrql)); + tm_start(n->lsrr_timer,n->ifa->rxmtint); /*ospf_dbdes_tx(n);*/ } + else die("NEGDONE and I'm not in EXSTART?\n"); break; case INM_EXDONE: neigh_chstate(n,NEIGHBOR_LOADING); diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 06ca56dc..0301154e 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -11,6 +11,8 @@ #define LOCAL_DEBUG +#define SIPH 64 /* FIXME Size Of IP header */ + #include #include "nest/bird.h" @@ -232,6 +234,18 @@ struct ospf_lsa_ext_tos { u32 tag; }; +struct ospf_lsreq_packet { + struct ospf_packet ospf_packet; +}; + +struct ospf_lsreq_header { + u16 padd1; + u8 padd2; + u8 type; + u32 id; + u32 rt; /* Advertising router */ +}; + struct ospf_neighbor { node n; @@ -258,12 +272,13 @@ struct ospf_neighbor 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? */ + slist lsrql; /* Link state request */ /* FIXME add hashing? */ siterator lsrqi; slist lsrtl; /* Link state retransmission list */ siterator lsrti; void *ldbdes; /* Last database description packet */ - timer *rxmt_timer; /* RXMT timer */ + timer *rxmt_timer; /* RXMT timer */ + timer *lsrr_timer; /* Link state requiest retransmition timer */ }; /* Definitions for interface state machine */ @@ -318,5 +333,6 @@ static void ospf_postconfig(struct proto_config *c); #include "proto/ospf/neighbor.h" #include "proto/ospf/topology.h" #include "proto/ospf/dbdes.h" +#include "proto/ospf/lsreq.h" #endif /* _BIRD_OSPF_H_ */ diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index b0ab477f..a176c44e 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -141,6 +141,7 @@ ospf_rx_hook(sock *sk, int size) break; case LSREQ: DBG("%s: Link state request received.\n", p->name); + ospf_lsreq_rx((struct ospf_lsreq_packet *)ps, p, ifa, size); break; case LSUPD: DBG("%s: Link state update received.\n", p->name); diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index fe236ba9..15163f93 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -197,6 +197,7 @@ addifa_rtlsa(struct ospf_iface *ifa) } make_rt_lsa(oa, po); + /* FIXME length? */ /*FIXME seq no++ */ /*FIXME lsa_flood(oa->rt) */ }