Annotation of embedaddon/quagga/ospfd/ospfd.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 1207: #if 0
1.1 misho 1208: /* XXX: unused? Leave for symmetry? */
1209: static int
1210: ospf_area_nssa_translator_role_unset (struct ospf *ospf,
1211: struct in_addr area_id)
1212: {
1213: struct ospf_area *area;
1214:
1215: area = ospf_area_lookup_by_area_id (ospf, area_id);
1216: if (area == NULL)
1217: return 0;
1218:
1219: area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
1220:
1221: ospf_area_check_free (ospf, area_id);
1222:
1223: return 1;
1224: }
1.1.1.2 ! misho 1225: #endif
1.1 misho 1226:
1227: int
1228: ospf_area_export_list_set (struct ospf *ospf,
1229: struct ospf_area *area, const char *list_name)
1230: {
1231: struct access_list *list;
1232: list = access_list_lookup (AFI_IP, list_name);
1233:
1234: EXPORT_LIST (area) = list;
1235:
1236: if (EXPORT_NAME (area))
1237: free (EXPORT_NAME (area));
1238:
1239: EXPORT_NAME (area) = strdup (list_name);
1240: ospf_schedule_abr_task (ospf);
1241:
1242: return 1;
1243: }
1244:
1245: int
1246: ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
1247: {
1248:
1249: EXPORT_LIST (area) = 0;
1250:
1251: if (EXPORT_NAME (area))
1252: free (EXPORT_NAME (area));
1253:
1254: EXPORT_NAME (area) = NULL;
1255:
1256: ospf_area_check_free (ospf, area->area_id);
1257:
1258: ospf_schedule_abr_task (ospf);
1259:
1260: return 1;
1261: }
1262:
1263: int
1264: ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area,
1265: const char *name)
1266: {
1267: struct access_list *list;
1268: list = access_list_lookup (AFI_IP, name);
1269:
1270: IMPORT_LIST (area) = list;
1271:
1272: if (IMPORT_NAME (area))
1273: free (IMPORT_NAME (area));
1274:
1275: IMPORT_NAME (area) = strdup (name);
1276: ospf_schedule_abr_task (ospf);
1277:
1278: return 1;
1279: }
1280:
1281: int
1282: ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
1283: {
1284: IMPORT_LIST (area) = 0;
1285:
1286: if (IMPORT_NAME (area))
1287: free (IMPORT_NAME (area));
1288:
1289: IMPORT_NAME (area) = NULL;
1290: ospf_area_check_free (ospf, area->area_id);
1291:
1292: ospf_schedule_abr_task (ospf);
1293:
1294: return 1;
1295: }
1296:
1297: int
1298: ospf_timers_refresh_set (struct ospf *ospf, int interval)
1299: {
1300: int time_left;
1301:
1302: if (ospf->lsa_refresh_interval == interval)
1303: return 1;
1304:
1305: time_left = ospf->lsa_refresh_interval -
1306: (quagga_time (NULL) - ospf->lsa_refresher_started);
1307:
1308: if (time_left > interval)
1309: {
1310: OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1311: ospf->t_lsa_refresher =
1312: thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
1313: }
1314: ospf->lsa_refresh_interval = interval;
1315:
1316: return 1;
1317: }
1318:
1319: int
1320: ospf_timers_refresh_unset (struct ospf *ospf)
1321: {
1322: int time_left;
1323:
1324: time_left = ospf->lsa_refresh_interval -
1325: (quagga_time (NULL) - ospf->lsa_refresher_started);
1326:
1327: if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
1328: {
1329: OSPF_TIMER_OFF (ospf->t_lsa_refresher);
1330: ospf->t_lsa_refresher =
1331: thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
1332: OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
1333: }
1334:
1335: ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
1336:
1337: return 1;
1338: }
1339:
1340:
1341: static struct ospf_nbr_nbma *
1342: ospf_nbr_nbma_new (void)
1343: {
1344: struct ospf_nbr_nbma *nbr_nbma;
1345:
1346: nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
1347: sizeof (struct ospf_nbr_nbma));
1348:
1349: nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1350: nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1351:
1352: return nbr_nbma;
1353: }
1354:
1355: static void
1356: ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
1357: {
1358: XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
1359: }
1360:
1361: static void
1362: ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
1363: {
1364: struct route_node *rn;
1365: struct prefix_ipv4 p;
1366:
1367: p.family = AF_INET;
1368: p.prefix = nbr_nbma->addr;
1369: p.prefixlen = IPV4_MAX_BITLEN;
1370:
1371: rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1372: if (rn)
1373: {
1374: ospf_nbr_nbma_free (rn->info);
1375: rn->info = NULL;
1376: route_unlock_node (rn);
1377: route_unlock_node (rn);
1378: }
1379: }
1380:
1381: static void
1382: ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
1383: {
1384: OSPF_TIMER_OFF (nbr_nbma->t_poll);
1385:
1386: if (nbr_nbma->nbr)
1387: {
1388: nbr_nbma->nbr->nbr_nbma = NULL;
1389: OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
1390: }
1391:
1392: if (nbr_nbma->oi)
1393: listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
1394: }
1395:
1396: static void
1397: ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
1398: struct ospf_interface *oi)
1399: {
1400: struct ospf_neighbor *nbr;
1401: struct route_node *rn;
1402: struct prefix p;
1403:
1404: if (oi->type != OSPF_IFTYPE_NBMA)
1405: return;
1406:
1407: if (nbr_nbma->nbr != NULL)
1408: return;
1409:
1410: if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
1411: return;
1412:
1413: nbr_nbma->oi = oi;
1414: listnode_add (oi->nbr_nbma, nbr_nbma);
1415:
1416: /* Get neighbor information from table. */
1417: p.family = AF_INET;
1418: p.prefixlen = IPV4_MAX_BITLEN;
1419: p.u.prefix4 = nbr_nbma->addr;
1420:
1421: rn = route_node_get (oi->nbrs, (struct prefix *)&p);
1422: if (rn->info)
1423: {
1424: nbr = rn->info;
1425: nbr->nbr_nbma = nbr_nbma;
1426: nbr_nbma->nbr = nbr;
1427:
1428: route_unlock_node (rn);
1429: }
1430: else
1431: {
1432: nbr = rn->info = ospf_nbr_new (oi);
1433: nbr->state = NSM_Down;
1434: nbr->src = nbr_nbma->addr;
1435: nbr->nbr_nbma = nbr_nbma;
1436: nbr->priority = nbr_nbma->priority;
1437: nbr->address = p;
1438:
1439: nbr_nbma->nbr = nbr;
1440:
1441: OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
1442: }
1443: }
1444:
1445: void
1446: ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
1447: {
1448: struct ospf_nbr_nbma *nbr_nbma;
1449: struct route_node *rn;
1450: struct prefix_ipv4 p;
1451:
1452: if (oi->type != OSPF_IFTYPE_NBMA)
1453: return;
1454:
1455: for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
1456: if ((nbr_nbma = rn->info))
1457: if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
1458: {
1459: p.family = AF_INET;
1460: p.prefix = nbr_nbma->addr;
1461: p.prefixlen = IPV4_MAX_BITLEN;
1462:
1463: if (prefix_match (oi->address, (struct prefix *)&p))
1464: ospf_nbr_nbma_add (nbr_nbma, oi);
1465: }
1466: }
1467:
1468: struct ospf_nbr_nbma *
1469: ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
1470: {
1471: struct route_node *rn;
1472: struct prefix_ipv4 p;
1473:
1474: p.family = AF_INET;
1475: p.prefix = nbr_addr;
1476: p.prefixlen = IPV4_MAX_BITLEN;
1477:
1478: rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
1479: if (rn)
1480: {
1481: route_unlock_node (rn);
1482: return rn->info;
1483: }
1484: return NULL;
1485: }
1486:
1487: struct ospf_nbr_nbma *
1488: ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
1489: {
1490: #if 0
1491: struct ospf_nbr_nbma *nbr_nbma;
1492: struct listnode *node;
1493: #endif
1494:
1495: if (ospf == NULL)
1496: return NULL;
1497:
1498: #if 0
1499: for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
1500: {
1501: if (first)
1502: {
1503: *addr = nbr_nbma->addr;
1504: return nbr_nbma;
1505: }
1506: else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
1507: {
1508: *addr = nbr_nbma->addr;
1509: return nbr_nbma;
1510: }
1511: }
1512: #endif
1513: return NULL;
1514: }
1515:
1516: int
1517: ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
1518: {
1519: struct ospf_nbr_nbma *nbr_nbma;
1520: struct ospf_interface *oi;
1521: struct prefix_ipv4 p;
1522: struct route_node *rn;
1523: struct listnode *node;
1524:
1525: nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1526: if (nbr_nbma)
1527: return 0;
1528:
1529: nbr_nbma = ospf_nbr_nbma_new ();
1530: nbr_nbma->addr = nbr_addr;
1531:
1532: p.family = AF_INET;
1533: p.prefix = nbr_addr;
1534: p.prefixlen = IPV4_MAX_BITLEN;
1535:
1536: rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
1537: rn->info = nbr_nbma;
1538:
1539: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1540: {
1541: if (oi->type == OSPF_IFTYPE_NBMA)
1542: if (prefix_match (oi->address, (struct prefix *)&p))
1543: {
1544: ospf_nbr_nbma_add (nbr_nbma, oi);
1545: break;
1546: }
1547: }
1548:
1549: return 1;
1550: }
1551:
1552: int
1553: ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
1554: {
1555: struct ospf_nbr_nbma *nbr_nbma;
1556:
1557: nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1558: if (nbr_nbma == NULL)
1559: return 0;
1560:
1561: ospf_nbr_nbma_down (nbr_nbma);
1562: ospf_nbr_nbma_delete (ospf, nbr_nbma);
1563:
1564: return 1;
1565: }
1566:
1567: int
1568: ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
1569: u_char priority)
1570: {
1571: struct ospf_nbr_nbma *nbr_nbma;
1572:
1573: nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1574: if (nbr_nbma == NULL)
1575: return 0;
1576:
1577: if (nbr_nbma->priority != priority)
1578: nbr_nbma->priority = priority;
1579:
1580: return 1;
1581: }
1582:
1583: int
1584: ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
1585: {
1586: struct ospf_nbr_nbma *nbr_nbma;
1587:
1588: nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1589: if (nbr_nbma == NULL)
1590: return 0;
1591:
1592: if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
1593: nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
1594:
1595: return 1;
1596: }
1597:
1598: int
1599: ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
1600: unsigned int interval)
1601: {
1602: struct ospf_nbr_nbma *nbr_nbma;
1603:
1604: nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
1605: if (nbr_nbma == NULL)
1606: return 0;
1607:
1608: if (nbr_nbma->v_poll != interval)
1609: {
1610: nbr_nbma->v_poll = interval;
1611: if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
1612: {
1613: OSPF_TIMER_OFF (nbr_nbma->t_poll);
1614: OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
1615: nbr_nbma->v_poll);
1616: }
1617: }
1618:
1619: return 1;
1620: }
1621:
1622: int
1623: ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
1624: {
1625: struct ospf_nbr_nbma *nbr_nbma;
1626:
1627: nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
1628: if (nbr_nbma == NULL)
1629: return 0;
1630:
1631: if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
1632: nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
1633:
1634: return 1;
1635: }
1636:
1637: void
1638: ospf_master_init ()
1639: {
1640: memset (&ospf_master, 0, sizeof (struct ospf_master));
1641:
1642: om = &ospf_master;
1643: om->ospf = list_new ();
1644: om->master = thread_master_create ();
1645: om->start_time = quagga_time (NULL);
1646: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>