Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / proto / ospf / lsupd.c @ 6b3f1a54

History | View | Annotate | Download (18 KB)

1
/*
2
 *        BIRD -- OSPF
3
 *
4
 *        (c) 2000--2004 Ondrej Filip <feela@network.cz>
5
 *        (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
6
 *        (c) 2009--2014 CZ.NIC z.s.p.o.
7
 *
8
 *        Can be freely distributed and used under the terms of the GNU GPL.
9
 */
10

    
11
#include "ospf.h"
12

    
13

    
14
/*
15
struct ospf_lsupd_packet
16
{
17
  struct ospf_packet hdr;
18
  // union ospf_auth auth;
19

20
  u32 lsa_count;
21
  void lsas[];
22
};
23
*/
24

    
25

    
26
void
27
ospf_dump_lsahdr(struct ospf_proto *p, struct ospf_lsa_header *lsa_n)
28
{
29
  struct ospf_lsa_header lsa;
30
  u32 lsa_etype;
31

    
32
  lsa_ntoh_hdr(lsa_n, &lsa);
33
  lsa_etype = lsa_get_etype(&lsa, p);
34

    
35
  log(L_TRACE "%s:     LSA      Type: %04x, Id: %R, Rt: %R, Seq: %08x, Age: %u, Sum: %04x",
36
      p->p.name, lsa_etype, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum);
37
}
38

    
39
void
40
ospf_dump_common(struct ospf_proto *p, struct ospf_packet *pkt)
41
{
42
  log(L_TRACE "%s:     length   %d", p->p.name, ntohs(pkt->length));
43
  log(L_TRACE "%s:     router   %R", p->p.name, ntohl(pkt->routerid));
44
}
45

    
46
static inline uint
47
ospf_lsupd_hdrlen(struct ospf_proto *p)
48
{
49
  return ospf_pkt_hdrlen(p) + 4; /* + u32 lsa count field */
50
}
51

    
52
static inline u32
53
ospf_lsupd_get_lsa_count(struct ospf_packet *pkt, uint hdrlen)
54
{
55
  u32 *c = ((void *) pkt) + hdrlen - 4;
56
  return ntohl(*c);
57
}
58

    
59
static inline void
60
ospf_lsupd_set_lsa_count(struct ospf_packet *pkt, uint hdrlen, u32 val)
61
{
62
  u32 *c = ((void *) pkt) + hdrlen - 4;
63
  *c = htonl(val);
64
}
65

    
66
static inline void
67
ospf_lsupd_body(struct ospf_proto *p, struct ospf_packet *pkt,
68
                uint *offset, uint *lsa_count)
69
{
70
  uint hlen = ospf_lsupd_hdrlen(p);
71
  *offset = hlen;
72
  *lsa_count = ospf_lsupd_get_lsa_count(pkt, hlen);
73
}
74

    
75
static void
76
ospf_dump_lsupd(struct ospf_proto *p, struct ospf_packet *pkt)
77
{
78
  uint offset, plen, i, lsa_count, lsa_len;
79

    
80
  ASSERT(pkt->type == LSUPD_P);
81
  ospf_dump_common(p, pkt);
82

    
83
  plen = ntohs(pkt->length);
84
  ospf_lsupd_body(p, pkt, &offset, &lsa_count);
85
  for (i = 0; i < lsa_count; i++)
86
  {
87
    if ((offset + sizeof(struct ospf_lsa_header)) > plen)
88
      goto invalid;
89

    
90
    struct ospf_lsa_header *lsa = ((void *) pkt) + offset;
91
    lsa_len = ntohs(lsa->length);
92

    
93
    if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header)))
94
      goto invalid;
95

    
96
    ospf_dump_lsahdr(p, lsa);
97
    offset += lsa_len;
98
  }
99
  return;
100

    
101
invalid:
102
  log(L_TRACE "%s:     LSA      invalid", p->p.name);
103
  return;
104
}
105

    
106

    
107
static inline void
108
ospf_lsa_lsrq_down(struct top_hash_entry *req, struct ospf_neighbor *n)
109
{
110
  if (req == n->lsrqi)
111
    n->lsrqi = SNODE_NEXT(req);
112

    
113
  s_rem_node(SNODE req);
114
  ospf_hash_delete(n->lsrqh, req);
115

    
116
  if (EMPTY_SLIST(n->lsrql))
117
  {
118
    tm_stop(n->lsrq_timer);
119

    
120
    if (n->state == NEIGHBOR_LOADING)
121
      ospf_neigh_sm(n, INM_LOADDONE);
122
  }
123
}
124

    
125
static inline void
126
ospf_lsa_lsrt_up(struct top_hash_entry *en, struct ospf_neighbor *n)
127
{
128
  struct top_hash_entry *ret = ospf_hash_get_entry(n->lsrth, en);
129

    
130
  if (!SNODE_VALID(ret))
131
  {
132
    en->ret_count++;
133
    s_add_tail(&n->lsrtl, SNODE ret);
134
  }
135

    
136
  ret->lsa = en->lsa;
137
  ret->lsa_body = LSA_BODY_DUMMY;
138

    
139
  if (!tm_active(n->lsrt_timer))
140
    tm_start(n->lsrt_timer, n->ifa->rxmtint S);
141
}
142

    
143
void
144
ospf_lsa_lsrt_down_(struct top_hash_entry *en, struct ospf_neighbor *n, struct top_hash_entry *ret)
145
{
146
  if (en)
147
    en->ret_count--;
148

    
149
  s_rem_node(SNODE ret);
150
  ospf_hash_delete(n->lsrth, ret);
151

    
152
  if (EMPTY_SLIST(n->lsrtl))
153
    tm_stop(n->lsrt_timer);
154
}
155

    
156
static inline int
157
ospf_lsa_lsrt_down(struct top_hash_entry *en, struct ospf_neighbor *n)
158
{
159
  struct top_hash_entry *ret = ospf_hash_find_entry(n->lsrth, en);
160

    
161
  if (ret)
162
    ospf_lsa_lsrt_down_(en, n, ret);
163

    
164
  return ret != NULL;
165
}
166

    
167
void
168
ospf_add_flushed_to_lsrt(struct ospf_proto *p, struct ospf_neighbor *n)
169
{
170
  struct top_hash_entry *en;
171

    
172
  WALK_SLIST(en, p->lsal)
173
    if ((en->lsa.age == LSA_MAXAGE) && (en->lsa_body != NULL) &&
174
        lsa_flooding_allowed(en->lsa_type, en->domain, n->ifa))
175
      ospf_lsa_lsrt_up(en, n);
176

    
177
  /* If we found any flushed LSA, we send them ASAP */
178
  if (tm_active(n->lsrt_timer))
179
    tm_start(n->lsrt_timer, 0);
180
}
181

    
182
static int ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa);
183

    
184
static void
185
ospf_enqueue_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa)
186
{
187
  if (ifa->flood_queue_used == ifa->flood_queue_size)
188
  {
189
    /* If we already have full queue, we send some packets */
190
    uint sent = ospf_flood_lsupd(p, ifa->flood_queue, ifa->flood_queue_used, ifa->flood_queue_used / 2, ifa);
191
    uint i;
192

    
193
    for (i = 0; i < sent; i++)
194
      ifa->flood_queue[i]->ret_count--;
195

    
196
    ifa->flood_queue_used -= sent;
197
    memmove(ifa->flood_queue, ifa->flood_queue + sent, ifa->flood_queue_used * sizeof(void *));
198
    bzero(ifa->flood_queue + ifa->flood_queue_used, sent * sizeof(void *));
199
  }
200

    
201
  en->ret_count++;
202
  ifa->flood_queue[ifa->flood_queue_used] = en;
203
  ifa->flood_queue_used++;
204

    
205
  if (!ev_active(p->flood_event))
206
    ev_schedule(p->flood_event);
207
}
208

    
209
void
210
ospf_flood_event(void *ptr)
211
{
212
  struct ospf_proto *p = ptr;
213
  struct ospf_iface *ifa;
214
  int i, count;
215

    
216
  WALK_LIST(ifa, p->iface_list)
217
  {
218
    if (ifa->flood_queue_used == 0)
219
      continue;
220

    
221
    count = ifa->flood_queue_used;
222
    ospf_flood_lsupd(p, ifa->flood_queue, count, count, ifa);
223

    
224
    for (i = 0; i < count; i++)
225
      ifa->flood_queue[i]->ret_count--;
226

    
227
    ifa->flood_queue_used = 0;
228
    bzero(ifa->flood_queue, count * sizeof(void *));
229
  }
230
}
231

    
232

    
233
/**
234
 * ospf_flood_lsa - send LSA to the neighbors
235
 * @p: OSPF protocol instance
236
 * @en: LSA entry
237
 * @from: neighbor than sent this LSA (or NULL if LSA is local)
238
 *
239
 * return value - was the LSA flooded back?
240
 */
241
int
242
ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
243
{
244
  struct ospf_iface *ifa;
245
  struct ospf_neighbor *n;
246

    
247
  /* RFC 2328 13.3 */
248

    
249
  int back = 0;
250
  WALK_LIST(ifa, p->iface_list)
251
  {
252
    if (ifa->stub)
253
      continue;
254

    
255
    if (! lsa_flooding_allowed(en->lsa_type, en->domain, ifa))
256
      continue;
257

    
258
    DBG("Wanted to flood LSA: Type: %u, ID: %R, RT: %R, SN: 0x%x, Age %u\n",
259
        hh->type, hh->id, hh->rt, hh->sn, hh->age);
260

    
261
    int used = 0;
262
    WALK_LIST(n, ifa->neigh_list)
263
    {
264
      /* 13.3 (1a) */
265
      if (n->state < NEIGHBOR_EXCHANGE)
266
        continue;
267

    
268
      /* 13.3 (1b) */
269
      if (n->state < NEIGHBOR_FULL)
270
      {
271
        struct top_hash_entry *req = ospf_hash_find_entry(n->lsrqh, en);
272
        if (req != NULL)
273
        {
274
          int cmp = lsa_comp(&en->lsa, &req->lsa);
275

    
276
          /* If same or newer, remove LSA from the link state request list */
277
          if (cmp > CMP_OLDER)
278
            ospf_lsa_lsrq_down(req, n);
279

    
280
          /* If older or same, skip processing of this neighbor */
281
          if (cmp < CMP_NEWER)
282
            continue;
283
        }
284
      }
285

    
286
      /* 13.3 (1c) */
287
      if (n == from)
288
        continue;
289

    
290
      /* In OSPFv3, there should be check whether receiving router understand
291
         that type of LSA (for LSA types with U-bit == 0). But as we do not support
292
         any optional LSA types, this is not needed yet */
293

    
294
      /* 13.3 (1d) - add LSA to the link state retransmission list */
295
      ospf_lsa_lsrt_up(en, n);
296

    
297
      used = 1;
298
    }
299

    
300
    /* 13.3 (2) */
301
    if (!used)
302
      continue;
303

    
304
    if (from && (from->ifa == ifa))
305
    {
306
      /* 13.3 (3) */
307
      if ((from->rid == ifa->drid) || (from->rid == ifa->bdrid))
308
        continue;
309

    
310
      /* 13.3 (4) */
311
      if (ifa->state == OSPF_IS_BACKUP)
312
        continue;
313

    
314
      back = 1;
315
    }
316

    
317
    /* 13.3 (5) - finally flood the packet */
318
    ospf_enqueue_lsa(p, en, ifa);
319
  }
320

    
321
  return back;
322
}
323

    
324
static uint
325
ospf_prepare_lsupd(struct ospf_proto *p, struct ospf_iface *ifa,
326
                   struct top_hash_entry **lsa_list, uint lsa_count)
327
{
328
  struct ospf_packet *pkt;
329
  uint hlen, pos, i, maxsize;
330

    
331
  pkt = ospf_tx_buffer(ifa);
332
  hlen = ospf_lsupd_hdrlen(p);
333
  maxsize = ospf_pkt_maxsize(ifa);
334

    
335
  ospf_pkt_fill_hdr(ifa, pkt, LSUPD_P);
336
  pos = hlen;
337

    
338
  for (i = 0; i < lsa_count; i++)
339
  {
340
    struct top_hash_entry *en = lsa_list[i];
341
    uint len = en->lsa.length;
342

    
343
    if ((pos + len) > maxsize)
344
    {
345
      /* The packet if full, stop adding LSAs and sent it */
346
      if (i > 0)
347
        break;
348

    
349
      /* LSA is larger than MTU, check buffer size */
350
      if (ospf_iface_assure_bufsize(ifa, pos + len) < 0)
351
      {
352
        /* Cannot fit in a tx buffer, skip that */
353
        log(L_ERR "%s: LSA too large to send on %s (Type: %04x, Id: %R, Rt: %R)",
354
            p->p.name, ifa->ifname, en->lsa_type, en->lsa.id, en->lsa.rt);
355
        break;
356
      }
357

    
358
      /* TX buffer could be reallocated */
359
      pkt = ospf_tx_buffer(ifa);
360
    }
361

    
362
    struct ospf_lsa_header *buf = ((void *) pkt) + pos;
363
    lsa_hton_hdr(&en->lsa, buf);
364
    lsa_hton_body(en->lsa_body, ((void *) buf) + sizeof(struct ospf_lsa_header),
365
                  len - sizeof(struct ospf_lsa_header));
366
    buf->age = htons(MIN(en->lsa.age + ifa->inftransdelay, LSA_MAXAGE));
367

    
368
    pos += len;
369
  }
370

    
371
  ospf_lsupd_set_lsa_count(pkt, hlen, i);
372
  pkt->length = htons(pos);
373

    
374
  return i;
375
}
376

    
377

    
378
static int
379
ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa)
380
{
381
  uint i, c;
382

    
383
  for (i = 0; i < lsa_min_count; i += c)
384
  {
385
    c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i);
386

    
387
    if (!c)        /* Too large LSA */
388
      { i++; continue; }
389

    
390
    OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
391
                "LSUPD packet flooded via %s", ifa->ifname);
392

    
393
    if (ifa->type == OSPF_IT_BCAST)
394
    {
395
      if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
396
        ospf_send_to_all(ifa);
397
      else
398
        ospf_send_to_des(ifa);
399
    }
400
    else
401
      ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
402
  }
403

    
404
  return i;
405
}
406

    
407
int
408
ospf_send_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, struct ospf_neighbor *n)
409
{
410
  struct ospf_iface *ifa = n->ifa;
411
  uint i, c;
412

    
413
  for (i = 0; i < lsa_count; i += c)
414
  {
415
    c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i);
416

    
417
    if (!c)        /* Too large LSA */
418
      { i++; continue; }
419

    
420
    OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
421
                "LSUPD packet sent to nbr %R on %s", n->rid, ifa->ifname);
422

    
423
    ospf_send_to(ifa, n->ip);
424
  }
425

    
426
  return i;
427
}
428

    
429
void
430
ospf_rxmt_lsupd(struct ospf_proto *p, struct ospf_neighbor *n)
431
{
432
  uint max = 2 * n->ifa->flood_queue_size;
433
  struct top_hash_entry *entries[max];
434
  struct top_hash_entry *ret, *nxt, *en;
435
  uint i = 0;
436

    
437
  /* ASSERT((n->state >= NEIGHBOR_EXCHANGE) && !EMPTY_SLIST(n->lsrtl)); */
438

    
439
  WALK_SLIST_DELSAFE(ret, nxt, n->lsrtl)
440
  {
441
    if (i == max)
442
      break;
443

    
444
    en = ospf_hash_find_entry(p->gr, ret);
445
    if (!en)
446
    {
447
      /* Probably flushed LSA, this should not happen */
448
      log(L_WARN "%s: LSA disappeared (Type: %04x, Id: %R, Rt: %R)",
449
          p->p.name, ret->lsa_type, ret->lsa.id, ret->lsa.rt);
450

    
451
      s_rem_node(SNODE ret);
452
      ospf_hash_delete(n->lsrth, ret);
453

    
454
      continue;
455
    }
456

    
457
    entries[i] = en;
458
    i++;
459
  }
460

    
461
  ospf_send_lsupd(p, entries, i, n);
462
}
463

    
464

    
465
static inline int
466
ospf_addr_is_local(struct ospf_proto *p, struct ospf_area *oa, ip_addr ip)
467
{
468
  struct ospf_iface *ifa;
469
  WALK_LIST(ifa, p->iface_list)
470
    if ((ifa->oa == oa) && ifa->addr && ipa_equal(ifa->addr->ip, ip))
471
      return 1;
472

    
473
  return 0;
474
}
475

    
476
void
477
ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
478
                   struct ospf_neighbor *n)
479
{
480
  struct ospf_proto *p = ifa->oa->po;
481
  const char *err_dsc = NULL;
482
  uint plen, err_val = 0;
483

    
484
  /* RFC 2328 13. */
485

    
486
  plen = ntohs(pkt->length);
487
  if (plen < ospf_lsupd_hdrlen(p))
488
  {
489
    LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)", n->rid, ifa->ifname, "too short", plen);
490
    return;
491
  }
492

    
493
  OSPF_PACKET(ospf_dump_lsupd, pkt, "LSUPD packet received from nbr %R on %s", n->rid, ifa->ifname);
494

    
495
  if (n->state < NEIGHBOR_EXCHANGE)
496
  {
497
    OSPF_TRACE(D_PACKETS, "LSUPD packet ignored - lesser state than Exchange");
498
    return;
499
  }
500

    
501
  ospf_neigh_sm(n, INM_HELLOREC);        /* Questionable */
502

    
503
  uint offset, i, lsa_count;
504
  ospf_lsupd_body(p, pkt, &offset, &lsa_count);
505

    
506
  for (i = 0; i < lsa_count; i++)
507
  {
508
    struct ospf_lsa_header lsa, *lsa_n;
509
    struct top_hash_entry *en;
510
    u32 lsa_len, lsa_type, lsa_domain;
511

    
512
    if ((offset + sizeof(struct ospf_lsa_header)) > plen)
513
      DROP("too short", plen);
514

    
515
    /* LSA header in network order */
516
    lsa_n = ((void *) pkt) + offset;
517
    lsa_len = ntohs(lsa_n->length);
518
    offset += lsa_len;
519

    
520
    if (offset > plen)
521
      DROP("too short", plen);
522

    
523
    if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header)))
524
      DROP("invalid LSA length", lsa_len);
525

    
526
    /* LSA header in host order */
527
    lsa_ntoh_hdr(lsa_n, &lsa);
528
    lsa_get_type_domain(&lsa, ifa, &lsa_type, &lsa_domain);
529

    
530
    DBG("Update Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
531
        lsa_type, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum);
532

    
533
    /* RFC 2328 13. (1) - verify LSA checksum */
534
    if ((lsa_n->checksum == 0) || !lsa_verify_checksum(lsa_n, lsa_len))
535
      SKIP("invalid checksum");
536

    
537
    /* RFC 2328 13. (2) */
538
    if (!lsa_type)
539
      SKIP("unknown type");
540

    
541
    /* RFC 5340 4.5.1 (2) and RFC 2328 13. (3) */
542
    if (!oa_is_ext(ifa->oa) && (LSA_SCOPE(lsa_type) == LSA_SCOPE_AS))
543
      SKIP("AS scope in stub area");
544

    
545
    /* Errata 3746 to RFC 2328 - rt-summary-LSAs forbidden in stub areas */
546
    if (!oa_is_ext(ifa->oa) && (lsa_type == LSA_T_SUM_RT))
547
      SKIP("rt-summary-LSA in stub area");
548

    
549
    /* RFC 5340 4.5.1 (3) */
550
    if (LSA_SCOPE(lsa_type) == LSA_SCOPE_RES)
551
      SKIP("invalid scope");
552

    
553
    /* Find local copy of LSA in link state database */
554
    en = ospf_hash_find(p->gr, lsa_domain, lsa.id, lsa.rt, lsa_type);
555

    
556
#ifdef LOCAL_DEBUG
557
    if (en)
558
      DBG("I have Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
559
          en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age, en->lsa.checksum);
560
#endif
561

    
562
    /* 13. (4) - ignore maxage LSA if i have no local copy */
563
    if ((lsa.age == LSA_MAXAGE) && !en && (p->padj == 0))
564
    {
565
      /* 13.5. - schedule ACKs (tbl 19, case 5) */
566
      ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
567
      continue;
568
    }
569

    
570
    /* 13. (5) - received LSA is newer (or no local copy) */
571
    if (!en || (lsa_comp(&lsa, &en->lsa) == CMP_NEWER))
572
    {
573
      /* 13. (5a) - enforce minimum time between updates for received LSAs */
574
      /* We also use this to ratelimit reactions to received self-originated LSAs */
575
      if (en && (lsa_inst_age(en) < MINLSARRIVAL))
576
      {
577
        OSPF_TRACE(D_EVENTS, "Skipping LSA received in less that MinLSArrival");
578
        continue;
579
      }
580

    
581
      /* Copy and validate LSA body */
582
      int blen = lsa.length - sizeof(struct ospf_lsa_header);
583
      void *body = mb_alloc(p->p.pool, blen);
584
      lsa_ntoh_body(lsa_n + 1, body, blen);
585

    
586
      if (lsa_validate(&lsa, lsa_type, ospf_is_v2(p), body) == 0)
587
      {
588
        mb_free(body);
589
        SKIP("invalid body");
590
      }
591

    
592
      /* 13. (5f) - handle self-originated LSAs, see also 13.4. */
593
      if ((lsa.rt == p->router_id) ||
594
          (ospf_is_v2(p) && (lsa_type == LSA_T_NET) && ospf_addr_is_local(p, ifa->oa, ipa_from_u32(lsa.id))))
595
      {
596
        OSPF_TRACE(D_EVENTS, "Received unexpected self-originated LSA");
597
        ospf_advance_lsa(p, en, &lsa, lsa_type, lsa_domain, body);
598
        continue;
599
      }
600

    
601
      /* 13. (5c) - remove old LSA from all retransmission lists
602
       *
603
       * We only need to remove it from the retransmission list of the neighbor
604
       * that send us the new LSA. The old LSA is automatically replaced in
605
       * retransmission lists by the new LSA.
606
       */
607
      if (en)
608
        ospf_lsa_lsrt_down(en, n);
609

    
610
#if 0
611
      /*
612
       * Old code for removing LSA from all retransmission lists. Must be done
613
       * before (5b), otherwise it also removes the new entries from (5b).
614
       */
615
      struct ospf_iface *ifi;
616
      struct ospf_neighbor *ni;
617

618
      WALK_LIST(ifi, p->iface_list)
619
        WALK_LIST(ni, ifi->neigh_list)
620
          if (ni->state > NEIGHBOR_EXSTART)
621
            ospf_lsa_lsrt_down(en, ni);
622
#endif
623

    
624
      /* 13. (5d) - install new LSA into database */
625
      en = ospf_install_lsa(p, &lsa, lsa_type, lsa_domain, body);
626

    
627
      /* RFC 5340 4.4.3 Events 6+7 - new Link LSA received */
628
      if (lsa_type == LSA_T_LINK)
629
        ospf_notify_net_lsa(ifa);
630

    
631
      /* 13. (5b) - flood new LSA */
632
      int flood_back = ospf_flood_lsa(p, en, n);
633

    
634
      /* 13.5. - schedule ACKs (tbl 19, cases 1+2) */
635
      if (! flood_back)
636
        if ((ifa->state != OSPF_IS_BACKUP) || (n->rid == ifa->drid))
637
          ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY);
638

    
639
      /* FIXME: remove LSA entry if it is LSA_MAXAGE and it is possible? */
640

    
641
      continue;
642
    }
643

    
644
    /* 13. (6) - received LSA is in Link state request list (but not newer) */
645
    if (ospf_hash_find_entry(n->lsrqh, en) != NULL)
646
      DROP1("error in LSA database exchange");
647

    
648
    /* 13. (7) - received LSA is same */
649
    if (lsa_comp(&lsa, &en->lsa) == CMP_SAME)
650
    {
651
      /* Duplicate LSA, treat as implicit ACK */
652
      int implicit_ack = ospf_lsa_lsrt_down(en, n);
653

    
654
      /* 13.5. - schedule ACKs (tbl 19, cases 3+4) */
655
      if (implicit_ack)
656
      {
657
        if ((ifa->state == OSPF_IS_BACKUP) && (n->rid == ifa->drid))
658
          ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY);
659
      }
660
      else
661
        ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
662

    
663
      continue;
664
    }
665

    
666
    /* 13. (8) - received LSA is older */
667
    {
668
      /* Seqnum is wrapping, wait until it is flushed */
669
      if ((en->lsa.age == LSA_MAXAGE) && (en->lsa.sn == LSA_MAXSEQNO))
670
        continue;
671

    
672
      /* Send newer local copy back to neighbor */
673
      /* FIXME - check for MinLSArrival ? */
674
      ospf_send_lsupd(p, &en, 1, n);
675

    
676
      continue;
677
    }
678

    
679
  skip:
680
    LOG_LSA1("Bad LSA (Type: %04x, Id: %R, Rt: %R) in LSUPD", lsa_type, lsa.id, lsa.rt);
681
    LOG_LSA2("  received from nbr %R on %s - %s", n->rid, ifa->ifname, err_dsc);
682
  }
683

    
684
  /* Send direct LSACKs */
685
  ospf_send_lsack(p, n, ACKL_DIRECT);
686

    
687
  /* Send enqueued LSAs immediately, do not wait for flood_event */
688
  if (ev_active(p->flood_event))
689
  {
690
    ev_postpone(p->flood_event);
691
    ospf_flood_event(p);
692
  }
693

    
694
  /*
695
   * During loading, we should ask for another batch of LSAs. This is only
696
   * vaguely mentioned in RFC 2328. We send a new LSREQ if all requests sent in
697
   * the last packet were already answered and/or removed from the LS request
698
   * list and therefore lsrqi is pointing to the first node of the list.
699
   */
700
  if (!EMPTY_SLIST(n->lsrql) && (n->lsrqi == SHEAD(n->lsrql)))
701
  {
702
    ospf_send_lsreq(p, n);
703
    tm_start(n->lsrq_timer, n->ifa->rxmtint S);
704
  }
705

    
706
  return;
707

    
708
drop:
709
  LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)",
710
          n->rid, ifa->ifname, err_dsc, err_val);
711

    
712
  /* Malformed LSUPD - there is no defined error event, we abuse BadLSReq */
713
  ospf_neigh_sm(n, INM_BADLSREQ);
714
  return;
715
}