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