]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospfd.c
*: add indent control files
[mirror_frr.git] / ospfd / ospfd.c
CommitLineData
718e3744 1/* OSPF version 2 daemon program.
896014f4
DL
2 * Copyright (C) 1999, 2000 Toshiaki Takada
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
718e3744 20
21#include <zebra.h>
22
23#include "thread.h"
24#include "vty.h"
25#include "command.h"
26#include "linklist.h"
27#include "prefix.h"
28#include "table.h"
29#include "if.h"
30#include "memory.h"
31#include "stream.h"
32#include "log.h"
33#include "sockunion.h" /* for inet_aton () */
34#include "zclient.h"
35#include "plist.h"
f102e75f 36#include "sockopt.h"
567b877d 37#include "bfd.h"
8efe88ea 38#include "defaults.h"
718e3744 39
40#include "ospfd/ospfd.h"
41#include "ospfd/ospf_network.h"
42#include "ospfd/ospf_interface.h"
43#include "ospfd/ospf_ism.h"
44#include "ospfd/ospf_asbr.h"
45#include "ospfd/ospf_lsa.h"
46#include "ospfd/ospf_lsdb.h"
47#include "ospfd/ospf_neighbor.h"
48#include "ospfd/ospf_nsm.h"
49#include "ospfd/ospf_spf.h"
50#include "ospfd/ospf_packet.h"
51#include "ospfd/ospf_dump.h"
52#include "ospfd/ospf_zebra.h"
53#include "ospfd/ospf_abr.h"
54#include "ospfd/ospf_flood.h"
55#include "ospfd/ospf_route.h"
56#include "ospfd/ospf_ase.h"
57
6b0655a2 58
ae19c240 59DEFINE_QOBJ_TYPE(ospf)
edd7c245 60
020709f9 61/* OSPF process wide configuration. */
62static struct ospf_master ospf_master;
63
64/* OSPF process wide configuration pointer to export. */
65struct ospf_master *om;
718e3744 66
67extern struct zclient *zclient;
18a6dce6 68extern struct in_addr router_id_zebra;
718e3744 69
6b0655a2 70
88d6cf37 71static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
72static void ospf_network_free (struct ospf *, struct ospf_network *);
73static void ospf_area_free (struct ospf_area *);
a49eb30a 74static void ospf_network_run (struct prefix *, struct ospf_area *);
52c62ab8
JAG
75static void ospf_network_run_interface (struct ospf *, struct interface *,
76 struct prefix *, struct ospf_area *);
77static void ospf_network_run_subnet (struct ospf *, struct connected *,
78 struct prefix *, struct ospf_area *);
917e2995
SH
79static int ospf_network_match_iface (const struct connected *,
80 const struct prefix *);
88d6cf37 81static void ospf_finish_final (struct ospf *);
718e3744 82
718e3744 83#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
6b0655a2 84
718e3744 85void
68980084 86ospf_router_id_update (struct ospf *ospf)
718e3744 87{
718e3744 88 struct in_addr router_id, router_id_old;
1eb8ef25 89 struct ospf_interface *oi;
a49eb30a 90 struct interface *ifp;
52dc7ee6 91 struct listnode *node;
2c19a6ec 92 int type;
718e3744 93
0bad4851
DS
94 if (!ospf->oi_running)
95 {
96 if (IS_DEBUG_OSPF_EVENT)
97 zlog_debug ("Router ospf not configured -- Router-ID update postponed");
98 return;
99 }
100
718e3744 101 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 102 zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
718e3744 103
68980084 104 router_id_old = ospf->router_id;
718e3744 105
1670008b
AS
106 /* Select the router ID based on these priorities:
107 1. Statically assigned router ID is always the first choice.
108 2. If there is no statically assigned router ID, then try to stick
109 with the most recent value, since changing router ID's is very
110 disruptive.
111 3. Last choice: just go with whatever the zebra daemon recommends.
112 */
68980084 113 if (ospf->router_id_static.s_addr != 0)
114 router_id = ospf->router_id_static;
1670008b
AS
115 else if (ospf->router_id.s_addr != 0)
116 router_id = ospf->router_id;
718e3744 117 else
18a6dce6 118 router_id = router_id_zebra;
718e3744 119
a707247e
DS
120
121 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
718e3744 122 {
2c19a6ec 123
1eb8ef25 124 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
25a346eb
JT
125 {
126 /* Some nbrs are identified by router_id, these needs
127 * to be rebuilt. Possible optimization would be to do
128 * oi->nbr_self->router_id = router_id for
129 * !(virtual | ptop) links
130 */
58136de9 131 ospf_nbr_self_reset (oi, router_id);
25a346eb 132 }
718e3744 133
134 /* If AS-external-LSA is queued, then flush those LSAs. */
68980084 135 if (router_id_old.s_addr == 0 && ospf->external_origin)
718e3744 136 {
718e3744 137 /* Originate each redistributed external route. */
138 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
68980084 139 if (ospf->external_origin & (1 << type))
ffa2c898
QY
140 thread_add_event(master, ospf_external_lsa_originate_timer,
141 ospf, type, NULL);
718e3744 142 /* Originate Deafult. */
68980084 143 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
ffa2c898
QY
144 thread_add_event(master, ospf_default_originate_timer, ospf, 0,
145 NULL);
718e3744 146
68980084 147 ospf->external_origin = 0;
718e3744 148 }
149
2c19a6ec
DS
150 /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF flag */
151 if (ospf->lsdb)
152 {
153 struct route_node *rn;
154 struct ospf_lsa *lsa;
155
156 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
157 if (IS_LSA_SELF(lsa))
158 ospf_lsa_flush_schedule(ospf, lsa);
159 }
160
161 ospf->router_id = router_id;
162 if (IS_DEBUG_OSPF_EVENT)
163 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
164
165 /* Flush (inline) all external LSAs which now match the new router-id,
166 need to adjust the OSPF_LSA_SELF flag, so the flush doesnt hit
167 asserts in ospf_refresher_unregister_lsa(). This step is needed
168 because the current quagga code does look-up for self-originated LSAs
169 based on the self router-id alone but expects OSPF_LSA_SELF to be
170 properly set */
171 if (ospf->lsdb)
172 {
173 struct route_node *rn;
174 struct ospf_lsa *lsa;
175
176 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
177 {
178 /* AdvRouter and Router ID is the same. */
179 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
180 {
181 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
182 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
183 ospf_lsa_flush_schedule(ospf, lsa);
184 }
185 }
186 }
187
188 /* Originate each redistributed external route. */
189 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
ffa2c898
QY
190 thread_add_event(master, ospf_external_lsa_originate_timer, ospf,
191 type, NULL);
192 thread_add_event(master, ospf_default_originate_timer, ospf, 0, NULL);
2c19a6ec 193
c363d386
PJ
194 /* update router-lsa's for each area */
195 ospf_router_lsa_update (ospf);
b29800a6 196
197 /* update ospf_interface's */
a49eb30a
JT
198 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
199 ospf_if_update (ospf, ifp);
718e3744 200 }
201}
6b0655a2 202
718e3744 203/* For OSPF area sort by area id. */
4dadc291 204static int
718e3744 205ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
206{
207 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
208 return 1;
209 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
210 return -1;
211 return 0;
212}
213
214/* Allocate new ospf structure. */
4dadc291 215static struct ospf *
7c8ff89e 216ospf_new (u_short instance)
718e3744 217{
218 int i;
219
220 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
221
7c8ff89e 222 new->instance = instance;
718e3744 223 new->router_id.s_addr = htonl (0);
224 new->router_id_static.s_addr = htonl (0);
225
d57834f6 226 new->abr_type = OSPF_ABR_DEFAULT;
718e3744 227 new->oiflist = list_new ();
228 new->vlinks = list_new ();
229 new->areas = list_new ();
230 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
231 new->networks = route_table_init ();
232 new->nbr_nbma = route_table_init ();
233
234 new->lsdb = ospf_lsdb_new ();
235
236 new->default_originate = DEFAULT_ORIGINATE_NONE;
237
7ffa8fa2
PJ
238 new->passive_interface_default = OSPF_IF_ACTIVE;
239
718e3744 240 new->new_external_route = route_table_init ();
241 new->old_external_route = route_table_init ();
242 new->external_lsas = route_table_init ();
88d6cf37 243
244 new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
31a5976b 245 new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
4ba4fc85
AB
246 new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
247
718e3744 248 /* Distribute parameter init. */
249 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
250 {
0d9551dc 251 new->dtag[i] = 0;
718e3744 252 }
253 new->default_metric = -1;
254 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
255
16e56a14
MR
256 /* LSA timers */
257 new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
258 new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
259
718e3744 260 /* SPF timer value init. */
261 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
262 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
d24f6e2a 263 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
264 new->spf_hold_multiplier = 1;
718e3744 265
266 /* MaxAge init. */
2449fcd6 267 new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
91e6a0e5 268 new->maxage_lsa = route_table_init();
66e78ae6
QY
269 new->t_maxage_walker = NULL;
270 thread_add_timer(master, ospf_lsa_maxage_walker, new, OSPF_LSA_MAXAGE_CHECK_INTERVAL,
271 &new->t_maxage_walker);
718e3744 272
273 /* Distance table init. */
274 new->distance_table = route_table_init ();
275
276 new->lsa_refresh_queue.index = 0;
277 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
66e78ae6
QY
278 new->t_lsa_refresher = NULL;
279 thread_add_timer(master, ospf_lsa_refresh_walker, new, new->lsa_refresh_interval,
280 &new->t_lsa_refresher);
cf672a86 281 new->lsa_refresher_started = monotime(NULL);
718e3744 282
5c33349b 283 if ((new->fd = ospf_sock_init()) < 0)
284 {
285 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
286 "a socket");
287 exit(1);
288 }
289 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
290 {
291 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
292 OSPF_MAX_PACKET_SIZE+1);
293 exit(1);
294 }
66e78ae6
QY
295 new->t_read = NULL;
296 thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
718e3744 297 new->oi_write_q = list_new ();
e8f45e82 298 new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
718e3744 299
692c7954 300 /* Enable "log-adjacency-changes" */
8efe88ea 301#if DFLT_OSPF_LOG_ADJACENCY_CHANGES
692c7954 302 SET_FLAG(new->config, OSPF_LOG_ADJACENCY_CHANGES);
8efe88ea 303#endif
3e7c8d04 304
ae19c240
DL
305 QOBJ_REG (new, ospf);
306
718e3744 307 return new;
308}
309
310struct ospf *
020709f9 311ospf_lookup ()
718e3744 312{
020709f9 313 if (listcount (om->ospf) == 0)
314 return NULL;
718e3744 315
16f1b9ee 316 return listgetdata ((struct listnode *)listhead (om->ospf));
020709f9 317}
318
7c8ff89e
DS
319struct ospf *
320ospf_lookup_instance (u_short instance)
321{
322 struct ospf *ospf;
323 struct listnode *node, *nnode;
324
325 if (listcount (om->ospf) == 0)
326 return NULL;
327
328 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
329 if ((ospf->instance == 0 && instance == 0)
330 || (ospf->instance && instance && ospf->instance == instance))
331 return ospf;
332
333 return NULL;
334}
335
52c62ab8
JAG
336static int
337ospf_is_ready (struct ospf *ospf)
338{
339 /* OSPF must be on and Router-ID must be configured. */
340 if (!ospf || ospf->router_id.s_addr == 0)
341 return 0;
342
343 return 1;
344}
345
4dadc291 346static void
020709f9 347ospf_add (struct ospf *ospf)
348{
349 listnode_add (om->ospf, ospf);
350}
718e3744 351
4dadc291 352static void
020709f9 353ospf_delete (struct ospf *ospf)
354{
355 listnode_delete (om->ospf, ospf);
356}
68980084 357
020709f9 358struct ospf *
359ospf_get ()
360{
361 struct ospf *ospf;
362
363 ospf = ospf_lookup ();
364 if (ospf == NULL)
365 {
7c8ff89e
DS
366 ospf = ospf_new (0);
367 ospf_add (ospf);
368
369 if (ospf->router_id_static.s_addr == 0)
370 ospf_router_id_update (ospf);
371
7c8ff89e 372 ospf_opaque_type11_lsa_init (ospf);
7c8ff89e
DS
373 }
374
375 return ospf;
376}
377
378struct ospf *
379ospf_get_instance (u_short instance)
380{
381 struct ospf *ospf;
382
383 ospf = ospf_lookup_instance (instance);
384 if (ospf == NULL)
385 {
386 ospf = ospf_new (instance);
020709f9 387 ospf_add (ospf);
388
389 if (ospf->router_id_static.s_addr == 0)
390 ospf_router_id_update (ospf);
718e3744 391
020709f9 392 ospf_opaque_type11_lsa_init (ospf);
020709f9 393 }
68980084 394
395 return ospf;
718e3744 396}
6b0655a2 397
c9c93d50 398/* Handle the second half of deferred shutdown. This is called either
399 * from the deferred-shutdown timer thread, or directly through
400 * ospf_deferred_shutdown_check.
88d6cf37 401 *
402 * Function is to cleanup G-R state, if required then call ospf_finish_final
403 * to complete shutdown of this ospf instance. Possibly exit if the
404 * whole process is being shutdown and this was the last OSPF instance.
405 */
406static void
c9c93d50 407ospf_deferred_shutdown_finish (struct ospf *ospf)
88d6cf37 408{
409 ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
c9c93d50 410 OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
88d6cf37 411
412 ospf_finish_final (ospf);
413
414 /* *ospf is now invalid */
415
416 /* ospfd being shut-down? If so, was this the last ospf instance? */
417 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
418 && (listcount (om->ospf) == 0))
66dd6fdb 419 {
66dd6fdb
DS
420 exit (0);
421 }
88d6cf37 422
423 return;
424}
425
426/* Timer thread for G-R */
427static int
c9c93d50 428ospf_deferred_shutdown_timer (struct thread *t)
88d6cf37 429{
430 struct ospf *ospf = THREAD_ARG(t);
431
c9c93d50 432 ospf_deferred_shutdown_finish (ospf);
88d6cf37 433
434 return 0;
435}
436
c9c93d50 437/* Check whether deferred-shutdown must be scheduled, otherwise call
88d6cf37 438 * down directly into second-half of instance shutdown.
439 */
440static void
c9c93d50 441ospf_deferred_shutdown_check (struct ospf *ospf)
88d6cf37 442{
443 unsigned long timeout;
444 struct listnode *ln;
445 struct ospf_area *area;
446
c9c93d50 447 /* deferred shutdown already running? */
448 if (ospf->t_deferred_shutdown)
88d6cf37 449 return;
450
451 /* Should we try push out max-metric LSAs? */
452 if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
453 {
454 for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
455 {
456 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
457
458 if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
c363d386 459 ospf_router_lsa_update_area (area);
88d6cf37 460 }
461 timeout = ospf->stub_router_shutdown_time;
462 }
463 else
c9c93d50 464 {
465 /* No timer needed */
466 ospf_deferred_shutdown_finish (ospf);
467 return;
468 }
88d6cf37 469
c9c93d50 470 OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
88d6cf37 471 timeout);
472 return;
473}
6b0655a2 474
88d6cf37 475/* Shut down the entire process */
476void
477ospf_terminate (void)
478{
479 struct ospf *ospf;
480 struct listnode *node, *nnode;
481
482 /* shutdown already in progress */
483 if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
484 return;
485
486 SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
487
4056a544
AS
488 /* exit immediately if OSPF not actually running */
489 if (listcount(om->ospf) == 0)
490 exit(0);
491
567b877d 492 bfd_gbl_exit();
88d6cf37 493 for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
494 ospf_finish (ospf);
495
496 /* Deliberately go back up, hopefully to thread scheduler, as
497 * One or more ospf_finish()'s may have deferred shutdown to a timer
498 * thread
499 */
ee514f71
DS
500 zclient_stop (zclient);
501 zclient_free (zclient);
88d6cf37 502}
718e3744 503
504void
505ospf_finish (struct ospf *ospf)
88d6cf37 506{
c9c93d50 507 /* let deferred shutdown decide */
508 ospf_deferred_shutdown_check (ospf);
88d6cf37 509
c9c93d50 510 /* if ospf_deferred_shutdown returns, then ospf_finish_final is
88d6cf37 511 * deferred to expiry of G-S timer thread. Return back up, hopefully
512 * to thread scheduler.
513 */
c9c93d50 514 return;
88d6cf37 515}
516
517/* Final cleanup of ospf instance */
518static void
519ospf_finish_final (struct ospf *ospf)
718e3744 520{
521 struct route_node *rn;
522 struct ospf_nbr_nbma *nbr_nbma;
68980084 523 struct ospf_lsa *lsa;
953cde65 524 struct interface *ifp;
1eb8ef25 525 struct ospf_interface *oi;
526 struct ospf_area *area;
527 struct ospf_vl_data *vl_data;
528 struct listnode *node, *nnode;
718e3744 529 int i;
ed2eb093 530 u_short instance = 0;
718e3744 531
ae19c240
DL
532 QOBJ_UNREG (ospf);
533
718e3744 534 ospf_opaque_type11_lsa_term (ospf);
88d6cf37 535
536 /* be nice if this worked, but it doesn't */
537 /*ospf_flush_self_originated_lsas_now (ospf);*/
538
539 /* Unregister redistribution */
718e3744 540 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
7c8ff89e
DS
541 {
542 struct list *red_list;
543 struct ospf_redist *red;
544
545 red_list = ospf->redist[i];
546 if (!red_list)
547 continue;
548
549 for (ALL_LIST_ELEMENTS(red_list, node, nnode, red))
550 ospf_redistribute_unset (ospf, i, red->instance);
551 }
29b5a044 552 ospf_redistribute_default_unset (ospf);
718e3744 553
1eb8ef25 554 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
555 ospf_remove_vls_through_area (ospf, area);
718e3744 556
1eb8ef25 557 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
558 ospf_vl_delete (ospf, vl_data);
718e3744 559
560 list_delete (ospf->vlinks);
561
953cde65
JT
562 /* Remove any ospf interface config params */
563 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
564 {
565 struct ospf_if_params *params;
566
567 params = IF_DEF_PARAMS (ifp);
568 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
569 UNSET_IF_PARAM (params, if_area);
570 }
571
718e3744 572 /* Reset interface. */
1eb8ef25 573 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
574 ospf_if_free (oi);
718e3744 575
576 /* Clear static neighbors */
577 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
578 if ((nbr_nbma = rn->info))
579 {
580 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
581
582 if (nbr_nbma->nbr)
583 {
584 nbr_nbma->nbr->nbr_nbma = NULL;
585 nbr_nbma->nbr = NULL;
586 }
587
588 if (nbr_nbma->oi)
589 {
590 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
591 nbr_nbma->oi = NULL;
592 }
593
594 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
595 }
596
597 route_table_finish (ospf->nbr_nbma);
598
599 /* Clear networks and Areas. */
600 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
601 {
602 struct ospf_network *network;
603
604 if ((network = rn->info) != NULL)
605 {
68980084 606 ospf_network_free (ospf, network);
718e3744 607 rn->info = NULL;
608 route_unlock_node (rn);
609 }
610 }
611
1eb8ef25 612 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 613 {
718e3744 614 listnode_delete (ospf->areas, area);
615 ospf_area_free (area);
616 }
617
618 /* Cancel all timers. */
619 OSPF_TIMER_OFF (ospf->t_external_lsa);
718e3744 620 OSPF_TIMER_OFF (ospf->t_spf_calc);
621 OSPF_TIMER_OFF (ospf->t_ase_calc);
622 OSPF_TIMER_OFF (ospf->t_maxage);
623 OSPF_TIMER_OFF (ospf->t_maxage_walker);
624 OSPF_TIMER_OFF (ospf->t_abr_task);
88d6cf37 625 OSPF_TIMER_OFF (ospf->t_asbr_check);
718e3744 626 OSPF_TIMER_OFF (ospf->t_distribute_update);
627 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
628 OSPF_TIMER_OFF (ospf->t_read);
629 OSPF_TIMER_OFF (ospf->t_write);
88d6cf37 630 OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
718e3744 631
632 close (ospf->fd);
5c33349b 633 stream_free(ospf->ibuf);
718e3744 634
68980084 635 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
636 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
68980084 637 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
638 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
639
718e3744 640 ospf_lsdb_delete_all (ospf->lsdb);
641 ospf_lsdb_free (ospf->lsdb);
642
91e6a0e5
DD
643 for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
644 {
645 struct ospf_lsa *lsa;
718e3744 646
91e6a0e5
DD
647 if ((lsa = rn->info) != NULL)
648 {
649 ospf_lsa_unlock (&lsa);
650 rn->info = NULL;
651 }
652 route_unlock_node (rn);
653 }
654 route_table_finish (ospf->maxage_lsa);
718e3744 655
656 if (ospf->old_table)
657 ospf_route_table_free (ospf->old_table);
658 if (ospf->new_table)
659 {
660 ospf_route_delete (ospf->new_table);
661 ospf_route_table_free (ospf->new_table);
662 }
663 if (ospf->old_rtrs)
664 ospf_rtrs_free (ospf->old_rtrs);
665 if (ospf->new_rtrs)
666 ospf_rtrs_free (ospf->new_rtrs);
667 if (ospf->new_external_route)
668 {
669 ospf_route_delete (ospf->new_external_route);
670 ospf_route_table_free (ospf->new_external_route);
671 }
672 if (ospf->old_external_route)
673 {
674 ospf_route_delete (ospf->old_external_route);
675 ospf_route_table_free (ospf->old_external_route);
676 }
677 if (ospf->external_lsas)
678 {
679 ospf_ase_external_lsas_finish (ospf->external_lsas);
680 }
681
682 list_delete (ospf->areas);
683
684 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
7c8ff89e
DS
685 {
686 struct list *ext_list;
687 struct listnode *node;
688 struct ospf_external *ext;
689
690 ext_list = om->external[i];
691 if (!ext_list)
692 continue;
693
694 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
695 {
696 if (ext->external_info)
697 for (rn = route_top (ext->external_info); rn; rn = route_next (rn))
698 {
699 if (rn->info == NULL)
700 continue;
701
702 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
703 rn->info = NULL;
704 route_unlock_node (rn);
705 }
706 }
707 }
718e3744 708
68980084 709 ospf_distance_reset (ospf);
718e3744 710 route_table_finish (ospf->distance_table);
711
7c8ff89e
DS
712 if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
713 instance = ospf->instance;
714
020709f9 715 ospf_delete (ospf);
718e3744 716
020709f9 717 XFREE (MTYPE_OSPF_TOP, ospf);
7c8ff89e
DS
718
719 if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
720 ospf_get_instance(instance);
721
718e3744 722}
723
6b0655a2 724
718e3744 725/* allocate new OSPF Area object */
4dadc291 726static struct ospf_area *
68980084 727ospf_area_new (struct ospf *ospf, struct in_addr area_id)
718e3744 728{
729 struct ospf_area *new;
730
731 /* Allocate new config_network. */
732 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
733
68980084 734 new->ospf = ospf;
718e3744 735
736 new->area_id = area_id;
86573dcb 737 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
718e3744 738
739 new->external_routing = OSPF_AREA_DEFAULT;
740 new->default_cost = 1;
741 new->auth_type = OSPF_AUTH_NULL;
88d6cf37 742
718e3744 743 /* New LSDB init. */
744 new->lsdb = ospf_lsdb_new ();
745
746 /* Self-originated LSAs initialize. */
747 new->router_lsa_self = NULL;
748
718e3744 749 ospf_opaque_type10_lsa_init (new);
718e3744 750
751 new->oiflist = list_new ();
752 new->ranges = route_table_init ();
753
754 if (area_id.s_addr == OSPF_AREA_BACKBONE)
68980084 755 ospf->backbone = new;
718e3744 756
757 return new;
758}
759
917e2995 760static void
718e3744 761ospf_area_free (struct ospf_area *area)
762{
68980084 763 struct route_node *rn;
764 struct ospf_lsa *lsa;
765
718e3744 766 /* Free LSDBs. */
68980084 767 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
768 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
769 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
770 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
771 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
772 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
773 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
774 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
718e3744 775
68980084 776 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
777 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
68980084 778 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
779 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
780 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
781 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
718e3744 782
783 ospf_lsdb_delete_all (area->lsdb);
784 ospf_lsdb_free (area->lsdb);
785
1fe6ed38 786 ospf_lsa_unlock (&area->router_lsa_self);
718e3744 787
788 route_table_finish (area->ranges);
789 list_delete (area->oiflist);
790
791 if (EXPORT_NAME (area))
792 free (EXPORT_NAME (area));
793
794 if (IMPORT_NAME (area))
795 free (IMPORT_NAME (area));
796
797 /* Cancel timer. */
88d6cf37 798 OSPF_TIMER_OFF (area->t_stub_router);
88d6cf37 799 OSPF_TIMER_OFF (area->t_opaque_lsa_self);
88d6cf37 800
718e3744 801 if (OSPF_IS_AREA_BACKBONE (area))
68980084 802 area->ospf->backbone = NULL;
718e3744 803
804 XFREE (MTYPE_OSPF_AREA, area);
805}
806
807void
68980084 808ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
718e3744 809{
810 struct ospf_area *area;
811
68980084 812 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 813 if (area &&
814 listcount (area->oiflist) == 0 &&
815 area->ranges->top == NULL &&
816 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
817 area->external_routing == OSPF_AREA_DEFAULT &&
818 area->no_summary == 0 &&
819 area->default_cost == 1 &&
820 EXPORT_NAME (area) == NULL &&
821 IMPORT_NAME (area) == NULL &&
822 area->auth_type == OSPF_AUTH_NULL)
823 {
68980084 824 listnode_delete (ospf->areas, area);
718e3744 825 ospf_area_free (area);
826 }
827}
828
829struct ospf_area *
86573dcb 830ospf_area_get (struct ospf *ospf, struct in_addr area_id)
718e3744 831{
832 struct ospf_area *area;
833
68980084 834 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 835 if (!area)
836 {
68980084 837 area = ospf_area_new (ospf, area_id);
68980084 838 listnode_add_sort (ospf->areas, area);
839 ospf_check_abr_status (ospf);
4ba4fc85
AB
840 if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
841 {
842 SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
843 }
718e3744 844 }
845
846 return area;
847}
848
849struct ospf_area *
68980084 850ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
718e3744 851{
852 struct ospf_area *area;
52dc7ee6 853 struct listnode *node;
718e3744 854
1eb8ef25 855 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
856 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
857 return area;
718e3744 858
859 return NULL;
860}
861
862void
863ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
864{
865 listnode_add (area->oiflist, oi);
866}
867
868void
869ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
870{
871 listnode_delete (area->oiflist, oi);
872}
873
52c62ab8
JAG
874
875
876static void
877add_ospf_interface (struct connected *co, struct ospf_area *area)
953cde65
JT
878{
879 struct ospf_interface *oi;
880
52c62ab8 881 oi = ospf_if_new (area->ospf, co->ifp, co->address);
953cde65
JT
882 oi->connected = co;
883
884 oi->area = area;
885
52c62ab8 886 oi->params = ospf_lookup_if_params (co->ifp, oi->address->u.prefix4);
953cde65
JT
887 oi->output_cost = ospf_if_get_output_cost (oi);
888
889 /* Relate ospf interface to ospf instance. */
890 oi->ospf = area->ospf;
891
892 /* update network type as interface flag */
893 /* If network type is specified previously,
894 skip network type setting. */
52c62ab8 895 oi->type = IF_DEF_PARAMS (co->ifp)->type;
953cde65
JT
896
897 /* Add pseudo neighbor. */
898 ospf_nbr_self_reset (oi, oi->ospf->router_id);
899
900 ospf_area_add_if (oi->area, oi);
901
52c62ab8
JAG
902 /*
903 * if router_id is not configured, dont bring up
904 * interfaces.
905 * ospf_router_id_update() will call ospf_if_update
906 * whenever r-id is configured instead.
907 */
908 if ((area->ospf->router_id.s_addr != 0)
909 && if_is_operative (co->ifp))
910 ospf_if_up (oi);
911
953cde65
JT
912}
913
914static void update_redistributed(struct ospf *ospf, int add_to_ospf)
915{
916 struct route_node *rn;
917 struct external_info *ei;
918 struct ospf_external *ext;
919
920 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT, 0))
921 if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) &&
922 EXTERNAL_INFO (ext))
923 {
924 for (rn = route_top (EXTERNAL_INFO (ext));
925 rn; rn = route_next (rn))
926 {
927 if ((ei = rn->info) != NULL)
928 {
929 if (add_to_ospf)
930 {
931 if (ospf_external_info_find_lsa (ospf, &ei->p))
932 if (!ospf_distribute_check_connected (ospf, ei))
933 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
934 ei->ifindex /*, ei->nexthop */);
935 }
936 else
937 {
938 if (!ospf_external_info_find_lsa (ospf, &ei->p))
939 if (ospf_distribute_check_connected (ospf, ei))
940 ospf_external_lsa_originate (ospf, ei);
941 }
942 }
943 }
944 }
945}
946
718e3744 947/* Config network statement related functions. */
4dadc291 948static struct ospf_network *
86573dcb 949ospf_network_new (struct in_addr area_id)
718e3744 950{
951 struct ospf_network *new;
952 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
953
954 new->area_id = area_id;
86573dcb 955 new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD;
718e3744 956
957 return new;
958}
959
917e2995 960static void
68980084 961ospf_network_free (struct ospf *ospf, struct ospf_network *network)
718e3744 962{
68980084 963 ospf_area_check_free (ospf, network->area_id);
964 ospf_schedule_abr_task (ospf);
718e3744 965 XFREE (MTYPE_OSPF_NETWORK, network);
966}
967
968int
969ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
86573dcb 970 struct in_addr area_id, int df)
718e3744 971{
972 struct ospf_network *network;
973 struct ospf_area *area;
974 struct route_node *rn;
718e3744 975
976 rn = route_node_get (ospf->networks, (struct prefix *)p);
977 if (rn->info)
978 {
979 /* There is already same network statement. */
980 route_unlock_node (rn);
981 return 0;
982 }
983
86573dcb
QY
984 rn->info = network = ospf_network_new (area_id);
985 network->area_id_fmt = df;
986 area = ospf_area_get (ospf, area_id);
987 ospf_area_display_format_set (ospf, area, df);
718e3744 988
989 /* Run network config now. */
a49eb30a 990 ospf_network_run ((struct prefix *)p, area);
718e3744 991
992 /* Update connected redistribute. */
953cde65 993 update_redistributed(ospf, 1); /* interfaces possibly added */
718e3744 994
68980084 995 ospf_area_check_free (ospf, area_id);
718e3744 996
997 return 1;
998}
999
1000int
1001ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
1002 struct in_addr area_id)
1003{
1004 struct route_node *rn;
1005 struct ospf_network *network;
a49eb30a
JT
1006 struct listnode *node, *nnode;
1007 struct ospf_interface *oi;
718e3744 1008
1009 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
1010 if (rn == NULL)
1011 return 0;
1012
1013 network = rn->info;
965f54f5 1014 route_unlock_node (rn);
718e3744 1015 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
1016 return 0;
1017
68980084 1018 ospf_network_free (ospf, rn->info);
718e3744 1019 rn->info = NULL;
965f54f5 1020 route_unlock_node (rn); /* initial reference */
718e3744 1021
a49eb30a
JT
1022 /* Find interfaces that not configured already. */
1023 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
1024 {
52c62ab8 1025 ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);
a49eb30a 1026 }
718e3744 1027
1028 /* Update connected redistribute. */
953cde65
JT
1029 update_redistributed(ospf, 0); /* interfaces possibly removed */
1030 ospf_area_check_free (ospf, area_id);
1031
1032 return 1;
1033}
1034
52c62ab8
JAG
1035/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means
1036 * there might not be any 'router ospf' config.
1037 *
1038 * Otherwise, doesn't do anything different to ospf_if_update for now
1039 */
1040void
1041ospf_interface_area_set (struct interface *ifp)
953cde65 1042{
52c62ab8
JAG
1043 struct ospf *ospf = ospf_get();
1044
1045 ospf_if_update (ospf, ifp);
1046 /* if_update does a update_redistributed */
1047
1048 return;
953cde65
JT
1049}
1050
52c62ab8
JAG
1051void
1052ospf_interface_area_unset (struct interface *ifp)
953cde65 1053{
52c62ab8 1054 struct route_node *rn_oi;
953cde65 1055 struct ospf *ospf;
953cde65
JT
1056
1057 ospf = ospf_lookup ();
1058 if (!ospf)
52c62ab8 1059 return; /* Ospf not ready yet */
953cde65 1060
52c62ab8
JAG
1061 /* Find interfaces that may need to be removed. */
1062 for (rn_oi = route_top (IF_OIFS (ifp)); rn_oi; rn_oi = route_next (rn_oi))
953cde65 1063 {
52c62ab8
JAG
1064 struct ospf_interface *oi;
1065
1066 if ( (oi = rn_oi->info) == NULL)
1067 continue;
1068
953cde65 1069 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
52c62ab8
JAG
1070 continue;
1071
1072 ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);
953cde65
JT
1073 }
1074
1075 /* Update connected redistribute. */
1076 update_redistributed(ospf, 0); /* interfaces possibly removed */
718e3744 1077}
1078
570f7598 1079/* Check whether interface matches given network
1080 * returns: 1, true. 0, false
1081 */
917e2995
SH
1082static int
1083ospf_network_match_iface(const struct connected *co, const struct prefix *net)
570f7598 1084{
e4529636 1085 /* new approach: more elegant and conceptually clean */
3bec29ac 1086 return prefix_match_network_statement(net, CONNECTED_PREFIX(co));
570f7598 1087}
1088
917e2995 1089static void
52c62ab8
JAG
1090ospf_update_interface_area (struct connected *co, struct ospf_area *area)
1091{
1092 struct ospf_interface *oi = ospf_if_table_lookup (co->ifp, co->address);
1093
1094 /* nothing to be done case */
1095 if (oi && oi->area == area){
1096 return;
1097 }
1098
1099 if (oi)
1100 ospf_if_free (oi);
1101
1102 add_ospf_interface (co, area);
1103}
1104
1105/* Run OSPF for the given subnet, taking into account the following
1106 * possible sources of area configuration, in the given order of preference:
1107 *
1108 * - Whether there is interface+address specific area configuration
1109 * - Whether there is a default area for the interface
1110 * - Whether there is an area given as a parameter.
1111 * - If no specific network prefix/area is supplied, whether there's
1112 * a matching network configured.
1113 */
1114static void
1115ospf_network_run_subnet (struct ospf *ospf, struct connected *co,
1116 struct prefix *p, struct ospf_area *given_area)
1117{
1118 struct ospf_interface *oi;
1119 struct ospf_if_params *params;
1120 struct ospf_area *area = NULL;
1121 struct route_node *rn;
1122 int configed = 0;
1123
1124 if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
1125 return;
1126
1127 if (co->address->family != AF_INET)
1128 return;
1129
1130 /* Try determine the appropriate area for this interface + address
1131 * Start by checking interface config
1132 */
1133 params = ospf_lookup_if_params (co->ifp, co->address->u.prefix4);
1134 if ( params && OSPF_IF_PARAM_CONFIGURED(params, if_area))
1135 area = ospf_area_get (ospf, params->if_area);
1136 else{
1137 params = IF_DEF_PARAMS (co->ifp);
1138 if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
1139 area = ospf_area_get (ospf, params->if_area);
1140 }
1141
1142 /* If we've found an interface and/or addr specific area, then we're
1143 * done
1144 */
1145 if (area)
1146 {
1147 ospf_update_interface_area (co, area);
1148 return;
1149 }
1150
1151 /* Otherwise, only remaining possibility is a matching network statement */
1152 if (p)
1153 {
1154 assert (given_area != NULL);
1155
1156 /* Which either was supplied as a parameter.. (e.g. cause a new
1157 * network/area was just added)..
1158 */
1159 if (p->family == co->address->family
1160 && ospf_network_match_iface (co, p))
1161 ospf_update_interface_area (co, given_area);
1162
1163 return;
1164 }
1165
1166 /* Else we have to search the existing network/area config to see
1167 * if any match..
1168 */
1169 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
1170 if (rn->info != NULL
1171 && ospf_network_match_iface (co, &rn->p))
1172 {
1173 struct ospf_network *network = (struct ospf_network *) rn->info;
1174 area = ospf_area_get (ospf, network->area_id);
1175 ospf_update_interface_area (co, area);
1176 configed = 1;
1177 }
1178
1179 /* If the subnet isn't in any area, deconfigure */
1180 if (!configed && (oi = ospf_if_table_lookup (co->ifp, co->address)))
1181 ospf_if_free (oi);
1182}
1183
1184static void
1185ospf_network_run_interface (struct ospf *ospf, struct interface *ifp,
1186 struct prefix *p,
1187 struct ospf_area *given_area)
718e3744 1188{
a49eb30a 1189 struct listnode *cnode;
1eb8ef25 1190 struct connected *co;
a49eb30a
JT
1191
1192 if (memcmp (ifp->name, "VLINK", 5) == 0)
1193 return;
1194
52c62ab8
JAG
1195 /* Network prefix without area is nonsensical */
1196 if (p)
1197 assert (given_area != NULL);
1198
a49eb30a
JT
1199 /* if interface prefix is match specified prefix,
1200 then create socket and join multicast group. */
1201 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
52c62ab8 1202 ospf_network_run_subnet (ospf, co, p, given_area);
a49eb30a
JT
1203}
1204
917e2995 1205static void
a49eb30a
JT
1206ospf_network_run (struct prefix *p, struct ospf_area *area)
1207{
1208 struct interface *ifp;
52dc7ee6 1209 struct listnode *node;
718e3744 1210
1211 /* Schedule Router ID Update. */
a49eb30a
JT
1212 if (area->ospf->router_id.s_addr == 0)
1213 ospf_router_id_update (area->ospf);
b29800a6 1214
718e3744 1215 /* Get target interface. */
1eb8ef25 1216 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
52c62ab8 1217 ospf_network_run_interface (area->ospf, ifp, p, area);
718e3744 1218}
1219
1220void
1221ospf_ls_upd_queue_empty (struct ospf_interface *oi)
1222{
1223 struct route_node *rn;
1eb8ef25 1224 struct listnode *node, *nnode;
52dc7ee6 1225 struct list *lst;
718e3744 1226 struct ospf_lsa *lsa;
1227
1228 /* empty ls update queue */
1229 for (rn = route_top (oi->ls_upd_queue); rn;
1230 rn = route_next (rn))
52dc7ee6 1231 if ((lst = (struct list *) rn->info))
718e3744 1232 {
1eb8ef25 1233 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
1fe6ed38 1234 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
718e3744 1235 list_free (lst);
1236 rn->info = NULL;
1237 }
1238
1239 /* remove update event */
1240 if (oi->t_ls_upd_event)
1241 {
1242 thread_cancel (oi->t_ls_upd_event);
1243 oi->t_ls_upd_event = NULL;
1244 }
1245}
1246
1247void
a49eb30a 1248ospf_if_update (struct ospf *ospf, struct interface *ifp)
718e3744 1249{
a49eb30a
JT
1250 if (!ospf)
1251 ospf = ospf_lookup ();
718e3744 1252
52c62ab8
JAG
1253 /* OSPF must be ready. */
1254 if (!ospf_is_ready (ospf))
a49eb30a
JT
1255 return;
1256
52c62ab8
JAG
1257 ospf_network_run_interface (ospf, ifp, NULL, NULL);
1258
1259 /* Update connected redistribute. */
1260 update_redistributed(ospf, 1);
718e3744 1261}
1262
1263void
68980084 1264ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
718e3744 1265{
1eb8ef25 1266 struct listnode *node, *nnode;
718e3744 1267 struct ospf_vl_data *vl_data;
1268
1eb8ef25 1269 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
1270 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
1271 ospf_vl_delete (ospf, vl_data);
718e3744 1272}
1273
6b0655a2 1274
7ba82f70 1275static const struct message ospf_area_type_msg[] =
718e3744 1276{
1277 { OSPF_AREA_DEFAULT, "Default" },
1278 { OSPF_AREA_STUB, "Stub" },
1279 { OSPF_AREA_NSSA, "NSSA" },
56b40679 1280 { 0 }
718e3744 1281};
718e3744 1282
4dadc291 1283static void
718e3744 1284ospf_area_type_set (struct ospf_area *area, int type)
1285{
52dc7ee6 1286 struct listnode *node;
718e3744 1287 struct ospf_interface *oi;
1288
1289 if (area->external_routing == type)
1290 {
1291 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 1292 zlog_debug ("Area[%s]: Types are the same, ignored.",
718e3744 1293 inet_ntoa (area->area_id));
1294 return;
1295 }
1296
1297 area->external_routing = type;
1298
1299 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 1300 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
56b40679 1301 lookup_msg(ospf_area_type_msg, type, NULL));
718e3744 1302
1303 switch (area->external_routing)
1304 {
1305 case OSPF_AREA_DEFAULT:
1eb8ef25 1306 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1307 if (oi->nbr_self != NULL)
1308 {
1309 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1310 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1311 }
718e3744 1312 break;
1313 case OSPF_AREA_STUB:
1eb8ef25 1314 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1315 if (oi->nbr_self != NULL)
1316 {
1317 if (IS_DEBUG_OSPF_EVENT)
1318 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
1319 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1320 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1321 if (IS_DEBUG_OSPF_EVENT)
1322 zlog_debug ("options set on %s: %x",
1323 IF_NAME (oi), OPTIONS (oi));
1324 }
718e3744 1325 break;
1326 case OSPF_AREA_NSSA:
1eb8ef25 1327 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
1328 if (oi->nbr_self != NULL)
1329 {
1330 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
1331 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
1332 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
1333 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
1334 }
718e3744 1335 break;
1336 default:
1337 break;
1338 }
1339
c363d386 1340 ospf_router_lsa_update_area (area);
68980084 1341 ospf_schedule_abr_task (area->ospf);
718e3744 1342}
1343
1344int
68980084 1345ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
718e3744 1346{
1347 if (area->shortcut_configured == mode)
1348 return 0;
1349
1350 area->shortcut_configured = mode;
c363d386 1351 ospf_router_lsa_update_area (area);
68980084 1352 ospf_schedule_abr_task (ospf);
718e3744 1353
68980084 1354 ospf_area_check_free (ospf, area->area_id);
718e3744 1355
1356 return 1;
1357}
1358
1359int
68980084 1360ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
718e3744 1361{
1362 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
c363d386 1363 ospf_router_lsa_update_area (area);
68980084 1364 ospf_area_check_free (ospf, area->area_id);
1365 ospf_schedule_abr_task (ospf);
718e3744 1366
1367 return 1;
1368}
1369
4dadc291 1370static int
718e3744 1371ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
1372{
1373 struct ospf_vl_data *vl;
52dc7ee6 1374 struct listnode *node;
718e3744 1375 int count = 0;
1376
1eb8ef25 1377 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1378 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1379 count++;
718e3744 1380
1381 return count;
1382}
1383
86573dcb
QY
1384int
1385ospf_area_display_format_set (struct ospf *ospf, struct ospf_area *area, int df)
1386{
1387 area->area_id_fmt = df;
1388
1389 return 1;
1390}
1391
718e3744 1392int
1393ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1394{
1395 struct ospf_area *area;
718e3744 1396
86573dcb 1397 area = ospf_area_get (ospf, area_id);
718e3744 1398 if (ospf_area_vlink_count (ospf, area))
1399 return 0;
1400
1401 if (area->external_routing != OSPF_AREA_STUB)
1402 ospf_area_type_set (area, OSPF_AREA_STUB);
1403
1404 return 1;
1405}
1406
1407int
1408ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1409{
1410 struct ospf_area *area;
1411
68980084 1412 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1413 if (area == NULL)
1414 return 1;
1415
1416 if (area->external_routing == OSPF_AREA_STUB)
1417 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1418
68980084 1419 ospf_area_check_free (ospf, area_id);
718e3744 1420
1421 return 1;
1422}
1423
1424int
1425ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1426{
1427 struct ospf_area *area;
718e3744 1428
86573dcb 1429 area = ospf_area_get (ospf, area_id);
718e3744 1430 area->no_summary = 1;
1431
1432 return 1;
1433}
1434
1435int
1436ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1437{
1438 struct ospf_area *area;
1439
68980084 1440 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1441 if (area == NULL)
1442 return 0;
1443
1444 area->no_summary = 0;
68980084 1445 ospf_area_check_free (ospf, area_id);
718e3744 1446
1447 return 1;
1448}
1449
1450int
1451ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1452{
1453 struct ospf_area *area;
718e3744 1454
86573dcb 1455 area = ospf_area_get (ospf, area_id);
718e3744 1456 if (ospf_area_vlink_count (ospf, area))
1457 return 0;
1458
1459 if (area->external_routing != OSPF_AREA_NSSA)
1460 {
1461 ospf_area_type_set (area, OSPF_AREA_NSSA);
1462 ospf->anyNSSA++;
1463 }
1464
084c7844 1465 /* set NSSA area defaults */
1466 area->no_summary = 0;
1467 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
d4a53d58 1468 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
084c7844 1469 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1470
718e3744 1471 return 1;
1472}
1473
1474int
1475ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1476{
1477 struct ospf_area *area;
1478
68980084 1479 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1480 if (area == NULL)
1481 return 0;
1482
1483 if (area->external_routing == OSPF_AREA_NSSA)
1484 {
1485 ospf->anyNSSA--;
1486 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1487 }
1488
68980084 1489 ospf_area_check_free (ospf, area_id);
718e3744 1490
1491 return 1;
1492}
1493
1494int
1495ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1496 int role)
1497{
1498 struct ospf_area *area;
1499
68980084 1500 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1501 if (area == NULL)
1502 return 0;
1503
084c7844 1504 area->NSSATranslatorRole = role;
718e3744 1505
1506 return 1;
1507}
1508
075e12f5 1509#if 0
4dadc291 1510/* XXX: unused? Leave for symmetry? */
1511static int
718e3744 1512ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1513 struct in_addr area_id)
1514{
1515 struct ospf_area *area;
1516
68980084 1517 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1518 if (area == NULL)
1519 return 0;
1520
084c7844 1521 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
718e3744 1522
68980084 1523 ospf_area_check_free (ospf, area_id);
718e3744 1524
1525 return 1;
1526}
075e12f5 1527#endif
718e3744 1528
1529int
68980084 1530ospf_area_export_list_set (struct ospf *ospf,
6c835671 1531 struct ospf_area *area, const char *list_name)
718e3744 1532{
1533 struct access_list *list;
1534 list = access_list_lookup (AFI_IP, list_name);
1535
1536 EXPORT_LIST (area) = list;
1537
1538 if (EXPORT_NAME (area))
1539 free (EXPORT_NAME (area));
1540
1541 EXPORT_NAME (area) = strdup (list_name);
68980084 1542 ospf_schedule_abr_task (ospf);
718e3744 1543
1544 return 1;
1545}
1546
1547int
68980084 1548ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
718e3744 1549{
1550
1551 EXPORT_LIST (area) = 0;
1552
1553 if (EXPORT_NAME (area))
1554 free (EXPORT_NAME (area));
1555
1556 EXPORT_NAME (area) = NULL;
1557
68980084 1558 ospf_area_check_free (ospf, area->area_id);
718e3744 1559
68980084 1560 ospf_schedule_abr_task (ospf);
718e3744 1561
1562 return 1;
1563}
1564
1565int
6c835671 1566ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1567 const char *name)
718e3744 1568{
1569 struct access_list *list;
1570 list = access_list_lookup (AFI_IP, name);
1571
1572 IMPORT_LIST (area) = list;
1573
1574 if (IMPORT_NAME (area))
1575 free (IMPORT_NAME (area));
1576
1577 IMPORT_NAME (area) = strdup (name);
68980084 1578 ospf_schedule_abr_task (ospf);
718e3744 1579
1580 return 1;
1581}
1582
1583int
68980084 1584ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
718e3744 1585{
1586 IMPORT_LIST (area) = 0;
1587
1588 if (IMPORT_NAME (area))
1589 free (IMPORT_NAME (area));
1590
1591 IMPORT_NAME (area) = NULL;
68980084 1592 ospf_area_check_free (ospf, area->area_id);
718e3744 1593
68980084 1594 ospf_schedule_abr_task (ospf);
718e3744 1595
1596 return 1;
1597}
1598
718e3744 1599int
1600ospf_timers_refresh_set (struct ospf *ospf, int interval)
1601{
1602 int time_left;
1603
1604 if (ospf->lsa_refresh_interval == interval)
1605 return 1;
1606
1607 time_left = ospf->lsa_refresh_interval -
cf672a86 1608 (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1609
1610 if (time_left > interval)
1611 {
1612 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
66e78ae6
QY
1613 thread_add_timer(master, ospf_lsa_refresh_walker, ospf, interval,
1614 &ospf->t_lsa_refresher);
718e3744 1615 }
1616 ospf->lsa_refresh_interval = interval;
1617
1618 return 1;
1619}
1620
1621int
1622ospf_timers_refresh_unset (struct ospf *ospf)
1623{
1624 int time_left;
1625
1626 time_left = ospf->lsa_refresh_interval -
cf672a86 1627 (monotime(NULL) - ospf->lsa_refresher_started);
718e3744 1628
1629 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1630 {
1631 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
66e78ae6
QY
1632 ospf->t_lsa_refresher = NULL;
1633 thread_add_timer(master, ospf_lsa_refresh_walker, ospf, OSPF_LSA_REFRESH_INTERVAL_DEFAULT,
1634 &ospf->t_lsa_refresher);
718e3744 1635 }
1636
1637 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1638
1639 return 1;
1640}
1641
6b0655a2 1642
4dadc291 1643static struct ospf_nbr_nbma *
1644ospf_nbr_nbma_new (void)
718e3744 1645{
1646 struct ospf_nbr_nbma *nbr_nbma;
1647
393deb9b 1648 nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
718e3744 1649 sizeof (struct ospf_nbr_nbma));
718e3744 1650
1651 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1652 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1653
1654 return nbr_nbma;
1655}
1656
4dadc291 1657static void
718e3744 1658ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1659{
1660 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1661}
1662
4dadc291 1663static void
718e3744 1664ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1665{
1666 struct route_node *rn;
1667 struct prefix_ipv4 p;
1668
1669 p.family = AF_INET;
1670 p.prefix = nbr_nbma->addr;
1671 p.prefixlen = IPV4_MAX_BITLEN;
1672
1673 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1674 if (rn)
1675 {
1676 ospf_nbr_nbma_free (rn->info);
1677 rn->info = NULL;
1678 route_unlock_node (rn);
1679 route_unlock_node (rn);
1680 }
1681}
1682
4dadc291 1683static void
718e3744 1684ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1685{
1686 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1687
1688 if (nbr_nbma->nbr)
1689 {
1690 nbr_nbma->nbr->nbr_nbma = NULL;
1691 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1692 }
1693
1694 if (nbr_nbma->oi)
1695 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1696}
1697
4dadc291 1698static void
718e3744 1699ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1700 struct ospf_interface *oi)
1701{
1702 struct ospf_neighbor *nbr;
1703 struct route_node *rn;
1704 struct prefix p;
1705
1706 if (oi->type != OSPF_IFTYPE_NBMA)
1707 return;
1708
1709 if (nbr_nbma->nbr != NULL)
1710 return;
1711
1712 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1713 return;
1714
1715 nbr_nbma->oi = oi;
1716 listnode_add (oi->nbr_nbma, nbr_nbma);
1717
1718 /* Get neighbor information from table. */
1719 p.family = AF_INET;
1720 p.prefixlen = IPV4_MAX_BITLEN;
1721 p.u.prefix4 = nbr_nbma->addr;
1722
1723 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1724 if (rn->info)
1725 {
1726 nbr = rn->info;
1727 nbr->nbr_nbma = nbr_nbma;
1728 nbr_nbma->nbr = nbr;
1729
1730 route_unlock_node (rn);
1731 }
1732 else
1733 {
1734 nbr = rn->info = ospf_nbr_new (oi);
1735 nbr->state = NSM_Down;
1736 nbr->src = nbr_nbma->addr;
1737 nbr->nbr_nbma = nbr_nbma;
1738 nbr->priority = nbr_nbma->priority;
1739 nbr->address = p;
1740
1741 nbr_nbma->nbr = nbr;
1742
1743 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1744 }
1745}
1746
1747void
68980084 1748ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
718e3744 1749{
1750 struct ospf_nbr_nbma *nbr_nbma;
1751 struct route_node *rn;
1752 struct prefix_ipv4 p;
1753
1754 if (oi->type != OSPF_IFTYPE_NBMA)
1755 return;
1756
68980084 1757 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
718e3744 1758 if ((nbr_nbma = rn->info))
1759 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1760 {
1761 p.family = AF_INET;
1762 p.prefix = nbr_nbma->addr;
1763 p.prefixlen = IPV4_MAX_BITLEN;
1764
1765 if (prefix_match (oi->address, (struct prefix *)&p))
1766 ospf_nbr_nbma_add (nbr_nbma, oi);
1767 }
1768}
1769
1770struct ospf_nbr_nbma *
1771ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1772{
1773 struct route_node *rn;
1774 struct prefix_ipv4 p;
1775
1776 p.family = AF_INET;
1777 p.prefix = nbr_addr;
1778 p.prefixlen = IPV4_MAX_BITLEN;
1779
1780 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1781 if (rn)
1782 {
1783 route_unlock_node (rn);
1784 return rn->info;
1785 }
1786 return NULL;
1787}
1788
1789struct ospf_nbr_nbma *
68980084 1790ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
718e3744 1791{
1792#if 0
1793 struct ospf_nbr_nbma *nbr_nbma;
52dc7ee6 1794 struct listnode *node;
718e3744 1795#endif
1796
68980084 1797 if (ospf == NULL)
718e3744 1798 return NULL;
1799
1800#if 0
1eb8ef25 1801 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
718e3744 1802 {
718e3744 1803 if (first)
1804 {
1805 *addr = nbr_nbma->addr;
1806 return nbr_nbma;
1807 }
1808 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1809 {
1810 *addr = nbr_nbma->addr;
1811 return nbr_nbma;
1812 }
1813 }
1814#endif
1815 return NULL;
1816}
1817
1818int
1819ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1820{
1821 struct ospf_nbr_nbma *nbr_nbma;
1822 struct ospf_interface *oi;
1823 struct prefix_ipv4 p;
1824 struct route_node *rn;
52dc7ee6 1825 struct listnode *node;
718e3744 1826
1827 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1828 if (nbr_nbma)
1829 return 0;
1830
1831 nbr_nbma = ospf_nbr_nbma_new ();
1832 nbr_nbma->addr = nbr_addr;
1833
1834 p.family = AF_INET;
1835 p.prefix = nbr_addr;
1836 p.prefixlen = IPV4_MAX_BITLEN;
1837
1838 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
14fcc0e6
JT
1839 if (rn->info)
1840 route_unlock_node (rn);
718e3744 1841 rn->info = nbr_nbma;
1842
1eb8ef25 1843 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
718e3744 1844 {
718e3744 1845 if (oi->type == OSPF_IFTYPE_NBMA)
1846 if (prefix_match (oi->address, (struct prefix *)&p))
1847 {
1848 ospf_nbr_nbma_add (nbr_nbma, oi);
1849 break;
1850 }
1851 }
1852
1853 return 1;
1854}
1855
1856int
1857ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1858{
1859 struct ospf_nbr_nbma *nbr_nbma;
1860
1861 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1862 if (nbr_nbma == NULL)
1863 return 0;
1864
1865 ospf_nbr_nbma_down (nbr_nbma);
1866 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1867
1868 return 1;
1869}
1870
1871int
1872ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1873 u_char priority)
1874{
1875 struct ospf_nbr_nbma *nbr_nbma;
1876
1877 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1878 if (nbr_nbma == NULL)
1879 return 0;
1880
1881 if (nbr_nbma->priority != priority)
1882 nbr_nbma->priority = priority;
1883
1884 return 1;
1885}
1886
1887int
1888ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1889{
1890 struct ospf_nbr_nbma *nbr_nbma;
1891
1892 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1893 if (nbr_nbma == NULL)
1894 return 0;
1895
1896 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1897 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1898
1899 return 1;
1900}
1901
1902int
1903ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
6c835671 1904 unsigned int interval)
718e3744 1905{
1906 struct ospf_nbr_nbma *nbr_nbma;
1907
1908 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1909 if (nbr_nbma == NULL)
1910 return 0;
1911
1912 if (nbr_nbma->v_poll != interval)
1913 {
1914 nbr_nbma->v_poll = interval;
1915 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1916 {
1917 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1918 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1919 nbr_nbma->v_poll);
1920 }
1921 }
1922
1923 return 1;
1924}
1925
1926int
1927ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1928{
1929 struct ospf_nbr_nbma *nbr_nbma;
1930
1931 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1932 if (nbr_nbma == NULL)
1933 return 0;
1934
1935 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1936 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1937
1938 return 1;
1939}
1940
718e3744 1941void
4f04a76b 1942ospf_master_init (struct thread_master *master)
718e3744 1943{
020709f9 1944 memset (&ospf_master, 0, sizeof (struct ospf_master));
1945
1946 om = &ospf_master;
1947 om->ospf = list_new ();
4f04a76b 1948 om->master = master;
020709f9 1949}