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