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 along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 #include "sockunion.h" /* for inet_aton() */
38 #include "ospfd/ospfd.h"
39 #include "ospfd/ospf_interface.h"
40 #include "ospfd/ospf_ism.h"
41 #include "ospfd/ospf_asbr.h"
42 #include "ospfd/ospf_lsa.h"
43 #include "ospfd/ospf_lsdb.h"
44 #include "ospfd/ospf_neighbor.h"
45 #include "ospfd/ospf_nsm.h"
46 #include "ospfd/ospf_flood.h"
47 #include "ospfd/ospf_packet.h"
48 #include "ospfd/ospf_spf.h"
49 #include "ospfd/ospf_dump.h"
50 #include "ospfd/ospf_route.h"
51 #include "ospfd/ospf_ase.h"
52 #include "ospfd/ospf_zebra.h"
54 DEFINE_MTYPE_STATIC(OSPFD
, OSPF_OPAQUE_FUNCTAB
, "OSPF opaque function table")
55 DEFINE_MTYPE_STATIC(OSPFD
, OPAQUE_INFO_PER_TYPE
, "OSPF opaque per-type info")
56 DEFINE_MTYPE_STATIC(OSPFD
, OPAQUE_INFO_PER_ID
, "OSPF opaque per-ID info")
58 /*------------------------------------------------------------------------*
59 * Followings are initialize/terminate functions for Opaque-LSAs handling.
60 *------------------------------------------------------------------------*/
62 #include "ospfd/ospf_te.h"
63 #include "ospfd/ospf_ri.h"
65 #ifdef SUPPORT_OSPF_API
66 int ospf_apiserver_init (void);
67 void ospf_apiserver_term (void);
68 /* Init apiserver? It's disabled by default. */
69 int ospf_apiserver_enable
;
70 #endif /* SUPPORT_OSPF_API */
72 static void ospf_opaque_register_vty (void);
73 static void ospf_opaque_funclist_init (void);
74 static void ospf_opaque_funclist_term (void);
75 static void free_opaque_info_per_type (void *val
);
76 static void free_opaque_info_per_id (void *val
);
77 static int ospf_opaque_lsa_install_hook (struct ospf_lsa
*lsa
);
78 static int ospf_opaque_lsa_delete_hook (struct ospf_lsa
*lsa
);
81 ospf_opaque_init (void)
83 ospf_opaque_register_vty ();
84 ospf_opaque_funclist_init ();
86 if (ospf_mpls_te_init () != 0)
89 if (ospf_router_info_init () != 0)
92 #ifdef SUPPORT_OSPF_API
93 if ((ospf_apiserver_enable
) && (ospf_apiserver_init () != 0))
95 #endif /* SUPPORT_OSPF_API */
101 ospf_opaque_term (void)
103 ospf_mpls_te_term ();
105 ospf_router_info_term ();
107 #ifdef SUPPORT_OSPF_API
108 ospf_apiserver_term ();
109 #endif /* SUPPORT_OSPF_API */
111 ospf_opaque_funclist_term ();
116 ospf_opaque_type9_lsa_init (struct ospf_interface
*oi
)
118 if (oi
->opaque_lsa_self
!= NULL
)
119 list_delete (oi
->opaque_lsa_self
);
121 oi
->opaque_lsa_self
= list_new ();
122 oi
->opaque_lsa_self
->del
= free_opaque_info_per_type
;
123 oi
->t_opaque_lsa_self
= NULL
;
128 ospf_opaque_type9_lsa_term (struct ospf_interface
*oi
)
130 OSPF_TIMER_OFF (oi
->t_opaque_lsa_self
);
131 if (oi
->opaque_lsa_self
!= NULL
)
132 list_delete (oi
->opaque_lsa_self
);
133 oi
->opaque_lsa_self
= NULL
;
138 ospf_opaque_type10_lsa_init (struct ospf_area
*area
)
140 if (area
->opaque_lsa_self
!= NULL
)
141 list_delete (area
->opaque_lsa_self
);
143 area
->opaque_lsa_self
= list_new ();
144 area
->opaque_lsa_self
->del
= free_opaque_info_per_type
;
145 area
->t_opaque_lsa_self
= NULL
;
147 #ifdef MONITOR_LSDB_CHANGE
148 area
->lsdb
->new_lsa_hook
= ospf_opaque_lsa_install_hook
;
149 area
->lsdb
->del_lsa_hook
= ospf_opaque_lsa_delete_hook
;
150 #endif /* MONITOR_LSDB_CHANGE */
155 ospf_opaque_type10_lsa_term (struct ospf_area
*area
)
157 #ifdef MONITOR_LSDB_CHANGE
158 area
->lsdb
->new_lsa_hook
=
159 area
->lsdb
->del_lsa_hook
= NULL
;
160 #endif /* MONITOR_LSDB_CHANGE */
162 OSPF_TIMER_OFF (area
->t_opaque_lsa_self
);
163 if (area
->opaque_lsa_self
!= NULL
)
164 list_delete (area
->opaque_lsa_self
);
165 area
->opaque_lsa_self
= NULL
;
170 ospf_opaque_type11_lsa_init (struct ospf
*top
)
172 if (top
->opaque_lsa_self
!= NULL
)
173 list_delete (top
->opaque_lsa_self
);
175 top
->opaque_lsa_self
= list_new ();
176 top
->opaque_lsa_self
->del
= free_opaque_info_per_type
;
177 top
->t_opaque_lsa_self
= NULL
;
179 #ifdef MONITOR_LSDB_CHANGE
180 top
->lsdb
->new_lsa_hook
= ospf_opaque_lsa_install_hook
;
181 top
->lsdb
->del_lsa_hook
= ospf_opaque_lsa_delete_hook
;
182 #endif /* MONITOR_LSDB_CHANGE */
187 ospf_opaque_type11_lsa_term (struct ospf
*top
)
189 #ifdef MONITOR_LSDB_CHANGE
190 top
->lsdb
->new_lsa_hook
=
191 top
->lsdb
->del_lsa_hook
= NULL
;
192 #endif /* MONITOR_LSDB_CHANGE */
194 OSPF_TIMER_OFF (top
->t_opaque_lsa_self
);
195 if (top
->opaque_lsa_self
!= NULL
)
196 list_delete (top
->opaque_lsa_self
);
197 top
->opaque_lsa_self
= NULL
;
202 ospf_opaque_type_name (u_char opaque_type
)
204 const char *name
= "Unknown";
208 case OPAQUE_TYPE_WILDCARD
: /* This is a special assignment! */
211 case OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA
:
212 name
= "Traffic Engineering LSA";
214 case OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC
:
215 name
= "Sycamore optical topology description";
217 case OPAQUE_TYPE_GRACE_LSA
:
220 case OPAQUE_TYPE_INTER_AS_LSA
:
221 name
= "Inter-AS TE-v2 LSA";
223 case OPAQUE_TYPE_ROUTER_INFORMATION_LSA
:
224 name
= "Router Information LSA";
227 if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type
))
231 u_int32_t bigger_range
= opaque_type
;
233 * Get around type-limits warning: comparison is always true due to limited range of data type
235 if (OPAQUE_TYPE_RANGE_RESERVED (bigger_range
))
236 name
= "Private/Experimental";
243 /*------------------------------------------------------------------------*
244 * Followings are management functions to store user specified callbacks.
245 *------------------------------------------------------------------------*/
247 struct opaque_info_per_type
; /* Forward declaration. */
249 struct ospf_opaque_functab
252 struct opaque_info_per_type
*oipt
;
254 int (* new_if_hook
)(struct interface
*ifp
);
255 int (* del_if_hook
)(struct interface
*ifp
);
256 void (* ism_change_hook
)(struct ospf_interface
*oi
, int old_status
);
257 void (* nsm_change_hook
)(struct ospf_neighbor
*nbr
, int old_status
);
258 void (* config_write_router
)(struct vty
*vty
);
259 void (* config_write_if
)(struct vty
*vty
, struct interface
*ifp
);
260 void (* config_write_debug
)(struct vty
*vty
);
261 void (* show_opaque_info
)(struct vty
*vty
, struct ospf_lsa
*lsa
);
262 int (* lsa_originator
)(void *arg
);
263 struct ospf_lsa
*(* lsa_refresher
)(struct ospf_lsa
*lsa
);
264 int (* new_lsa_hook
)(struct ospf_lsa
*lsa
);
265 int (* del_lsa_hook
)(struct ospf_lsa
*lsa
);
268 /* Handle LSA-9/10/11 altogether. */
269 static struct list
*ospf_opaque_wildcard_funclist
;
270 static struct list
*ospf_opaque_type9_funclist
;
271 static struct list
*ospf_opaque_type10_funclist
;
272 static struct list
*ospf_opaque_type11_funclist
;
275 ospf_opaque_del_functab (void *val
)
277 XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB
, val
);
282 ospf_opaque_funclist_init (void)
284 struct list
*funclist
;
286 funclist
= ospf_opaque_wildcard_funclist
= list_new ();
287 funclist
->del
= ospf_opaque_del_functab
;
289 funclist
= ospf_opaque_type9_funclist
= list_new ();
290 funclist
->del
= ospf_opaque_del_functab
;
292 funclist
= ospf_opaque_type10_funclist
= list_new ();
293 funclist
->del
= ospf_opaque_del_functab
;
295 funclist
= ospf_opaque_type11_funclist
= list_new ();
296 funclist
->del
= ospf_opaque_del_functab
;
301 ospf_opaque_funclist_term (void)
303 struct list
*funclist
;
305 funclist
= ospf_opaque_wildcard_funclist
;
306 list_delete (funclist
);
308 funclist
= ospf_opaque_type9_funclist
;
309 list_delete (funclist
);
311 funclist
= ospf_opaque_type10_funclist
;
312 list_delete (funclist
);
314 funclist
= ospf_opaque_type11_funclist
;
315 list_delete (funclist
);
320 ospf_get_opaque_funclist (u_char lsa_type
)
322 struct list
*funclist
= NULL
;
326 case OPAQUE_TYPE_WILDCARD
:
328 * This is an ugly trick to handle type-9/10/11 LSA altogether.
329 * Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor
330 * an officially assigned opaque-type.
331 * Though it is possible that the value might be officially used
332 * in the future, we use it internally as a special label, for now.
334 funclist
= ospf_opaque_wildcard_funclist
;
336 case OSPF_OPAQUE_LINK_LSA
:
337 funclist
= ospf_opaque_type9_funclist
;
339 case OSPF_OPAQUE_AREA_LSA
:
340 funclist
= ospf_opaque_type10_funclist
;
342 case OSPF_OPAQUE_AS_LSA
:
343 funclist
= ospf_opaque_type11_funclist
;
346 zlog_warn ("ospf_get_opaque_funclist: Unexpected LSA-type(%u)", lsa_type
);
352 /* XXX: such a huge argument list can /not/ be healthy... */
354 ospf_register_opaque_functab (
357 int (* new_if_hook
)(struct interface
*ifp
),
358 int (* del_if_hook
)(struct interface
*ifp
),
359 void (* ism_change_hook
)(struct ospf_interface
*oi
, int old_status
),
360 void (* nsm_change_hook
)(struct ospf_neighbor
*nbr
, int old_status
),
361 void (* config_write_router
)(struct vty
*vty
),
362 void (* config_write_if
)(struct vty
*vty
, struct interface
*ifp
),
363 void (* config_write_debug
)(struct vty
*vty
),
364 void (* show_opaque_info
)(struct vty
*vty
, struct ospf_lsa
*lsa
),
365 int (* lsa_originator
)(void *arg
),
366 struct ospf_lsa
*(* lsa_refresher
)(struct ospf_lsa
*lsa
),
367 int (* new_lsa_hook
)(struct ospf_lsa
*lsa
),
368 int (* del_lsa_hook
)(struct ospf_lsa
*lsa
))
370 struct list
*funclist
;
371 struct ospf_opaque_functab
*new;
374 if ((funclist
= ospf_get_opaque_funclist (lsa_type
)) == NULL
)
376 zlog_warn ("ospf_register_opaque_functab: Cannot get funclist"
377 " for Type-%u LSAs?",
383 struct listnode
*node
, *nnode
;
384 struct ospf_opaque_functab
*functab
;
386 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
387 if (functab
->opaque_type
== opaque_type
)
389 zlog_warn ("ospf_register_opaque_functab: Duplicated entry?:"
390 " lsa_type(%u), opaque_type(%u)",
391 lsa_type
, opaque_type
);
396 if ((new = XCALLOC (MTYPE_OSPF_OPAQUE_FUNCTAB
,
397 sizeof (struct ospf_opaque_functab
))) == NULL
)
399 zlog_warn ("ospf_register_opaque_functab: XMALLOC: %s",
400 safe_strerror (errno
));
404 new->opaque_type
= opaque_type
;
406 new->new_if_hook
= new_if_hook
;
407 new->del_if_hook
= del_if_hook
;
408 new->ism_change_hook
= ism_change_hook
;
409 new->nsm_change_hook
= nsm_change_hook
;
410 new->config_write_router
= config_write_router
;
411 new->config_write_if
= config_write_if
;
412 new->config_write_debug
= config_write_debug
;
413 new->show_opaque_info
= show_opaque_info
;
414 new->lsa_originator
= lsa_originator
;
415 new->lsa_refresher
= lsa_refresher
;
416 new->new_lsa_hook
= new_lsa_hook
;
417 new->del_lsa_hook
= del_lsa_hook
;
419 listnode_add (funclist
, new);
427 ospf_delete_opaque_functab (u_char lsa_type
, u_char opaque_type
)
429 struct list
*funclist
;
430 struct listnode
*node
, *nnode
;
431 struct ospf_opaque_functab
*functab
;
433 if ((funclist
= ospf_get_opaque_funclist (lsa_type
)) != NULL
)
434 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
436 if (functab
->opaque_type
== opaque_type
)
438 /* Cleanup internal control information, if it still remains. */
439 if (functab
->oipt
!= NULL
)
440 free_opaque_info_per_type (functab
->oipt
);
442 /* Dequeue listnode entry from the list. */
443 listnode_delete (funclist
, functab
);
445 /* Avoid misjudgement in the next lookup. */
446 if (listcount (funclist
) == 0)
447 funclist
->head
= funclist
->tail
= NULL
;
449 XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB
, functab
);
457 static struct ospf_opaque_functab
*
458 ospf_opaque_functab_lookup (struct ospf_lsa
*lsa
)
460 struct list
*funclist
;
461 struct listnode
*node
;
462 struct ospf_opaque_functab
*functab
;
463 u_char key
= GET_OPAQUE_TYPE (ntohl (lsa
->data
->id
.s_addr
));
465 if ((funclist
= ospf_get_opaque_funclist (lsa
->data
->type
)) != NULL
)
466 for (ALL_LIST_ELEMENTS_RO (funclist
, node
, functab
))
467 if (functab
->opaque_type
== key
)
473 /*------------------------------------------------------------------------*
474 * Followings are management functions for self-originated LSA entries.
475 *------------------------------------------------------------------------*/
478 * Opaque-LSA control information per opaque-type.
479 * Single Opaque-Type may have multiple instances; each of them will be
480 * identified by their opaque-id.
482 struct opaque_info_per_type
487 enum { PROC_NORMAL
, PROC_SUSPEND
} status
;
490 * Thread for (re-)origination scheduling for this opaque-type.
492 * Initial origination of Opaque-LSAs is controlled by generic
493 * Opaque-LSA handling module so that same opaque-type entries are
494 * called all at once when certain conditions are met.
495 * However, there might be cases that some Opaque-LSA clients need
496 * to (re-)originate their own Opaque-LSAs out-of-sync with others.
497 * This thread is prepared for that specific purpose.
499 struct thread
*t_opaque_lsa_self
;
502 * Backpointer to an "owner" which is LSA-type dependent.
503 * type-9: struct ospf_interface
504 * type-10: struct ospf_area
505 * type-11: struct ospf
509 /* Collection of callback functions for this opaque-type. */
510 struct ospf_opaque_functab
*functab
;
512 /* List of Opaque-LSA control informations per opaque-id. */
513 struct list
*id_list
;
516 /* Opaque-LSA control information per opaque-id. */
517 struct opaque_info_per_id
521 /* Thread for refresh/flush scheduling for this opaque-type/id. */
522 struct thread
*t_opaque_lsa_self
;
524 /* Backpointer to Opaque-LSA control information per opaque-type. */
525 struct opaque_info_per_type
*opqctl_type
;
527 /* Here comes an actual Opaque-LSA entry for this opaque-type/id. */
528 struct ospf_lsa
*lsa
;
531 static struct opaque_info_per_type
*register_opaque_info_per_type (struct ospf_opaque_functab
*functab
, struct ospf_lsa
*new);
532 static struct opaque_info_per_type
*lookup_opaque_info_by_type (struct ospf_lsa
*lsa
);
533 static struct opaque_info_per_id
*register_opaque_info_per_id (struct opaque_info_per_type
*oipt
, struct ospf_lsa
*new);
534 static struct opaque_info_per_id
*lookup_opaque_info_by_id (struct opaque_info_per_type
*oipt
, struct ospf_lsa
*lsa
);
535 static struct opaque_info_per_id
*register_opaque_lsa (struct ospf_lsa
*new);
538 static struct opaque_info_per_type
*
539 register_opaque_info_per_type (struct ospf_opaque_functab
*functab
,
540 struct ospf_lsa
*new)
543 struct opaque_info_per_type
*oipt
;
545 if ((oipt
= XCALLOC (MTYPE_OPAQUE_INFO_PER_TYPE
,
546 sizeof (struct opaque_info_per_type
))) == NULL
)
548 zlog_warn ("register_opaque_info_per_type: XMALLOC: %s", safe_strerror (errno
));
552 switch (new->data
->type
)
554 case OSPF_OPAQUE_LINK_LSA
:
555 oipt
->owner
= new->oi
;
556 listnode_add (new->oi
->opaque_lsa_self
, oipt
);
558 case OSPF_OPAQUE_AREA_LSA
:
559 oipt
->owner
= new->area
;
560 listnode_add (new->area
->opaque_lsa_self
, oipt
);
562 case OSPF_OPAQUE_AS_LSA
:
563 top
= ospf_lookup ();
564 if (new->area
!= NULL
&& (top
= new->area
->ospf
) == NULL
)
566 free_opaque_info_per_type ((void *) oipt
);
568 goto out
; /* This case may not exist. */
571 listnode_add (top
->opaque_lsa_self
, oipt
);
574 zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data
->type
);
575 free_opaque_info_per_type ((void *) oipt
);
577 goto out
; /* This case may not exist. */
580 oipt
->lsa_type
= new->data
->type
;
581 oipt
->opaque_type
= GET_OPAQUE_TYPE (ntohl (new->data
->id
.s_addr
));
582 oipt
->status
= PROC_NORMAL
;
583 oipt
->t_opaque_lsa_self
= NULL
;
584 oipt
->functab
= functab
;
585 functab
->oipt
= oipt
;
586 oipt
->id_list
= list_new ();
587 oipt
->id_list
->del
= free_opaque_info_per_id
;
594 free_opaque_info_per_type (void *val
)
596 struct opaque_info_per_type
*oipt
= (struct opaque_info_per_type
*) val
;
597 struct opaque_info_per_id
*oipi
;
598 struct ospf_lsa
*lsa
;
599 struct listnode
*node
, *nnode
;
601 /* Control information per opaque-id may still exist. */
602 for (ALL_LIST_ELEMENTS (oipt
->id_list
, node
, nnode
, oipi
))
604 if ((lsa
= oipi
->lsa
) == NULL
)
606 if (IS_LSA_MAXAGE (lsa
))
608 ospf_opaque_lsa_flush_schedule (lsa
);
611 /* Remove "oipt" from its owner's self-originated LSA list. */
612 switch (oipt
->lsa_type
)
614 case OSPF_OPAQUE_LINK_LSA
:
616 struct ospf_interface
*oi
= (struct ospf_interface
*)(oipt
->owner
);
617 listnode_delete (oi
->opaque_lsa_self
, oipt
);
620 case OSPF_OPAQUE_AREA_LSA
:
622 struct ospf_area
*area
= (struct ospf_area
*)(oipt
->owner
);
623 listnode_delete (area
->opaque_lsa_self
, oipt
);
626 case OSPF_OPAQUE_AS_LSA
:
628 struct ospf
*top
= (struct ospf
*)(oipt
->owner
);
629 listnode_delete (top
->opaque_lsa_self
, oipt
);
633 zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt
->lsa_type
);
634 break; /* This case may not exist. */
637 OSPF_TIMER_OFF (oipt
->t_opaque_lsa_self
);
638 list_delete (oipt
->id_list
);
639 XFREE (MTYPE_OPAQUE_INFO_PER_TYPE
, oipt
);
643 static struct opaque_info_per_type
*
644 lookup_opaque_info_by_type (struct ospf_lsa
*lsa
)
647 struct ospf_area
*area
;
648 struct ospf_interface
*oi
;
649 struct list
*listtop
= NULL
;
650 struct listnode
*node
, *nnode
;
651 struct opaque_info_per_type
*oipt
= NULL
;
652 u_char key
= GET_OPAQUE_TYPE (ntohl (lsa
->data
->id
.s_addr
));
654 switch (lsa
->data
->type
)
656 case OSPF_OPAQUE_LINK_LSA
:
657 if ((oi
= lsa
->oi
) != NULL
)
658 listtop
= oi
->opaque_lsa_self
;
660 zlog_warn ("Type-9 Opaque-LSA: Reference to OI is missing?");
662 case OSPF_OPAQUE_AREA_LSA
:
663 if ((area
= lsa
->area
) != NULL
)
664 listtop
= area
->opaque_lsa_self
;
666 zlog_warn ("Type-10 Opaque-LSA: Reference to AREA is missing?");
668 case OSPF_OPAQUE_AS_LSA
:
669 top
= ospf_lookup ();
670 if ((area
= lsa
->area
) != NULL
&& (top
= area
->ospf
) == NULL
)
672 zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?");
673 break; /* Unlikely to happen. */
675 listtop
= top
->opaque_lsa_self
;
678 zlog_warn ("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", lsa
->data
->type
);
683 for (ALL_LIST_ELEMENTS (listtop
, node
, nnode
, oipt
))
684 if (oipt
->opaque_type
== key
)
690 static struct opaque_info_per_id
*
691 register_opaque_info_per_id (struct opaque_info_per_type
*oipt
,
692 struct ospf_lsa
*new)
694 struct opaque_info_per_id
*oipi
;
696 if ((oipi
= XCALLOC (MTYPE_OPAQUE_INFO_PER_ID
,
697 sizeof (struct opaque_info_per_id
))) == NULL
)
699 zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", safe_strerror (errno
));
702 oipi
->opaque_id
= GET_OPAQUE_ID (ntohl (new->data
->id
.s_addr
));
703 oipi
->t_opaque_lsa_self
= NULL
;
704 oipi
->opqctl_type
= oipt
;
705 oipi
->lsa
= ospf_lsa_lock (new);
707 listnode_add (oipt
->id_list
, oipi
);
714 free_opaque_info_per_id (void *val
)
716 struct opaque_info_per_id
*oipi
= (struct opaque_info_per_id
*) val
;
718 OSPF_TIMER_OFF (oipi
->t_opaque_lsa_self
);
719 if (oipi
->lsa
!= NULL
)
720 ospf_lsa_unlock (&oipi
->lsa
);
721 XFREE (MTYPE_OPAQUE_INFO_PER_ID
, oipi
);
725 static struct opaque_info_per_id
*
726 lookup_opaque_info_by_id (struct opaque_info_per_type
*oipt
,
727 struct ospf_lsa
*lsa
)
729 struct listnode
*node
, *nnode
;
730 struct opaque_info_per_id
*oipi
;
731 u_int32_t key
= GET_OPAQUE_ID (ntohl (lsa
->data
->id
.s_addr
));
733 for (ALL_LIST_ELEMENTS (oipt
->id_list
, node
, nnode
, oipi
))
734 if (oipi
->opaque_id
== key
)
740 static struct opaque_info_per_id
*
741 register_opaque_lsa (struct ospf_lsa
*new)
743 struct ospf_opaque_functab
*functab
;
744 struct opaque_info_per_type
*oipt
;
745 struct opaque_info_per_id
*oipi
= NULL
;
747 if ((functab
= ospf_opaque_functab_lookup (new)) == NULL
)
750 if ((oipt
= lookup_opaque_info_by_type (new)) == NULL
751 && (oipt
= register_opaque_info_per_type (functab
, new)) == NULL
)
754 if ((oipi
= register_opaque_info_per_id (oipt
, new)) == NULL
)
761 /*------------------------------------------------------------------------*
762 * Followings are (vty) configuration functions for Opaque-LSAs handling.
763 *------------------------------------------------------------------------*/
765 DEFUN (capability_opaque
,
766 capability_opaque_cmd
,
768 "Enable specific OSPF feature\n"
771 VTY_DECLVAR_CONTEXT(ospf
, ospf
);
773 /* Turn on the "master switch" of opaque-lsa capability. */
774 if (!CHECK_FLAG (ospf
->config
, OSPF_OPAQUE_CAPABLE
))
776 if (IS_DEBUG_OSPF_EVENT
)
777 zlog_debug ("Opaque capability: OFF -> ON");
779 SET_FLAG (ospf
->config
, OSPF_OPAQUE_CAPABLE
);
780 ospf_renegotiate_optional_capabilities (ospf
);
788 "OSPF specific commands\n"
789 "Enable the Opaque-LSA capability (rfc2370)\n")
791 return capability_opaque (self
, vty
, argc
, argv
);
794 DEFUN (no_capability_opaque
,
795 no_capability_opaque_cmd
,
796 "no capability opaque",
798 "Enable specific OSPF feature\n"
801 VTY_DECLVAR_CONTEXT(ospf
, ospf
);
803 /* Turn off the "master switch" of opaque-lsa capability. */
804 if (CHECK_FLAG (ospf
->config
, OSPF_OPAQUE_CAPABLE
))
806 if (IS_DEBUG_OSPF_EVENT
)
807 zlog_debug ("Opaque capability: ON -> OFF");
809 UNSET_FLAG (ospf
->config
, OSPF_OPAQUE_CAPABLE
);
810 ospf_renegotiate_optional_capabilities (ospf
);
815 DEFUN (no_ospf_opaque
,
817 "no ospf opaque-lsa",
819 "OSPF specific commands\n"
820 "Enable the Opaque-LSA capability (rfc2370)\n")
822 return no_capability_opaque (self
, vty
, argc
, argv
);
826 ospf_opaque_register_vty (void)
828 install_element (OSPF_NODE
, &capability_opaque_cmd
);
829 install_element (OSPF_NODE
, &no_capability_opaque_cmd
);
830 install_element (OSPF_NODE
, &ospf_opaque_cmd
);
831 install_element (OSPF_NODE
, &no_ospf_opaque_cmd
);
835 /*------------------------------------------------------------------------*
836 * Followings are collection of user-registered function callers.
837 *------------------------------------------------------------------------*/
840 opaque_lsa_new_if_callback (struct list
*funclist
, struct interface
*ifp
)
842 struct listnode
*node
, *nnode
;
843 struct ospf_opaque_functab
*functab
;
846 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
847 if (functab
->new_if_hook
!= NULL
)
848 if ((* functab
->new_if_hook
)(ifp
) != 0)
856 opaque_lsa_del_if_callback (struct list
*funclist
, struct interface
*ifp
)
858 struct listnode
*node
, *nnode
;
859 struct ospf_opaque_functab
*functab
;
862 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
863 if (functab
->del_if_hook
!= NULL
)
864 if ((* functab
->del_if_hook
)(ifp
) != 0)
872 opaque_lsa_ism_change_callback (struct list
*funclist
,
873 struct ospf_interface
*oi
, int old_status
)
875 struct listnode
*node
, *nnode
;
876 struct ospf_opaque_functab
*functab
;
878 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
879 if (functab
->ism_change_hook
!= NULL
)
880 (* functab
->ism_change_hook
)(oi
, old_status
);
886 opaque_lsa_nsm_change_callback (struct list
*funclist
,
887 struct ospf_neighbor
*nbr
, int old_status
)
889 struct listnode
*node
, *nnode
;
890 struct ospf_opaque_functab
*functab
;
892 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
893 if (functab
->nsm_change_hook
!= NULL
)
894 (* functab
->nsm_change_hook
)(nbr
, old_status
);
899 opaque_lsa_config_write_router_callback (struct list
*funclist
,
902 struct listnode
*node
, *nnode
;
903 struct ospf_opaque_functab
*functab
;
905 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
906 if (functab
->config_write_router
!= NULL
)
907 (* functab
->config_write_router
)(vty
);
912 opaque_lsa_config_write_if_callback (struct list
*funclist
,
913 struct vty
*vty
, struct interface
*ifp
)
915 struct listnode
*node
, *nnode
;
916 struct ospf_opaque_functab
*functab
;
918 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
919 if (functab
->config_write_if
!= NULL
)
920 (* functab
->config_write_if
)(vty
, ifp
);
925 opaque_lsa_config_write_debug_callback (struct list
*funclist
, struct vty
*vty
)
927 struct listnode
*node
, *nnode
;
928 struct ospf_opaque_functab
*functab
;
930 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
931 if (functab
->config_write_debug
!= NULL
)
932 (* functab
->config_write_debug
)(vty
);
937 opaque_lsa_originate_callback (struct list
*funclist
, void *lsa_type_dependent
)
939 struct listnode
*node
, *nnode
;
940 struct ospf_opaque_functab
*functab
;
943 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
944 if (functab
->lsa_originator
!= NULL
)
945 if ((* functab
->lsa_originator
)(lsa_type_dependent
) != 0)
953 new_lsa_callback (struct list
*funclist
, struct ospf_lsa
*lsa
)
955 struct listnode
*node
, *nnode
;
956 struct ospf_opaque_functab
*functab
;
959 /* This function handles ALL types of LSAs, not only opaque ones. */
960 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
961 if (functab
->new_lsa_hook
!= NULL
)
962 if ((* functab
->new_lsa_hook
)(lsa
) != 0)
970 del_lsa_callback (struct list
*funclist
, struct ospf_lsa
*lsa
)
972 struct listnode
*node
, *nnode
;
973 struct ospf_opaque_functab
*functab
;
976 /* This function handles ALL types of LSAs, not only opaque ones. */
977 for (ALL_LIST_ELEMENTS (funclist
, node
, nnode
, functab
))
978 if (functab
->del_lsa_hook
!= NULL
)
979 if ((* functab
->del_lsa_hook
)(lsa
) != 0)
986 /*------------------------------------------------------------------------*
987 * Followings are glue functions to call Opaque-LSA specific processing.
988 *------------------------------------------------------------------------*/
991 ospf_opaque_new_if (struct interface
*ifp
)
993 struct list
*funclist
;
996 funclist
= ospf_opaque_wildcard_funclist
;
997 if (opaque_lsa_new_if_callback (funclist
, ifp
) != 0)
1000 funclist
= ospf_opaque_type9_funclist
;
1001 if (opaque_lsa_new_if_callback (funclist
, ifp
) != 0)
1004 funclist
= ospf_opaque_type10_funclist
;
1005 if (opaque_lsa_new_if_callback (funclist
, ifp
) != 0)
1008 funclist
= ospf_opaque_type11_funclist
;
1009 if (opaque_lsa_new_if_callback (funclist
, ifp
) != 0)
1018 ospf_opaque_del_if (struct interface
*ifp
)
1020 struct list
*funclist
;
1023 funclist
= ospf_opaque_wildcard_funclist
;
1024 if (opaque_lsa_del_if_callback (funclist
, ifp
) != 0)
1027 funclist
= ospf_opaque_type9_funclist
;
1028 if (opaque_lsa_del_if_callback (funclist
, ifp
) != 0)
1031 funclist
= ospf_opaque_type10_funclist
;
1032 if (opaque_lsa_del_if_callback (funclist
, ifp
) != 0)
1035 funclist
= ospf_opaque_type11_funclist
;
1036 if (opaque_lsa_del_if_callback (funclist
, ifp
) != 0)
1045 ospf_opaque_ism_change (struct ospf_interface
*oi
, int old_status
)
1047 struct list
*funclist
;
1049 funclist
= ospf_opaque_wildcard_funclist
;
1050 opaque_lsa_ism_change_callback (funclist
, oi
, old_status
);
1052 funclist
= ospf_opaque_type9_funclist
;
1053 opaque_lsa_ism_change_callback (funclist
, oi
, old_status
);
1055 funclist
= ospf_opaque_type10_funclist
;
1056 opaque_lsa_ism_change_callback (funclist
, oi
, old_status
);
1058 funclist
= ospf_opaque_type11_funclist
;
1059 opaque_lsa_ism_change_callback (funclist
, oi
, old_status
);
1065 ospf_opaque_nsm_change (struct ospf_neighbor
*nbr
, int old_state
)
1068 struct list
*funclist
;
1070 if ((top
= oi_to_top (nbr
->oi
)) == NULL
)
1073 if (old_state
!= NSM_Full
&& nbr
->state
== NSM_Full
)
1075 if (CHECK_FLAG (nbr
->options
, OSPF_OPTION_O
))
1077 if (! CHECK_FLAG (top
->opaque
, OPAQUE_OPERATION_READY_BIT
))
1079 if (IS_DEBUG_OSPF_EVENT
)
1080 zlog_debug ("Opaque-LSA: Now get operational!");
1082 SET_FLAG (top
->opaque
, OPAQUE_OPERATION_READY_BIT
);
1085 ospf_opaque_lsa_originate_schedule (nbr
->oi
, NULL
);
1089 if (old_state
== NSM_Full
&& nbr
->state
!= NSM_Full
)
1093 * If no more opaque-capable full-state neighbor remains in the
1094 * flooding scope which corresponds to Opaque-LSA type, periodic
1095 * LS flooding should be stopped.
1101 funclist
= ospf_opaque_wildcard_funclist
;
1102 opaque_lsa_nsm_change_callback (funclist
, nbr
, old_state
);
1104 funclist
= ospf_opaque_type9_funclist
;
1105 opaque_lsa_nsm_change_callback (funclist
, nbr
, old_state
);
1107 funclist
= ospf_opaque_type10_funclist
;
1108 opaque_lsa_nsm_change_callback (funclist
, nbr
, old_state
);
1110 funclist
= ospf_opaque_type11_funclist
;
1111 opaque_lsa_nsm_change_callback (funclist
, nbr
, old_state
);
1118 ospf_opaque_config_write_router (struct vty
*vty
, struct ospf
*ospf
)
1120 struct list
*funclist
;
1122 if (CHECK_FLAG (ospf
->config
, OSPF_OPAQUE_CAPABLE
))
1123 vty_out (vty
, " capability opaque%s", VTY_NEWLINE
);
1125 funclist
= ospf_opaque_wildcard_funclist
;
1126 opaque_lsa_config_write_router_callback (funclist
, vty
);
1128 funclist
= ospf_opaque_type9_funclist
;
1129 opaque_lsa_config_write_router_callback (funclist
, vty
);
1131 funclist
= ospf_opaque_type10_funclist
;
1132 opaque_lsa_config_write_router_callback (funclist
, vty
);
1134 funclist
= ospf_opaque_type11_funclist
;
1135 opaque_lsa_config_write_router_callback (funclist
, vty
);
1141 ospf_opaque_config_write_if (struct vty
*vty
, struct interface
*ifp
)
1143 struct list
*funclist
;
1145 funclist
= ospf_opaque_wildcard_funclist
;
1146 opaque_lsa_config_write_if_callback (funclist
, vty
, ifp
);
1148 funclist
= ospf_opaque_type9_funclist
;
1149 opaque_lsa_config_write_if_callback (funclist
, vty
, ifp
);
1151 funclist
= ospf_opaque_type10_funclist
;
1152 opaque_lsa_config_write_if_callback (funclist
, vty
, ifp
);
1154 funclist
= ospf_opaque_type11_funclist
;
1155 opaque_lsa_config_write_if_callback (funclist
, vty
, ifp
);
1161 ospf_opaque_config_write_debug (struct vty
*vty
)
1163 struct list
*funclist
;
1165 funclist
= ospf_opaque_wildcard_funclist
;
1166 opaque_lsa_config_write_debug_callback (funclist
, vty
);
1168 funclist
= ospf_opaque_type9_funclist
;
1169 opaque_lsa_config_write_debug_callback (funclist
, vty
);
1171 funclist
= ospf_opaque_type10_funclist
;
1172 opaque_lsa_config_write_debug_callback (funclist
, vty
);
1174 funclist
= ospf_opaque_type11_funclist
;
1175 opaque_lsa_config_write_debug_callback (funclist
, vty
);
1181 show_opaque_info_detail (struct vty
*vty
, struct ospf_lsa
*lsa
)
1183 struct lsa_header
*lsah
= (struct lsa_header
*) lsa
->data
;
1184 u_int32_t lsid
= ntohl (lsah
->id
.s_addr
);
1185 u_char opaque_type
= GET_OPAQUE_TYPE (lsid
);
1186 u_int32_t opaque_id
= GET_OPAQUE_ID (lsid
);
1187 struct ospf_opaque_functab
*functab
;
1189 /* Switch output functionality by vty address. */
1192 vty_out (vty
, " Opaque-Type %u (%s)%s", opaque_type
,
1193 ospf_opaque_type_name (opaque_type
), VTY_NEWLINE
);
1194 vty_out (vty
, " Opaque-ID 0x%x%s", opaque_id
, VTY_NEWLINE
);
1196 vty_out (vty
, " Opaque-Info: %u octets of data%s%s",
1197 ntohs (lsah
->length
) - OSPF_LSA_HEADER_SIZE
,
1198 VALID_OPAQUE_INFO_LEN(lsah
) ? "" : "(Invalid length?)",
1203 zlog_debug (" Opaque-Type %u (%s)", opaque_type
,
1204 ospf_opaque_type_name (opaque_type
));
1205 zlog_debug (" Opaque-ID 0x%x", opaque_id
);
1207 zlog_debug (" Opaque-Info: %u octets of data%s",
1208 ntohs (lsah
->length
) - OSPF_LSA_HEADER_SIZE
,
1209 VALID_OPAQUE_INFO_LEN(lsah
) ? "" : "(Invalid length?)");
1212 /* Call individual output functions. */
1213 if ((functab
= ospf_opaque_functab_lookup (lsa
)) != NULL
)
1214 if (functab
->show_opaque_info
!= NULL
)
1215 (* functab
->show_opaque_info
)(vty
, lsa
);
1221 ospf_opaque_lsa_dump (struct stream
*s
, u_int16_t length
)
1223 struct ospf_lsa lsa
;
1225 lsa
.data
= (struct lsa_header
*) STREAM_PNT (s
);
1226 show_opaque_info_detail (NULL
, &lsa
);
1231 ospf_opaque_lsa_install_hook (struct ospf_lsa
*lsa
)
1233 struct list
*funclist
;
1237 * Some Opaque-LSA user may want to monitor every LSA installation
1238 * into the LSDB, regardless with target LSA type.
1240 funclist
= ospf_opaque_wildcard_funclist
;
1241 if (new_lsa_callback (funclist
, lsa
) != 0)
1244 funclist
= ospf_opaque_type9_funclist
;
1245 if (new_lsa_callback (funclist
, lsa
) != 0)
1248 funclist
= ospf_opaque_type10_funclist
;
1249 if (new_lsa_callback (funclist
, lsa
) != 0)
1252 funclist
= ospf_opaque_type11_funclist
;
1253 if (new_lsa_callback (funclist
, lsa
) != 0)
1262 ospf_opaque_lsa_delete_hook (struct ospf_lsa
*lsa
)
1264 struct list
*funclist
;
1268 * Some Opaque-LSA user may want to monitor every LSA deletion
1269 * from the LSDB, regardless with target LSA type.
1271 funclist
= ospf_opaque_wildcard_funclist
;
1272 if (del_lsa_callback (funclist
, lsa
) != 0)
1275 funclist
= ospf_opaque_type9_funclist
;
1276 if (del_lsa_callback (funclist
, lsa
) != 0)
1279 funclist
= ospf_opaque_type10_funclist
;
1280 if (del_lsa_callback (funclist
, lsa
) != 0)
1283 funclist
= ospf_opaque_type11_funclist
;
1284 if (del_lsa_callback (funclist
, lsa
) != 0)
1292 /*------------------------------------------------------------------------*
1293 * Followings are Opaque-LSA origination/refresh management functions.
1294 *------------------------------------------------------------------------*/
1296 static int ospf_opaque_type9_lsa_originate (struct thread
*t
);
1297 static int ospf_opaque_type10_lsa_originate (struct thread
*t
);
1298 static int ospf_opaque_type11_lsa_originate (struct thread
*t
);
1299 static void ospf_opaque_lsa_reoriginate_resume (struct list
*listtop
, void *arg
);
1302 ospf_opaque_lsa_originate_schedule (struct ospf_interface
*oi
, int *delay0
)
1305 struct ospf_area
*area
;
1306 struct listnode
*node
, *nnode
;
1307 struct opaque_info_per_type
*oipt
;
1310 if ((top
= oi_to_top (oi
)) == NULL
|| (area
= oi
->area
) == NULL
)
1312 zlog_warn ("ospf_opaque_lsa_originate_schedule: Invalid argument?");
1316 /* It may not a right time to schedule origination now. */
1317 if (! CHECK_FLAG (top
->opaque
, OPAQUE_OPERATION_READY_BIT
))
1319 if (IS_DEBUG_OSPF_EVENT
)
1320 zlog_debug ("ospf_opaque_lsa_originate_schedule: Not operational.");
1321 goto out
; /* This is not an error. */
1328 * There might be some entries that have been waiting for triggering
1329 * of per opaque-type re-origination get resumed.
1331 ospf_opaque_lsa_reoriginate_resume ( oi
->opaque_lsa_self
, (void *) oi
);
1332 ospf_opaque_lsa_reoriginate_resume (area
->opaque_lsa_self
, (void *) area
);
1333 ospf_opaque_lsa_reoriginate_resume ( top
->opaque_lsa_self
, (void *) top
);
1336 * Now, schedule origination of all Opaque-LSAs per opaque-type.
1338 if (! list_isempty (ospf_opaque_type9_funclist
)
1339 && list_isempty (oi
->opaque_lsa_self
)
1340 && oi
->t_opaque_lsa_self
== NULL
)
1342 if (IS_DEBUG_OSPF_EVENT
)
1343 zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d ms later.", delay
);
1344 oi
->t_opaque_lsa_self
= NULL
;
1345 thread_add_timer_msec(master
, ospf_opaque_type9_lsa_originate
, oi
, delay
,
1346 &oi
->t_opaque_lsa_self
);
1347 delay
+= top
->min_ls_interval
;
1350 if (! list_isempty (ospf_opaque_type10_funclist
)
1351 && list_isempty (area
->opaque_lsa_self
)
1352 && area
->t_opaque_lsa_self
== NULL
)
1355 * One AREA may contain multiple OIs, but above 2nd and 3rd
1356 * conditions prevent from scheduling the originate function
1359 if (IS_DEBUG_OSPF_EVENT
)
1360 zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d ms later.", delay
);
1361 area
->t_opaque_lsa_self
= NULL
;
1362 thread_add_timer_msec(master
, ospf_opaque_type10_lsa_originate
, area
, delay
,
1363 &area
->t_opaque_lsa_self
);
1364 delay
+= top
->min_ls_interval
;
1367 if (! list_isempty (ospf_opaque_type11_funclist
)
1368 && list_isempty (top
->opaque_lsa_self
)
1369 && top
->t_opaque_lsa_self
== NULL
)
1372 * One OSPF may contain multiple AREAs, but above 2nd and 3rd
1373 * conditions prevent from scheduling the originate function
1376 if (IS_DEBUG_OSPF_EVENT
)
1377 zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d ms later.", delay
);
1378 top
->t_opaque_lsa_self
= NULL
;
1379 thread_add_timer_msec(master
, ospf_opaque_type11_lsa_originate
, top
, delay
,
1380 &top
->t_opaque_lsa_self
);
1381 delay
+= top
->min_ls_interval
;
1385 * Following section treats a special situation that this node's
1386 * opaque capability has changed as "ON -> OFF -> ON".
1388 if (! list_isempty (ospf_opaque_type9_funclist
)
1389 && ! list_isempty (oi
->opaque_lsa_self
))
1391 for (ALL_LIST_ELEMENTS (oi
->opaque_lsa_self
, node
, nnode
, oipt
))
1394 * removed the test for
1395 * (! list_isempty (oipt->id_list)) * Handler is already active. *
1396 * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
1399 if (oipt
->t_opaque_lsa_self
!= NULL
/* Waiting for a thread call. */
1400 || oipt
->status
== PROC_SUSPEND
) /* Cannot originate now. */
1403 ospf_opaque_lsa_reoriginate_schedule ((void *) oi
,
1404 OSPF_OPAQUE_LINK_LSA
, oipt
->opaque_type
);
1408 if (! list_isempty (ospf_opaque_type10_funclist
)
1409 && ! list_isempty (area
->opaque_lsa_self
))
1411 for (ALL_LIST_ELEMENTS (area
->opaque_lsa_self
, node
, nnode
, oipt
))
1414 * removed the test for
1415 * (! list_isempty (oipt->id_list)) * Handler is already active. *
1416 * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
1419 if (oipt
->t_opaque_lsa_self
!= NULL
/* Waiting for a thread call. */
1420 || oipt
->status
== PROC_SUSPEND
) /* Cannot originate now. */
1423 ospf_opaque_lsa_reoriginate_schedule ((void *) area
,
1424 OSPF_OPAQUE_AREA_LSA
, oipt
->opaque_type
);
1428 if (! list_isempty (ospf_opaque_type11_funclist
)
1429 && ! list_isempty (top
->opaque_lsa_self
))
1431 for (ALL_LIST_ELEMENTS (top
->opaque_lsa_self
, node
, nnode
, oipt
))
1434 * removed the test for
1435 * (! list_isempty (oipt->id_list)) * Handler is already active. *
1436 * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
1439 if (oipt
->t_opaque_lsa_self
!= NULL
/* Waiting for a thread call. */
1440 || oipt
->status
== PROC_SUSPEND
) /* Cannot originate now. */
1443 ospf_opaque_lsa_reoriginate_schedule ((void *) top
,
1444 OSPF_OPAQUE_AS_LSA
, oipt
->opaque_type
);
1456 ospf_opaque_type9_lsa_originate (struct thread
*t
)
1458 struct ospf_interface
*oi
;
1461 oi
= THREAD_ARG (t
);
1462 oi
->t_opaque_lsa_self
= NULL
;
1464 if (IS_DEBUG_OSPF_EVENT
)
1465 zlog_debug ("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s",
1468 rc
= opaque_lsa_originate_callback (ospf_opaque_type9_funclist
, oi
);
1474 ospf_opaque_type10_lsa_originate (struct thread
*t
)
1476 struct ospf_area
*area
;
1479 area
= THREAD_ARG (t
);
1480 area
->t_opaque_lsa_self
= NULL
;
1482 if (IS_DEBUG_OSPF_EVENT
)
1483 zlog_debug ("Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s",
1484 inet_ntoa (area
->area_id
));
1486 rc
= opaque_lsa_originate_callback (ospf_opaque_type10_funclist
, area
);
1492 ospf_opaque_type11_lsa_originate (struct thread
*t
)
1497 top
= THREAD_ARG (t
);
1498 top
->t_opaque_lsa_self
= NULL
;
1500 if (IS_DEBUG_OSPF_EVENT
)
1501 zlog_debug ("Timer[Type11-LSA]: Originate AS-External Opaque-LSAs");
1503 rc
= opaque_lsa_originate_callback (ospf_opaque_type11_funclist
, top
);
1509 ospf_opaque_lsa_reoriginate_resume (struct list
*listtop
, void *arg
)
1511 struct listnode
*node
, *nnode
;
1512 struct opaque_info_per_type
*oipt
;
1513 struct ospf_opaque_functab
*functab
;
1515 if (listtop
== NULL
)
1519 * Pickup oipt entries those which in SUSPEND status, and give
1520 * them a chance to start re-origination now.
1522 for (ALL_LIST_ELEMENTS (listtop
, node
, nnode
, oipt
))
1524 if (oipt
->status
!= PROC_SUSPEND
)
1527 oipt
->status
= PROC_NORMAL
;
1529 if ((functab
= oipt
->functab
) == NULL
1530 || functab
->lsa_originator
== NULL
)
1533 if ((* functab
->lsa_originator
)(arg
) != 0)
1535 zlog_warn ("ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", oipt
->opaque_type
);
1545 ospf_opaque_lsa_install (struct ospf_lsa
*lsa
, int rt_recalc
)
1547 struct ospf_lsa
*new = NULL
;
1548 struct opaque_info_per_type
*oipt
;
1549 struct opaque_info_per_id
*oipi
;
1552 /* Don't take "rt_recalc" into consideration for now. *//* XXX */
1554 if (! IS_LSA_SELF (lsa
))
1556 new = lsa
; /* Don't touch this LSA. */
1560 if (IS_DEBUG_OSPF (lsa
, LSA_INSTALL
))
1561 zlog_debug ("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
)));
1563 /* Replace the existing lsa with the new one. */
1564 if ((oipt
= lookup_opaque_info_by_type (lsa
)) != NULL
1565 && (oipi
= lookup_opaque_info_by_id (oipt
, lsa
)) != NULL
)
1567 ospf_lsa_unlock (&oipi
->lsa
);
1568 oipi
->lsa
= ospf_lsa_lock (lsa
);
1570 /* Register the new lsa entry and get its control info. */
1572 if ((oipi
= register_opaque_lsa (lsa
)) == NULL
)
1574 zlog_warn ("ospf_opaque_lsa_install: register_opaque_lsa() ?");
1579 * Make use of a common mechanism (ospf_lsa_refresh_walker)
1580 * for periodic refresh of self-originated Opaque-LSAs.
1582 switch (lsa
->data
->type
)
1584 case OSPF_OPAQUE_LINK_LSA
:
1585 if ((top
= oi_to_top (lsa
->oi
)) == NULL
)
1587 /* Above conditions must have passed. */
1588 zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
1592 case OSPF_OPAQUE_AREA_LSA
:
1593 if (lsa
->area
== NULL
|| (top
= lsa
->area
->ospf
) == NULL
)
1595 /* Above conditions must have passed. */
1596 zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
1600 case OSPF_OPAQUE_AS_LSA
:
1601 top
= ospf_lookup ();
1602 if (lsa
->area
!= NULL
&& (top
= lsa
->area
->ospf
) == NULL
)
1604 /* Above conditions must have passed. */
1605 zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
1610 zlog_warn ("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", lsa
->data
->type
);
1614 ospf_refresher_register_lsa (top
, lsa
);
1622 ospf_opaque_lsa_refresh (struct ospf_lsa
*lsa
)
1625 struct ospf_opaque_functab
*functab
;
1626 struct ospf_lsa
*new = NULL
;
1628 ospf
= ospf_lookup ();
1630 if ((functab
= ospf_opaque_functab_lookup (lsa
)) == NULL
1631 || functab
->lsa_refresher
== NULL
)
1634 * Though this LSA seems to have originated on this node, the
1635 * handling module for this "lsa-type and opaque-type" was
1636 * already deleted sometime ago.
1637 * Anyway, this node still has a responsibility to flush this
1638 * LSA from the routing domain.
1640 if (IS_DEBUG_OSPF_EVENT
)
1641 zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
1643 lsa
->data
->ls_age
= htons (OSPF_LSA_MAXAGE
);
1644 ospf_lsa_flush (ospf
, lsa
);
1647 new = (* functab
->lsa_refresher
)(lsa
);
1652 /*------------------------------------------------------------------------*
1653 * Followings are re-origination/refresh/flush operations of Opaque-LSAs,
1654 * triggered by external interventions (vty session, signaling, etc).
1655 *------------------------------------------------------------------------*/
1657 #define OSPF_OPAQUE_TIMER_ON(T,F,L,V) thread_add_timer_msec (master, (F), (L), (V), &(T))
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:"
1684 " Type-9 Opaque-LSA: Invalid parameter?");
1687 if ((top
= oi_to_top (oi
)) == NULL
)
1689 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?",
1693 if (!list_isempty (ospf_opaque_type9_funclist
)
1694 && list_isempty (oi
->opaque_lsa_self
)
1695 && oi
->t_opaque_lsa_self
!= NULL
)
1697 zlog_warn ("Type-9 Opaque-LSA (opaque_type=%u):"
1698 " Common origination for OI(%s) has already started",
1699 opaque_type
, IF_NAME (oi
));
1702 func
= ospf_opaque_type9_lsa_reoriginate_timer
;
1704 case OSPF_OPAQUE_AREA_LSA
:
1705 if ((area
= (struct ospf_area
*) lsa_type_dependent
) == NULL
)
1707 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
1708 " Type-10 Opaque-LSA: Invalid parameter?");
1711 if ((top
= area
->ospf
) == NULL
)
1713 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
1714 " AREA(%s) -> TOP?", inet_ntoa (area
->area_id
));
1717 if (!list_isempty (ospf_opaque_type10_funclist
)
1718 && list_isempty (area
->opaque_lsa_self
)
1719 && area
->t_opaque_lsa_self
!= NULL
)
1721 zlog_warn ("Type-10 Opaque-LSA (opaque_type=%u):"
1722 " Common origination for AREA(%s) has already started",
1723 opaque_type
, inet_ntoa (area
->area_id
));
1726 func
= ospf_opaque_type10_lsa_reoriginate_timer
;
1728 case OSPF_OPAQUE_AS_LSA
:
1729 if ((top
= (struct ospf
*) lsa_type_dependent
) == NULL
)
1731 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
1732 " Type-11 Opaque-LSA: Invalid parameter?");
1735 if (!list_isempty (ospf_opaque_type11_funclist
)
1736 && list_isempty (top
->opaque_lsa_self
)
1737 && top
->t_opaque_lsa_self
!= NULL
)
1739 zlog_warn ("Type-11 Opaque-LSA (opaque_type=%u):"
1740 " Common origination has already started", opaque_type
);
1744 /* Fake "area" to pass "ospf" to a lookup function later. */
1748 func
= ospf_opaque_type11_lsa_reoriginate_timer
;
1751 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
1752 " Unexpected LSA-type(%u)",
1757 /* It may not a right time to schedule reorigination now. */
1758 if (!CHECK_FLAG (top
->opaque
, OPAQUE_OPERATION_READY_BIT
))
1760 if (IS_DEBUG_OSPF_EVENT
)
1761 zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Not operational.");
1762 goto out
; /* This is not an error. */
1765 /* Generate a dummy lsa to be passed for a lookup function. */
1766 lsa
= pseudo_lsa (oi
, area
, lsa_type
, opaque_type
);
1768 if ((oipt
= lookup_opaque_info_by_type (lsa
)) == NULL
)
1770 struct ospf_opaque_functab
*functab
;
1771 if ((functab
= ospf_opaque_functab_lookup (lsa
)) == NULL
)
1773 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
1774 " No associated function?: lsa_type(%u),"
1776 lsa_type
, opaque_type
);
1779 if ((oipt
= register_opaque_info_per_type (functab
, lsa
)) == NULL
)
1781 zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
1782 " Cannot get a control info?: lsa_type(%u),"
1784 lsa_type
, opaque_type
);
1789 if (oipt
->t_opaque_lsa_self
!= NULL
)
1791 if (IS_DEBUG_OSPF_EVENT
)
1792 zlog_debug ("Type-%u Opaque-LSA has already scheduled to"
1793 " RE-ORIGINATE: [opaque-type=%u]",
1794 lsa_type
, GET_OPAQUE_TYPE (ntohl (lsa
->data
->id
.s_addr
)));
1799 * Different from initial origination time, in which various conditions
1800 * (opaque capability, neighbor status etc) are assured by caller of
1801 * the originating function "ospf_opaque_lsa_originate_schedule ()",
1802 * it is highly possible that these conditions might not be satisfied
1803 * at the time of re-origination function is to be called.
1805 delay
= top
->min_ls_interval
; /* XXX */
1807 if (IS_DEBUG_OSPF_EVENT
)
1808 zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d"
1809 " ms later: [opaque-type=%u]",
1811 GET_OPAQUE_TYPE (ntohl (lsa
->data
->id
.s_addr
)));
1813 OSPF_OPAQUE_TIMER_ON (oipt
->t_opaque_lsa_self
, func
, oipt
, delay
* 1000);
1819 static struct ospf_lsa
*
1820 pseudo_lsa (struct ospf_interface
*oi
, struct ospf_area
*area
,
1821 u_char lsa_type
, u_char opaque_type
)
1823 static struct ospf_lsa lsa
= { 0 };
1824 static struct lsa_header lsah
= { 0 };
1831 lsah
.type
= lsa_type
;
1832 tmp
= SET_OPAQUE_LSID (opaque_type
, 0); /* Opaque-ID is unused here. */
1833 lsah
.id
.s_addr
= htonl (tmp
);
1839 ospf_opaque_type9_lsa_reoriginate_timer (struct thread
*t
)
1841 struct opaque_info_per_type
*oipt
;
1842 struct ospf_opaque_functab
*functab
;
1844 struct ospf_interface
*oi
;
1847 oipt
= THREAD_ARG (t
);
1848 oipt
->t_opaque_lsa_self
= NULL
;
1850 if ((functab
= oipt
->functab
) == NULL
1851 || functab
->lsa_originator
== NULL
)
1853 zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: No associated function?");
1857 oi
= (struct ospf_interface
*) oipt
->owner
;
1858 if ((top
= oi_to_top (oi
)) == NULL
)
1860 zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?");
1864 if (! CHECK_FLAG (top
->config
, OSPF_OPAQUE_CAPABLE
)
1865 || ! ospf_if_is_enable (oi
)
1866 || ospf_nbr_count_opaque_capable (oi
) == 0)
1868 if (IS_DEBUG_OSPF_EVENT
)
1869 zlog_debug ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt
->opaque_type
);
1871 oipt
->status
= PROC_SUSPEND
;
1876 if (IS_DEBUG_OSPF_EVENT
)
1877 zlog_debug ("Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", oipt
->opaque_type
, IF_NAME (oi
));
1879 rc
= (* functab
->lsa_originator
)(oi
);
1885 ospf_opaque_type10_lsa_reoriginate_timer (struct thread
*t
)
1887 struct opaque_info_per_type
*oipt
;
1888 struct ospf_opaque_functab
*functab
;
1889 struct listnode
*node
, *nnode
;
1891 struct ospf_area
*area
;
1892 struct ospf_interface
*oi
;
1895 oipt
= THREAD_ARG (t
);
1896 oipt
->t_opaque_lsa_self
= NULL
;
1898 if ((functab
= oipt
->functab
) == NULL
1899 || functab
->lsa_originator
== NULL
)
1901 zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: No associated function?");
1905 area
= (struct ospf_area
*) oipt
->owner
;
1906 if (area
== NULL
|| (top
= area
->ospf
) == NULL
)
1908 zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");
1912 /* There must be at least one "opaque-capable, full-state" neighbor. */
1914 for (ALL_LIST_ELEMENTS (area
->oiflist
, node
, nnode
, oi
))
1916 if ((n
= ospf_nbr_count_opaque_capable (oi
)) > 0)
1920 if (n
== 0 || ! CHECK_FLAG (top
->config
, OSPF_OPAQUE_CAPABLE
))
1922 if (IS_DEBUG_OSPF_EVENT
)
1923 zlog_debug ("Suspend re-origination of Type-10 Opaque-LSAs"
1924 " (opaque-type=%u) for a while...",
1927 oipt
->status
= PROC_SUSPEND
;
1932 if (IS_DEBUG_OSPF_EVENT
)
1933 zlog_debug ("Timer[Type10-LSA]: Re-originate Opaque-LSAs"
1934 " (opaque-type=%u) for Area %s",
1935 oipt
->opaque_type
, inet_ntoa (area
->area_id
));
1937 rc
= (* functab
->lsa_originator
)(area
);
1943 ospf_opaque_type11_lsa_reoriginate_timer (struct thread
*t
)
1945 struct opaque_info_per_type
*oipt
;
1946 struct ospf_opaque_functab
*functab
;
1950 oipt
= THREAD_ARG (t
);
1951 oipt
->t_opaque_lsa_self
= NULL
;
1953 if ((functab
= oipt
->functab
) == NULL
1954 || functab
->lsa_originator
== NULL
)
1956 zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer:"
1957 " No associated function?");
1961 if ((top
= (struct ospf
*) oipt
->owner
) == NULL
)
1963 zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?");
1967 if (! CHECK_FLAG (top
->config
, OSPF_OPAQUE_CAPABLE
))
1969 if (IS_DEBUG_OSPF_EVENT
)
1970 zlog_debug ("Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", oipt
->opaque_type
);
1972 oipt
->status
= PROC_SUSPEND
;
1977 if (IS_DEBUG_OSPF_EVENT
)
1978 zlog_debug ("Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", oipt
->opaque_type
);
1980 rc
= (* functab
->lsa_originator
)(top
);
1986 ospf_opaque_lsa_refresh_schedule (struct ospf_lsa
*lsa0
)
1988 struct opaque_info_per_type
*oipt
;
1989 struct opaque_info_per_id
*oipi
;
1990 struct ospf_lsa
*lsa
;
1994 if ((oipt
= lookup_opaque_info_by_type (lsa0
)) == NULL
1995 || (oipi
= lookup_opaque_info_by_id (oipt
, lsa0
)) == NULL
)
1997 zlog_warn ("ospf_opaque_lsa_refresh_schedule: Invalid parameter?");
2001 /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
2002 if ((lsa
= oipi
->lsa
) == NULL
)
2004 zlog_warn ("ospf_opaque_lsa_refresh_schedule: Something wrong?");
2008 if (oipi
->t_opaque_lsa_self
!= NULL
)
2010 if (IS_DEBUG_OSPF_EVENT
)
2011 zlog_debug ("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
)));
2015 /* Delete this lsa from neighbor retransmit-list. */
2016 switch (lsa
->data
->type
)
2018 case OSPF_OPAQUE_LINK_LSA
:
2019 case OSPF_OPAQUE_AREA_LSA
:
2020 ospf_ls_retransmit_delete_nbr_area (lsa
->area
, lsa
);
2022 case OSPF_OPAQUE_AS_LSA
:
2023 top
= ospf_lookup ();
2024 if ((lsa0
->area
!= NULL
) && (lsa0
->area
->ospf
!= NULL
))
2025 top
= lsa0
->area
->ospf
;
2026 ospf_ls_retransmit_delete_nbr_as (top
, lsa
);
2029 zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa
->data
->type
);
2033 delay
= ospf_lsa_refresh_delay (lsa
);
2035 if (IS_DEBUG_OSPF_EVENT
)
2036 zlog_debug ("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
)));
2038 OSPF_OPAQUE_TIMER_ON (oipi
->t_opaque_lsa_self
,
2039 ospf_opaque_lsa_refresh_timer
, oipi
, delay
* 1000);
2045 ospf_opaque_lsa_refresh_timer (struct thread
*t
)
2047 struct opaque_info_per_id
*oipi
;
2048 struct ospf_opaque_functab
*functab
;
2049 struct ospf_lsa
*lsa
;
2051 if (IS_DEBUG_OSPF_EVENT
)
2052 zlog_debug ("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)");
2054 oipi
= THREAD_ARG (t
);
2055 oipi
->t_opaque_lsa_self
= NULL
;
2057 if ((lsa
= oipi
->lsa
) != NULL
)
2058 if ((functab
= oipi
->opqctl_type
->functab
) != NULL
)
2059 if (functab
->lsa_refresher
!= NULL
)
2060 (* functab
->lsa_refresher
)(lsa
);
2066 ospf_opaque_lsa_flush_schedule (struct ospf_lsa
*lsa0
)
2068 struct opaque_info_per_type
*oipt
;
2069 struct opaque_info_per_id
*oipi
;
2070 struct ospf_lsa
*lsa
;
2073 top
= ospf_lookup ();
2075 if ((oipt
= lookup_opaque_info_by_type (lsa0
)) == NULL
2076 || (oipi
= lookup_opaque_info_by_id (oipt
, lsa0
)) == NULL
)
2078 zlog_warn ("ospf_opaque_lsa_flush_schedule: Invalid parameter?");
2082 /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
2083 if ((lsa
= oipi
->lsa
) == NULL
)
2085 zlog_warn ("ospf_opaque_lsa_flush_schedule: Something wrong?");
2089 /* Delete this lsa from neighbor retransmit-list. */
2090 switch (lsa
->data
->type
)
2092 case OSPF_OPAQUE_LINK_LSA
:
2093 case OSPF_OPAQUE_AREA_LSA
:
2094 ospf_ls_retransmit_delete_nbr_area (lsa
->area
, lsa
);
2096 case OSPF_OPAQUE_AS_LSA
:
2097 if ((lsa0
->area
!= NULL
) && (lsa0
->area
->ospf
!= NULL
))
2098 top
= lsa0
->area
->ospf
;
2099 ospf_ls_retransmit_delete_nbr_as (top
, lsa
);
2102 zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa
->data
->type
);
2106 /* Dequeue listnode entry from the list. */
2107 listnode_delete (oipt
->id_list
, oipi
);
2109 /* Avoid misjudgement in the next lookup. */
2110 if (listcount (oipt
->id_list
) == 0)
2111 oipt
->id_list
->head
= oipt
->id_list
->tail
= NULL
;
2113 /* Disassociate internal control information with the given lsa. */
2114 free_opaque_info_per_id ((void *) oipi
);
2116 /* Force given lsa's age to MaxAge. */
2117 lsa
->data
->ls_age
= htons (OSPF_LSA_MAXAGE
);
2119 if (IS_DEBUG_OSPF_EVENT
)
2120 zlog_debug ("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
)));
2122 /* This lsa will be flushed and removed eventually. */
2123 ospf_lsa_flush (top
, lsa
);
2130 ospf_opaque_self_originated_lsa_received (struct ospf_neighbor
*nbr
,
2131 struct ospf_lsa
*lsa
)
2135 if ((top
= oi_to_top (nbr
->oi
)) == NULL
)
2139 * Since these LSA entries are not yet installed into corresponding
2140 * LSDB, just flush them without calling ospf_ls_maxage() afterward.
2142 lsa
->data
->ls_age
= htons (OSPF_LSA_MAXAGE
);
2143 switch (lsa
->data
->type
)
2145 case OSPF_OPAQUE_LINK_LSA
:
2146 ospf_flood_through_area (nbr
->oi
->area
, NULL
/*inbr*/, lsa
);
2148 case OSPF_OPAQUE_AREA_LSA
:
2149 ospf_flood_through_area (nbr
->oi
->area
, NULL
/*inbr*/, lsa
);
2151 case OSPF_OPAQUE_AS_LSA
:
2152 ospf_flood_through_as (top
, NULL
/*inbr*/, lsa
);
2155 zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa
->data
->type
);
2158 ospf_lsa_discard (lsa
); /* List "lsas" will be deleted by caller. */
2161 /*------------------------------------------------------------------------*
2162 * Followings are util functions; probably be used by Opaque-LSAs only...
2163 *------------------------------------------------------------------------*/
2166 oi_to_top (struct ospf_interface
*oi
)
2168 struct ospf
*top
= NULL
;
2169 struct ospf_area
*area
;
2171 if (oi
== NULL
|| (area
= oi
->area
) == NULL
|| (top
= area
->ospf
) == NULL
)
2172 zlog_warn ("Broken relationship for \"OI -> AREA -> OSPF\"?");