Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsupd.c @ 23d67029

History | View | Annotate | Download (14.2 KB)

1 de769e24 Ondrej Filip
/*
2
 *        BIRD -- OSPF
3
 *
4 6f3203fa Ondrej Filip
 *        (c) 2000--2004 Ondrej Filip <feela@network.cz>
5 de769e24 Ondrej Filip
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9
#include "ospf.h"
10
11 39e517d4 Ondrej Filip
/**
12 6f3203fa Ondrej Filip
 * ospf_lsupd_flood - send received or generated lsa to the neighbors
13 39e517d4 Ondrej Filip
 * @n: neighbor than sent this lsa (or NULL if generated)
14 d6c28f3a Ondrej Filip
 * @hn: LSA header followed by lsa body in network endianity (may be NULL) 
15
 * @hh: LSA header in host endianity (must be filled)
16 39e517d4 Ondrej Filip
 * @iff: interface which received this LSA (or NULL if LSA is generated)
17
 * @oa: ospf_area which is the LSA generated for
18
 * @rtl: add this LSA into retransmission list
19
 *
20 d6c28f3a Ondrej Filip
 * return value - was the LSA flooded back?
21 39e517d4 Ondrej Filip
 */
22
23 84228eee Ondrej Filip
int
24 6f3203fa Ondrej Filip
ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
25
                 struct ospf_lsa_header *hh, struct ospf_iface *iff,
26
                 struct ospf_area *oa, int rtl)
27 2c971094 Ondrej Filip
{
28
  struct ospf_iface *ifa;
29
  struct ospf_neighbor *nn;
30
  struct top_hash_entry *en;
31 6f3203fa Ondrej Filip
  struct proto_ospf *po = oa->po;
32
  struct proto *p = &po->proto;
33 d6c28f3a Ondrej Filip
  int ret, retval = 0;
34 2c971094 Ondrej Filip
35
  /* pg 148 */
36 b181f444 Ondrej Filip
  WALK_LIST(ifa, po->iface_list)
37 2c971094 Ondrej Filip
  {
38 6f3203fa Ondrej Filip
    if (ifa->stub)
39
      continue;
40 52fa3e38 Ondrej Filip
41 6f3203fa Ondrej Filip
    if (hh->type == LSA_T_EXT)
42 2c971094 Ondrej Filip
    {
43 6f3203fa Ondrej Filip
      if (ifa->type == OSPF_IT_VLINK)
44
        continue;
45
      if (ifa->oa->stub)
46
        continue;
47 2c971094 Ondrej Filip
    }
48
    else
49
    {
50 86c84d76 Ondrej Filip
      if (ifa->oa != oa)
51
        continue;
52 2c971094 Ondrej Filip
    }
53 23d67029 Ondrej Zajicek
54
    DBG("Wanted to flood LSA: Type: %u, ID: %I, RT: %I, SN: 0x%x, Age %u\n",
55
        hh->type, hh->id, hh->rt, hh->sn, hh->age);
56
57 6f3203fa Ondrej Filip
    ret = 0;
58 b181f444 Ondrej Filip
    WALK_LIST(nn, ifa->neigh_list)
59 2c971094 Ondrej Filip
    {
60 6f3203fa Ondrej Filip
      if (nn->state < NEIGHBOR_EXCHANGE)
61
        continue;
62
      if (nn->state < NEIGHBOR_FULL)
63 2c971094 Ondrej Filip
      {
64 86c84d76 Ondrej Filip
        if ((en = ospf_hash_find_header(nn->lsrqh, nn->ifa->oa->areaid, hh)) != NULL)
65 2c971094 Ondrej Filip
        {
66 23d67029 Ondrej Zajicek
          DBG("That LSA found in lsreq list for neigh %I\n", nn->rid);
67
68 6f3203fa Ondrej Filip
          switch (lsa_comp(hh, &en->lsa))
69 2c971094 Ondrej Filip
          {
70 6f3203fa Ondrej Filip
          case CMP_OLDER:
71
            continue;
72
            break;
73
          case CMP_SAME:
74
            s_rem_node(SNODE en);
75
            if (en->lsa_body != NULL)
76
              mb_free(en->lsa_body);
77
            en->lsa_body = NULL;
78
            DBG("Removing from lsreq list for neigh %I\n", nn->rid);
79
            ospf_hash_delete(nn->lsrqh, en);
80
            if (EMPTY_SLIST(nn->lsrql))
81
              ospf_neigh_sm(nn, INM_LOADDONE);
82
            continue;
83
            break;
84
          case CMP_NEWER:
85
            s_rem_node(SNODE en);
86
            if (en->lsa_body != NULL)
87
              mb_free(en->lsa_body);
88
            en->lsa_body = NULL;
89
            DBG("Removing from lsreq list for neigh %I\n", nn->rid);
90
            ospf_hash_delete(nn->lsrqh, en);
91
            if (EMPTY_SLIST(nn->lsrql))
92
              ospf_neigh_sm(nn, INM_LOADDONE);
93
            break;
94
          default:
95
            bug("Bug in lsa_comp?");
96 2c971094 Ondrej Filip
          }
97
        }
98
      }
99 39e517d4 Ondrej Filip
100 6f3203fa Ondrej Filip
      if (nn == n)
101
        continue;
102 39e517d4 Ondrej Filip
103 6f3203fa Ondrej Filip
      if (rtl)
104 9669362f Ondrej Filip
      {
105 86c84d76 Ondrej Filip
        if ((en = ospf_hash_find_header(nn->lsrth, nn->ifa->oa->areaid, hh)) == NULL)
106 6f3203fa Ondrej Filip
        {
107 86c84d76 Ondrej Filip
          en = ospf_hash_get_header(nn->lsrth, nn->ifa->oa, hh);
108 6f3203fa Ondrej Filip
        }
109
        else
110
        {
111
          s_rem_node(SNODE en);
112
        }
113
        s_add_tail(&nn->lsrtl, SNODE en);
114
        memcpy(&en->lsa, hh, sizeof(struct ospf_lsa_header));
115 23d67029 Ondrej Zajicek
        DBG("Adding that LSA for flood to %I\n", nn->ip);
116 9669362f Ondrej Filip
      }
117
      else
118
      {
119 86c84d76 Ondrej Filip
        if ((en = ospf_hash_find_header(nn->lsrth, nn->ifa->oa->areaid, hh)) != NULL)
120 6f3203fa Ondrej Filip
        {
121
          s_rem_node(SNODE en);
122
          if (en->lsa_body != NULL)
123
            mb_free(en->lsa_body);
124
          en->lsa_body = NULL;
125
          ospf_hash_delete(nn->lsrth, en);
126
        }
127 9669362f Ondrej Filip
      }
128 39e517d4 Ondrej Filip
129 6f3203fa Ondrej Filip
      ret = 1;
130 2c971094 Ondrej Filip
    }
131 37282678 Ondrej Filip
132 6f3203fa Ondrej Filip
    if (ret == 0)
133
      continue;                        /* pg 150 (2) */
134 37282678 Ondrej Filip
135 6f3203fa Ondrej Filip
    if (ifa == iff)
136 2c971094 Ondrej Filip
    {
137 6f3203fa Ondrej Filip
      if ((n->rid == iff->drid) || n->rid == iff->bdrid)
138
        continue;                /* pg 150 (3) */
139
      if (iff->state == OSPF_IS_BACKUP)
140
        continue;                /* pg 150 (4) */
141
      retval = 1;
142 2c971094 Ondrej Filip
    }
143 740d16d9 Ondrej Filip
144 2c971094 Ondrej Filip
    {
145
      sock *sk;
146 d6c28f3a Ondrej Filip
      u16 len, age;
147 2c971094 Ondrej Filip
      struct ospf_lsupd_packet *pk;
148
      struct ospf_packet *op;
149 d6c28f3a Ondrej Filip
      struct ospf_lsa_header *lh;
150 2c971094 Ondrej Filip
151 3b16080c Ondrej Filip
      if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_VLINK))
152 6f3203fa Ondrej Filip
        sk = ifa->ip_sk;
153
      else
154 3b16080c Ondrej Filip
        sk = ifa->hello_sk;
155 2c971094 Ondrej Filip
156 6f3203fa Ondrej Filip
      pk = (struct ospf_lsupd_packet *) sk->tbuf;
157
      op = (struct ospf_packet *) sk->tbuf;
158 2c971094 Ondrej Filip
159 3e2bd0f1 Ondrej Filip
      ospf_pkt_fill_hdr(ifa, pk, LSUPD_P);
160 6f3203fa Ondrej Filip
      pk->lsano = htonl(1);
161 39e517d4 Ondrej Filip
162 6f3203fa Ondrej Filip
      lh = (struct ospf_lsa_header *) (pk + 1);
163 d6c28f3a Ondrej Filip
164
      /* Copy LSA into the packet */
165 6f3203fa Ondrej Filip
      if (hn)
166 38130b86 Ondrej Filip
      {
167 6f3203fa Ondrej Filip
        memcpy(lh, hn, ntohs(hn->length));
168 38130b86 Ondrej Filip
      }
169
      else
170
      {
171 6f3203fa Ondrej Filip
        u8 *help;
172 38130b86 Ondrej Filip
        struct top_hash_entry *en;
173 249fdef7 Ondrej Filip
174 6f3203fa Ondrej Filip
        htonlsah(hh, lh);
175
        help = (u8 *) (lh + 1);
176 86c84d76 Ondrej Filip
        en = ospf_hash_find_header(po->gr, oa->areaid, hh);
177 6f3203fa Ondrej Filip
        htonlsab(en->lsa_body, help, hh->type, hh->length
178
                 - sizeof(struct ospf_lsa_header));
179 38130b86 Ondrej Filip
      }
180 39e517d4 Ondrej Filip
181 6f3203fa Ondrej Filip
      len = sizeof(struct ospf_lsupd_packet) + ntohs(lh->length);
182 d6c28f3a Ondrej Filip
183
      age = ntohs(lh->age);
184
      age += ifa->inftransdelay;
185 6f3203fa Ondrej Filip
      if (age > LSA_MAXAGE)
186
        age = LSA_MAXAGE;
187 d6c28f3a Ondrej Filip
      lh->age = htons(age);
188
189 6f3203fa Ondrej Filip
      op->length = htons(len);
190 d3995c49 Ondrej Filip
      OSPF_TRACE(D_PACKETS, "LS upd flooded via %s", ifa->iface->name);
191 52586ccd Ondrej Zajicek
      DBG("ID=%I, AGE=%d, SEQ=%x\n", ntohl(lh->id), ntohs(lh->age),
192 3b16080c Ondrej Filip
          ntohl(lh->sn));
193 2c971094 Ondrej Filip
194 3b16080c Ondrej Filip
      switch (ifa->type)
195 2c971094 Ondrej Filip
      {
196 3b16080c Ondrej Filip
      case OSPF_IT_NBMA:
197 6f3203fa Ondrej Filip
        if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
198 3e2bd0f1 Ondrej Filip
          ospf_send_to_agt(sk, ifa, NEIGHBOR_EXCHANGE);
199 6f3203fa Ondrej Filip
        else
200 3e2bd0f1 Ondrej Filip
          ospf_send_to_bdr(sk, ifa);
201 3b16080c Ondrej Filip
        break;
202
203
      case OSPF_IT_VLINK:
204
        ospf_send_to(sk, ifa->vip, ifa);
205
        break;
206
207
      default:
208 6f3203fa Ondrej Filip
        if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR) ||
209
            (ifa->type == OSPF_IT_PTP))
210 3e2bd0f1 Ondrej Filip
          ospf_send_to(sk, AllSPFRouters, ifa);
211 6f3203fa Ondrej Filip
        else
212 3e2bd0f1 Ondrej Filip
          ospf_send_to(sk, AllDRouters, ifa);
213 2c971094 Ondrej Filip
      }
214
    }
215
  }
216 84228eee Ondrej Filip
  return retval;
217 2c971094 Ondrej Filip
}
218
219 6f3203fa Ondrej Filip
void                                /* I send all I received in LSREQ */
220
ospf_lsupd_send_list(struct ospf_neighbor *n, list * l)
221 f45fd316 Ondrej Filip
{
222
  struct l_lsr_head *llsh;
223
  u16 len;
224
  u32 lsano;
225
  struct top_hash_entry *en;
226
  struct ospf_lsupd_packet *pk;
227
  struct ospf_packet *op;
228 86c84d76 Ondrej Filip
  struct ospf_area *oa = n->ifa->oa;
229
  struct proto_ospf *po = oa->po;
230
  struct proto *p = &po->proto;
231 f45fd316 Ondrej Filip
  void *pktpos;
232
233 6f3203fa Ondrej Filip
  if (EMPTY_LIST(*l))
234
    return;
235 f45fd316 Ondrej Filip
236 6f3203fa Ondrej Filip
  pk = (struct ospf_lsupd_packet *) n->ifa->ip_sk->tbuf;
237
  op = (struct ospf_packet *) n->ifa->ip_sk->tbuf;
238 9f940976 Ondrej Filip
239
  DBG("LSupd: 1st packet\n");
240 6f3203fa Ondrej Filip
241 3e2bd0f1 Ondrej Filip
  ospf_pkt_fill_hdr(n->ifa, pk, LSUPD_P);
242
  len = sizeof(struct ospf_lsupd_packet);
243 6f3203fa Ondrej Filip
  lsano = 0;
244
  pktpos = (pk + 1);
245 f45fd316 Ondrej Filip
246
  WALK_LIST(llsh, *l)
247
  {
248 86c84d76 Ondrej Filip
    if ((en = ospf_hash_find(po->gr, oa->areaid, llsh->lsh.id, llsh->lsh.rt,
249 6f3203fa Ondrej Filip
                             llsh->lsh.type)) == NULL)
250
      continue;                        /* Probably flushed LSA */
251 3b16080c Ondrej Filip
    /* FIXME This is a bug! I cannot flush LSA that is in lsrt */
252 cd22a62b Ondrej Filip
253 23d67029 Ondrej Zajicek
    DBG("Sending LSA: Type=%u, ID=%I, RT=%I, SN: 0x%x, Age: %u\n",
254
        llsh->lsh.type, llsh->lsh.id, llsh->lsh.rt, en->lsa.sn, en->lsa.age);
255 3e2bd0f1 Ondrej Filip
    if (((u32) (len + en->lsa.length)) > ospf_pkt_maxsize(n->ifa))
256 f45fd316 Ondrej Filip
    {
257 6f3203fa Ondrej Filip
      pk->lsano = htonl(lsano);
258 3e2bd0f1 Ondrej Filip
      op->length = htons(len);
259 6f3203fa Ondrej Filip
260 3e2bd0f1 Ondrej Filip
      ospf_send_to(n->ifa->ip_sk, n->ip, n->ifa);
261 d3995c49 Ondrej Filip
      OSPF_TRACE(D_PACKETS, "LS upd sent to %I (%d LSAs)", n->ip, lsano);
262 f45fd316 Ondrej Filip
263 9f940976 Ondrej Filip
      DBG("LSupd: next packet\n");
264 3e2bd0f1 Ondrej Filip
      ospf_pkt_fill_hdr(n->ifa, pk, LSUPD_P);
265
      len = sizeof(struct ospf_lsupd_packet);
266 6f3203fa Ondrej Filip
      lsano = 0;
267
      pktpos = (pk + 1);
268 f45fd316 Ondrej Filip
    }
269
    htonlsah(&(en->lsa), pktpos);
270 6f3203fa Ondrej Filip
    pktpos = pktpos + sizeof(struct ospf_lsa_header);
271 d345cda5 Ondrej Filip
    htonlsab(en->lsa_body, pktpos, en->lsa.type, en->lsa.length
272 6f3203fa Ondrej Filip
             - sizeof(struct ospf_lsa_header));
273
    pktpos = pktpos + en->lsa.length - sizeof(struct ospf_lsa_header);
274
    len += en->lsa.length;
275 9f940976 Ondrej Filip
    lsano++;
276 f45fd316 Ondrej Filip
  }
277 6f3203fa Ondrej Filip
  if (lsano > 0)
278 b477a9a8 Ondrej Filip
  {
279 6f3203fa Ondrej Filip
    pk->lsano = htonl(lsano);
280 3e2bd0f1 Ondrej Filip
    op->length = htons(len);
281 9f940976 Ondrej Filip
282 d3995c49 Ondrej Filip
    OSPF_TRACE(D_PACKETS, "LS upd sent to %I (%d LSAs)", n->ip, lsano);
283 3e2bd0f1 Ondrej Filip
    ospf_send_to(n->ifa->ip_sk, n->ip, n->ifa);
284 b477a9a8 Ondrej Filip
  }
285 f45fd316 Ondrej Filip
}
286
287 de769e24 Ondrej Filip
void
288 9b7de4c4 Ondrej Filip
ospf_lsupd_receive(struct ospf_lsupd_packet *ps,
289 5e3436d2 Ondrej Filip
                   struct ospf_iface *ifa, struct ospf_neighbor *n)
290 de769e24 Ondrej Filip
{
291 5e3436d2 Ondrej Filip
  u32 area;
292
  struct ospf_neighbor *ntmp;
293 394acced Ondrej Filip
  struct ospf_lsa_header *lsa;
294 8496b2e4 Ondrej Filip
  struct ospf_area *oa;
295 86c84d76 Ondrej Filip
  struct proto_ospf *po = ifa->oa->po;
296
  struct proto *p = &po->proto;
297 5e3436d2 Ondrej Filip
  unsigned int i, sendreq = 1, size = ntohs(ps->ospf_packet.length);
298 39e517d4 Ondrej Filip
299 6f3203fa Ondrej Filip
  if (n->state < NEIGHBOR_EXCHANGE)
300 394acced Ondrej Filip
  {
301 6f3203fa Ondrej Filip
    OSPF_TRACE(D_PACKETS,
302
               "Received lsupd in lesser state than EXCHANGE from (%I)",
303
               n->ip);
304 394acced Ondrej Filip
    return;
305
  }
306 39e517d4 Ondrej Filip
307 6f3203fa Ondrej Filip
  if (size <=
308
      (sizeof(struct ospf_lsupd_packet) + sizeof(struct ospf_lsa_header)))
309 5da1f935 Ondrej Filip
  {
310 39e517d4 Ondrej Filip
    log(L_WARN "Received lsupd from %I is too short!", n->ip);
311 5da1f935 Ondrej Filip
    return;
312
  }
313 394acced Ondrej Filip
314 d3995c49 Ondrej Filip
  OSPF_TRACE(D_PACKETS, "Received LS upd from %I", n->ip);
315 39e517d4 Ondrej Filip
  ospf_neigh_sm(n, INM_HELLOREC);        /* Questionable */
316 9669362f Ondrej Filip
317 6f3203fa Ondrej Filip
  lsa = (struct ospf_lsa_header *) (ps + 1);
318
  area = htonl(ps->ospf_packet.areaid);
319
  oa = ospf_find_area((struct proto_ospf *) p, area);
320 39e517d4 Ondrej Filip
321 6f3203fa Ondrej Filip
  for (i = 0; i < ntohl(ps->lsano); i++,
322
       lsa = (struct ospf_lsa_header *) (((u8 *) lsa) + ntohs(lsa->length)))
323 394acced Ondrej Filip
  {
324 921a93f2 Ondrej Filip
    struct ospf_lsa_header lsatmp;
325
    struct top_hash_entry *lsadb;
326 5e3436d2 Ondrej Filip
    unsigned diff = ((u8 *) lsa) - ((u8 *) ps), lenn = ntohs(lsa->length);
327
    u16 chsum;
328 13741548 Ondrej Filip
329 6f3203fa Ondrej Filip
    if (((diff + sizeof(struct ospf_lsa_header)) >= size)
330
        || ((lenn + diff) > size))
331 39e517d4 Ondrej Filip
    {
332
      log(L_WARN "Received lsupd from %I is too short!", n->ip);
333
      ospf_neigh_sm(n, INM_BADLSREQ);
334
      break;
335
    }
336 13741548 Ondrej Filip
337 6f3203fa Ondrej Filip
    if ((lenn <= sizeof(struct ospf_lsa_header))
338
        || (lenn != (4 * (lenn / 4))))
339 13741548 Ondrej Filip
    {
340 39e517d4 Ondrej Filip
      log(L_WARN "Received LSA from %I with bad length", n->ip);
341
      ospf_neigh_sm(n, INM_BADLSREQ);
342 13741548 Ondrej Filip
      break;
343
    }
344 39e517d4 Ondrej Filip
345 2c971094 Ondrej Filip
    /* pg 143 (1) */
346 6f3203fa Ondrej Filip
    chsum = lsa->checksum;
347 d5d9693c Ondrej Filip
    if (chsum != lsasum_check(lsa, NULL))
348 394acced Ondrej Filip
    {
349 39e517d4 Ondrej Filip
      log(L_WARN "Received bad lsa checksum from %I", n->ip);
350 8496b2e4 Ondrej Filip
      continue;
351
    }
352 39e517d4 Ondrej Filip
353 2c971094 Ondrej Filip
    /* pg 143 (2) */
354 6f3203fa Ondrej Filip
    if ((lsa->type < LSA_T_RT) || (lsa->type > LSA_T_EXT))
355 8496b2e4 Ondrej Filip
    {
356 39e517d4 Ondrej Filip
      log(L_WARN "Unknown LSA type from %I", n->ip);
357 8496b2e4 Ondrej Filip
      continue;
358 394acced Ondrej Filip
    }
359 39e517d4 Ondrej Filip
360 2c971094 Ondrej Filip
    /* pg 143 (3) */
361 6f3203fa Ondrej Filip
    if ((lsa->type == LSA_T_EXT) && oa->stub)
362 8496b2e4 Ondrej Filip
    {
363 39e517d4 Ondrej Filip
      log(L_WARN "Received External LSA in stub area from %I", n->ip);
364 8496b2e4 Ondrej Filip
      continue;
365
    }
366 39e517d4 Ondrej Filip
367 6f3203fa Ondrej Filip
    ntohlsah(lsa, &lsatmp);
368 39e517d4 Ondrej Filip
369 273fd2c1 Ondrej Filip
    DBG("Update Type: %u ID: %I RT: %I, Sn: 0x%08x Age: %u, Sum: %u\n",
370 6f3203fa Ondrej Filip
        lsatmp.type, lsatmp.id, lsatmp.rt, lsatmp.sn, lsatmp.age,
371
        lsatmp.checksum);
372 39e517d4 Ondrej Filip
373 86c84d76 Ondrej Filip
    lsadb = ospf_hash_find_header(po->gr, oa->areaid, &lsatmp);
374 39e517d4 Ondrej Filip
375
#ifdef LOCAL_DEBUG
376 6f3203fa Ondrej Filip
    if (lsadb)
377 273fd2c1 Ondrej Filip
      DBG("I have Type: %u ID: %I RT: %I, Sn: 0x%08x Age: %u, Sum: %u\n",
378 6f3203fa Ondrej Filip
          lsadb->lsa.type, lsadb->lsa.id, lsadb->lsa.rt, lsadb->lsa.sn,
379
          lsadb->lsa.age, lsadb->lsa.checksum);
380 39e517d4 Ondrej Filip
#endif
381 d8852b36 Ondrej Filip
382 2c971094 Ondrej Filip
    /* pg 143 (4) */
383 86c84d76 Ondrej Filip
    if ((lsatmp.age == LSA_MAXAGE) && (lsadb == NULL) && can_flush_lsa(po))
384 921a93f2 Ondrej Filip
    {
385 8e15e048 Ondrej Filip
      ospf_lsack_enqueue(n, lsa, ACKL_DIRECT);
386 39e517d4 Ondrej Filip
      continue;
387 921a93f2 Ondrej Filip
    }
388 39e517d4 Ondrej Filip
389 2c971094 Ondrej Filip
    /* pg 144 (5) */
390 6f3203fa Ondrej Filip
    if ((lsadb == NULL) || (lsa_comp(&lsatmp, &lsadb->lsa) == CMP_NEWER))
391 921a93f2 Ondrej Filip
    {
392 6f3203fa Ondrej Filip
      struct ospf_iface *ift = NULL;
393 39e517d4 Ondrej Filip
      void *body;
394
      struct ospf_iface *nifa;
395
      int self = (lsatmp.rt == p->cf->global->router_id);
396
397
      DBG("PG143(5): Received LSA is newer\n");
398
399 d6c28f3a Ondrej Filip
      /* pg 145 (5f) - premature aging of self originated lsa */
400 6f3203fa Ondrej Filip
      if ((!self) && (lsatmp.type == LSA_T_NET))
401 39e517d4 Ondrej Filip
      {
402 6f3203fa Ondrej Filip
        WALK_LIST(nifa, po->iface_list)
403
        {
404 3b16080c Ondrej Filip
          if (!nifa->iface)
405
            continue;
406
          if (ipa_equal(nifa->iface->addr->ip, ipa_from_u32(lsatmp.id)))
407 6f3203fa Ondrej Filip
          {
408
            self = 1;
409
            break;
410
          }
411
        }
412 39e517d4 Ondrej Filip
      }
413
414 6f3203fa Ondrej Filip
      if (self)
415 39e517d4 Ondrej Filip
      {
416 6f3203fa Ondrej Filip
        struct top_hash_entry *en;
417
418
        if ((lsatmp.age == LSA_MAXAGE) && (lsatmp.sn == LSA_MAXSEQNO))
419
        {
420
          ospf_lsack_enqueue(n, lsa, ACKL_DIRECT);
421
          continue;
422
        }
423
424
        lsatmp.age = LSA_MAXAGE;
425
        lsatmp.sn = LSA_MAXSEQNO;
426
        lsa->age = htons(LSA_MAXAGE);
427
        lsa->sn = htonl(LSA_MAXSEQNO);
428
        OSPF_TRACE(D_EVENTS, "Premature aging self originated lsa.");
429
        OSPF_TRACE(D_EVENTS, "Type: %d, Id: %I, Rt: %I", lsatmp.type,
430
                   lsatmp.id, lsatmp.rt);
431 d5d9693c Ondrej Filip
        lsasum_check(lsa, (lsa + 1));        /* It also calculates chsum! */
432 6f3203fa Ondrej Filip
        lsatmp.checksum = ntohs(lsa->checksum);
433
        ospf_lsupd_flood(NULL, lsa, &lsatmp, NULL, oa, 0);
434 86c84d76 Ondrej Filip
        if (en = ospf_hash_find_header(po->gr, oa->areaid, &lsatmp))
435 6f3203fa Ondrej Filip
        {
436
          ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1);
437
        }
438
        continue;
439 39e517d4 Ondrej Filip
      }
440 32fa4a5a Ondrej Filip
441 2c971094 Ondrej Filip
      /* pg 144 (5a) */
442 6f3203fa Ondrej Filip
      if (lsadb && ((now - lsadb->inst_t) <= MINLSARRIVAL))        /* FIXME: test for flooding? */
443 85c92555 Ondrej Filip
      {
444 6f3203fa Ondrej Filip
        DBG("I got it in less that MINLSARRIVAL\n");
445
        sendreq = 0;
446 85c92555 Ondrej Filip
        continue;
447
      }
448 6f3203fa Ondrej Filip
449
      if (ospf_lsupd_flood(n, lsa, &lsatmp, ifa, ifa->oa, 1) == 0)
450 84228eee Ondrej Filip
      {
451 6f3203fa Ondrej Filip
        DBG("Wasn't flooded back\n");        /* ps 144(5e), pg 153 */
452
        if (ifa->state == OSPF_IS_BACKUP)
453 84228eee Ondrej Filip
        {
454 6f3203fa Ondrej Filip
          if (ifa->drid == n->rid)
455
            ospf_lsack_enqueue(n, lsa, ACKL_DELAY);
456 84228eee Ondrej Filip
        }
457 6f3203fa Ondrej Filip
        else
458
          ospf_lsack_enqueue(n, lsa, ACKL_DELAY);
459 84228eee Ondrej Filip
      }
460 2c971094 Ondrej Filip
461 921a93f2 Ondrej Filip
      /* Remove old from all ret lists */
462 2c971094 Ondrej Filip
      /* pg 144 (5c) */
463 6f3203fa Ondrej Filip
      if (lsadb)
464 b181f444 Ondrej Filip
        WALK_LIST(ift, po->iface_list)
465
          WALK_LIST(ntmp, ift->neigh_list)
466 62924172 Ondrej Filip
      {
467 6f3203fa Ondrej Filip
        struct top_hash_entry *en;
468
        if (ntmp->state > NEIGHBOR_EXSTART)
469 86c84d76 Ondrej Filip
          if ((en = ospf_hash_find_header(ntmp->lsrth, ntmp->ifa->oa->areaid, &lsadb->lsa)) != NULL)
470 6f3203fa Ondrej Filip
          {
471
            s_rem_node(SNODE en);
472
            if (en->lsa_body != NULL)
473
              mb_free(en->lsa_body);
474
            en->lsa_body = NULL;
475
            ospf_hash_delete(ntmp->lsrth, en);
476
          }
477
      }
478
479
      if ((lsatmp.age == LSA_MAXAGE) && (lsatmp.sn == LSA_MAXSEQNO)
480 86c84d76 Ondrej Filip
          && lsadb && can_flush_lsa(po))
481 6f3203fa Ondrej Filip
      {
482 86c84d76 Ondrej Filip
        flush_lsa(lsadb, po);
483 b8f17cf1 Ondrej Filip
        schedule_rtcalc(po);
484 6f3203fa Ondrej Filip
        continue;
485
      }                                /* FIXME lsack? */
486 921a93f2 Ondrej Filip
487 2c971094 Ondrej Filip
      /* pg 144 (5d) */
488 6f3203fa Ondrej Filip
      body =
489
        mb_alloc(p->pool, lsatmp.length - sizeof(struct ospf_lsa_header));
490
      ntohlsab(lsa + 1, body, lsatmp.type,
491
               lsatmp.length - sizeof(struct ospf_lsa_header));
492
      lsadb = lsa_install_new(&lsatmp, body, oa);
493 10000b96 Ondrej Filip
      DBG("New LSA installed in DB\n");
494 d8852b36 Ondrej Filip
495 921a93f2 Ondrej Filip
      continue;
496
    }
497
498 d6c28f3a Ondrej Filip
    /* FIXME pg145 (6) */
499 921a93f2 Ondrej Filip
500 2c971094 Ondrej Filip
    /* pg145 (7) */
501 6f3203fa Ondrej Filip
    if (lsa_comp(&lsatmp, &lsadb->lsa) == CMP_SAME)
502 921a93f2 Ondrej Filip
    {
503 84228eee Ondrej Filip
      struct top_hash_entry *en;
504 d6c28f3a Ondrej Filip
      DBG("PG145(7) Got the same LSA\n");
505 86c84d76 Ondrej Filip
      if ((en = ospf_hash_find_header(n->lsrth, n->ifa->oa->areaid, &lsadb->lsa)) != NULL)
506 84228eee Ondrej Filip
      {
507 6f3203fa Ondrej Filip
        /* pg145 (7a) */
508
        s_rem_node(SNODE en);
509
        if (en->lsa_body != NULL)
510
          mb_free(en->lsa_body);
511
        en->lsa_body = NULL;
512
        ospf_hash_delete(n->lsrth, en);
513
        if (ifa->state == OSPF_IS_BACKUP)
514
        {
515
          if (n->rid == ifa->drid)
516
            ospf_lsack_enqueue(n, lsa, ACKL_DELAY);
517
        }
518 84228eee Ondrej Filip
      }
519
      else
520
      {
521 6f3203fa Ondrej Filip
        /* pg145 (7b) */
522
        ospf_lsack_enqueue(n, lsa, ACKL_DIRECT);
523 84228eee Ondrej Filip
      }
524 9b7de4c4 Ondrej Filip
      sendreq = 0;
525 84228eee Ondrej Filip
      continue;
526 921a93f2 Ondrej Filip
    }
527
528 2c971094 Ondrej Filip
    /* pg145 (8) */
529 6f3203fa Ondrej Filip
    if ((lsadb->lsa.age == LSA_MAXAGE) && (lsadb->lsa.sn == LSA_MAXSEQNO))
530 67315ef6 Ondrej Filip
    {
531
      continue;
532
    }
533 921a93f2 Ondrej Filip
534 2c971094 Ondrej Filip
    {
535
      list l;
536 a548a7e1 Ondrej Filip
      struct l_lsr_head ll;
537 2c971094 Ondrej Filip
      init_list(&l);
538 6f3203fa Ondrej Filip
      ll.lsh.id = lsadb->lsa.id;
539
      ll.lsh.rt = lsadb->lsa.rt;
540
      ll.lsh.type = lsadb->lsa.type;
541
      add_tail(&l, NODE & ll);
542
      ospf_lsupd_send_list(n, &l);
543 2c971094 Ondrej Filip
    }
544 394acced Ondrej Filip
  }
545 39e517d4 Ondrej Filip
546 c76ba51a Ondrej Filip
  /* Send direct LSAs */
547
  ospf_lsack_send(n, ACKL_DIRECT);
548
549 6f3203fa Ondrej Filip
  if (sendreq && (n->state == NEIGHBOR_LOADING))
550 489f800b Ondrej Filip
  {
551 6f3203fa Ondrej Filip
    ospf_lsreq_send(n);                /* Ask for another part of neighbor's database */
552 489f800b Ondrej Filip
  }
553 de769e24 Ondrej Filip
}
554
555 4bd28fb6 Ondrej Filip
void
556 6f3203fa Ondrej Filip
ospf_lsupd_flush_nlsa(struct top_hash_entry *en, struct ospf_area *oa)
557 4bd28fb6 Ondrej Filip
{
558 6f3203fa Ondrej Filip
  struct ospf_lsa_header *lsa = &en->lsa;
559
  struct proto_ospf *po = oa->po;
560
  struct proto *p = &po->proto;
561 4bd28fb6 Ondrej Filip
562 6f3203fa Ondrej Filip
  lsa->age = LSA_MAXAGE;
563
  lsa->sn = LSA_MAXSEQNO;
564 d5d9693c Ondrej Filip
  lsasum_calculate(lsa, en->lsa_body);
565 d3995c49 Ondrej Filip
  OSPF_TRACE(D_EVENTS, "Premature aging self originated lsa!");
566
  OSPF_TRACE(D_EVENTS, "Type: %d, Id: %I, Rt: %I", lsa->type,
567 6f3203fa Ondrej Filip
             lsa->id, lsa->rt);
568
  ospf_lsupd_flood(NULL, NULL, lsa, NULL, oa, 0);
569 4bd28fb6 Ondrej Filip
}