Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / dbdes.c @ 44724025

History | View | Annotate | Download (8.62 KB)

1 4364b47e Ondrej Filip
/*
2
 *        BIRD -- OSPF
3
 *
4 30147b89 Ondrej Filip
 *        (c) 1999-2000 Ondrej Filip <feela@network.cz>
5 4364b47e Ondrej Filip
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9
#include "ospf.h"
10
11
void
12
ospf_dbdes_tx(struct ospf_neighbor *n)
13
{
14
  struct ospf_dbdes_packet *pkt;
15
  struct ospf_packet *op;
16
  struct ospf_iface *ifa;
17
  u16 length;
18
  struct proto *p;
19 30147b89 Ondrej Filip
  u16 i,j;
20
  u8 *aa,*bb;
21 4364b47e Ondrej Filip
22
  ifa=n->ifa;
23
24
  p=(struct proto *)(ifa->proto);
25
26
  switch(n->state)
27
  {
28
    case NEIGHBOR_EXSTART:                /* Send empty packets */
29 96501dfe Ondrej Filip
      n->myimms.bit.i=1;
30 963ea03d Ondrej Filip
      pkt=(struct ospf_dbdes_packet *)(ifa->ip_sk->tbuf);
31
      op=(struct ospf_packet *)pkt;
32 4364b47e Ondrej Filip
      fill_ospf_pkt_hdr(ifa, pkt, DBDES);
33 3fba2096 Ondrej Filip
      pkt->iface_mtu=htons(ifa->iface->mtu);        /*FIXME NOT for VLINK! */
34 4364b47e Ondrej Filip
      pkt->options= ifa->options;
35
      pkt->imms=n->myimms;
36 910e557b Ondrej Filip
      pkt->ddseq=htonl(n->dds);
37 4364b47e Ondrej Filip
      length=sizeof(struct ospf_dbdes_packet);
38
      op->length=htons(length);
39
      ospf_pkt_finalize(ifa, op);
40
      sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO);
41 44724025 Ondrej Filip
      debug("%s: DB_DES (I) sent for %I.\n", p->name, n->rid);
42 30147b89 Ondrej Filip
      break;
43
44
    case NEIGHBOR_EXCHANGE:
45 96501dfe Ondrej Filip
      n->myimms.bit.i=0;
46 910e557b Ondrej Filip
      if(((n->myimms.bit.ms) && (n->dds==n->ddr+1)) ||
47
         ((!(n->myimms.bit.ms)) && (n->dds==n->ddr)))
48 30147b89 Ondrej Filip
      {
49
        snode *sn;                        /* Send next */
50 ce17d4c1 Ondrej Filip
        struct ospf_lsa_header *lsa;
51 963ea03d Ondrej Filip
52
        pkt=n->ldbdes;
53
        op=(struct ospf_packet *)pkt;
54 30147b89 Ondrej Filip
        
55
        fill_ospf_pkt_hdr(ifa, pkt, DBDES);
56 963ea03d Ondrej Filip
        pkt->iface_mtu=htons(ifa->iface->mtu);
57 30147b89 Ondrej Filip
        pkt->options= ifa->options;
58 910e557b Ondrej Filip
        pkt->ddseq=htonl(n->dds);
59 30147b89 Ondrej Filip
60 963ea03d Ondrej Filip
        j=i=(ifa->iface->mtu-sizeof(struct ospf_dbdes_packet))/
61 ce17d4c1 Ondrej Filip
                sizeof(struct ospf_lsa_header);        /* Number of lsaheaders */
62 30147b89 Ondrej Filip
        lsa=(n->ldbdes+sizeof(struct ospf_dbdes_packet));
63
64 910e557b Ondrej Filip
        if(n->myimms.bit.m)
65
        {
66 2560c886 Ondrej Filip
          sn=s_get(&(n->dbsi));
67 910e557b Ondrej Filip
68 2560c886 Ondrej Filip
          DBG("Number of LSA: %d\n", j);
69
          for(;i>0;i--)
70
          {
71
            struct top_hash_entry *en;
72 30147b89 Ondrej Filip
          
73 2560c886 Ondrej Filip
            en=(struct top_hash_entry *)sn;
74
            htonlsah(&(en->lsa), lsa);
75
            DBG("Working on: %d\n", i);
76
            debug("\t%04x %08x %08x %p\n", en->lsa.type, en->lsa.id,
77
              en->lsa.rt, en->lsa_body);
78
79 d8852b36 Ondrej Filip
            if(sn==STAIL(n->ifa->oa->lsal))
80 2560c886 Ondrej Filip
            {
81
              break;        /* Should set some flag? */
82
              }
83
            sn=sn->next;
84
            lsa++;
85
          }
86
          i--;
87 963ea03d Ondrej Filip
88 d8852b36 Ondrej Filip
          if(sn==STAIL(n->ifa->oa->lsal))
89 30147b89 Ondrej Filip
          {
90 2560c886 Ondrej Filip
            DBG("Number of LSA NOT sent: %d\n", i);
91
            DBG("M bit unset.\n");
92
            n->myimms.bit.m=0;        /* Unset more bit */
93 30147b89 Ondrej Filip
          }
94
95 2560c886 Ondrej Filip
          s_put(&(n->dbsi),sn);
96 910e557b Ondrej Filip
        }
97 963ea03d Ondrej Filip
98 96501dfe Ondrej Filip
        pkt->imms.byte=n->myimms.byte;
99 30147b89 Ondrej Filip
100 963ea03d Ondrej Filip
        length=(j-i)*sizeof(struct ospf_lsa_header)+
101 ce17d4c1 Ondrej Filip
                sizeof(struct ospf_dbdes_packet);
102 30147b89 Ondrej Filip
        op->length=htons(length);
103 96501dfe Ondrej Filip
        
104 30147b89 Ondrej Filip
        ospf_pkt_finalize(ifa, op);
105
      }
106
107 910e557b Ondrej Filip
    case NEIGHBOR_LOADING:
108
    case NEIGHBOR_FULL:
109
110 30147b89 Ondrej Filip
      aa=ifa->ip_sk->tbuf;
111
      bb=n->ldbdes;
112 963ea03d Ondrej Filip
      op=n->ldbdes;
113 30147b89 Ondrej Filip
      length=ntohs(op->length);
114
115
      for(i=0; i<ifa->iface->mtu; i++)
116
      {
117 96501dfe Ondrej Filip
        *(aa+i)=*(bb+i);        /* Copy last sent packet again */
118 30147b89 Ondrej Filip
      }
119 04c6319a Ondrej Filip
120
      {
121
        u8 ii;
122
        u8 *jj=ifa->ip_sk->tbuf;
123
124
        for(ii=0;ii<length;ii+=4)
125
        {
126
          DBG("Out dump: %d,%d,%d,%d\n", *(jj+ii), *(jj+ii+1), *(jj+ii+2), *(jj+ii+3));
127
        }
128
      }
129
130 30147b89 Ondrej Filip
      sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO);
131 44724025 Ondrej Filip
      debug("%s: DB_DES sent to %I.\n", p->name, n->rid);
132 910e557b Ondrej Filip
      if(n->myimms.bit.ms) tm_start(n->rxmt_timer,ifa->rxmtint);
133
      else
134
      {
135
        if((n->myimms.bit.m==0) && (n->imms.bit.m==0) &&
136
          (n->state==NEIGHBOR_EXCHANGE))
137
        {
138
          ospf_neigh_sm(n, INM_EXDONE);
139
          if(n->myimms.bit.ms) tm_stop(n->rxmt_timer);
140
          else tm_start(n->rxmt_timer,ifa->rxmtint);
141
        }
142
      }
143
      break;
144 4364b47e Ondrej Filip
145
    default:                                /* Ignore it */
146 910e557b Ondrej Filip
      die("Bug in dbdes sending\n");
147 4364b47e Ondrej Filip
      break;
148
  }
149
}
150
151
void
152
rxmt_timer_hook(timer *timer)
153
{
154
  struct ospf_iface *ifa;
155
  struct proto *p;
156
  struct ospf_neighbor *n;
157
158 910e557b Ondrej Filip
  n=(struct ospf_neighbor *)timer->data;
159
  ifa=n->ifa;
160 4364b47e Ondrej Filip
  p=(struct proto *)(ifa->proto);
161 44724025 Ondrej Filip
  debug("%s: RXMT timer fired on interface %s for neigh: %I.\n",
162 2560c886 Ondrej Filip
    p->name, ifa->iface->name, n->rid);
163 910e557b Ondrej Filip
  if(n->state<NEIGHBOR_LOADING) ospf_dbdes_tx(n);
164 2560c886 Ondrej Filip
  else
165
  {
166
    tm_stop(n->rxmt_timer);
167
           /* FIXME I should dealloc ldbdes */
168
  }
169 910e557b Ondrej Filip
}
170
171
void
172
ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct proto *p,
173
  struct ospf_neighbor *n)
174
{
175
  struct ospf_lsa_header *plsa,lsa;
176
  struct top_hash_entry *he,*sn;
177
  struct top_graph *gr;
178 6d2b3211 Ondrej Filip
  struct ospf_packet *op;
179
  int i,j;
180 910e557b Ondrej Filip
181
  gr=n->ifa->oa->gr;
182 6d2b3211 Ondrej Filip
  op=(struct ospf_packet *)ps;
183 910e557b Ondrej Filip
184
  plsa=(void *)(ps+1);
185 6d2b3211 Ondrej Filip
186
  j=(ntohs(op->length)-sizeof(struct ospf_dbdes_packet))/
187
    sizeof( struct ospf_lsa_header);
188
189
  for(i=0;i<j;i++)
190
  {
191 95eb1dba Ondrej Filip
    ntohlsah(plsa+i, &lsa);
192
    if(((he=ospf_hash_find(gr,lsa.id,lsa.rt,lsa.type))==NULL)||
193
      (lsa_comp(&lsa, &(he->lsa))==1))
194
    {
195 394acced Ondrej Filip
      /* Is this condition necessary? */
196 95eb1dba Ondrej Filip
      if(ospf_hash_find(n->lsrqh,lsa.id,lsa.rt,lsa.type)==NULL)
197
      {
198
        sn=ospf_hash_get(n->lsrqh,lsa.id,lsa.rt,lsa.type);
199
        ntohlsah(plsa+i, &(sn->lsa));
200
        s_add_tail(&(n->lsrql), SNODE sn);
201
      }
202 d8852b36 Ondrej Filip
      /* FIXME and the next part of condition? */
203 95eb1dba Ondrej Filip
    }
204 6d2b3211 Ondrej Filip
  }
205 4364b47e Ondrej Filip
}
206
207
void
208
ospf_dbdes_rx(struct ospf_dbdes_packet *ps, struct proto *p,
209
  struct ospf_iface *ifa, u16 size)
210
{
211
  u32 nrid, myrid;
212
  struct ospf_neighbor *n;
213
  u8 i;
214
215
  nrid=ntohl(((struct ospf_packet *)ps)->routerid);
216
217
  myrid=p->cf->global->router_id;
218
219
  if((n=find_neigh(ifa, nrid))==NULL)
220
  {
221 44724025 Ondrej Filip
    debug("%s: Received dbdes from unknown neigbor! (%I)\n", p->name,
222 4364b47e Ondrej Filip
      nrid);
223
    return ;
224
  }
225
226
  if(ifa->iface->mtu<size)
227
  {
228 44724025 Ondrej Filip
    debug("%s: Received dbdes larger than MTU from (%I)!\n", p->name, nrid);
229 4364b47e Ondrej Filip
    return ;
230
  }
231
232
  switch(n->state)
233
  {
234
    case NEIGHBOR_DOWN:
235
    case NEIGHBOR_ATTEMPT:
236
    case NEIGHBOR_2WAY:
237 44724025 Ondrej Filip
        debug("%s: Received dbdes from %I in bad state.\n", p->name, nrid);
238 4364b47e Ondrej Filip
        return;
239
      break;
240
    case NEIGHBOR_INIT:
241
        ospf_neigh_sm(n, INM_2WAYREC);
242
        if(n->state!=NEIGHBOR_EXSTART) return;
243
    case NEIGHBOR_EXSTART:
244 04c6319a Ondrej Filip
        if((ps->imms.bit.m && ps->imms.bit.ms && ps->imms.bit.i)
245
          && (n->rid > myrid) &&
246 4364b47e Ondrej Filip
          (size == sizeof(struct ospf_dbdes_packet)))
247
        {
248
          /* I'm slave! */
249 910e557b Ondrej Filip
          n->dds=ntohl(ps->ddseq);
250
          n->ddr=ntohl(ps->ddseq);
251 4364b47e Ondrej Filip
          n->options=ps->options;
252 04c6319a Ondrej Filip
          n->myimms.bit.ms=0;
253
          n->imms.byte=ps->imms.byte;
254 44724025 Ondrej Filip
          debug("%s: I'm slave to %I. \n", p->name, nrid);
255 4364b47e Ondrej Filip
          ospf_neigh_sm(n, INM_NEGDONE);
256 910e557b Ondrej Filip
          tm_stop(n->rxmt_timer);
257
          ospf_dbdes_tx(n);
258
          break;
259 4364b47e Ondrej Filip
        }
260
        else
261
        {
262 04c6319a Ondrej Filip
          if(((ps->imms.bit.i==0) && (ps->imms.bit.ms==0)) &&
263 910e557b Ondrej Filip
            (n->rid < myrid) && (n->dds == ntohl(ps->ddseq)))
264 4364b47e Ondrej Filip
          {
265
            /* I'm master! */
266
            n->options=ps->options;
267 910e557b Ondrej Filip
            n->ddr=ntohl(ps->ddseq)-1;
268 04c6319a Ondrej Filip
            n->imms.byte=ps->imms.byte;
269 44724025 Ondrej Filip
            debug("%s: I'm master to %I. \n", p->name, nrid);
270 4364b47e Ondrej Filip
            ospf_neigh_sm(n, INM_NEGDONE);
271
          }
272
          else
273
          {
274 44724025 Ondrej Filip
            debug("%s: Nothing happend to %I (imms=%u)", p->name, nrid,
275 910e557b Ondrej Filip
              ps->imms.byte);
276 4364b47e Ondrej Filip
            break;
277
          }
278
        }
279
    case NEIGHBOR_EXCHANGE:
280 04c6319a Ondrej Filip
        if((ps->imms.byte==n->imms.byte) && (ps->options=n->options) &&
281 910e557b Ondrej Filip
          (ntohl(ps->ddseq)==n->ddr))
282 4364b47e Ondrej Filip
        {
283
          /* Duplicate packet */
284 44724025 Ondrej Filip
          debug("%s: Received duplicate dbdes from (%I)!\n", p->name, nrid);
285 04c6319a Ondrej Filip
          if(n->imms.bit.ms==0)
286 4364b47e Ondrej Filip
          {
287
            ospf_dbdes_tx(n);
288
          }
289
          return;
290
        }
291
292 910e557b Ondrej Filip
        n->ddr=ntohl(ps->ddseq);
293
294
        if(ps->imms.bit.ms!=n->imms.bit.ms) /* M/S bit differs */
295 4364b47e Ondrej Filip
        {
296 910e557b Ondrej Filip
          DBG("SEQMIS-BIT-MS\n");
297 4364b47e Ondrej Filip
          ospf_neigh_sm(n, INM_SEQMIS);
298
          break;
299
        }
300
301 04c6319a Ondrej Filip
        if(ps->imms.bit.i)        /* I bit is set */
302 4364b47e Ondrej Filip
        {
303 963ea03d Ondrej Filip
          DBG("SEQMIS-BIT-I\n");
304 4364b47e Ondrej Filip
          ospf_neigh_sm(n, INM_SEQMIS);
305
          break;
306
        }
307
308 2560c886 Ondrej Filip
        n->imms.byte=ps->imms.byte;
309
310 4364b47e Ondrej Filip
        if(ps->options!=n->options)        /* Options differs */
311
        {
312 963ea03d Ondrej Filip
          DBG("SEQMIS-OPT\n");
313 4364b47e Ondrej Filip
          ospf_neigh_sm(n, INM_SEQMIS);
314
          break;
315
        }
316
317 04c6319a Ondrej Filip
        if(n->myimms.bit.ms)
318 4364b47e Ondrej Filip
        {
319 910e557b Ondrej Filip
          if(ntohl(ps->ddseq)!=n->dds)                /* MASTER */
320 4364b47e Ondrej Filip
          {
321 963ea03d Ondrej Filip
            DBG("SEQMIS-MASTER\n");
322 4364b47e Ondrej Filip
            ospf_neigh_sm(n, INM_SEQMIS);
323
            break;
324
          }
325 910e557b Ondrej Filip
          n->dds++;
326
          DBG("Incrementing dds\n");
327
          ospf_dbdes_reqladd(ps,p,n);
328
          if((n->myimms.bit.m==0) && (ps->imms.bit.m==0))
329
          {
330
            ospf_neigh_sm(n, INM_EXDONE);
331
          }
332
          else
333
          {
334
            ospf_dbdes_tx(n);
335
          }
336
337 4364b47e Ondrej Filip
        }
338
        else
339
        {
340 2560c886 Ondrej Filip
          if(ntohl(ps->ddseq)!=(n->dds+1))        /* SLAVE */
341 4364b47e Ondrej Filip
          {
342 963ea03d Ondrej Filip
            DBG("SEQMIS-SLAVE\n");
343 4364b47e Ondrej Filip
            ospf_neigh_sm(n, INM_SEQMIS);
344
            break;
345
          }
346 2560c886 Ondrej Filip
          n->ddr=ntohl(ps->ddseq);
347
          n->dds=ntohl(ps->ddseq);
348 910e557b Ondrej Filip
          ospf_dbdes_reqladd(ps,p,n);
349
          ospf_dbdes_tx(n);
350 4364b47e Ondrej Filip
        }
351
352
      break;
353
    case NEIGHBOR_LOADING:
354
    case NEIGHBOR_FULL:
355 04c6319a Ondrej Filip
        if((ps->imms.byte==n->imms.byte) && (ps->options=n->options) &&
356 4364b47e Ondrej Filip
          (ps->ddseq==n->dds)) /* Only duplicate are accepted */
357
        {
358 44724025 Ondrej Filip
          debug("%s: Received duplicate dbdes from (%I)!\n", p->name, nrid);
359 4364b47e Ondrej Filip
          return;
360
        }
361
        else
362
        {
363
          ospf_neigh_sm(n, INM_SEQMIS);
364
        }
365
      break;
366
    defaut:
367 44724025 Ondrej Filip
      die("%s: Received dbdes from %I in unknown state.\n", p->name, nrid);
368 4364b47e Ondrej Filip
      break;
369
   }
370
}