]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospfd.c
2005-10-28 Paul Jakma <paul.jakma@sun.com>
[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"
33#include "sockunion.h" /* for inet_aton () */
34#include "zclient.h"
35#include "plist.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_zebra.h"
50#include "ospfd/ospf_abr.h"
51#include "ospfd/ospf_flood.h"
52#include "ospfd/ospf_route.h"
53#include "ospfd/ospf_ase.h"
54
020709f9 55\f
edd7c245 56
020709f9 57/* OSPF process wide configuration. */
58static struct ospf_master ospf_master;
59
60/* OSPF process wide configuration pointer to export. */
61struct ospf_master *om;
718e3744 62
63extern struct zclient *zclient;
18a6dce6 64extern struct in_addr router_id_zebra;
718e3744 65
66\f
68980084 67void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
68void ospf_network_free (struct ospf *, struct ospf_network *);
718e3744 69void ospf_area_free (struct ospf_area *);
70void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
71
718e3744 72#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
73
74void
68980084 75ospf_router_id_update (struct ospf *ospf)
718e3744 76{
718e3744 77 struct in_addr router_id, router_id_old;
1eb8ef25 78 struct ospf_interface *oi;
52dc7ee6 79 struct listnode *node;
718e3744 80
81 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 82 zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
718e3744 83
68980084 84 router_id_old = ospf->router_id;
718e3744 85
68980084 86 if (ospf->router_id_static.s_addr != 0)
87 router_id = ospf->router_id_static;
718e3744 88 else
18a6dce6 89 router_id = router_id_zebra;
718e3744 90
68980084 91 ospf->router_id = router_id;
718e3744 92
93 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 94 zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
718e3744 95
96 if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
97 {
1eb8ef25 98 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
99 /* Update self-neighbor's router_id. */
100 oi->nbr_self->router_id = router_id;
718e3744 101
102 /* If AS-external-LSA is queued, then flush those LSAs. */
68980084 103 if (router_id_old.s_addr == 0 && ospf->external_origin)
718e3744 104 {
105 int type;
106 /* Originate each redistributed external route. */
107 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
68980084 108 if (ospf->external_origin & (1 << type))
718e3744 109 thread_add_event (master, ospf_external_lsa_originate_timer,
68980084 110 ospf, type);
718e3744 111 /* Originate Deafult. */
68980084 112 if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
718e3744 113 thread_add_event (master, ospf_default_originate_timer,
68980084 114 &ospf->default_originate, 0);
718e3744 115
68980084 116 ospf->external_origin = 0;
718e3744 117 }
118
68980084 119 OSPF_TIMER_ON (ospf->t_router_lsa_update,
718e3744 120 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
121 }
122}
123
124int
125ospf_router_id_update_timer (struct thread *thread)
126{
020709f9 127 struct ospf *ospf = THREAD_ARG (thread);
68980084 128
718e3744 129 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 130 zlog_debug ("Router-ID: Update timer fired!");
718e3744 131
68980084 132 ospf->t_router_id_update = NULL;
133 ospf_router_id_update (ospf);
718e3744 134
135 return 0;
136}
137\f
138/* For OSPF area sort by area id. */
4dadc291 139static int
718e3744 140ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
141{
142 if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
143 return 1;
144 if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
145 return -1;
146 return 0;
147}
148
149/* Allocate new ospf structure. */
4dadc291 150static struct ospf *
151ospf_new (void)
718e3744 152{
153 int i;
154
155 struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
156
157 new->router_id.s_addr = htonl (0);
158 new->router_id_static.s_addr = htonl (0);
159
d57834f6 160 new->abr_type = OSPF_ABR_DEFAULT;
718e3744 161 new->oiflist = list_new ();
162 new->vlinks = list_new ();
163 new->areas = list_new ();
164 new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
165 new->networks = route_table_init ();
166 new->nbr_nbma = route_table_init ();
167
168 new->lsdb = ospf_lsdb_new ();
169
170 new->default_originate = DEFAULT_ORIGINATE_NONE;
171
172 new->new_external_route = route_table_init ();
173 new->old_external_route = route_table_init ();
174 new->external_lsas = route_table_init ();
175
176 /* Distribute parameter init. */
177 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
178 {
179 new->dmetric[i].type = -1;
180 new->dmetric[i].value = -1;
181 }
182 new->default_metric = -1;
183 new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
184
185 /* SPF timer value init. */
186 new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
187 new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
d24f6e2a 188 new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
189 new->spf_hold_multiplier = 1;
718e3744 190
191 /* MaxAge init. */
192 new->maxage_lsa = list_new ();
193 new->t_maxage_walker =
194 thread_add_timer (master, ospf_lsa_maxage_walker,
68980084 195 new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
718e3744 196
197 /* Distance table init. */
198 new->distance_table = route_table_init ();
199
200 new->lsa_refresh_queue.index = 0;
201 new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
202 new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
203 new, new->lsa_refresh_interval);
204 new->lsa_refresher_started = time (NULL);
205
5c33349b 206 if ((new->fd = ospf_sock_init()) < 0)
207 {
208 zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
209 "a socket");
210 exit(1);
211 }
212 if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
213 {
214 zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
215 OSPF_MAX_PACKET_SIZE+1);
216 exit(1);
217 }
218 new->t_read = thread_add_read (master, ospf_read, new, new->fd);
718e3744 219 new->oi_write_q = list_new ();
220
221 return new;
222}
223
224struct ospf *
020709f9 225ospf_lookup ()
718e3744 226{
020709f9 227 if (listcount (om->ospf) == 0)
228 return NULL;
718e3744 229
1eb8ef25 230 return listgetdata (listhead (om->ospf));
020709f9 231}
232
4dadc291 233static void
020709f9 234ospf_add (struct ospf *ospf)
235{
236 listnode_add (om->ospf, ospf);
237}
718e3744 238
4dadc291 239static void
020709f9 240ospf_delete (struct ospf *ospf)
241{
242 listnode_delete (om->ospf, ospf);
243}
68980084 244
020709f9 245struct ospf *
246ospf_get ()
247{
248 struct ospf *ospf;
249
250 ospf = ospf_lookup ();
251 if (ospf == NULL)
252 {
253 ospf = ospf_new ();
254 ospf_add (ospf);
255
256 if (ospf->router_id_static.s_addr == 0)
257 ospf_router_id_update (ospf);
718e3744 258
259#ifdef HAVE_OPAQUE_LSA
020709f9 260 ospf_opaque_type11_lsa_init (ospf);
718e3744 261#endif /* HAVE_OPAQUE_LSA */
020709f9 262 }
68980084 263
264 return ospf;
718e3744 265}
266
267void
268ospf_finish (struct ospf *ospf)
269{
270 struct route_node *rn;
271 struct ospf_nbr_nbma *nbr_nbma;
68980084 272 struct ospf_lsa *lsa;
1eb8ef25 273 struct ospf_interface *oi;
274 struct ospf_area *area;
275 struct ospf_vl_data *vl_data;
276 struct listnode *node, *nnode;
718e3744 277 int i;
278
279#ifdef HAVE_OPAQUE_LSA
280 ospf_opaque_type11_lsa_term (ospf);
281#endif /* HAVE_OPAQUE_LSA */
282
283 /* Unredister redistribution */
284 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
020709f9 285 ospf_redistribute_unset (ospf, i);
718e3744 286
1eb8ef25 287 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
288 ospf_remove_vls_through_area (ospf, area);
718e3744 289
1eb8ef25 290 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
291 ospf_vl_delete (ospf, vl_data);
718e3744 292
293 list_delete (ospf->vlinks);
294
295 /* Reset interface. */
1eb8ef25 296 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
297 ospf_if_free (oi);
718e3744 298
299 /* Clear static neighbors */
300 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
301 if ((nbr_nbma = rn->info))
302 {
303 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
304
305 if (nbr_nbma->nbr)
306 {
307 nbr_nbma->nbr->nbr_nbma = NULL;
308 nbr_nbma->nbr = NULL;
309 }
310
311 if (nbr_nbma->oi)
312 {
313 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
314 nbr_nbma->oi = NULL;
315 }
316
317 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
318 }
319
320 route_table_finish (ospf->nbr_nbma);
321
322 /* Clear networks and Areas. */
323 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
324 {
325 struct ospf_network *network;
326
327 if ((network = rn->info) != NULL)
328 {
68980084 329 ospf_network_free (ospf, network);
718e3744 330 rn->info = NULL;
331 route_unlock_node (rn);
332 }
333 }
334
1eb8ef25 335 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 336 {
718e3744 337 listnode_delete (ospf->areas, area);
338 ospf_area_free (area);
339 }
340
341 /* Cancel all timers. */
342 OSPF_TIMER_OFF (ospf->t_external_lsa);
343 OSPF_TIMER_OFF (ospf->t_router_id_update);
344 OSPF_TIMER_OFF (ospf->t_router_lsa_update);
345 OSPF_TIMER_OFF (ospf->t_spf_calc);
346 OSPF_TIMER_OFF (ospf->t_ase_calc);
347 OSPF_TIMER_OFF (ospf->t_maxage);
348 OSPF_TIMER_OFF (ospf->t_maxage_walker);
349 OSPF_TIMER_OFF (ospf->t_abr_task);
350 OSPF_TIMER_OFF (ospf->t_distribute_update);
351 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
352 OSPF_TIMER_OFF (ospf->t_read);
353 OSPF_TIMER_OFF (ospf->t_write);
354
355 close (ospf->fd);
5c33349b 356 stream_free(ospf->ibuf);
718e3744 357
358#ifdef HAVE_OPAQUE_LSA
68980084 359 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
360 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
718e3744 361#endif /* HAVE_OPAQUE_LSA */
68980084 362 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
363 ospf_discard_from_db (ospf, ospf->lsdb, lsa);
364
718e3744 365 ospf_lsdb_delete_all (ospf->lsdb);
366 ospf_lsdb_free (ospf->lsdb);
367
1eb8ef25 368 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
369 ospf_lsa_unlock (lsa);
718e3744 370
371 list_delete (ospf->maxage_lsa);
372
373 if (ospf->old_table)
374 ospf_route_table_free (ospf->old_table);
375 if (ospf->new_table)
376 {
377 ospf_route_delete (ospf->new_table);
378 ospf_route_table_free (ospf->new_table);
379 }
380 if (ospf->old_rtrs)
381 ospf_rtrs_free (ospf->old_rtrs);
382 if (ospf->new_rtrs)
383 ospf_rtrs_free (ospf->new_rtrs);
384 if (ospf->new_external_route)
385 {
386 ospf_route_delete (ospf->new_external_route);
387 ospf_route_table_free (ospf->new_external_route);
388 }
389 if (ospf->old_external_route)
390 {
391 ospf_route_delete (ospf->old_external_route);
392 ospf_route_table_free (ospf->old_external_route);
393 }
394 if (ospf->external_lsas)
395 {
396 ospf_ase_external_lsas_finish (ospf->external_lsas);
397 }
398
399 list_delete (ospf->areas);
400
401 for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
402 if (EXTERNAL_INFO (i) != NULL)
403 for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
404 {
405 if (rn->info == NULL)
406 continue;
407
408 XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
409 rn->info = NULL;
410 route_unlock_node (rn);
411 }
412
68980084 413 ospf_distance_reset (ospf);
718e3744 414 route_table_finish (ospf->distance_table);
415
020709f9 416 ospf_delete (ospf);
718e3744 417
020709f9 418 XFREE (MTYPE_OSPF_TOP, ospf);
718e3744 419}
420
421\f
422/* allocate new OSPF Area object */
4dadc291 423static struct ospf_area *
68980084 424ospf_area_new (struct ospf *ospf, struct in_addr area_id)
718e3744 425{
426 struct ospf_area *new;
427
428 /* Allocate new config_network. */
429 new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
430
68980084 431 new->ospf = ospf;
718e3744 432
433 new->area_id = area_id;
434
435 new->external_routing = OSPF_AREA_DEFAULT;
436 new->default_cost = 1;
437 new->auth_type = OSPF_AUTH_NULL;
438
439 /* New LSDB init. */
440 new->lsdb = ospf_lsdb_new ();
441
442 /* Self-originated LSAs initialize. */
443 new->router_lsa_self = NULL;
444
445#ifdef HAVE_OPAQUE_LSA
446 ospf_opaque_type10_lsa_init (new);
447#endif /* HAVE_OPAQUE_LSA */
448
449 new->oiflist = list_new ();
450 new->ranges = route_table_init ();
451
452 if (area_id.s_addr == OSPF_AREA_BACKBONE)
68980084 453 ospf->backbone = new;
718e3744 454
455 return new;
456}
457
458void
459ospf_area_free (struct ospf_area *area)
460{
68980084 461 struct route_node *rn;
462 struct ospf_lsa *lsa;
463
718e3744 464 /* Free LSDBs. */
68980084 465 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
466 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
467 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
468 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
469 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
470 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
471 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
472 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
718e3744 473
68980084 474 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
475 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
718e3744 476#ifdef HAVE_OPAQUE_LSA
68980084 477 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
478 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
479 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
480 ospf_discard_from_db (area->ospf, area->lsdb, lsa);
718e3744 481#endif /* HAVE_OPAQUE_LSA */
482
483 ospf_lsdb_delete_all (area->lsdb);
484 ospf_lsdb_free (area->lsdb);
485
718e3744 486 ospf_lsa_unlock (area->router_lsa_self);
487
488 route_table_finish (area->ranges);
489 list_delete (area->oiflist);
490
491 if (EXPORT_NAME (area))
492 free (EXPORT_NAME (area));
493
494 if (IMPORT_NAME (area))
495 free (IMPORT_NAME (area));
496
497 /* Cancel timer. */
498 OSPF_TIMER_OFF (area->t_router_lsa_self);
499
500 if (OSPF_IS_AREA_BACKBONE (area))
68980084 501 area->ospf->backbone = NULL;
718e3744 502
503 XFREE (MTYPE_OSPF_AREA, area);
504}
505
506void
68980084 507ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
718e3744 508{
509 struct ospf_area *area;
510
68980084 511 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 512 if (area &&
513 listcount (area->oiflist) == 0 &&
514 area->ranges->top == NULL &&
515 area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
516 area->external_routing == OSPF_AREA_DEFAULT &&
517 area->no_summary == 0 &&
518 area->default_cost == 1 &&
519 EXPORT_NAME (area) == NULL &&
520 IMPORT_NAME (area) == NULL &&
521 area->auth_type == OSPF_AUTH_NULL)
522 {
68980084 523 listnode_delete (ospf->areas, area);
718e3744 524 ospf_area_free (area);
525 }
526}
527
528struct ospf_area *
68980084 529ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
718e3744 530{
531 struct ospf_area *area;
532
68980084 533 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 534 if (!area)
535 {
68980084 536 area = ospf_area_new (ospf, area_id);
718e3744 537 area->format = format;
68980084 538 listnode_add_sort (ospf->areas, area);
539 ospf_check_abr_status (ospf);
718e3744 540 }
541
542 return area;
543}
544
545struct ospf_area *
68980084 546ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
718e3744 547{
548 struct ospf_area *area;
52dc7ee6 549 struct listnode *node;
718e3744 550
1eb8ef25 551 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
552 if (IPV4_ADDR_SAME (&area->area_id, &area_id))
553 return area;
718e3744 554
555 return NULL;
556}
557
558void
559ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
560{
561 listnode_add (area->oiflist, oi);
562}
563
564void
565ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
566{
567 listnode_delete (area->oiflist, oi);
568}
569
570\f
571/* Config network statement related functions. */
4dadc291 572static struct ospf_network *
718e3744 573ospf_network_new (struct in_addr area_id, int format)
574{
575 struct ospf_network *new;
576 new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
577
578 new->area_id = area_id;
579 new->format = format;
580
581 return new;
582}
583
584void
68980084 585ospf_network_free (struct ospf *ospf, struct ospf_network *network)
718e3744 586{
68980084 587 ospf_area_check_free (ospf, network->area_id);
588 ospf_schedule_abr_task (ospf);
718e3744 589 XFREE (MTYPE_OSPF_NETWORK, network);
590}
591
592int
593ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
594 struct in_addr area_id)
595{
596 struct ospf_network *network;
597 struct ospf_area *area;
598 struct route_node *rn;
599 struct external_info *ei;
147193a2 600 int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 601
602 rn = route_node_get (ospf->networks, (struct prefix *)p);
603 if (rn->info)
604 {
605 /* There is already same network statement. */
606 route_unlock_node (rn);
607 return 0;
608 }
609
610 rn->info = network = ospf_network_new (area_id, ret);
68980084 611 area = ospf_area_get (ospf, area_id, ret);
718e3744 612
613 /* Run network config now. */
614 ospf_network_run (ospf, (struct prefix *)p, area);
615
616 /* Update connected redistribute. */
617 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
618 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
619 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
620 rn; rn = route_next (rn))
621 if ((ei = rn->info) != NULL)
68980084 622 if (ospf_external_info_find_lsa (ospf, &ei->p))
623 if (!ospf_distribute_check_connected (ospf, ei))
624 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
5339cfdb 625 ei->ifindex /*, ei->nexthop */);
718e3744 626
68980084 627 ospf_area_check_free (ospf, area_id);
718e3744 628
629 return 1;
630}
631
632int
633ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
634 struct in_addr area_id)
635{
636 struct route_node *rn;
637 struct ospf_network *network;
638 struct external_info *ei;
639
640 rn = route_node_lookup (ospf->networks, (struct prefix *)p);
641 if (rn == NULL)
642 return 0;
643
644 network = rn->info;
645 if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
646 return 0;
647
68980084 648 ospf_network_free (ospf, rn->info);
718e3744 649 rn->info = NULL;
650 route_unlock_node (rn);
651
68980084 652 ospf_if_update (ospf);
718e3744 653
654 /* Update connected redistribute. */
655 if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
656 if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
657 for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
658 rn; rn = route_next (rn))
659 if ((ei = rn->info) != NULL)
68980084 660 if (!ospf_external_info_find_lsa (ospf, &ei->p))
661 if (ospf_distribute_check_connected (ospf, ei))
662 ospf_external_lsa_originate (ospf, ei);
718e3744 663
664 return 1;
665}
666
570f7598 667/* Check whether interface matches given network
668 * returns: 1, true. 0, false
669 */
670int
671ospf_network_match_iface(struct connected *co, struct prefix *net)
672{
673 /* Behaviour to match both Cisco where:
674 * iface address lies within network specified -> ospf
675 * and zebra 0.9[2ish-3]:
676 * PtP special case: network specified == iface peer addr -> ospf
677 */
8f40e891 678
f3ae74cd 679 /* For PtP, match if peer address matches network address exactly.
680 * This can be addr/32 or addr/p for p < 32, but the addr must match
681 * exactly; this is not a test for falling within the prefix. This
8f40e891 682 * test is solely for compatibility with zebra.
8f40e891 683 */
f3ae74cd 684 if (if_is_pointopoint (co->ifp) && co->destination &&
685 IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4)))
686 return 1;
687
688#if 0
689 /* Decline to accept PtP if dst address does not match the
690 * prefix. (ifdefed out because this is a workaround, not the
691 * desired behavior.) */
692 if (if_is_pointopoint (co->ifp) &&
693 ! prefix_match (net, co->destination))
694 return 0;
695#endif
696
697 /* If the address is within the prefix, accept. Note that this
698 * applies to PtP as well as other types.
699 */
700 if (prefix_match (net, co->address))
701 return 1;
702
703 return 0; /* no match */
570f7598 704}
705
718e3744 706void
707ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
708{
709 struct interface *ifp;
1eb8ef25 710 struct connected *co;
52dc7ee6 711 struct listnode *node;
718e3744 712
713 /* Schedule Router ID Update. */
714 if (ospf->router_id_static.s_addr == 0)
715 if (ospf->t_router_id_update == NULL)
716 {
020709f9 717 OSPF_TIMER_ON (ospf->t_router_id_update, ospf_router_id_update_timer,
718 OSPF_ROUTER_ID_UPDATE_DELAY);
718e3744 719 }
720
721 /* Get target interface. */
1eb8ef25 722 for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
718e3744 723 {
1eb8ef25 724 struct listnode *cnode;
718e3744 725
718e3744 726 if (memcmp (ifp->name, "VLINK", 5) == 0)
727 continue;
728
729 /* if interface prefix is match specified prefix,
730 then create socket and join multicast group. */
1eb8ef25 731 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
718e3744 732 {
718e3744 733 struct prefix *addr;
800dc105 734
e7b050cb 735 if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
736 continue;
718e3744 737
3fb9cd6e 738 if (CONNECTED_POINTOPOINT_HOST(co))
718e3744 739 addr = co->destination;
740 else
741 addr = co->address;
742
cb3f37d2 743 if (p->family == co->address->family
68980084 744 && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
cb3f37d2 745 && ospf_network_match_iface(co,p))
570f7598 746 {
1eb8ef25 747 struct ospf_interface *oi;
718e3744 748
68980084 749 oi = ospf_if_new (ospf, ifp, co->address);
718e3744 750 oi->connected = co;
751
752 oi->nbr_self->address = *oi->address;
753
718e3744 754 oi->area = area;
755
756 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
757 oi->output_cost = ospf_if_get_output_cost (oi);
758
759 if (area->external_routing != OSPF_AREA_DEFAULT)
760 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
761 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
762
763 /* Add pseudo neighbor. */
764 ospf_nbr_add_self (oi);
765
766 /* Make sure pseudo neighbor's router_id. */
68980084 767 oi->nbr_self->router_id = ospf->router_id;
718e3744 768 oi->nbr_self->src = oi->address->u.prefix4;
769
770 /* Relate ospf interface to ospf instance. */
68980084 771 oi->ospf = ospf;
718e3744 772
773 /* update network type as interface flag */
774 /* If network type is specified previously,
775 skip network type setting. */
776 oi->type = IF_DEF_PARAMS (ifp)->type;
777
778 /* Set area flag. */
779 switch (area->external_routing)
780 {
781 case OSPF_AREA_DEFAULT:
782 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
783 break;
784 case OSPF_AREA_STUB:
785 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
786 break;
718e3744 787 case OSPF_AREA_NSSA:
788 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
789 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
790 break;
718e3744 791 }
792
793 ospf_area_add_if (oi->area, oi);
794
2e3b2e47 795 if (if_is_operative (ifp))
718e3744 796 ospf_if_up (oi);
797
798 break;
799 }
800 }
801 }
802}
803
804void
805ospf_ls_upd_queue_empty (struct ospf_interface *oi)
806{
807 struct route_node *rn;
1eb8ef25 808 struct listnode *node, *nnode;
52dc7ee6 809 struct list *lst;
718e3744 810 struct ospf_lsa *lsa;
811
812 /* empty ls update queue */
813 for (rn = route_top (oi->ls_upd_queue); rn;
814 rn = route_next (rn))
52dc7ee6 815 if ((lst = (struct list *) rn->info))
718e3744 816 {
1eb8ef25 817 for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
818 ospf_lsa_unlock (lsa);
718e3744 819 list_free (lst);
820 rn->info = NULL;
821 }
822
823 /* remove update event */
824 if (oi->t_ls_upd_event)
825 {
826 thread_cancel (oi->t_ls_upd_event);
827 oi->t_ls_upd_event = NULL;
828 }
829}
830
831void
68980084 832ospf_if_update (struct ospf *ospf)
718e3744 833{
834 struct route_node *rn;
1eb8ef25 835 struct listnode *node, *nnode;
718e3744 836 struct ospf_network *network;
837 struct ospf_area *area;
1eb8ef25 838 struct ospf_interface *oi;
718e3744 839
68980084 840 if (ospf != NULL)
718e3744 841 {
842 /* Update Router ID scheduled. */
68980084 843 if (ospf->router_id_static.s_addr == 0)
844 if (ospf->t_router_id_update == NULL)
718e3744 845 {
020709f9 846 OSPF_TIMER_ON (ospf->t_router_id_update,
847 ospf_router_id_update_timer,
848 OSPF_ROUTER_ID_UPDATE_DELAY);
718e3744 849 }
850
851 /* Find interfaces that not configured already. */
1eb8ef25 852 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
718e3744 853 {
854 int found = 0;
718e3744 855 struct connected *co = oi->connected;
856
718e3744 857 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
858 continue;
859
68980084 860 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
718e3744 861 {
862 if (rn->info == NULL)
863 continue;
864
570f7598 865 if (ospf_network_match_iface(co,&rn->p))
718e3744 866 {
867 found = 1;
868 route_unlock_node (rn);
869 break;
870 }
871 }
872
873 if (found == 0)
874 ospf_if_free (oi);
875 }
876
877 /* Run each interface. */
68980084 878 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
718e3744 879 if (rn->info != NULL)
880 {
881 network = (struct ospf_network *) rn->info;
68980084 882 area = ospf_area_get (ospf, network->area_id, network->format);
883 ospf_network_run (ospf, &rn->p, area);
718e3744 884 }
885 }
886}
887
888void
68980084 889ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
718e3744 890{
1eb8ef25 891 struct listnode *node, *nnode;
718e3744 892 struct ospf_vl_data *vl_data;
893
1eb8ef25 894 for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
895 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
896 ospf_vl_delete (ospf, vl_data);
718e3744 897}
898
899\f
900struct message ospf_area_type_msg[] =
901{
902 { OSPF_AREA_DEFAULT, "Default" },
903 { OSPF_AREA_STUB, "Stub" },
904 { OSPF_AREA_NSSA, "NSSA" },
905};
906int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
907
4dadc291 908static void
718e3744 909ospf_area_type_set (struct ospf_area *area, int type)
910{
52dc7ee6 911 struct listnode *node;
718e3744 912 struct ospf_interface *oi;
913
914 if (area->external_routing == type)
915 {
916 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 917 zlog_debug ("Area[%s]: Types are the same, ignored.",
718e3744 918 inet_ntoa (area->area_id));
919 return;
920 }
921
922 area->external_routing = type;
923
924 if (IS_DEBUG_OSPF_EVENT)
9b0e25c0 925 zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
718e3744 926 LOOKUP (ospf_area_type_msg, type));
927
928 switch (area->external_routing)
929 {
930 case OSPF_AREA_DEFAULT:
1eb8ef25 931 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
932 if (oi->nbr_self != NULL)
933 {
934 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
935 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
936 }
718e3744 937 break;
938 case OSPF_AREA_STUB:
1eb8ef25 939 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
940 if (oi->nbr_self != NULL)
941 {
942 if (IS_DEBUG_OSPF_EVENT)
943 zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
944 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
945 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
946 if (IS_DEBUG_OSPF_EVENT)
947 zlog_debug ("options set on %s: %x",
948 IF_NAME (oi), OPTIONS (oi));
949 }
718e3744 950 break;
951 case OSPF_AREA_NSSA:
1eb8ef25 952 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
953 if (oi->nbr_self != NULL)
954 {
955 zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
956 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
957 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
958 zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
959 }
718e3744 960 break;
961 default:
962 break;
963 }
964
965 ospf_router_lsa_timer_add (area);
68980084 966 ospf_schedule_abr_task (area->ospf);
718e3744 967}
968
969int
68980084 970ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
718e3744 971{
972 if (area->shortcut_configured == mode)
973 return 0;
974
975 area->shortcut_configured = mode;
976 ospf_router_lsa_timer_add (area);
68980084 977 ospf_schedule_abr_task (ospf);
718e3744 978
68980084 979 ospf_area_check_free (ospf, area->area_id);
718e3744 980
981 return 1;
982}
983
984int
68980084 985ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
718e3744 986{
987 area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
988 ospf_router_lsa_timer_add (area);
68980084 989 ospf_area_check_free (ospf, area->area_id);
990 ospf_schedule_abr_task (ospf);
718e3744 991
992 return 1;
993}
994
4dadc291 995static int
718e3744 996ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
997{
998 struct ospf_vl_data *vl;
52dc7ee6 999 struct listnode *node;
718e3744 1000 int count = 0;
1001
1eb8ef25 1002 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
1003 if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
1004 count++;
718e3744 1005
1006 return count;
1007}
1008
1009int
1010ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
1011{
1012 struct ospf_area *area;
147193a2 1013 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 1014
68980084 1015 area = ospf_area_get (ospf, area_id, format);
718e3744 1016 if (ospf_area_vlink_count (ospf, area))
1017 return 0;
1018
1019 if (area->external_routing != OSPF_AREA_STUB)
1020 ospf_area_type_set (area, OSPF_AREA_STUB);
1021
1022 return 1;
1023}
1024
1025int
1026ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
1027{
1028 struct ospf_area *area;
1029
68980084 1030 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1031 if (area == NULL)
1032 return 1;
1033
1034 if (area->external_routing == OSPF_AREA_STUB)
1035 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1036
68980084 1037 ospf_area_check_free (ospf, area_id);
718e3744 1038
1039 return 1;
1040}
1041
1042int
1043ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
1044{
1045 struct ospf_area *area;
147193a2 1046 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 1047
68980084 1048 area = ospf_area_get (ospf, area_id, format);
718e3744 1049 area->no_summary = 1;
1050
1051 return 1;
1052}
1053
1054int
1055ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
1056{
1057 struct ospf_area *area;
1058
68980084 1059 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1060 if (area == NULL)
1061 return 0;
1062
1063 area->no_summary = 0;
68980084 1064 ospf_area_check_free (ospf, area_id);
718e3744 1065
1066 return 1;
1067}
1068
1069int
1070ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
1071{
1072 struct ospf_area *area;
147193a2 1073 int format = OSPF_AREA_ID_FORMAT_ADDRESS;
718e3744 1074
68980084 1075 area = ospf_area_get (ospf, area_id, format);
718e3744 1076 if (ospf_area_vlink_count (ospf, area))
1077 return 0;
1078
1079 if (area->external_routing != OSPF_AREA_NSSA)
1080 {
1081 ospf_area_type_set (area, OSPF_AREA_NSSA);
1082 ospf->anyNSSA++;
1083 }
1084
084c7844 1085 /* set NSSA area defaults */
1086 area->no_summary = 0;
1087 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
d4a53d58 1088 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
084c7844 1089 area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
1090
718e3744 1091 return 1;
1092}
1093
1094int
1095ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
1096{
1097 struct ospf_area *area;
1098
68980084 1099 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1100 if (area == NULL)
1101 return 0;
1102
1103 if (area->external_routing == OSPF_AREA_NSSA)
1104 {
1105 ospf->anyNSSA--;
1106 ospf_area_type_set (area, OSPF_AREA_DEFAULT);
1107 }
1108
68980084 1109 ospf_area_check_free (ospf, area_id);
718e3744 1110
1111 return 1;
1112}
1113
1114int
1115ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
1116 int role)
1117{
1118 struct ospf_area *area;
1119
68980084 1120 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1121 if (area == NULL)
1122 return 0;
1123
084c7844 1124 area->NSSATranslatorRole = role;
718e3744 1125
1126 return 1;
1127}
1128
4dadc291 1129/* XXX: unused? Leave for symmetry? */
1130static int
718e3744 1131ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1132 struct in_addr area_id)
1133{
1134 struct ospf_area *area;
1135
68980084 1136 area = ospf_area_lookup_by_area_id (ospf, area_id);
718e3744 1137 if (area == NULL)
1138 return 0;
1139
084c7844 1140 area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
718e3744 1141
68980084 1142 ospf_area_check_free (ospf, area_id);
718e3744 1143
1144 return 1;
1145}
1146
1147int
68980084 1148ospf_area_export_list_set (struct ospf *ospf,
6c835671 1149 struct ospf_area *area, const char *list_name)
718e3744 1150{
1151 struct access_list *list;
1152 list = access_list_lookup (AFI_IP, list_name);
1153
1154 EXPORT_LIST (area) = list;
1155
1156 if (EXPORT_NAME (area))
1157 free (EXPORT_NAME (area));
1158
1159 EXPORT_NAME (area) = strdup (list_name);
68980084 1160 ospf_schedule_abr_task (ospf);
718e3744 1161
1162 return 1;
1163}
1164
1165int
68980084 1166ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
718e3744 1167{
1168
1169 EXPORT_LIST (area) = 0;
1170
1171 if (EXPORT_NAME (area))
1172 free (EXPORT_NAME (area));
1173
1174 EXPORT_NAME (area) = NULL;
1175
68980084 1176 ospf_area_check_free (ospf, area->area_id);
718e3744 1177
68980084 1178 ospf_schedule_abr_task (ospf);
718e3744 1179
1180 return 1;
1181}
1182
1183int
6c835671 1184ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1185 const char *name)
718e3744 1186{
1187 struct access_list *list;
1188 list = access_list_lookup (AFI_IP, name);
1189
1190 IMPORT_LIST (area) = list;
1191
1192 if (IMPORT_NAME (area))
1193 free (IMPORT_NAME (area));
1194
1195 IMPORT_NAME (area) = strdup (name);
68980084 1196 ospf_schedule_abr_task (ospf);
718e3744 1197
1198 return 1;
1199}
1200
1201int
68980084 1202ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
718e3744 1203{
1204 IMPORT_LIST (area) = 0;
1205
1206 if (IMPORT_NAME (area))
1207 free (IMPORT_NAME (area));
1208
1209 IMPORT_NAME (area) = NULL;
68980084 1210 ospf_area_check_free (ospf, area->area_id);
718e3744 1211
68980084 1212 ospf_schedule_abr_task (ospf);
718e3744 1213
1214 return 1;
1215}
1216
718e3744 1217int
1218ospf_timers_refresh_set (struct ospf *ospf, int interval)
1219{
1220 int time_left;
1221
1222 if (ospf->lsa_refresh_interval == interval)
1223 return 1;
1224
1225 time_left = ospf->lsa_refresh_interval -
1226 (time (NULL) - ospf->lsa_refresher_started);
1227
1228 if (time_left > interval)
1229 {
1230 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1231 ospf->t_lsa_refresher =
1232 thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1233 }
1234 ospf->lsa_refresh_interval = interval;
1235
1236 return 1;
1237}
1238
1239int
1240ospf_timers_refresh_unset (struct ospf *ospf)
1241{
1242 int time_left;
1243
1244 time_left = ospf->lsa_refresh_interval -
1245 (time (NULL) - ospf->lsa_refresher_started);
1246
1247 if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1248 {
1249 OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1250 ospf->t_lsa_refresher =
1251 thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1252 OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1253 }
1254
1255 ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1256
1257 return 1;
1258}
1259
1260\f
4dadc291 1261static struct ospf_nbr_nbma *
1262ospf_nbr_nbma_new (void)
718e3744 1263{
1264 struct ospf_nbr_nbma *nbr_nbma;
1265
1266 nbr_nbma = XMALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1267 sizeof (struct ospf_nbr_nbma));
1268 memset (nbr_nbma, 0, sizeof (struct ospf_nbr_nbma));
1269
1270 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1271 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1272
1273 return nbr_nbma;
1274}
1275
4dadc291 1276static void
718e3744 1277ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1278{
1279 XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1280}
1281
4dadc291 1282static void
718e3744 1283ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1284{
1285 struct route_node *rn;
1286 struct prefix_ipv4 p;
1287
1288 p.family = AF_INET;
1289 p.prefix = nbr_nbma->addr;
1290 p.prefixlen = IPV4_MAX_BITLEN;
1291
1292 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1293 if (rn)
1294 {
1295 ospf_nbr_nbma_free (rn->info);
1296 rn->info = NULL;
1297 route_unlock_node (rn);
1298 route_unlock_node (rn);
1299 }
1300}
1301
4dadc291 1302static void
718e3744 1303ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1304{
1305 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1306
1307 if (nbr_nbma->nbr)
1308 {
1309 nbr_nbma->nbr->nbr_nbma = NULL;
1310 OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1311 }
1312
1313 if (nbr_nbma->oi)
1314 listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1315}
1316
4dadc291 1317static void
718e3744 1318ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1319 struct ospf_interface *oi)
1320{
1321 struct ospf_neighbor *nbr;
1322 struct route_node *rn;
1323 struct prefix p;
1324
1325 if (oi->type != OSPF_IFTYPE_NBMA)
1326 return;
1327
1328 if (nbr_nbma->nbr != NULL)
1329 return;
1330
1331 if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1332 return;
1333
1334 nbr_nbma->oi = oi;
1335 listnode_add (oi->nbr_nbma, nbr_nbma);
1336
1337 /* Get neighbor information from table. */
1338 p.family = AF_INET;
1339 p.prefixlen = IPV4_MAX_BITLEN;
1340 p.u.prefix4 = nbr_nbma->addr;
1341
1342 rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1343 if (rn->info)
1344 {
1345 nbr = rn->info;
1346 nbr->nbr_nbma = nbr_nbma;
1347 nbr_nbma->nbr = nbr;
1348
1349 route_unlock_node (rn);
1350 }
1351 else
1352 {
1353 nbr = rn->info = ospf_nbr_new (oi);
1354 nbr->state = NSM_Down;
1355 nbr->src = nbr_nbma->addr;
1356 nbr->nbr_nbma = nbr_nbma;
1357 nbr->priority = nbr_nbma->priority;
1358 nbr->address = p;
1359
1360 nbr_nbma->nbr = nbr;
1361
1362 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1363 }
1364}
1365
1366void
68980084 1367ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
718e3744 1368{
1369 struct ospf_nbr_nbma *nbr_nbma;
1370 struct route_node *rn;
1371 struct prefix_ipv4 p;
1372
1373 if (oi->type != OSPF_IFTYPE_NBMA)
1374 return;
1375
68980084 1376 for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
718e3744 1377 if ((nbr_nbma = rn->info))
1378 if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1379 {
1380 p.family = AF_INET;
1381 p.prefix = nbr_nbma->addr;
1382 p.prefixlen = IPV4_MAX_BITLEN;
1383
1384 if (prefix_match (oi->address, (struct prefix *)&p))
1385 ospf_nbr_nbma_add (nbr_nbma, oi);
1386 }
1387}
1388
1389struct ospf_nbr_nbma *
1390ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1391{
1392 struct route_node *rn;
1393 struct prefix_ipv4 p;
1394
1395 p.family = AF_INET;
1396 p.prefix = nbr_addr;
1397 p.prefixlen = IPV4_MAX_BITLEN;
1398
1399 rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1400 if (rn)
1401 {
1402 route_unlock_node (rn);
1403 return rn->info;
1404 }
1405 return NULL;
1406}
1407
1408struct ospf_nbr_nbma *
68980084 1409ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
718e3744 1410{
1411#if 0
1412 struct ospf_nbr_nbma *nbr_nbma;
52dc7ee6 1413 struct listnode *node;
718e3744 1414#endif
1415
68980084 1416 if (ospf == NULL)
718e3744 1417 return NULL;
1418
1419#if 0
1eb8ef25 1420 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
718e3744 1421 {
718e3744 1422 if (first)
1423 {
1424 *addr = nbr_nbma->addr;
1425 return nbr_nbma;
1426 }
1427 else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1428 {
1429 *addr = nbr_nbma->addr;
1430 return nbr_nbma;
1431 }
1432 }
1433#endif
1434 return NULL;
1435}
1436
1437int
1438ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1439{
1440 struct ospf_nbr_nbma *nbr_nbma;
1441 struct ospf_interface *oi;
1442 struct prefix_ipv4 p;
1443 struct route_node *rn;
52dc7ee6 1444 struct listnode *node;
718e3744 1445
1446 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1447 if (nbr_nbma)
1448 return 0;
1449
1450 nbr_nbma = ospf_nbr_nbma_new ();
1451 nbr_nbma->addr = nbr_addr;
1452
1453 p.family = AF_INET;
1454 p.prefix = nbr_addr;
1455 p.prefixlen = IPV4_MAX_BITLEN;
1456
1457 rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1458 rn->info = nbr_nbma;
1459
1eb8ef25 1460 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
718e3744 1461 {
718e3744 1462 if (oi->type == OSPF_IFTYPE_NBMA)
1463 if (prefix_match (oi->address, (struct prefix *)&p))
1464 {
1465 ospf_nbr_nbma_add (nbr_nbma, oi);
1466 break;
1467 }
1468 }
1469
1470 return 1;
1471}
1472
1473int
1474ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1475{
1476 struct ospf_nbr_nbma *nbr_nbma;
1477
1478 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1479 if (nbr_nbma == NULL)
1480 return 0;
1481
1482 ospf_nbr_nbma_down (nbr_nbma);
1483 ospf_nbr_nbma_delete (ospf, nbr_nbma);
1484
1485 return 1;
1486}
1487
1488int
1489ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1490 u_char priority)
1491{
1492 struct ospf_nbr_nbma *nbr_nbma;
1493
1494 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1495 if (nbr_nbma == NULL)
1496 return 0;
1497
1498 if (nbr_nbma->priority != priority)
1499 nbr_nbma->priority = priority;
1500
1501 return 1;
1502}
1503
1504int
1505ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1506{
1507 struct ospf_nbr_nbma *nbr_nbma;
1508
1509 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1510 if (nbr_nbma == NULL)
1511 return 0;
1512
1513 if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1514 nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1515
1516 return 1;
1517}
1518
1519int
1520ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
6c835671 1521 unsigned int interval)
718e3744 1522{
1523 struct ospf_nbr_nbma *nbr_nbma;
1524
1525 nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1526 if (nbr_nbma == NULL)
1527 return 0;
1528
1529 if (nbr_nbma->v_poll != interval)
1530 {
1531 nbr_nbma->v_poll = interval;
1532 if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1533 {
1534 OSPF_TIMER_OFF (nbr_nbma->t_poll);
1535 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1536 nbr_nbma->v_poll);
1537 }
1538 }
1539
1540 return 1;
1541}
1542
1543int
1544ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1545{
1546 struct ospf_nbr_nbma *nbr_nbma;
1547
1548 nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1549 if (nbr_nbma == NULL)
1550 return 0;
1551
1552 if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1553 nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1554
1555 return 1;
1556}
1557
718e3744 1558void
020709f9 1559ospf_master_init ()
718e3744 1560{
020709f9 1561 memset (&ospf_master, 0, sizeof (struct ospf_master));
1562
1563 om = &ospf_master;
1564 om->ospf = list_new ();
1565 om->master = thread_master_create ();
1566 om->start_time = time (NULL);
1567}