2
* Copyright (C) 1999 Yasuhiro Ohara
4
* This file is part of GNU Zebra.
6
* GNU Zebra is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the
8
* Free Software Foundation; either version 2, or (at your option) any
11
* GNU Zebra is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with GNU Zebra; see the file COPYING. If not, write to the
18
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
* Boston, MA 02111-1307, USA.
24
/* check validity and put lsa in reqestlist if needed. */
25
/* returns -1 if SeqNumMismatch required. */
27
ospf6_dbex_check_dbdesc_lsa_header (struct ospf6_lsa_header *lsa_header,
28
struct ospf6_neighbor *from)
30
struct ospf6_lsa *received = NULL;
31
struct ospf6_lsa *have = NULL;
33
received = ospf6_lsa_summary_create
34
((struct ospf6_lsa_header__ *) lsa_header);
36
/* case when received is AS-External though neighbor belongs stub area */
37
if (lsa_header->type == htons (OSPF6_LSA_TYPE_AS_EXTERNAL) &&
38
ospf6_area_is_stub (from->ospf6_interface->area))
40
zlog_err ("DbDesc %s receive from %s", from->str, received->str);
41
zlog_err (" E-bit mismatch: %s", received->str);
42
ospf6_lsa_delete (received);
46
/* if already have newer database copy, check next LSA */
47
have = ospf6_lsdb_lookup (lsa_header->type, lsa_header->ls_id,
49
ospf6_lsa_get_scope (lsa_header->type,
50
from->ospf6_interface));
53
/* if we don't have database copy, add request */
54
if (IS_OSPF6_DUMP_DBEX)
55
zlog_info ("Have no database copy, Request");
56
ospf6_neighbor_request_add (received, from);
60
/* if database copy is less recent, add request */
61
if (ospf6_lsa_check_recent (received, have) < 0)
63
if (IS_OSPF6_DUMP_DBEX)
64
zlog_info ("Database copy less recent, Request");
65
ospf6_neighbor_request_add (received, from);
72
/* Direct acknowledgement */
74
ospf6_dbex_acknowledge_direct (struct ospf6_lsa *lsa,
75
struct ospf6_neighbor *o6n)
77
struct iovec directack[MAXIOVLIST];
80
if (IS_OSPF6_DUMP_DBEX)
81
zlog_info ("DBEX: [%s:%s] direct ack %s ",
82
o6n->str, o6n->ospf6_interface->interface->name,
85
/* clear pointers to fragments of packet for direct acknowledgement */
86
iov_clear (directack, MAXIOVLIST);
88
/* set pointer of LSA to send */
89
OSPF6_MESSAGE_ATTACH (directack, lsa->header,
90
sizeof (struct ospf6_lsa_header));
92
/* age update and add InfTransDelay */
93
ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);
95
/* send unicast packet to neighbor's ipaddress */
96
ospf6_message_send (OSPF6_MESSAGE_TYPE_LSACK, directack, &o6n->hisaddr,
97
o6n->ospf6_interface->if_id);
100
/* Delayed acknowledgement */
102
ospf6_dbex_acknowledge_delayed (struct ospf6_lsa *lsa,
103
struct ospf6_interface *o6i)
107
if (IS_OSPF6_DUMP_DBEX)
108
zlog_info ("DBEX: [%s] delayed ack %s", o6i->interface->name, lsa->str);
110
/* attach delayed acknowledge list */
111
ospf6_lsa_age_current (lsa);
112
ospf6_interface_delayed_ack_add (lsa, o6i);
114
/* if not yet, schedule delayed acknowledge RxmtInterval later.
115
timers should be *less than* RxmtInterval
116
or needless retrans will ensue */
117
if (o6i->thread_send_lsack_delayed == NULL)
118
o6i->thread_send_lsack_delayed
119
= thread_add_timer (master, ospf6_send_lsack_delayed,
120
o6i, o6i->rxmt_interval - 1);
125
/* RFC2328 section 13 (4):
126
if MaxAge LSA and if we have no instance, and no neighbor
127
is in states Exchange or Loading */
128
/* returns 1 if match this case, else returns 0 */
130
ospf6_dbex_is_maxage_to_be_dropped (struct ospf6_lsa *received,
131
struct ospf6_neighbor *from)
135
if (! IS_LSA_MAXAGE (received))
138
if (ospf6_lsdb_lookup (received->header->type, received->header->id,
139
received->header->adv_router,
140
ospf6_lsa_get_scope (received->header->type,
141
from->ospf6_interface)))
144
if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (received->header->type)))
147
(*from->ospf6_interface->foreach_nei)
148
(from->ospf6_interface, &count, NBS_EXCHANGE, ospf6_count_state);
149
(*from->ospf6_interface->foreach_nei)
150
(from->ospf6_interface, &count, NBS_LOADING, ospf6_count_state);
154
else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (received->header->type)))
157
(*from->ospf6_interface->area->foreach_nei)
158
(from->ospf6_interface->area, &count, NBS_EXCHANGE, ospf6_count_state);
159
(*from->ospf6_interface->area->foreach_nei)
160
(from->ospf6_interface->area, &count, NBS_LOADING, ospf6_count_state);
164
else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (received->header->type)))
167
(*from->ospf6_interface->area->ospf6->foreach_nei)
168
(from->ospf6_interface->area->ospf6, &count, NBS_EXCHANGE,
170
(*from->ospf6_interface->area->ospf6->foreach_nei)
171
(from->ospf6_interface->area->ospf6, &count, NBS_LOADING,
181
ospf6_dbex_remove_retrans (void *arg, int val, void *obj)
183
struct ospf6_lsa *rem;
184
struct ospf6_neighbor *nei = (struct ospf6_neighbor *) obj;
185
struct ospf6_lsa *lsa = (struct ospf6_lsa *) arg;
187
rem = ospf6_lsdb_lookup_lsdb (lsa->header->type, lsa->header->id,
188
lsa->header->adv_router, nei->retrans_list);
191
ospf6_neighbor_retrans_remove (rem, nei);
192
ospf6_maxage_remover ();
197
ospf6_dbex_remove_from_all_retrans_list (struct ospf6_lsa *lsa)
199
struct ospf6_interface *o6i;
200
struct ospf6_area *o6a;
202
if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (htons (lsa->header->type)))
205
(*o6i->foreach_nei) (o6i, lsa, 0, ospf6_dbex_remove_retrans);
207
else if (OSPF6_LSA_IS_SCOPE_AREA (htons (lsa->header->type)))
210
(*o6a->foreach_nei) (o6a, lsa, 0, ospf6_dbex_remove_retrans);
212
else if (OSPF6_LSA_IS_SCOPE_AS (htons (lsa->header->type)))
214
(*ospf6->foreach_nei) (ospf6, lsa, 0, ospf6_dbex_remove_retrans);
218
/* RFC2328 section 13 */
220
ospf6_dbex_receive_lsa (struct ospf6_lsa_header *lsa_header,
221
struct ospf6_neighbor *from)
223
struct ospf6_lsa *received, *have, *rem;
225
int ismore_recent, acktype;
226
unsigned short cksum;
227
struct ospf6_lsa_slot *slot;
229
received = have = (struct ospf6_lsa *)NULL;
231
recent_reason = "no instance";
233
zlog_info ("Receive LSA (header -> %p)", lsa_header);
235
/* make lsa structure for received lsa */
236
received = ospf6_lsa_create (lsa_header);
239
if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (htons (lsa_header->type)))
240
received->scope = from->ospf6_interface;
241
else if (OSPF6_LSA_IS_SCOPE_AREA (htons (lsa_header->type)))
242
received->scope = from->ospf6_interface->area;
243
else if (OSPF6_LSA_IS_SCOPE_AS (htons (lsa_header->type)))
244
received->scope = from->ospf6_interface->area->ospf6;
246
/* (1) LSA Checksum */
247
cksum = ntohs (lsa_header->checksum);
248
if (ntohs (ospf6_lsa_checksum (lsa_header)) != cksum)
250
if (IS_OSPF6_DUMP_DBEX)
251
zlog_info ("DBEX: received %s from %s%%%s"
252
": wrong checksum, drop",
253
received->str, from->str,
254
from->ospf6_interface->interface->name);
255
ospf6_lsa_delete (received);
259
/* (3) Ebit Missmatch: AS-External-LSA */
260
if (lsa_header->type == htons (OSPF6_LSA_TYPE_AS_EXTERNAL) &&
261
ospf6_area_is_stub (from->ospf6_interface->area))
263
if (IS_OSPF6_DUMP_DBEX)
264
zlog_info ("DBEX: received %s from %s%%%s"
265
": E-bit mismatch, drop",
266
received->str, from->str,
267
from->ospf6_interface->interface->name);
268
ospf6_lsa_delete (received);
272
/* (4) if MaxAge LSA and if we have no instance, and no neighbor
273
is in states Exchange or Loading */
274
if (ospf6_dbex_is_maxage_to_be_dropped (received, from))
277
if (IS_OSPF6_DUMP_DBEX)
278
zlog_info ("DBEX: received %s from %s%%%s"
279
": MaxAge, no instance, no neighbor exchange, drop",
280
received->str, from->str,
281
from->ospf6_interface->interface->name);
283
/* a) Acknowledge back to neighbor (13.5) */
284
/* Direct Acknowledgement */
285
ospf6_dbex_acknowledge_direct (received, from);
288
ospf6_lsa_delete (received);
293
/* lookup the same database copy in lsdb */
294
have = ospf6_lsdb_lookup (lsa_header->type, lsa_header->ls_id,
296
ospf6_lsa_get_scope (lsa_header->type,
297
from->ospf6_interface));
300
ismore_recent = ospf6_lsa_check_recent (received, have);
301
if (ntohl (received->header->seqnum) == ntohl (have->header->seqnum))
302
SET_FLAG (received->flag, OSPF6_LSA_FLAG_DUPLICATE);
305
/* if no database copy or received is more recent */
306
if (!have || ismore_recent < 0)
308
/* in case we have no database copy */
311
/* (a) MinLSArrival check */
312
gettimeofday (&now, (struct timezone *)NULL);
313
if (have && SEC_TVDIFF (&now, &have->installed) < OSPF6_MIN_LS_ARRIVAL)
315
//if (IS_OSPF6_DUMP_DBEX)
316
zlog_info ("DBEX: Receive new LSA from %s: %s seq: %#x age: %d "
317
"within MinLSArrival, drop: %ld.%06ld",
318
from->str, received->str,
319
ntohl (received->header->seqnum),
320
ntohs (received->header->age),
321
now.tv_sec, now.tv_usec);
323
/* this will do free this lsa */
324
ospf6_lsa_delete (received);
325
return; /* examin next lsa */
328
//if (IS_OSPF6_DUMP_DBEX)
329
zlog_info ("DBEX: Receive new LSA from %s: %s seq: %#x age: %d: "
331
from->str, received->str,
332
ntohl (received->header->seqnum),
333
ntohs (received->header->age),
334
now.tv_sec, now.tv_usec);
336
/* (b) immediately flood */
337
ospf6_dbex_flood (received, from);
340
/* Because New LSDB do not permit two LSA having the same identifier
341
exist in a LSDB list, above ospf6_dbex_flood() will remove
342
the old instance automatically. thus bellow is not needed. */
343
/* (c) remove database copy from all neighbor's retranslist */
345
ospf6_dbex_remove_from_all_retrans_list (have);
348
/* (d), installing lsdb, which may cause routing
349
table calculation (replacing database copy) */
350
ospf6_lsdb_install (received);
352
/* (e) possibly acknowledge */
353
acktype = ack_type (received, ismore_recent, from);
354
if (acktype == DIRECT_ACK)
356
if (IS_OSPF6_DUMP_DBEX)
357
zlog_info ("DBEX: Direct Ack to %s", from->str);
358
ospf6_dbex_acknowledge_direct (received, from);
360
else if (acktype == DELAYED_ACK)
362
if (IS_OSPF6_DUMP_DBEX)
363
zlog_info ("DBEX: Delayed Ack to %s", from->str);
364
ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface);
368
if (IS_OSPF6_DUMP_DBEX)
369
zlog_info ("DBEX: No Ack to %s", from->str);
373
/* Self Originated LSA, section 13.4 */
374
if (received->lsa_hdr->lsh_advrtr == ospf6->router_id
375
&& (! have || ismore_recent < 0))
377
/* we're going to make new lsa or to flush this LSA. */
378
if (IS_OSPF6_DUMP_DBEX)
379
zlog_info ("DBEX: Self-originated LSA %s from %s:%s",
380
received->str, from->str,
381
from->ospf6_interface->interface->name);
382
if (IS_OSPF6_DUMP_DBEX)
383
zlog_info ("DBEX: %s: Make new one/Flush", received->str);
385
SET_FLAG (received->flag, OSPF6_LSA_FLAG_REFRESH);
386
slot = ospf6_lsa_slot_get (received->header->type);
387
if (slot && slot->func_refresh)
389
(*slot->func_refresh) (received);
393
zlog_warn ("Can't Refresh LSA: Unknown type: %#x, Flush",
394
ntohs (received->header->type));
395
ospf6_lsa_premature_aging (received);
399
else if (ospf6_lsdb_lookup_lsdb (received->header->type,
400
received->header->id,
401
received->header->adv_router,
403
/* (6) if there is instance on sending neighbor's request list */
405
/* if no database copy, should go above state (5) */
408
zlog_warn ("DBEX: [%s:%s] received LSA %s is not newer,"
409
" and is on his requestlist: Generate BadLSReq",
410
from->str, from->ospf6_interface->interface->name,
414
thread_add_event (master, bad_lsreq, from, 0);
416
ospf6_lsa_delete (received);
418
else if (ismore_recent == 0) /* (7) if neither is more recent */
420
/* (a) if on retranslist, Treat this LSA as an Ack: Implied Ack */
421
rem = ospf6_lsdb_lookup_lsdb (received->header->type,
422
received->header->id,
423
received->header->adv_router,
427
if (IS_OSPF6_DUMP_DBEX)
428
zlog_info ("DBEX: Implied Ack from %s, (remove retrans)",
430
SET_FLAG (received->flag, OSPF6_LSA_FLAG_IMPLIEDACK);
431
ospf6_neighbor_retrans_remove (rem, from);
434
/* (b) possibly acknowledge */
435
acktype = ack_type (received, ismore_recent, from);
436
if (acktype == DIRECT_ACK)
438
if (IS_OSPF6_DUMP_DBEX)
439
zlog_info ("DBEX: Direct Ack to %s", from->str);
440
ospf6_dbex_acknowledge_direct (received, from);
442
else if (acktype == DELAYED_ACK)
444
if (IS_OSPF6_DUMP_DBEX)
445
zlog_info ("DBEX: Delayed Ack to %s", from->str);
446
ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface);
450
if (IS_OSPF6_DUMP_DBEX)
451
zlog_info ("DBEX: No Ack to %s", from->str);
453
ospf6_lsa_delete (received);
455
else /* (8) previous database copy is more recent */
457
/* If Seqnumber Wrapping, simply discard
458
Otherwise, Send database copy of this LSA to this neighbor */
459
if (! IS_LSA_MAXAGE (received) ||
460
received->lsa_hdr->lsh_seqnum != MAX_SEQUENCE_NUMBER)
462
if (IS_OSPF6_DUMP_DBEX)
463
zlog_info ("DBEX: database is more recent: send back to %s",
465
ospf6_send_lsupdate_direct (have, from);
467
ospf6_lsa_delete (received);
471
/* RFC2328: Table 19: Sending link state acknowledgements. */
473
ack_type (struct ospf6_lsa *newp, int ismore_recent,
474
struct ospf6_neighbor *from)
476
struct ospf6_interface *ospf6_interface;
477
struct ospf6_lsa *have;
480
assert (from && from->ospf6_interface);
481
ospf6_interface = from->ospf6_interface;
483
if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_FLOODBACK))
486
if (ismore_recent < 0)
488
if (ospf6_interface->state != IFS_BDR)
491
if (ospf6_interface->dr == from->router_id)
496
if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) &&
497
CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK))
499
if (ospf6_interface->state != IFS_BDR)
502
if (ospf6_interface->dr == from->router_id)
508
if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) &&
509
! CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK))
512
have = ospf6_lsdb_lookup (newp->header->type, newp->header->id,
513
newp->header->adv_router,
514
ospf6_lsa_get_scope (newp->header->type,
515
from->ospf6_interface));
518
ospf6->foreach_nei (ospf6, &count, NBS_EXCHANGE, ospf6_count_state);
519
ospf6->foreach_nei (ospf6, &count, NBS_LOADING, ospf6_count_state);
521
if (IS_LSA_MAXAGE (newp) && have == NULL && count == 0)
528
ospf6_dbex_flood_linklocal (struct ospf6_lsa *lsa, struct ospf6_interface *o6i,
529
struct ospf6_neighbor *from)
531
struct ospf6_neighbor *o6n = (struct ospf6_neighbor *) NULL;
532
int ismore_recent, addretrans = 0;
534
struct ospf6_lsa *req;
536
/* (1) for each neighbor */
537
for (n = listhead (o6i->neighbor_list); n; nextnode (n))
539
o6n = (struct ospf6_neighbor *) getdata (n);
542
if (o6n->state < NBS_EXCHANGE)
543
continue; /* examin next neighbor */
546
if (o6n->state == NBS_EXCHANGE
547
|| o6n->state == NBS_LOADING)
549
req = ospf6_lsdb_lookup_lsdb (lsa->header->type,
551
lsa->header->adv_router,
555
ismore_recent = ospf6_lsa_check_recent (lsa, req);
556
if (ismore_recent > 0)
558
continue; /* examin next neighbor */
560
else if (ismore_recent == 0)
562
ospf6_neighbor_request_remove (req, o6n);
563
continue; /* examin next neighbor */
565
else /* ismore_recent < 0 (the new LSA is more recent) */
567
ospf6_neighbor_request_remove (req, o6n);
573
if (from && from->router_id == o6n->router_id)
574
continue; /* examin next neighbor */
576
/* (d) add retranslist */
577
if (IS_OSPF6_DUMP_DBEX)
578
zlog_info ("DBEX: schedule flooding [%s:%s]: %s",
579
o6n->str, o6n->ospf6_interface->interface->name,
581
ospf6_neighbor_retrans_add (lsa, o6n);
583
if (o6n->send_update == (struct thread *) NULL)
585
thread_add_timer (master, ospf6_send_lsupdate_rxmt, o6n,
586
o6n->ospf6_interface->rxmt_interval);
591
return; /* examin next interface */
593
if (from && from->ospf6_interface == o6i)
595
if (IS_OSPF6_DUMP_DBEX)
596
zlog_info ("DBEX: flood back %s to %s",
597
lsa->str, o6i->interface->name);
598
/* note occurence of floodback */
599
SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_FLOODBACK);
603
if (from && from->ospf6_interface == o6i)
605
/* if from DR or BDR, don't need to flood this interface */
606
if (from->router_id == from->ospf6_interface->dr ||
607
from->router_id == from->ospf6_interface->bdr)
608
return; /* examin next interface */
611
/* (4) if I'm BDR, DR will flood this interface */
612
if (from && from->ospf6_interface == o6i
613
&& o6i->state == IFS_BDR)
614
return; /* examin next interface */
616
if (IS_OSPF6_DUMP_DBEX)
617
zlog_info ("Flood to interface %s", o6i->interface->name);
619
/* (5) send LinkState Update */
620
ospf6_send_lsupdate_flood (lsa, o6i);
625
/* RFC2328 section 13.3 */
627
ospf6_dbex_flood_area (struct ospf6_lsa *lsa, struct ospf6_area *area,
628
struct ospf6_neighbor *from)
631
struct ospf6_interface *ospf6_interface;
633
assert (lsa && lsa->lsa_hdr && area);
635
/* for each eligible ospf_ifs */
636
for (n = listhead (area->if_list); n; nextnode (n))
638
ospf6_interface = (struct ospf6_interface *) getdata (n);
639
ospf6_dbex_flood_linklocal (lsa, ospf6_interface, from);
644
ospf6_dbex_flood_as (struct ospf6_lsa *lsa, struct ospf6 *ospf6,
645
struct ospf6_neighbor *from)
648
struct ospf6_area *o6a;
650
assert (lsa && lsa->lsa_hdr && ospf6);
652
/* for each attached area */
653
for (n = listhead (ospf6->area_list); n; nextnode (n))
655
o6a = (struct ospf6_area *) getdata (n);
656
ospf6_dbex_flood_area (lsa, o6a, from);
660
/* flood ospf6_lsa within appropriate scope */
662
ospf6_dbex_flood (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
664
struct ospf6_area *o6a;
665
struct ospf6_interface *o6i;
667
struct ospf6_lsa_header *lsa_header;
669
lsa_header = (struct ospf6_lsa_header *) lsa->lsa_hdr;
671
if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa_header->type)))
673
o6i = (struct ospf6_interface *) lsa->scope;
676
if (IS_OSPF6_DUMP_DBEX)
677
zlog_info ("Flood Linklocal: %s", o6i->interface->name);
678
ospf6_dbex_flood_linklocal (lsa, o6i, from);
680
else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa_header->type)))
682
o6a = (struct ospf6_area *) lsa->scope;
685
if (IS_OSPF6_DUMP_DBEX)
686
zlog_info ("Flood Area: %s", o6a->str);
687
ospf6_dbex_flood_area (lsa, o6a, from);
689
else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa_header->type)))
691
o6 = (struct ospf6 *) lsa->scope;
694
if (IS_OSPF6_DUMP_DBEX)
695
zlog_info ("Flood AS");
696
ospf6_dbex_flood_as (lsa, o6, from);
700
zlog_warn ("Can't Flood %s: scope unknown", lsa->str);