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