2
* This is an implementation of rfc2370.
3
* Copyright (C) 2001 KDD R&D Laboratories, Inc.
4
* http://www.kddlabs.co.jp/
6
* This file is part of GNU Zebra.
8
* GNU Zebra is free software; you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License as published by the
10
* Free Software Foundation; either version 2, or (at your option) any
13
* GNU Zebra is distributed in the hope that it will be useful, but
14
* WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with GNU Zebra; see the file COPYING. If not, write to the Free
20
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24
/***** MTYPE definitions are not reflected to "memory.h" yet. *****/
25
#define MTYPE_OSPF_OPAQUE_FUNCTAB 0
26
#define MTYPE_OPAQUE_INFO_PER_TYPE 0
27
#define MTYPE_OPAQUE_INFO_PER_ID 0
30
#ifdef HAVE_OPAQUE_LSA
43
#include "sockunion.h" /* for inet_aton() */
45
#include "ospfd/ospfd.h"
46
#include "ospfd/ospf_interface.h"
47
#include "ospfd/ospf_ism.h"
48
#include "ospfd/ospf_asbr.h"
49
#include "ospfd/ospf_lsa.h"
50
#include "ospfd/ospf_lsdb.h"
51
#include "ospfd/ospf_neighbor.h"
52
#include "ospfd/ospf_nsm.h"
53
#include "ospfd/ospf_flood.h"
54
#include "ospfd/ospf_packet.h"
55
#include "ospfd/ospf_spf.h"
56
#include "ospfd/ospf_dump.h"
57
#include "ospfd/ospf_route.h"
58
#include "ospfd/ospf_ase.h"
59
#include "ospfd/ospf_zebra.h"
61
/*------------------------------------------------------------------------*
62
* Followings are initialize/terminate functions for Opaque-LSAs handling.
63
*------------------------------------------------------------------------*/
66
#include "ospfd/ospf_te.h"
67
#endif /* HAVE_OSPF_TE */
69
#ifdef SUPPORT_OSPF_API
70
int ospf_apiserver_init (void);
71
void ospf_apiserver_term (void);
72
#endif /* SUPPORT_OSPF_API */
74
static void ospf_opaque_register_vty (void);
75
static void ospf_opaque_funclist_init (void);
76
static void ospf_opaque_funclist_term (void);
77
static void free_opaque_info_per_type (void *val);
78
static void free_opaque_info_per_id (void *val);
79
static int ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa);
80
static int ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa);
83
ospf_opaque_init (void)
85
ospf_opaque_register_vty ();
86
ospf_opaque_funclist_init ();
89
if (ospf_mpls_te_init () != 0)
91
#endif /* HAVE_OSPF_TE */
93
#ifdef SUPPORT_OSPF_API
94
if (ospf_apiserver_init () != 0)
96
#endif /* SUPPORT_OSPF_API */
102
ospf_opaque_term (void)
105
ospf_mpls_te_term ();
106
#endif /* HAVE_OSPF_TE */
108
#ifdef SUPPORT_OSPF_API
109
ospf_apiserver_term ();
110
#endif /* SUPPORT_OSPF_API */
112
ospf_opaque_funclist_term ();
117
ospf_opaque_type9_lsa_init (struct ospf_interface *oi)
119
if (oi->opaque_lsa_self != NULL)
120
list_delete (oi->opaque_lsa_self);
122
oi->opaque_lsa_self = list_new ();
123
oi->opaque_lsa_self->del = free_opaque_info_per_type;
124
oi->t_opaque_lsa_self = NULL;
129
ospf_opaque_type9_lsa_term (struct ospf_interface *oi)
131
OSPF_TIMER_OFF (oi->t_opaque_lsa_self);
132
if (oi->opaque_lsa_self != NULL)
133
list_delete (oi->opaque_lsa_self);
134
oi->opaque_lsa_self = NULL;
139
ospf_opaque_type10_lsa_init (struct ospf_area *area)
141
if (area->opaque_lsa_self != NULL)
142
list_delete (area->opaque_lsa_self);
144
area->opaque_lsa_self = list_new ();
145
area->opaque_lsa_self->del = free_opaque_info_per_type;
146
area->t_opaque_lsa_self = NULL;
148
#ifdef MONITOR_LSDB_CHANGE
149
area->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook;
150
area->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook;
151
#endif /* MONITOR_LSDB_CHANGE */
156
ospf_opaque_type10_lsa_term (struct ospf_area *area)
158
#ifdef MONITOR_LSDB_CHANGE
159
area->lsdb->new_lsa_hook =
160
area->lsdb->del_lsa_hook = NULL;
161
#endif /* MONITOR_LSDB_CHANGE */
163
OSPF_TIMER_OFF (area->t_opaque_lsa_self);
164
if (area->opaque_lsa_self != NULL)
165
list_delete (area->opaque_lsa_self);
166
area->opaque_lsa_self = NULL;
171
ospf_opaque_type11_lsa_init (struct ospf *top)
173
if (top->opaque_lsa_self != NULL)
174
list_delete (top->opaque_lsa_self);
176
top->opaque_lsa_self = list_new ();
177
top->opaque_lsa_self->del = free_opaque_info_per_type;
178
top->t_opaque_lsa_self = NULL;
180
#ifdef MONITOR_LSDB_CHANGE
181
top->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook;
182
top->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook;
183
#endif /* MONITOR_LSDB_CHANGE */
188
ospf_opaque_type11_lsa_term (struct ospf *top)
190
#ifdef MONITOR_LSDB_CHANGE
191
top->lsdb->new_lsa_hook =
192
top->lsdb->del_lsa_hook = NULL;
193
#endif /* MONITOR_LSDB_CHANGE */
195
OSPF_TIMER_OFF (top->t_opaque_lsa_self);
196
if (top->opaque_lsa_self != NULL)
197
list_delete (top->opaque_lsa_self);
198
top->opaque_lsa_self = NULL;
203
ospf_opaque_type_name (u_char opaque_type)
205
const char *name = "Unknown";
209
case OPAQUE_TYPE_WILDCARD: /* This is a special assignment! */
212
case OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA:
213
name = "Traffic Engineering LSA";
215
case OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC:
216
name = "Sycamore optical topology description";
218
case OPAQUE_TYPE_GRACE_LSA:
222
if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type))
224
else if (OPAQUE_TYPE_RANGE_RESERVED (opaque_type))
225
name = "Private/Experimental";
231
/*------------------------------------------------------------------------*
232
* Followings are management functions to store user specified callbacks.
233
*------------------------------------------------------------------------*/
235
struct opaque_info_per_type; /* Forward declaration. */
237
struct ospf_opaque_functab
240
struct opaque_info_per_type *oipt;
242
int (* new_if_hook)(struct interface *ifp);
243
int (* del_if_hook)(struct interface *ifp);
244
void (* ism_change_hook)(struct ospf_interface *oi, int old_status);
245
void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status);
246
void (* config_write_router)(struct vty *vty);
247
void (* config_write_if )(struct vty *vty, struct interface *ifp);
248
void (* config_write_debug )(struct vty *vty);
249
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa);
250
int (* lsa_originator)(void *arg);
251
void (* lsa_refresher )(struct ospf_lsa *lsa);
252
int (* new_lsa_hook)(struct ospf_lsa *lsa);
253
int (* del_lsa_hook)(struct ospf_lsa *lsa);
256
static list ospf_opaque_wildcard_funclist; /* Handle LSA-9/10/11 altogether. */
257
static list ospf_opaque_type9_funclist;
258
static list ospf_opaque_type10_funclist;
259
static list ospf_opaque_type11_funclist;
262
ospf_opaque_del_functab (void *val)
264
XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, val);
269
ospf_opaque_funclist_init (void)
273
funclist = ospf_opaque_wildcard_funclist = list_new ();
274
funclist->del = ospf_opaque_del_functab;
276
funclist = ospf_opaque_type9_funclist = list_new ();
277
funclist->del = ospf_opaque_del_functab;
279
funclist = ospf_opaque_type10_funclist = list_new ();
280
funclist->del = ospf_opaque_del_functab;
282
funclist = ospf_opaque_type11_funclist = list_new ();
283
funclist->del = ospf_opaque_del_functab;
288
ospf_opaque_funclist_term (void)
292
funclist = ospf_opaque_wildcard_funclist;
293
list_delete (funclist);
295
funclist = ospf_opaque_type9_funclist;
296
list_delete (funclist);
298
funclist = ospf_opaque_type10_funclist;
299
list_delete (funclist);
301
funclist = ospf_opaque_type11_funclist;
302
list_delete (funclist);
307
ospf_get_opaque_funclist (u_char lsa_type)
309
list funclist = NULL;
313
case OPAQUE_TYPE_WILDCARD:
315
* This is an ugly trick to handle type-9/10/11 LSA altogether.
316
* Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor
317
* an officially assigned opaque-type.
318
* Though it is possible that the value might be officially used
319
* in the future, we use it internally as a special label, for now.
321
funclist = ospf_opaque_wildcard_funclist;
323
case OSPF_OPAQUE_LINK_LSA:
324
funclist = ospf_opaque_type9_funclist;
326
case OSPF_OPAQUE_AREA_LSA:
327
funclist = ospf_opaque_type10_funclist;
329
case OSPF_OPAQUE_AS_LSA:
330
funclist = ospf_opaque_type11_funclist;
333
zlog_warn ("ospf_get_opaque_funclist: Unexpected LSA-type(%u)", lsa_type);
340
ospf_register_opaque_functab (
343
int (* new_if_hook)(struct interface *ifp),
344
int (* del_if_hook)(struct interface *ifp),
345
void (* ism_change_hook)(struct ospf_interface *oi, int old_status),
346
void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status),
347
void (* config_write_router)(struct vty *vty),
348
void (* config_write_if )(struct vty *vty, struct interface *ifp),
349
void (* config_write_debug )(struct vty *vty),
350
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa),
351
int (* lsa_originator)(void *arg),
352
void (* lsa_refresher )(struct ospf_lsa *lsa),
353
int (* new_lsa_hook)(struct ospf_lsa *lsa),
354
int (* del_lsa_hook)(struct ospf_lsa *lsa))
357
struct ospf_opaque_functab *new;
360
if ((funclist = ospf_get_opaque_funclist (lsa_type)) == NULL)
362
zlog_warn ("ospf_register_opaque_functab: Cannot get funclist for Type-%u LSAs?", lsa_type);
368
struct ospf_opaque_functab *functab;
370
for (node = listhead (funclist); node; nextnode (node))
371
if ((functab = getdata (node)) != NULL)
372
if (functab->opaque_type == opaque_type)
374
zlog_warn ("ospf_register_opaque_functab: Duplicated entry?: lsa_type(%u), opaque_type(%u)", lsa_type, opaque_type);
379
if ((new = XCALLOC (MTYPE_OSPF_OPAQUE_FUNCTAB,
380
sizeof (struct ospf_opaque_functab))) == NULL)
382
zlog_warn ("ospf_register_opaque_functab: XMALLOC: %s", strerror (errno));
386
new->opaque_type = opaque_type;
388
new->new_if_hook = new_if_hook;
389
new->del_if_hook = del_if_hook;
390
new->ism_change_hook = ism_change_hook;
391
new->nsm_change_hook = nsm_change_hook;
392
new->config_write_router = config_write_router;
393
new->config_write_if = config_write_if;
394
new->config_write_debug = config_write_debug;
395
new->show_opaque_info = show_opaque_info;
396
new->lsa_originator = lsa_originator;
397
new->lsa_refresher = lsa_refresher;
398
new->new_lsa_hook = new_lsa_hook;
399
new->del_lsa_hook = del_lsa_hook;
401
listnode_add (funclist, new);
409
ospf_delete_opaque_functab (u_char lsa_type, u_char opaque_type)
413
struct ospf_opaque_functab *functab;
415
if ((funclist = ospf_get_opaque_funclist (lsa_type)) != NULL)
416
for (node = listhead (funclist); node; nextnode (node))
418
if ((functab = getdata (node)) != NULL
419
&& functab->opaque_type == opaque_type)
421
/* Cleanup internal control information, if it still remains. */
422
if (functab->oipt != NULL)
423
free_opaque_info_per_type (functab->oipt);
425
/* Dequeue listnode entry from the list. */
426
listnode_delete (funclist, functab);
428
/* Avoid misjudgement in the next lookup. */
429
if (listcount (funclist) == 0)
430
funclist->head = funclist->tail = NULL;
432
XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, functab);
440
static struct ospf_opaque_functab *
441
ospf_opaque_functab_lookup (struct ospf_lsa *lsa)
445
struct ospf_opaque_functab *functab;
446
u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));
448
if ((funclist = ospf_get_opaque_funclist (lsa->data->type)) != NULL)
449
for (node = listhead (funclist); node; nextnode (node))
450
if ((functab = getdata (node)) != NULL)
451
if (functab->opaque_type == key)
457
/*------------------------------------------------------------------------*
458
* Followings are management functions for self-originated LSA entries.
459
*------------------------------------------------------------------------*/
462
* Opaque-LSA control information per opaque-type.
463
* Single Opaque-Type may have multiple instances; each of them will be
464
* identified by their opaque-id.
466
struct opaque_info_per_type
471
enum { PROC_NORMAL, PROC_SUSPEND } status;
474
* Thread for (re-)origination scheduling for this opaque-type.
476
* Initial origination of Opaque-LSAs is controlled by generic
477
* Opaque-LSA handling module so that same opaque-type entries are
478
* called all at once when certain conditions are met.
479
* However, there might be cases that some Opaque-LSA clients need
480
* to (re-)originate their own Opaque-LSAs out-of-sync with others.
481
* This thread is prepared for that specific purpose.
483
struct thread *t_opaque_lsa_self;
486
* Backpointer to an "owner" which is LSA-type dependent.
487
* type-9: struct ospf_interface
488
* type-10: struct ospf_area
489
* type-11: struct ospf
493
/* Collection of callback functions for this opaque-type. */
494
struct ospf_opaque_functab *functab;
496
/* List of Opaque-LSA control informations per opaque-id. */
500
/* Opaque-LSA control information per opaque-id. */
501
struct opaque_info_per_id
505
/* Thread for refresh/flush scheduling for this opaque-type/id. */
506
struct thread *t_opaque_lsa_self;
508
/* Backpointer to Opaque-LSA control information per opaque-type. */
509
struct opaque_info_per_type *opqctl_type;
511
/* Here comes an actual Opaque-LSA entry for this opaque-type/id. */
512
struct ospf_lsa *lsa;
515
static struct opaque_info_per_type *register_opaque_info_per_type (struct ospf_opaque_functab *functab, struct ospf_lsa *new);
516
static struct opaque_info_per_type *lookup_opaque_info_by_type (struct ospf_lsa *lsa);
517
static struct opaque_info_per_id *register_opaque_info_per_id (struct opaque_info_per_type *oipt, struct ospf_lsa *new);
518
static struct opaque_info_per_id *lookup_opaque_info_by_id (struct opaque_info_per_type *oipt, struct ospf_lsa *lsa);
519
static struct opaque_info_per_id *register_opaque_lsa (struct ospf_lsa *new);
522
static struct opaque_info_per_type *
523
register_opaque_info_per_type (struct ospf_opaque_functab *functab,
524
struct ospf_lsa *new)
527
struct opaque_info_per_type *oipt;
529
if ((oipt = XCALLOC (MTYPE_OPAQUE_INFO_PER_TYPE,
530
sizeof (struct opaque_info_per_type))) == NULL)
532
zlog_warn ("register_opaque_info_per_type: XMALLOC: %s", strerror (errno));
536
switch (new->data->type)
538
case OSPF_OPAQUE_LINK_LSA:
539
oipt->owner = new->oi;
540
listnode_add (new->oi->opaque_lsa_self, oipt);
542
case OSPF_OPAQUE_AREA_LSA:
543
oipt->owner = new->area;
544
listnode_add (new->area->opaque_lsa_self, oipt);
546
case OSPF_OPAQUE_AS_LSA:
547
top = ospf_lookup ();
548
if (new->area != NULL && (top = new->area->ospf) == NULL)
550
free_opaque_info_per_type ((void *) oipt);
552
goto out; /* This case may not exist. */
555
listnode_add (top->opaque_lsa_self, oipt);
558
zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type);
559
free_opaque_info_per_type ((void *) oipt);
561
goto out; /* This case may not exist. */
564
oipt->lsa_type = new->data->type;
565
oipt->opaque_type = GET_OPAQUE_TYPE (ntohl (new->data->id.s_addr));
566
oipt->status = PROC_NORMAL;
567
oipt->t_opaque_lsa_self = NULL;
568
oipt->functab = functab;
569
functab->oipt = oipt;
570
oipt->id_list = list_new ();
571
oipt->id_list->del = free_opaque_info_per_id;
578
free_opaque_info_per_type (void *val)
580
struct opaque_info_per_type *oipt = (struct opaque_info_per_type *) val;
581
struct opaque_info_per_id *oipi;
582
struct ospf_lsa *lsa;
585
/* Control information per opaque-id may still exist. */
586
for (node = listhead (oipt->id_list); node; nextnode (node))
588
if ((oipi = getdata (node)) == NULL)
590
if ((lsa = oipi->lsa) == NULL)
592
if (IS_LSA_MAXAGE (lsa))
594
ospf_opaque_lsa_flush_schedule (lsa);
597
/* Remove "oipt" from its owner's self-originated LSA list. */
598
switch (oipt->lsa_type)
600
case OSPF_OPAQUE_LINK_LSA:
602
struct ospf_interface *oi = (struct ospf_interface *)(oipt->owner);
603
listnode_delete (oi->opaque_lsa_self, oipt);
606
case OSPF_OPAQUE_AREA_LSA:
608
struct ospf_area *area = (struct ospf_area *)(oipt->owner);
609
listnode_delete (area->opaque_lsa_self, oipt);
612
case OSPF_OPAQUE_AS_LSA:
614
struct ospf *top = (struct ospf *)(oipt->owner);
615
listnode_delete (top->opaque_lsa_self, oipt);
619
zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt->lsa_type);
620
break; /* This case may not exist. */
623
OSPF_TIMER_OFF (oipt->t_opaque_lsa_self);
624
list_delete (oipt->id_list);
625
XFREE (MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
629
static struct opaque_info_per_type *
630
lookup_opaque_info_by_type (struct ospf_lsa *lsa)
633
struct ospf_area *area;
634
struct ospf_interface *oi;
637
struct opaque_info_per_type *oipt = NULL;
638
u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));
640
switch (lsa->data->type)
642
case OSPF_OPAQUE_LINK_LSA:
643
if ((oi = lsa->oi) != NULL)
644
listtop = oi->opaque_lsa_self;
646
zlog_warn ("Type-9 Opaque-LSA: Reference to OI is missing?");
648
case OSPF_OPAQUE_AREA_LSA:
649
if ((area = lsa->area) != NULL)
650
listtop = area->opaque_lsa_self;
652
zlog_warn ("Type-10 Opaque-LSA: Reference to AREA is missing?");
654
case OSPF_OPAQUE_AS_LSA:
655
top = ospf_lookup ();
656
if ((area = lsa->area) != NULL && (top = area->ospf) == NULL)
658
zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?");
659
break; /* Unlikely to happen. */
661
listtop = top->opaque_lsa_self;
664
zlog_warn ("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", lsa->data->type);
669
for (node = listhead (listtop); node; nextnode (node))
670
if ((oipt = getdata (node)) != NULL)
671
if (oipt->opaque_type == key)
677
static struct opaque_info_per_id *
678
register_opaque_info_per_id (struct opaque_info_per_type *oipt,
679
struct ospf_lsa *new)
681
struct opaque_info_per_id *oipi;
683
if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID,
684
sizeof (struct opaque_info_per_id))) == NULL)
686
zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", strerror (errno));
689
oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr));
690
oipi->t_opaque_lsa_self = NULL;
691
oipi->opqctl_type = oipt;
692
oipi->lsa = ospf_lsa_lock (new);
694
listnode_add (oipt->id_list, oipi);
701
free_opaque_info_per_id (void *val)
703
struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val;
705
OSPF_TIMER_OFF (oipi->t_opaque_lsa_self);
706
if (oipi->lsa != NULL)
707
ospf_lsa_unlock (oipi->lsa);
708
XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi);
712
static struct opaque_info_per_id *
713
lookup_opaque_info_by_id (struct opaque_info_per_type *oipt,
714
struct ospf_lsa *lsa)
717
struct opaque_info_per_id *oipi;
718
u_int32_t key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr));
720
for (node = listhead (oipt->id_list); node; nextnode (node))
721
if ((oipi = getdata (node)) != NULL)
722
if (oipi->opaque_id == key)
728
static struct opaque_info_per_id *
729
register_opaque_lsa (struct ospf_lsa *new)
731
struct ospf_opaque_functab *functab;
732
struct opaque_info_per_type *oipt;
733
struct opaque_info_per_id *oipi = NULL;
735
if ((functab = ospf_opaque_functab_lookup (new)) == NULL)
738
if ((oipt = lookup_opaque_info_by_type (new)) == NULL
739
&& (oipt = register_opaque_info_per_type (functab, new)) == NULL)
742
if ((oipi = register_opaque_info_per_id (oipt, new)) == NULL)
749
/*------------------------------------------------------------------------*
750
* Followings are (vty) configuration functions for Opaque-LSAs handling.
751
*------------------------------------------------------------------------*/
753
DEFUN (capability_opaque,
754
capability_opaque_cmd,
756
"Enable specific OSPF feature\n"
759
struct ospf *ospf = (struct ospf *) vty->index;
761
/* Turn on the "master switch" of opaque-lsa capability. */
762
if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
764
if (IS_DEBUG_OSPF_EVENT)
765
zlog_info ("Opaque capability: OFF -> ON");
767
SET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);
768
ospf_renegotiate_optional_capabilities (ospf);
773
ALIAS (capability_opaque,
774
ospf_opaque_capable_cmd,
776
"OSPF specific commands\n"
777
"Enable the Opaque-LSA capability (rfc2370)\n")
779
DEFUN (no_capability_opaque,
780
no_capability_opaque_cmd,
781
"no capability opaque",
783
"Enable specific OSPF feature\n"
786
struct ospf *ospf = (struct ospf *) vty->index;
788
/* Turn off the "master switch" of opaque-lsa capability. */
789
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
791
if (IS_DEBUG_OSPF_EVENT)
792
zlog_info ("Opaque capability: ON -> OFF");
794
UNSET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);
795
ospf_renegotiate_optional_capabilities (ospf);
800
ALIAS (no_capability_opaque,
801
no_ospf_opaque_capable_cmd,
802
"no ospf opaque-lsa",
804
"OSPF specific commands\n"
805
"Disable the Opaque-LSA capability (rfc2370)\n")
808
ospf_opaque_register_vty (void)
810
install_element (OSPF_NODE, &capability_opaque_cmd);
811
install_element (OSPF_NODE, &no_capability_opaque_cmd);
812
install_element (OSPF_NODE, &ospf_opaque_capable_cmd);
813
install_element (OSPF_NODE, &no_ospf_opaque_capable_cmd);
817
/*------------------------------------------------------------------------*
818
* Followings are collection of user-registered function callers.
819
*------------------------------------------------------------------------*/
822
opaque_lsa_new_if_callback (list funclist, struct interface *ifp)
825
struct ospf_opaque_functab *functab;
828
for (node = listhead (funclist); node; nextnode (node))
829
if ((functab = getdata (node)) != NULL)
830
if (functab->new_if_hook != NULL)
831
if ((* functab->new_if_hook)(ifp) != 0)
839
opaque_lsa_del_if_callback (list funclist, struct interface *ifp)
842
struct ospf_opaque_functab *functab;
845
for (node = listhead (funclist); node; nextnode (node))
846
if ((functab = getdata (node)) != NULL)
847
if (functab->del_if_hook != NULL)
848
if ((* functab->del_if_hook)(ifp) != 0)
856
opaque_lsa_ism_change_callback (list funclist,
857
struct ospf_interface *oi, int old_status)
860
struct ospf_opaque_functab *functab;
862
for (node = listhead (funclist); node; nextnode (node))
863
if ((functab = getdata (node)) != NULL)
864
if (functab->ism_change_hook != NULL)
865
(* functab->ism_change_hook)(oi, old_status);
870
opaque_lsa_nsm_change_callback (list funclist,
871
struct ospf_neighbor *nbr, int old_status)
874
struct ospf_opaque_functab *functab;
876
for (node = listhead (funclist); node; nextnode (node))
877
if ((functab = getdata (node)) != NULL)
878
if (functab->nsm_change_hook != NULL)
879
(* functab->nsm_change_hook)(nbr, old_status);
884
opaque_lsa_config_write_router_callback (list funclist, struct vty *vty)
887
struct ospf_opaque_functab *functab;
889
for (node = listhead (funclist); node; nextnode (node))
890
if ((functab = getdata (node)) != NULL)
891
if (functab->config_write_router != NULL)
892
(* functab->config_write_router)(vty);
897
opaque_lsa_config_write_if_callback (list funclist,
898
struct vty *vty, struct interface *ifp)
901
struct ospf_opaque_functab *functab;
903
for (node = listhead (funclist); node; nextnode (node))
904
if ((functab = getdata (node)) != NULL)
905
if (functab->config_write_if != NULL)
906
(* functab->config_write_if)(vty, ifp);
911
opaque_lsa_config_write_debug_callback (list funclist, struct vty *vty)
914
struct ospf_opaque_functab *functab;
916
for (node = listhead (funclist); node; nextnode (node))
917
if ((functab = getdata (node)) != NULL)
918
if (functab->config_write_debug != NULL)
919
(* functab->config_write_debug)(vty);
924
opaque_lsa_originate_callback (list funclist, void *lsa_type_dependent)
927
struct ospf_opaque_functab *functab;
930
for (node = listhead (funclist); node; nextnode (node))
931
if ((functab = getdata (node)) != NULL)
932
if (functab->lsa_originator != NULL)
933
if ((* functab->lsa_originator)(lsa_type_dependent) != 0)
941
new_lsa_callback (list funclist, struct ospf_lsa *lsa)
944
struct ospf_opaque_functab *functab;
947
/* This function handles ALL types of LSAs, not only opaque ones. */
948
for (node = listhead (funclist); node; nextnode (node))
949
if ((functab = getdata (node)) != NULL)
950
if (functab->new_lsa_hook != NULL)
951
if ((* functab->new_lsa_hook)(lsa) != 0)
959
del_lsa_callback (list funclist, struct ospf_lsa *lsa)
962
struct ospf_opaque_functab *functab;
965
/* This function handles ALL types of LSAs, not only opaque ones. */
966
for (node = listhead (funclist); node; nextnode (node))
967
if ((functab = getdata (node)) != NULL)
968
if (functab->del_lsa_hook != NULL)
969
if ((* functab->del_lsa_hook)(lsa) != 0)
976
/*------------------------------------------------------------------------*
977
* Followings are glue functions to call Opaque-LSA specific processing.
978
*------------------------------------------------------------------------*/
981
ospf_opaque_new_if (struct interface *ifp)
986
funclist = ospf_opaque_wildcard_funclist;
987
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
990
funclist = ospf_opaque_type9_funclist;
991
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
994
funclist = ospf_opaque_type10_funclist;
995
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
998
funclist = ospf_opaque_type11_funclist;
999
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
1008
ospf_opaque_del_if (struct interface *ifp)
1013
funclist = ospf_opaque_wildcard_funclist;
1014
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
1017
funclist = ospf_opaque_type9_funclist;
1018
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
1021
funclist = ospf_opaque_type10_funclist;
1022
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
1025
funclist = ospf_opaque_type11_funclist;
1026
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
1035
ospf_opaque_ism_change (struct ospf_interface *oi, int old_status)
1039
funclist = ospf_opaque_wildcard_funclist;
1040
opaque_lsa_ism_change_callback (funclist, oi, old_status);
1042
funclist = ospf_opaque_type9_funclist;
1043
opaque_lsa_ism_change_callback (funclist, oi, old_status);
1045
funclist = ospf_opaque_type10_funclist;
1046
opaque_lsa_ism_change_callback (funclist, oi, old_status);
1048
funclist = ospf_opaque_type11_funclist;
1049
opaque_lsa_ism_change_callback (funclist, oi, old_status);
1055
ospf_opaque_nsm_change (struct ospf_neighbor *nbr, int old_state)
1060
if ((top = oi_to_top (nbr->oi)) == NULL)
1063
if (old_state != NSM_Full && nbr->state == NSM_Full)
1065
if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1067
if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
1069
if (IS_DEBUG_OSPF_EVENT)
1070
zlog_info ("Opaque-LSA: Now get operational!");
1072
SET_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT);
1075
ospf_opaque_lsa_originate_schedule (nbr->oi, NULL);
1079
if (old_state == NSM_Full && nbr->state != NSM_Full)
1083
* If no more opaque-capable full-state neighbor remains in the
1084
* flooding scope which corresponds to Opaque-LSA type, periodic
1085
* LS flooding should be stopped.
1091
funclist = ospf_opaque_wildcard_funclist;
1092
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
1094
funclist = ospf_opaque_type9_funclist;
1095
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
1097
funclist = ospf_opaque_type10_funclist;
1098
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
1100
funclist = ospf_opaque_type11_funclist;
1101
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
1108
ospf_opaque_config_write_router (struct vty *vty, struct ospf *ospf)
1112
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
1113
vty_out (vty, " capability opaque%s", VTY_NEWLINE);
1115
funclist = ospf_opaque_wildcard_funclist;
1116
opaque_lsa_config_write_router_callback (funclist, vty);
1118
funclist = ospf_opaque_type9_funclist;
1119
opaque_lsa_config_write_router_callback (funclist, vty);
1121
funclist = ospf_opaque_type10_funclist;
1122
opaque_lsa_config_write_router_callback (funclist, vty);
1124
funclist = ospf_opaque_type11_funclist;
1125
opaque_lsa_config_write_router_callback (funclist, vty);
1131
ospf_opaque_config_write_if (struct vty *vty, struct interface *ifp)
1135
funclist = ospf_opaque_wildcard_funclist;
1136
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
1138
funclist = ospf_opaque_type9_funclist;
1139
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
1141
funclist = ospf_opaque_type10_funclist;
1142
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
1144
funclist = ospf_opaque_type11_funclist;
1145
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
1151
ospf_opaque_config_write_debug (struct vty *vty)
1155
funclist = ospf_opaque_wildcard_funclist;
1156
opaque_lsa_config_write_debug_callback (funclist, vty);
1158
funclist = ospf_opaque_type9_funclist;
1159
opaque_lsa_config_write_debug_callback (funclist, vty);
1161
funclist = ospf_opaque_type10_funclist;
1162
opaque_lsa_config_write_debug_callback (funclist, vty);
1164
funclist = ospf_opaque_type11_funclist;
1165
opaque_lsa_config_write_debug_callback (funclist, vty);
1171
show_opaque_info_detail (struct vty *vty, struct ospf_lsa *lsa)
1173
struct lsa_header *lsah = (struct lsa_header *) lsa->data;
1174
u_int32_t lsid = ntohl (lsah->id.s_addr);
1175
u_char opaque_type = GET_OPAQUE_TYPE (lsid);
1176
u_int32_t opaque_id = GET_OPAQUE_ID (lsid);
1177
struct ospf_opaque_functab *functab;
1179
/* Switch output functionality by vty address. */
1182
vty_out (vty, " Opaque-Type %u (%s)%s", opaque_type,
1183
ospf_opaque_type_name (opaque_type), VTY_NEWLINE);
1184
vty_out (vty, " Opaque-ID 0x%x%s", opaque_id, VTY_NEWLINE);
1186
vty_out (vty, " Opaque-Info: %u octets of data%s%s",
1187
ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE,
1188
VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)",
1193
zlog_info (" Opaque-Type %u (%s)", opaque_type,
1194
ospf_opaque_type_name (opaque_type));
1195
zlog_info (" Opaque-ID 0x%x", opaque_id);
1197
zlog_info (" Opaque-Info: %u octets of data%s",
1198
ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE,
1199
VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)");
1202
/* Call individual output functions. */
1203
if ((functab = ospf_opaque_functab_lookup (lsa)) != NULL)
1204
if (functab->show_opaque_info != NULL)
1205
(* functab->show_opaque_info)(vty, lsa);
1211
ospf_opaque_lsa_dump (struct stream *s, u_int16_t length)
1213
struct ospf_lsa lsa;
1215
lsa.data = (struct lsa_header *) STREAM_PNT (s);
1216
show_opaque_info_detail (NULL, &lsa);
1221
ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa)
1227
* Some Opaque-LSA user may want to monitor every LSA installation
1228
* into the LSDB, regardless with target LSA type.
1230
funclist = ospf_opaque_wildcard_funclist;
1231
if (new_lsa_callback (funclist, lsa) != 0)
1234
funclist = ospf_opaque_type9_funclist;
1235
if (new_lsa_callback (funclist, lsa) != 0)
1238
funclist = ospf_opaque_type10_funclist;
1239
if (new_lsa_callback (funclist, lsa) != 0)
1242
funclist = ospf_opaque_type11_funclist;
1243
if (new_lsa_callback (funclist, lsa) != 0)
1252
ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa)
1258
* Some Opaque-LSA user may want to monitor every LSA deletion
1259
* from the LSDB, regardless with target LSA type.
1261
funclist = ospf_opaque_wildcard_funclist;
1262
if (del_lsa_callback (funclist, lsa) != 0)
1265
funclist = ospf_opaque_type9_funclist;
1266
if (del_lsa_callback (funclist, lsa) != 0)
1269
funclist = ospf_opaque_type10_funclist;
1270
if (del_lsa_callback (funclist, lsa) != 0)
1273
funclist = ospf_opaque_type11_funclist;
1274
if (del_lsa_callback (funclist, lsa) != 0)
1282
/*------------------------------------------------------------------------*
1283
* Followings are Opaque-LSA origination/refresh management functions.
1284
*------------------------------------------------------------------------*/
1286
static int ospf_opaque_type9_lsa_originate (struct thread *t);
1287
static int ospf_opaque_type10_lsa_originate (struct thread *t);
1288
static int ospf_opaque_type11_lsa_originate (struct thread *t);
1289
static void ospf_opaque_lsa_reoriginate_resume (list listtop, void *arg);
1292
ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0)
1295
struct ospf_area *area;
1297
struct opaque_info_per_type *oipt;
1300
if ((top = oi_to_top (oi)) == NULL || (area = oi->area) == NULL)
1302
zlog_warn ("ospf_opaque_lsa_originate_schedule: Invalid argument?");
1306
/* It may not a right time to schedule origination now. */
1307
if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
1309
if (IS_DEBUG_OSPF_EVENT)
1310
zlog_info ("ospf_opaque_lsa_originate_schedule: Not operational.");
1311
goto out; /* This is not an error. */
1313
if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
1315
if (IS_DEBUG_OSPF_EVENT)
1316
zlog_info ("ospf_opaque_lsa_originate_schedule: Under blockade.");
1317
goto out; /* This is not an error, too. */
1324
* There might be some entries that have been waiting for triggering
1325
* of per opaque-type re-origination get resumed.
1327
ospf_opaque_lsa_reoriginate_resume ( oi->opaque_lsa_self, (void *) oi);
1328
ospf_opaque_lsa_reoriginate_resume (area->opaque_lsa_self, (void *) area);
1329
ospf_opaque_lsa_reoriginate_resume ( top->opaque_lsa_self, (void *) top);
1332
* Now, schedule origination of all Opaque-LSAs per opaque-type.
1334
if (! list_isempty (ospf_opaque_type9_funclist)
1335
&& list_isempty (oi->opaque_lsa_self)
1336
&& oi->t_opaque_lsa_self == NULL)
1338
if (IS_DEBUG_OSPF_EVENT)
1339
zlog_info ("Schedule Type-9 Opaque-LSA origination in %d sec later.", delay);
1340
oi->t_opaque_lsa_self =
1341
thread_add_timer (master, ospf_opaque_type9_lsa_originate, oi, delay);
1342
delay += OSPF_MIN_LS_INTERVAL;
1345
if (! list_isempty (ospf_opaque_type10_funclist)
1346
&& list_isempty (area->opaque_lsa_self)
1347
&& area->t_opaque_lsa_self == NULL)
1350
* One AREA may contain multiple OIs, but above 2nd and 3rd
1351
* conditions prevent from scheduling the originate function
1354
if (IS_DEBUG_OSPF_EVENT)
1355
zlog_info ("Schedule Type-10 Opaque-LSA origination in %d sec later.", delay);
1356
area->t_opaque_lsa_self =
1357
thread_add_timer (master, ospf_opaque_type10_lsa_originate,
1359
delay += OSPF_MIN_LS_INTERVAL;
1362
if (! list_isempty (ospf_opaque_type11_funclist)
1363
&& list_isempty (top->opaque_lsa_self)
1364
&& top->t_opaque_lsa_self == NULL)
1367
* One OSPF may contain multiple AREAs, but above 2nd and 3rd
1368
* conditions prevent from scheduling the originate function
1371
if (IS_DEBUG_OSPF_EVENT)
1372
zlog_info ("Schedule Type-11 Opaque-LSA origination in %d sec later.", delay);
1373
top->t_opaque_lsa_self =
1374
thread_add_timer (master, ospf_opaque_type11_lsa_originate,
1376
delay += OSPF_MIN_LS_INTERVAL;
1380
* Following section treats a special situation that this node's
1381
* opaque capability has changed as "ON -> OFF -> ON".
1383
if (! list_isempty (ospf_opaque_type9_funclist)
1384
&& ! list_isempty (oi->opaque_lsa_self))
1386
for (node = listhead (oi->opaque_lsa_self); node; nextnode (node))
1389
* removed the test for
1390
* (! list_isempty (oipt->id_list)) * Handler is already active. *
1391
* because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
1394
if ((oipt = getdata (node)) == NULL /* Something wrong? */
1395
|| oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
1396
|| oipt->status == PROC_SUSPEND) /* Cannot originate now. */
1399
ospf_opaque_lsa_reoriginate_schedule ((void *) oi,
1400
OSPF_OPAQUE_LINK_LSA, oipt->opaque_type);
1404
if (! list_isempty (ospf_opaque_type10_funclist)
1405
&& ! list_isempty (area->opaque_lsa_self))
1407
for (node = listhead (area->opaque_lsa_self); node; nextnode (node))
1410
* removed the test for
1411
* (! list_isempty (oipt->id_list)) * Handler is already active. *
1412
* because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
1415
if ((oipt = getdata (node)) == NULL /* Something wrong? */
1416
|| oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
1417
|| oipt->status == PROC_SUSPEND) /* Cannot originate now. */
1420
ospf_opaque_lsa_reoriginate_schedule ((void *) area,
1421
OSPF_OPAQUE_AREA_LSA, oipt->opaque_type);
1425
if (! list_isempty (ospf_opaque_type11_funclist)
1426
&& ! list_isempty (top->opaque_lsa_self))
1428
for (node = listhead (top->opaque_lsa_self); node; nextnode (node))
1431
* removed the test for
1432
* (! list_isempty (oipt->id_list)) * Handler is already active. *
1433
* because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
1436
if ((oipt = getdata (node)) == NULL /* Something wrong? */
1437
|| oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
1438
|| oipt->status == PROC_SUSPEND) /* Cannot originate now. */
1441
ospf_opaque_lsa_reoriginate_schedule ((void *) top,
1442
OSPF_OPAQUE_AS_LSA, oipt->opaque_type);
1454
ospf_opaque_type9_lsa_originate (struct thread *t)
1456
struct ospf_interface *oi;
1459
oi = THREAD_ARG (t);
1460
oi->t_opaque_lsa_self = NULL;
1462
if (IS_DEBUG_OSPF_EVENT)
1463
zlog_info ("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s",
1466
rc = opaque_lsa_originate_callback (ospf_opaque_type9_funclist, oi);
1472
ospf_opaque_type10_lsa_originate (struct thread *t)
1474
struct ospf_area *area;
1477
area = THREAD_ARG (t);
1478
area->t_opaque_lsa_self = NULL;
1480
if (IS_DEBUG_OSPF_EVENT)
1481
zlog_info ("Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s",
1482
inet_ntoa (area->area_id));
1484
rc = opaque_lsa_originate_callback (ospf_opaque_type10_funclist, area);
1490
ospf_opaque_type11_lsa_originate (struct thread *t)
1495
top = THREAD_ARG (t);
1496
top->t_opaque_lsa_self = NULL;
1498
if (IS_DEBUG_OSPF_EVENT)
1499
zlog_info ("Timer[Type11-LSA]: Originate AS-External Opaque-LSAs");
1501
rc = opaque_lsa_originate_callback (ospf_opaque_type11_funclist, top);
1507
ospf_opaque_lsa_reoriginate_resume (list listtop, void *arg)
1510
struct opaque_info_per_type *oipt;
1511
struct ospf_opaque_functab *functab;
1513
if (listtop == NULL)
1517
* Pickup oipt entries those which in SUSPEND status, and give
1518
* them a chance to start re-origination now.
1520
for (node = listhead (listtop); node; nextnode (node))
1522
if ((oipt = getdata (node)) == NULL
1523
|| oipt->status != PROC_SUSPEND)
1526
oipt->status = PROC_NORMAL;
1528
if ((functab = oipt->functab) == NULL
1529
|| functab->lsa_originator == NULL)
1532
if ((* functab->lsa_originator)(arg) != 0)
1534
zlog_warn ("ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", oipt->opaque_type);
1544
ospf_opaque_lsa_install (struct ospf_lsa *lsa, int rt_recalc)
1546
struct ospf_lsa *new = NULL;
1547
struct opaque_info_per_type *oipt;
1548
struct opaque_info_per_id *oipi;
1551
/* Don't take "rt_recalc" into consideration for now. *//* XXX */
1553
if (! IS_LSA_SELF (lsa))
1555
new = lsa; /* Don't touch this LSA. */
1559
if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
1560
zlog_info ("Install Type-%u Opaque-LSA: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
1562
/* Replace the existing lsa with the new one. */
1563
if ((oipt = lookup_opaque_info_by_type (lsa)) != NULL
1564
&& (oipi = lookup_opaque_info_by_id (oipt, lsa)) != NULL)
1566
ospf_lsa_unlock (oipi->lsa);
1567
oipi->lsa = ospf_lsa_lock (lsa);
1569
/* Register the new lsa entry and get its control info. */
1571
if ((oipi = register_opaque_lsa (lsa)) == NULL)
1573
zlog_warn ("ospf_opaque_lsa_install: register_opaque_lsa() ?");
1578
* Make use of a common mechanism (ospf_lsa_refresh_walker)
1579
* for periodic refresh of self-originated Opaque-LSAs.
1581
switch (lsa->data->type)
1583
case OSPF_OPAQUE_LINK_LSA:
1584
if ((top = oi_to_top (lsa->oi)) == NULL)
1586
/* Above conditions must have passed. */
1587
zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
1591
case OSPF_OPAQUE_AREA_LSA:
1592
if (lsa->area == NULL || (top = lsa->area->ospf) == NULL)
1594
/* Above conditions must have passed. */
1595
zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
1599
case OSPF_OPAQUE_AS_LSA:
1600
top = ospf_lookup ();
1601
if (lsa->area != NULL && (top = lsa->area->ospf) == NULL)
1603
/* Above conditions must have passed. */
1604
zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
1609
zlog_warn ("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", lsa->data->type);
1613
ospf_refresher_register_lsa (top, lsa);
1621
ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
1624
struct ospf_opaque_functab *functab;
1626
ospf = ospf_lookup ();
1628
if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL
1629
|| functab->lsa_refresher == NULL)
1632
* Though this LSA seems to have originated on this node, the
1633
* handling module for this "lsa-type and opaque-type" was
1634
* already deleted sometime ago.
1635
* Anyway, this node still has a responsibility to flush this
1636
* LSA from the routing domain.
1638
if (IS_DEBUG_OSPF_EVENT)
1639
zlog_info ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));
1641
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
1642
ospf_lsa_maxage (ospf, lsa);
1645
(* functab->lsa_refresher)(lsa);
1650
/*------------------------------------------------------------------------*
1651
* Followings are re-origination/refresh/flush operations of Opaque-LSAs,
1652
* triggered by external interventions (vty session, signaling, etc).
1653
*------------------------------------------------------------------------*/
1655
#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \
1657
(T) = thread_add_timer (master, (F), (L), (V))
1659
static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type);
1660
static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t);
1661
static int ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t);
1662
static int ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t);
1663
static int ospf_opaque_lsa_refresh_timer (struct thread *t);
1666
ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,
1667
u_char lsa_type, u_char opaque_type)
1670
struct ospf_area dummy, *area = NULL;
1671
struct ospf_interface *oi = NULL;
1673
struct ospf_lsa *lsa;
1674
struct opaque_info_per_type *oipt;
1675
int (* func)(struct thread *t) = NULL;
1680
case OSPF_OPAQUE_LINK_LSA:
1681
if ((oi = (struct ospf_interface *) lsa_type_dependent) == NULL)
1683
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-9 Opaque-LSA: Invalid parameter?");
1686
if ((top = oi_to_top (oi)) == NULL)
1688
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?", IF_NAME (oi));
1691
if (! list_isempty (ospf_opaque_type9_funclist)
1692
&& list_isempty (oi->opaque_lsa_self)
1693
&& oi->t_opaque_lsa_self != NULL)
1695
zlog_warn ("Type-9 Opaque-LSA (opaque_type=%u): Common origination for OI(%s) has already started", opaque_type, IF_NAME (oi));
1698
func = ospf_opaque_type9_lsa_reoriginate_timer;
1700
case OSPF_OPAQUE_AREA_LSA:
1701
if ((area = (struct ospf_area *) lsa_type_dependent) == NULL)
1703
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-10 Opaque-LSA: Invalid parameter?");
1706
if ((top = area->ospf) == NULL)
1708
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: AREA(%s) -> TOP?", inet_ntoa (area->area_id));
1711
if (! list_isempty (ospf_opaque_type10_funclist)
1712
&& list_isempty (area->opaque_lsa_self)
1713
&& area->t_opaque_lsa_self != NULL)
1715
zlog_warn ("Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%s) has already started", opaque_type, inet_ntoa (area->area_id));
1718
func = ospf_opaque_type10_lsa_reoriginate_timer;
1720
case OSPF_OPAQUE_AS_LSA:
1721
if ((top = (struct ospf *) lsa_type_dependent) == NULL)
1723
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-11 Opaque-LSA: Invalid parameter?");
1726
if (! list_isempty (ospf_opaque_type11_funclist)
1727
&& list_isempty (top->opaque_lsa_self)
1728
&& top->t_opaque_lsa_self != NULL)
1730
zlog_warn ("Type-11 Opaque-LSA (opaque_type=%u): Common origination has already started", opaque_type);
1734
/* Fake "area" to pass "ospf" to a lookup function later. */
1738
func = ospf_opaque_type11_lsa_reoriginate_timer;
1741
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Unexpected LSA-type(%u)", lsa_type);
1745
/* It may not a right time to schedule reorigination now. */
1746
if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
1748
if (IS_DEBUG_OSPF_EVENT)
1749
zlog_info ("ospf_opaque_lsa_reoriginate_schedule: Not operational.");
1750
goto out; /* This is not an error. */
1752
if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
1754
if (IS_DEBUG_OSPF_EVENT)
1755
zlog_info ("ospf_opaque_lsa_reoriginate_schedule: Under blockade.");
1756
goto out; /* This is not an error, too. */
1759
/* Generate a dummy lsa to be passed for a lookup function. */
1760
lsa = pseudo_lsa (oi, area, lsa_type, opaque_type);
1762
if ((oipt = lookup_opaque_info_by_type (lsa)) == NULL)
1764
struct ospf_opaque_functab *functab;
1765
if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL)
1767
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: No associated function?: lsa_type(%u), opaque_type(%u)", lsa_type, opaque_type);
1770
if ((oipt = register_opaque_info_per_type (functab, lsa)) == NULL)
1772
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Cannot get a control info?: lsa_type(%u), opaque_type(%u)", lsa_type, opaque_type);
1777
if (oipt->t_opaque_lsa_self != NULL)
1779
if (IS_DEBUG_OSPF_EVENT)
1780
zlog_info ("Type-%u Opaque-LSA has already scheduled to RE-ORIGINATE: [opaque-type=%u]", lsa_type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));
1785
* Different from initial origination time, in which various conditions
1786
* (opaque capability, neighbor status etc) are assured by caller of
1787
* the originating function "ospf_opaque_lsa_originate_schedule ()",
1788
* it is highly possible that these conditions might not be satisfied
1789
* at the time of re-origination function is to be called.
1791
delay = OSPF_MIN_LS_INTERVAL; /* XXX */
1793
if (IS_DEBUG_OSPF_EVENT)
1794
zlog_info ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d sec later: [opaque-type=%u]", lsa_type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));
1796
OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay);
1802
static struct ospf_lsa *
1803
pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area,
1804
u_char lsa_type, u_char opaque_type)
1806
static struct ospf_lsa lsa = { 0 };
1807
static struct lsa_header lsah = { 0 };
1814
lsah.type = lsa_type;
1815
tmp = SET_OPAQUE_LSID (opaque_type, 0); /* Opaque-ID is unused here. */
1816
lsah.id.s_addr = htonl (tmp);
1822
ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t)
1824
struct opaque_info_per_type *oipt;
1825
struct ospf_opaque_functab *functab;
1827
struct ospf_interface *oi;
1830
oipt = THREAD_ARG (t);
1831
oipt->t_opaque_lsa_self = NULL;
1833
if ((functab = oipt->functab) == NULL
1834
|| functab->lsa_originator == NULL)
1836
zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: No associated function?");
1840
oi = (struct ospf_interface *) oipt->owner;
1841
if ((top = oi_to_top (oi)) == NULL)
1843
zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?");
1847
if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)
1848
|| ! ospf_if_is_enable (oi)
1849
|| ospf_nbr_count_opaque_capable (oi) == 0)
1851
if (IS_DEBUG_OSPF_EVENT)
1852
zlog_info ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
1854
oipt->status = PROC_SUSPEND;
1859
if (IS_DEBUG_OSPF_EVENT)
1860
zlog_info ("Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", oipt->opaque_type, IF_NAME (oi));
1862
rc = (* functab->lsa_originator)(oi);
1868
ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t)
1870
struct opaque_info_per_type *oipt;
1871
struct ospf_opaque_functab *functab;
1874
struct ospf_area *area;
1875
struct ospf_interface *oi;
1878
oipt = THREAD_ARG (t);
1879
oipt->t_opaque_lsa_self = NULL;
1881
if ((functab = oipt->functab) == NULL
1882
|| functab->lsa_originator == NULL)
1884
zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: No associated function?");
1888
area = (struct ospf_area *) oipt->owner;
1889
if (area == NULL || (top = area->ospf) == NULL)
1891
zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");
1895
/* There must be at least one "opaque-capable, full-state" neighbor. */
1897
for (node = listhead (area->oiflist); node; nextnode (node))
1899
if ((oi = getdata (node)) == NULL)
1901
if ((n = ospf_nbr_count_opaque_capable (oi)) > 0)
1905
if (n == 0 || ! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
1907
if (IS_DEBUG_OSPF_EVENT)
1908
zlog_info ("Suspend re-origination of Type-10 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
1910
oipt->status = PROC_SUSPEND;
1915
if (IS_DEBUG_OSPF_EVENT)
1916
zlog_info ("Timer[Type10-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for Area %s", oipt->opaque_type, inet_ntoa (area->area_id));
1918
rc = (* functab->lsa_originator)(area);
1924
ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t)
1926
struct opaque_info_per_type *oipt;
1927
struct ospf_opaque_functab *functab;
1931
oipt = THREAD_ARG (t);
1932
oipt->t_opaque_lsa_self = NULL;
1934
if ((functab = oipt->functab) == NULL
1935
|| functab->lsa_originator == NULL)
1937
zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: No associated function?");
1941
if ((top = (struct ospf *) oipt->owner) == NULL)
1943
zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?");
1947
if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
1949
if (IS_DEBUG_OSPF_EVENT)
1950
zlog_info ("Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
1952
oipt->status = PROC_SUSPEND;
1957
if (IS_DEBUG_OSPF_EVENT)
1958
zlog_info ("Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", oipt->opaque_type);
1960
rc = (* functab->lsa_originator)(top);
1965
extern int ospf_lsa_refresh_delay (struct ospf_lsa *); /* ospf_lsa.c */
1968
ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
1970
struct ospf *ospf = ospf;
1971
struct opaque_info_per_type *oipt;
1972
struct opaque_info_per_id *oipi;
1973
struct ospf_lsa *lsa;
1976
ospf = ospf_lookup ();
1978
if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
1979
|| (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
1981
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Invalid parameter?");
1985
/* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
1986
if ((lsa = oipi->lsa) == NULL)
1988
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Something wrong?");
1992
if (oipi->t_opaque_lsa_self != NULL)
1994
if (IS_DEBUG_OSPF_EVENT)
1995
zlog_info ("Type-%u Opaque-LSA has already scheduled to REFRESH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
1999
/* Delete this lsa from neighbor retransmit-list. */
2000
switch (lsa->data->type)
2002
case OSPF_OPAQUE_LINK_LSA:
2003
case OSPF_OPAQUE_AREA_LSA:
2004
ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
2006
case OSPF_OPAQUE_AS_LSA:
2007
ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
2010
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);
2014
delay = ospf_lsa_refresh_delay (lsa);
2016
if (IS_DEBUG_OSPF_EVENT)
2017
zlog_info ("Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", lsa->data->type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
2019
OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self,
2020
ospf_opaque_lsa_refresh_timer, oipi, delay);
2026
ospf_opaque_lsa_refresh_timer (struct thread *t)
2028
struct opaque_info_per_id *oipi;
2029
struct ospf_opaque_functab *functab;
2030
struct ospf_lsa *lsa;
2032
if (IS_DEBUG_OSPF_EVENT)
2033
zlog_info ("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)");
2035
oipi = THREAD_ARG (t);
2036
oipi->t_opaque_lsa_self = NULL;
2038
if ((lsa = oipi->lsa) != NULL)
2039
if ((functab = oipi->opqctl_type->functab) != NULL)
2040
if (functab->lsa_refresher != NULL)
2041
(* functab->lsa_refresher)(lsa);
2047
ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
2049
struct ospf *ospf = ospf;
2050
struct opaque_info_per_type *oipt;
2051
struct opaque_info_per_id *oipi;
2052
struct ospf_lsa *lsa;
2054
ospf = ospf_lookup ();
2056
if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
2057
|| (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
2059
zlog_warn ("ospf_opaque_lsa_flush_schedule: Invalid parameter?");
2063
/* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
2064
if ((lsa = oipi->lsa) == NULL)
2066
zlog_warn ("ospf_opaque_lsa_flush_schedule: Something wrong?");
2070
/* Delete this lsa from neighbor retransmit-list. */
2071
switch (lsa->data->type)
2073
case OSPF_OPAQUE_LINK_LSA:
2074
case OSPF_OPAQUE_AREA_LSA:
2075
ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
2077
case OSPF_OPAQUE_AS_LSA:
2078
ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
2081
zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);
2085
/* Dequeue listnode entry from the list. */
2086
listnode_delete (oipt->id_list, oipi);
2088
/* Avoid misjudgement in the next lookup. */
2089
if (listcount (oipt->id_list) == 0)
2090
oipt->id_list->head = oipt->id_list->tail = NULL;
2092
/* Disassociate internal control information with the given lsa. */
2094
free_opaque_info_per_id ((void *) oipi);
2096
/* Force given lsa's age to MaxAge. */
2097
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2099
if (IS_DEBUG_OSPF_EVENT)
2100
zlog_info ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
2102
/* This lsa will be flushed and removed eventually. */
2103
ospf_lsa_maxage (ospf, lsa);
2109
/*------------------------------------------------------------------------*
2110
* Followings are control functions to block origination after restart.
2111
*------------------------------------------------------------------------*/
2113
static void ospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs, struct ospf_neighbor *inbr, struct ospf_lsa *lsa);
2114
static void ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi);
2115
static void ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area);
2116
static void ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top);
2117
static unsigned long ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type);
2120
ospf_opaque_adjust_lsreq (struct ospf_neighbor *nbr, list lsas)
2123
struct ospf_area *area;
2124
struct ospf_interface *oi;
2125
listnode node1, node2;
2126
struct ospf_lsa *lsa;
2128
if ((top = oi_to_top (nbr->oi)) == NULL)
2132
* If an instance of self-originated Opaque-LSA is found in the given
2133
* LSA list, and it is not installed to LSDB yet, exclude it from the
2134
* list "nbr->ls_req". In this way, it is assured that an LSReq message,
2135
* which might be sent in the process of flooding, will not request for
2136
* the LSA to be flushed immediately; otherwise, depending on timing,
2137
* an LSUpd message will carry instances of target LSAs with MaxAge,
2138
* while other LSUpd message might carry old LSA instances (non-MaxAge).
2139
* Obviously, the latter would trigger miserable situations that repeat
2140
* installation and removal of unwanted LSAs indefinitely.
2142
for (node1 = listhead (lsas); node1; nextnode (node1))
2144
if ((lsa = getdata (node1)) == NULL)
2147
/* Filter out unwanted LSAs. */
2148
if (! IS_OPAQUE_LSA (lsa->data->type))
2150
if (! IPV4_ADDR_SAME (&lsa->data->adv_router, &top->router_id))
2154
* Don't touch an LSA which has MaxAge; two possible cases.
2156
* 1) This LSA has originally flushed by myself (received LSUpd
2157
* message's router-id is equal to my router-id), and flooded
2158
* back by an opaque-capable router.
2160
* 2) This LSA has expired in an opaque-capable router and thus
2161
* flushed by the router.
2163
if (IS_LSA_MAXAGE (lsa))
2166
/* If the LSA has installed in the LSDB, nothing to do here. */
2167
if (ospf_lsa_lookup_by_header (nbr->oi->area, lsa->data) != NULL)
2170
/* Ok, here we go. */
2171
switch (lsa->data->type)
2173
case OSPF_OPAQUE_LINK_LSA:
2175
ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);
2177
case OSPF_OPAQUE_AREA_LSA:
2178
area = nbr->oi->area;
2179
for (node2 = listhead (area->oiflist); node2; nextnode (node2))
2181
if ((oi = getdata (node2)) == NULL)
2183
ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);
2186
case OSPF_OPAQUE_AS_LSA:
2187
for (node2 = listhead (top->oiflist); node2; nextnode (node2))
2189
if ((oi = getdata (node2)) == NULL)
2191
ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);
2204
ospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs,
2205
struct ospf_neighbor *inbr,
2206
struct ospf_lsa *lsa)
2208
struct route_node *rn;
2209
struct ospf_neighbor *onbr;
2210
struct ospf_lsa *ls_req;
2212
for (rn = route_top (nbrs); rn; rn = route_next (rn))
2214
if ((onbr = rn->info) == NULL)
2218
if ((ls_req = ospf_ls_request_lookup (onbr, lsa)) == NULL)
2221
if (IS_DEBUG_OSPF_EVENT)
2222
zlog_info ("LSA[%s]: Exclude this entry from LSReq to send.", dump_lsa_key (lsa));
2224
ospf_ls_request_delete (onbr, ls_req);
2225
/* ospf_check_nbr_loading (onbr);*//* XXX */
2232
ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, list lsas)
2235
listnode node, next;
2236
struct ospf_lsa *lsa;
2239
if ((top = oi_to_top (nbr->oi)) == NULL)
2242
before = IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque);
2244
for (node = listhead (lsas); node; node = next)
2248
if ((lsa = getdata (node)) == NULL)
2251
listnode_delete (lsas, lsa);
2254
* Since these LSA entries are not yet installed into corresponding
2255
* LSDB, just flush them without calling ospf_ls_maxage() afterward.
2257
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2258
switch (lsa->data->type)
2260
case OSPF_OPAQUE_LINK_LSA:
2261
SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
2262
ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);
2264
case OSPF_OPAQUE_AREA_LSA:
2265
SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
2266
ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);
2268
case OSPF_OPAQUE_AS_LSA:
2269
SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT);
2270
ospf_flood_through_as (top, NULL/*inbr*/, lsa);
2273
zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type);
2277
ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */
2280
if (before == 0 && IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
2282
if (IS_DEBUG_OSPF_EVENT)
2283
zlog_info ("Block Opaque-LSA origination: OFF -> ON");
2291
ospf_opaque_ls_ack_received (struct ospf_neighbor *nbr, list acks)
2295
struct ospf_lsa *lsa;
2296
char type9_lsa_rcv = 0, type10_lsa_rcv = 0, type11_lsa_rcv = 0;
2298
if ((top = oi_to_top (nbr->oi)) == NULL)
2301
for (node = listhead (acks); node; nextnode (node))
2303
if ((lsa = getdata (node)) == NULL)
2306
switch (lsa->data->type)
2308
case OSPF_OPAQUE_LINK_LSA:
2310
/* Callback function... */
2312
case OSPF_OPAQUE_AREA_LSA:
2314
/* Callback function... */
2316
case OSPF_OPAQUE_AS_LSA:
2318
/* Callback function... */
2321
zlog_warn ("ospf_opaque_ls_ack_received: Unexpected LSA-type(%u)", lsa->data->type);
2326
if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
2329
struct ospf_interface *oi;
2332
&& CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT))
2333
ospf_opaque_type9_lsa_rxmt_nbr_check (nbr->oi);
2336
&& CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT))
2337
ospf_opaque_type10_lsa_rxmt_nbr_check (nbr->oi->area);
2340
&& CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT))
2341
ospf_opaque_type11_lsa_rxmt_nbr_check (top);
2343
if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
2344
goto out; /* Blocking still in progress. */
2346
if (IS_DEBUG_OSPF_EVENT)
2347
zlog_info ("Block Opaque-LSA origination: ON -> OFF");
2349
if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
2350
goto out; /* Opaque capability condition must have changed. */
2352
/* Ok, let's start origination of Opaque-LSAs. */
2353
delay = OSPF_MIN_LS_INTERVAL;
2354
for (node = listhead (top->oiflist); node; nextnode (node))
2356
if ((oi = getdata (node)) == NULL)
2359
if (! ospf_if_is_enable (oi)
2360
|| ospf_nbr_count_opaque_capable (oi) == 0)
2363
ospf_opaque_lsa_originate_schedule (oi, &delay);
2372
ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi)
2376
n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_LINK_LSA);
2379
if (IS_DEBUG_OSPF_EVENT)
2380
zlog_info ("Self-originated type-9 Opaque-LSAs: OI(%s): Flush completed", IF_NAME (oi));
2382
UNSET_FLAG (oi->area->ospf->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
2388
ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area)
2391
struct ospf_interface *oi;
2392
unsigned long n = 0;
2394
for (node = listhead (area->oiflist); node; nextnode (node))
2396
if ((oi = getdata (node)) == NULL)
2399
if (area->area_id.s_addr != OSPF_AREA_BACKBONE
2400
&& oi->type == OSPF_IFTYPE_VIRTUALLINK)
2403
n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AREA_LSA);
2410
if (IS_DEBUG_OSPF_EVENT)
2411
zlog_info ("Self-originated type-10 Opaque-LSAs: AREA(%s): Flush completed", inet_ntoa (area->area_id));
2413
UNSET_FLAG (area->ospf->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
2420
ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top)
2423
struct ospf_interface *oi;
2424
unsigned long n = 0;
2426
for (node = listhead (top->oiflist); node; nextnode (node))
2428
if ((oi = getdata (node)) == NULL)
2433
case OSPF_IFTYPE_VIRTUALLINK:
2439
n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AS_LSA);
2446
if (IS_DEBUG_OSPF_EVENT)
2447
zlog_info ("Self-originated type-11 Opaque-LSAs: Flush completed");
2449
UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT);
2456
static unsigned long
2457
ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type)
2459
struct route_node *rn;
2460
struct ospf_neighbor *nbr;
2462
unsigned long n = 0;
2464
for (rn = route_top (nbrs); rn; rn = route_next (rn))
2466
if ((nbr = rn->info) == NULL)
2468
if ((top = oi_to_top (nbr->oi)) == NULL)
2470
if (IPV4_ADDR_SAME (&nbr->router_id, &top->router_id))
2472
n += ospf_ls_retransmit_count_self (nbr, lsa_type);
2478
/*------------------------------------------------------------------------*
2479
* Followings are util functions; probably be used by Opaque-LSAs only...
2480
*------------------------------------------------------------------------*/
2483
htonf (float *src, float *dst)
2487
memcpy (&lu1, src, sizeof (u_int32_t));
2489
memcpy (dst, &lu2, sizeof (u_int32_t));
2494
ntohf (float *src, float *dst)
2498
memcpy (&lu1, src, sizeof (u_int32_t));
2500
memcpy (dst, &lu2, sizeof (u_int32_t));
2505
oi_to_top (struct ospf_interface *oi)
2507
struct ospf *top = NULL;
2508
struct ospf_area *area;
2510
if (oi == NULL || (area = oi->area) == NULL || (top = area->ospf) == NULL)
2511
zlog_warn ("Broken relationship for \"OI -> AREA -> OSPF\"?");
2516
#endif /* HAVE_OPAQUE_LSA */