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