Annotation of embedaddon/quagga/ospfd/ospf_interface.c, revision 1.1.1.2
1.1 misho 1: /*
2: * OSPF Interface functions.
3: * Copyright (C) 1999, 2000 Toshiaki Takada
4: *
5: * This file is part of GNU Zebra.
6: *
7: * GNU Zebra is free software; you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as published
9: * by the Free Software Foundation; either version 2, or (at your
10: * option) any later version.
11: *
12: * GNU Zebra is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with GNU Zebra; see the file COPYING. If not, write to the
19: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20: * Boston, MA 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "thread.h"
26: #include "linklist.h"
27: #include "prefix.h"
28: #include "if.h"
29: #include "table.h"
30: #include "memory.h"
31: #include "command.h"
32: #include "stream.h"
33: #include "log.h"
34:
35: #include "ospfd/ospfd.h"
36: #include "ospfd/ospf_spf.h"
37: #include "ospfd/ospf_interface.h"
38: #include "ospfd/ospf_ism.h"
39: #include "ospfd/ospf_asbr.h"
40: #include "ospfd/ospf_lsa.h"
41: #include "ospfd/ospf_lsdb.h"
42: #include "ospfd/ospf_neighbor.h"
43: #include "ospfd/ospf_nsm.h"
44: #include "ospfd/ospf_packet.h"
45: #include "ospfd/ospf_abr.h"
46: #include "ospfd/ospf_network.h"
47: #include "ospfd/ospf_dump.h"
48: #ifdef HAVE_SNMP
49: #include "ospfd/ospf_snmp.h"
50: #endif /* HAVE_SNMP */
51:
52:
53: int
54: ospf_if_get_output_cost (struct ospf_interface *oi)
55: {
56: /* If all else fails, use default OSPF cost */
57: u_int32_t cost;
58: u_int32_t bw, refbw;
59:
60: bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH;
61: refbw = oi->ospf->ref_bandwidth;
62:
63: /* A specifed ip ospf cost overrides a calculated one. */
64: if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) ||
65: OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd))
66: cost = OSPF_IF_PARAM (oi, output_cost_cmd);
67: /* See if a cost can be calculated from the zebra processes
68: interface bandwidth field. */
69: else
70: {
71: cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
72: if (cost < 1)
73: cost = 1;
74: else if (cost > 65535)
75: cost = 65535;
76: }
77:
78: return cost;
79: }
80:
81: void
82: ospf_if_recalculate_output_cost (struct interface *ifp)
83: {
84: u_int32_t newcost;
85: struct route_node *rn;
86:
87: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
88: {
89: struct ospf_interface *oi;
90:
91: if ( (oi = rn->info) == NULL)
92: continue;
93:
94: newcost = ospf_if_get_output_cost (oi);
95:
96: /* Is actual output cost changed? */
97: if (oi->output_cost != newcost)
98: {
99: oi->output_cost = newcost;
100: ospf_router_lsa_update_area (oi->area);
101: }
102: }
103: }
104:
105: /* Simulate down/up on the interface. This is needed, for example, when
106: the MTU changes. */
107: void
108: ospf_if_reset(struct interface *ifp)
109: {
110: struct route_node *rn;
111:
112: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
113: {
114: struct ospf_interface *oi;
115:
116: if ( (oi = rn->info) == NULL)
117: continue;
118:
119: ospf_if_down(oi);
120: ospf_if_up(oi);
121: }
122: }
123:
124: void
125: ospf_if_reset_variables (struct ospf_interface *oi)
126: {
127: /* Set default values. */
128: /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */
129:
130: if (oi->vl_data)
131: oi->type = OSPF_IFTYPE_VIRTUALLINK;
132: else
133: /* preserve network-type */
134: if (oi->type != OSPF_IFTYPE_NBMA)
135: oi->type = OSPF_IFTYPE_BROADCAST;
136:
137: oi->state = ISM_Down;
138:
139: oi->crypt_seqnum = 0;
140:
141: /* This must be short, (less than RxmtInterval)
142: - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being
143: held back for too long - MAG */
144: oi->v_ls_ack = 1;
145: }
146:
147: /* lookup oi for specified prefix/ifp */
148: struct ospf_interface *
149: ospf_if_table_lookup (struct interface *ifp, struct prefix *prefix)
150: {
151: struct prefix p;
152: struct route_node *rn;
153: struct ospf_interface *rninfo = NULL;
154:
155: p = *prefix;
156: p.prefixlen = IPV4_MAX_PREFIXLEN;
157:
158: /* route_node_get implicitely locks */
159: if ((rn = route_node_lookup (IF_OIFS (ifp), &p)))
160: {
161: rninfo = (struct ospf_interface *) rn->info;
162: route_unlock_node (rn);
163: }
164:
165: return rninfo;
166: }
167:
168: static void
169: ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi)
170: {
171: struct route_node *rn;
172: struct prefix p;
173:
174: p = *oi->address;
175: p.prefixlen = IPV4_MAX_PREFIXLEN;
176:
177: rn = route_node_get (IF_OIFS (ifp), &p);
178: /* rn->info should either be NULL or equal to this oi
179: * as route_node_get may return an existing node
180: */
181: assert (!rn->info || rn->info == oi);
182: rn->info = oi;
183: }
184:
185: static void
186: ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi)
187: {
188: struct route_node *rn;
189: struct prefix p;
190:
191: p = *oi->address;
192: p.prefixlen = IPV4_MAX_PREFIXLEN;
193:
194: rn = route_node_lookup (IF_OIFS (oi->ifp), &p);
195: assert (rn);
196: assert (rn->info);
197: rn->info = NULL;
198: route_unlock_node (rn);
199: route_unlock_node (rn);
200: }
201:
202: struct ospf_interface *
203: ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
204: {
205: struct ospf_interface *oi;
206:
207: if ((oi = ospf_if_table_lookup (ifp, p)) == NULL)
208: {
209: oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface));
210: memset (oi, 0, sizeof (struct ospf_interface));
211: }
212: else
213: return oi;
214:
215: /* Set zebra interface pointer. */
216: oi->ifp = ifp;
217: oi->address = p;
218:
219: ospf_add_to_if (ifp, oi);
220: listnode_add (ospf->oiflist, oi);
221:
222: /* Initialize neighbor list. */
223: oi->nbrs = route_table_init ();
224:
225: /* Initialize static neighbor list. */
226: oi->nbr_nbma = list_new ();
227:
228: /* Initialize Link State Acknowledgment list. */
229: oi->ls_ack = list_new ();
230: oi->ls_ack_direct.ls_ack = list_new ();
231:
232: /* Set default values. */
233: ospf_if_reset_variables (oi);
234:
235: /* Add pseudo neighbor. */
236: oi->nbr_self = ospf_nbr_new (oi);
237:
238: oi->ls_upd_queue = route_table_init ();
239: oi->t_ls_upd_event = NULL;
240: oi->t_ls_ack_direct = NULL;
241:
242: oi->crypt_seqnum = time (NULL);
243:
244: #ifdef HAVE_OPAQUE_LSA
245: ospf_opaque_type9_lsa_init (oi);
246: #endif /* HAVE_OPAQUE_LSA */
247:
248: oi->ospf = ospf;
249:
250: return oi;
251: }
252:
253: /* Restore an interface to its pre UP state
254: Used from ism_interface_down only */
255: void
256: ospf_if_cleanup (struct ospf_interface *oi)
257: {
258: struct route_node *rn;
259: struct listnode *node, *nnode;
260: struct ospf_neighbor *nbr;
261: struct ospf_nbr_nbma *nbr_nbma;
262: struct ospf_lsa *lsa;
263:
264: /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
265: /* delete all static neighbors attached to this interface */
266: for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma))
267: {
268: OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
269:
270: if (nbr_nbma->nbr)
271: {
272: nbr_nbma->nbr->nbr_nbma = NULL;
273: nbr_nbma->nbr = NULL;
274: }
275:
276: nbr_nbma->oi = NULL;
277:
278: listnode_delete (oi->nbr_nbma, nbr_nbma);
279: }
280:
281: /* send Neighbor event KillNbr to all associated neighbors. */
282: for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
283: if ((nbr = rn->info) != NULL)
284: if (nbr != oi->nbr_self)
285: OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr);
286:
287: /* Cleanup Link State Acknowlegdment list. */
288: for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa))
289: ospf_lsa_unlock (&lsa); /* oi->ls_ack */
290: list_delete_all_node (oi->ls_ack);
291:
292: oi->crypt_seqnum = 0;
293:
294: /* Empty link state update queue */
295: ospf_ls_upd_queue_empty (oi);
296:
297: /* Reset pseudo neighbor. */
298: ospf_nbr_delete (oi->nbr_self);
299: oi->nbr_self = ospf_nbr_new (oi);
300: ospf_nbr_add_self (oi);
301: }
302:
303: void
304: ospf_if_free (struct ospf_interface *oi)
305: {
306: ospf_if_down (oi);
307:
308: assert (oi->state == ISM_Down);
309:
310: #ifdef HAVE_OPAQUE_LSA
311: ospf_opaque_type9_lsa_term (oi);
312: #endif /* HAVE_OPAQUE_LSA */
313:
314: /* Free Pseudo Neighbour */
315: ospf_nbr_delete (oi->nbr_self);
316:
317: route_table_finish (oi->nbrs);
318: route_table_finish (oi->ls_upd_queue);
319:
320: /* Free any lists that should be freed */
321: list_free (oi->nbr_nbma);
322:
323: list_free (oi->ls_ack);
324: list_free (oi->ls_ack_direct.ls_ack);
325:
326: ospf_delete_from_if (oi->ifp, oi);
327:
328: listnode_delete (oi->ospf->oiflist, oi);
329: listnode_delete (oi->area->oiflist, oi);
330:
331: thread_cancel_event (master, oi);
332:
333: memset (oi, 0, sizeof (*oi));
334: XFREE (MTYPE_OSPF_IF, oi);
335: }
336:
337:
338: /*
339: * check if interface with given address is configured and
340: * return it if yes. special treatment for PtP networks.
341: */
342: struct ospf_interface *
343: ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
344: {
345: struct listnode *node, *nnode;
346: struct ospf_interface *oi;
347: struct prefix_ipv4 addr;
348:
349: addr.family = AF_INET;
350: addr.prefix = *address;
351: addr.prefixlen = IPV4_MAX_PREFIXLEN;
352:
353: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
354: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
355: {
356: if (oi->type == OSPF_IFTYPE_POINTOPOINT)
357: {
358: /* special leniency: match if addr is anywhere on peer subnet */
359: if (prefix_match(CONNECTED_PREFIX(oi->connected),
360: (struct prefix *)&addr))
361: return oi;
362: }
363: else
364: {
365: if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4))
366: return oi;
367: }
368: }
369: return NULL;
370: }
371:
372: int
373: ospf_if_is_up (struct ospf_interface *oi)
374: {
375: return if_is_up (oi->ifp);
376: }
377:
378: struct ospf_interface *
379: ospf_if_exists (struct ospf_interface *oic)
380: {
381: struct listnode *node;
382: struct ospf *ospf;
383: struct ospf_interface *oi;
384:
385: if ((ospf = ospf_lookup ()) == NULL)
386: return NULL;
387:
388: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
389: if (oi == oic)
390: return oi;
391:
392: return NULL;
393: }
394:
1.1.1.2 ! misho 395: /* Lookup OSPF interface by router LSA posistion */
! 396: struct ospf_interface *
! 397: ospf_if_lookup_by_lsa_pos (struct ospf_area *area, int lsa_pos)
! 398: {
! 399: struct listnode *node;
! 400: struct ospf_interface *oi;
! 401:
! 402: for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
! 403: {
! 404: if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end)
! 405: return oi;
! 406: }
! 407: return NULL;
! 408: }
! 409:
1.1 misho 410: struct ospf_interface *
411: ospf_if_lookup_by_local_addr (struct ospf *ospf,
412: struct interface *ifp, struct in_addr address)
413: {
414: struct listnode *node;
415: struct ospf_interface *oi;
416:
417: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
418: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
419: {
420: if (ifp && oi->ifp != ifp)
421: continue;
422:
423: if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
424: return oi;
425: }
426:
427: return NULL;
428: }
429:
430: struct ospf_interface *
431: ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
432: {
433: struct listnode *node;
434: struct ospf_interface *oi;
435:
436: /* Check each Interface. */
437: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
438: {
439: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
440: {
441: struct prefix ptmp;
442:
443: prefix_copy (&ptmp, CONNECTED_PREFIX(oi->connected));
444: apply_mask (&ptmp);
445: if (prefix_same (&ptmp, (struct prefix *) p))
446: return oi;
447: }
448: }
449: return NULL;
450: }
451:
452: /* determine receiving interface by ifp and source address */
453: struct ospf_interface *
454: ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
455: struct interface *ifp)
456: {
457: struct route_node *rn;
458: struct prefix_ipv4 addr;
459: struct ospf_interface *oi, *match;
460:
461: addr.family = AF_INET;
462: addr.prefix = src;
463: addr.prefixlen = IPV4_MAX_BITLEN;
464:
465: match = NULL;
466:
467: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
468: {
469: oi = rn->info;
470:
471: if (!oi) /* oi can be NULL for PtP aliases */
472: continue;
473:
474: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
475: continue;
476:
477: if (if_is_loopback (oi->ifp))
478: continue;
479:
480: if (prefix_match (CONNECTED_PREFIX(oi->connected),
481: (struct prefix *) &addr))
482: {
483: if ( (match == NULL) ||
484: (match->address->prefixlen < oi->address->prefixlen)
485: )
486: match = oi;
487: }
488: }
489:
490: return match;
491: }
492:
493: void
494: ospf_if_stream_set (struct ospf_interface *oi)
495: {
496: /* set output fifo queue. */
497: if (oi->obuf == NULL)
498: oi->obuf = ospf_fifo_new ();
499: }
500:
501: void
502: ospf_if_stream_unset (struct ospf_interface *oi)
503: {
504: struct ospf *ospf = oi->ospf;
505:
506: if (oi->obuf)
507: {
508: ospf_fifo_free (oi->obuf);
509: oi->obuf = NULL;
510:
511: if (oi->on_write_q)
512: {
513: listnode_delete (ospf->oi_write_q, oi);
514: if (list_isempty(ospf->oi_write_q))
515: OSPF_TIMER_OFF (ospf->t_write);
516: oi->on_write_q = 0;
517: }
518: }
519: }
520:
521:
522: static struct ospf_if_params *
523: ospf_new_if_params (void)
524: {
525: struct ospf_if_params *oip;
526:
527: oip = XCALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));
528:
529: if (!oip)
530: return NULL;
531:
532: UNSET_IF_PARAM (oip, output_cost_cmd);
533: UNSET_IF_PARAM (oip, transmit_delay);
534: UNSET_IF_PARAM (oip, retransmit_interval);
535: UNSET_IF_PARAM (oip, passive_interface);
536: UNSET_IF_PARAM (oip, v_hello);
537: UNSET_IF_PARAM (oip, fast_hello);
538: UNSET_IF_PARAM (oip, v_wait);
539: UNSET_IF_PARAM (oip, priority);
540: UNSET_IF_PARAM (oip, type);
541: UNSET_IF_PARAM (oip, auth_simple);
542: UNSET_IF_PARAM (oip, auth_crypt);
543: UNSET_IF_PARAM (oip, auth_type);
544:
545: oip->auth_crypt = list_new ();
546:
547: oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
548:
549: return oip;
550: }
551:
552: void
553: ospf_del_if_params (struct ospf_if_params *oip)
554: {
555: list_delete (oip->auth_crypt);
556: XFREE (MTYPE_OSPF_IF_PARAMS, oip);
557: }
558:
559: void
560: ospf_free_if_params (struct interface *ifp, struct in_addr addr)
561: {
562: struct ospf_if_params *oip;
563: struct prefix_ipv4 p;
564: struct route_node *rn;
565:
566: p.family = AF_INET;
567: p.prefixlen = IPV4_MAX_PREFIXLEN;
568: p.prefix = addr;
569: rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
570: if (!rn || !rn->info)
571: return;
572:
573: oip = rn->info;
574: route_unlock_node (rn);
575:
576: if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
577: !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
578: !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
579: !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
580: !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
581: !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) &&
582: !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
583: !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
584: !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
585: !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
586: !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
587: listcount (oip->auth_crypt) == 0 &&
588: ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
589: {
590: ospf_del_if_params (oip);
591: rn->info = NULL;
592: route_unlock_node (rn);
593: }
594: }
595:
596: struct ospf_if_params *
597: ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
598: {
599: struct prefix_ipv4 p;
600: struct route_node *rn;
601:
602: p.family = AF_INET;
603: p.prefixlen = IPV4_MAX_PREFIXLEN;
604: p.prefix = addr;
605:
606: rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
607:
608: if (rn)
609: {
610: route_unlock_node (rn);
611: return rn->info;
612: }
613:
614: return NULL;
615: }
616:
617: struct ospf_if_params *
618: ospf_get_if_params (struct interface *ifp, struct in_addr addr)
619: {
620: struct prefix_ipv4 p;
621: struct route_node *rn;
622:
623: p.family = AF_INET;
624: p.prefixlen = IPV4_MAX_PREFIXLEN;
625: p.prefix = addr;
626:
627: rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
628:
629: if (rn->info == NULL)
630: rn->info = ospf_new_if_params ();
631: else
632: route_unlock_node (rn);
633:
634: return rn->info;
635: }
636:
637: void
638: ospf_if_update_params (struct interface *ifp, struct in_addr addr)
639: {
640: struct route_node *rn;
641: struct ospf_interface *oi;
642:
643: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
644: {
645: if ((oi = rn->info) == NULL)
646: continue;
647:
648: if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
649: oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
650: }
651: }
652:
653: int
654: ospf_if_new_hook (struct interface *ifp)
655: {
656: int rc = 0;
657:
658: ifp->info = XCALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
659:
660: IF_OIFS (ifp) = route_table_init ();
661: IF_OIFS_PARAMS (ifp) = route_table_init ();
662:
663: IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
664:
665: SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
666: IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
667:
668: SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
669: IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
670:
671: SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
672: IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
673:
674: IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
675:
676: SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
677: IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
678:
679: SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello);
680: IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
681:
682: SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
683: IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
684:
685: SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
686: memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
687:
688: SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
689: IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
690:
691: #ifdef HAVE_OPAQUE_LSA
692: rc = ospf_opaque_new_if (ifp);
693: #endif /* HAVE_OPAQUE_LSA */
694: return rc;
695: }
696:
697: static int
698: ospf_if_delete_hook (struct interface *ifp)
699: {
700: int rc = 0;
701: struct route_node *rn;
702: #ifdef HAVE_OPAQUE_LSA
703: rc = ospf_opaque_del_if (ifp);
704: #endif /* HAVE_OPAQUE_LSA */
705:
706: route_table_finish (IF_OIFS (ifp));
707:
708: for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
709: if (rn->info)
710: ospf_del_if_params (rn->info);
711: route_table_finish (IF_OIFS_PARAMS (ifp));
712:
713: ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp));
714: XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
715: ifp->info = NULL;
716:
717: return rc;
718: }
719:
720: int
721: ospf_if_is_enable (struct ospf_interface *oi)
722: {
723: if (!if_is_loopback (oi->ifp))
724: if (if_is_up (oi->ifp))
725: return 1;
726:
727: return 0;
728: }
729:
730: void
731: ospf_if_set_multicast(struct ospf_interface *oi)
732: {
733: if ((oi->state > ISM_Loopback) &&
734: (oi->type != OSPF_IFTYPE_LOOPBACK) &&
735: (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
736: (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
737: {
738: /* The interface should belong to the OSPF-all-routers group. */
739: if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) &&
740: (ospf_if_add_allspfrouters(oi->ospf, oi->address,
741: oi->ifp->ifindex) >= 0))
742: /* Set the flag only if the system call to join succeeded. */
743: OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
744: }
745: else
746: {
747: /* The interface should NOT belong to the OSPF-all-routers group. */
748: if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
749: {
750: /* Only actually drop if this is the last reference */
751: if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
752: ospf_if_drop_allspfrouters (oi->ospf, oi->address,
753: oi->ifp->ifindex);
754: /* Unset the flag regardless of whether the system call to leave
755: the group succeeded, since it's much safer to assume that
756: we are not a member. */
757: OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS);
758: }
759: }
760:
761: if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
762: (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
763: ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
764: (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
765: {
766: /* The interface should belong to the OSPF-designated-routers group. */
767: if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) &&
768: (ospf_if_add_alldrouters(oi->ospf, oi->address,
769: oi->ifp->ifindex) >= 0))
770: /* Set the flag only if the system call to join succeeded. */
771: OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
772: }
773: else
774: {
775: /* The interface should NOT belong to the OSPF-designated-routers group */
776: if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
777: {
778: /* drop only if last reference */
779: if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
780: ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
781:
782: /* Unset the flag regardless of whether the system call to leave
783: the group succeeded, since it's much safer to assume that
784: we are not a member. */
785: OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
786: }
787: }
788: }
789:
790: int
791: ospf_if_up (struct ospf_interface *oi)
792: {
793: if (oi == NULL)
794: return 0;
795:
796: if (oi->type == OSPF_IFTYPE_LOOPBACK)
797: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
798: else
799: {
800: struct ospf *ospf = ospf_lookup ();
801: if (ospf != NULL)
802: ospf_adjust_sndbuflen (ospf, oi->ifp->mtu);
803: else
804: zlog_warn ("%s: ospf_lookup() returned NULL", __func__);
805: ospf_if_stream_set (oi);
806: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
807: }
808:
809: return 1;
810: }
811:
812: int
813: ospf_if_down (struct ospf_interface *oi)
814: {
815: if (oi == NULL)
816: return 0;
817:
818: OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
1.1.1.2 ! misho 819: /* delete position in router LSA */
! 820: oi->lsa_pos_beg = 0;
! 821: oi->lsa_pos_end = 0;
1.1 misho 822: /* Shutdown packet reception and sending */
823: ospf_if_stream_unset (oi);
824:
825: return 1;
826: }
827:
828:
829: /* Virtual Link related functions. */
830:
831: struct ospf_vl_data *
832: ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
833: {
834: struct ospf_vl_data *vl_data;
835:
836: vl_data = XCALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
837:
838: vl_data->vl_peer.s_addr = vl_peer.s_addr;
839: vl_data->vl_area_id = area->area_id;
840: vl_data->format = area->format;
841:
842: return vl_data;
843: }
844:
845: void
846: ospf_vl_data_free (struct ospf_vl_data *vl_data)
847: {
848: XFREE (MTYPE_OSPF_VL_DATA, vl_data);
849: }
850:
851: u_int vlink_count = 0;
852:
853: struct ospf_interface *
854: ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
855: {
856: struct ospf_interface * voi;
857: struct interface * vi;
858: char ifname[INTERFACE_NAMSIZ + 1];
859: struct ospf_area *area;
860: struct in_addr area_id;
861: struct connected *co;
862: struct prefix_ipv4 *p;
863:
864: if (IS_DEBUG_OSPF_EVENT)
865: zlog_debug ("ospf_vl_new(): Start");
866: if (vlink_count == OSPF_VL_MAX_COUNT)
867: {
868: if (IS_DEBUG_OSPF_EVENT)
869: zlog_debug ("ospf_vl_new(): Alarm: "
870: "cannot create more than OSPF_MAX_VL_COUNT virtual links");
871: return NULL;
872: }
873:
874: if (IS_DEBUG_OSPF_EVENT)
875: zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");
876:
877: snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
878: vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
879: co = connected_new ();
880: co->ifp = vi;
881: listnode_add (vi->connected, co);
882:
883: p = prefix_ipv4_new ();
884: p->family = AF_INET;
885: p->prefix.s_addr = 0;
886: p->prefixlen = 0;
887:
888: co->address = (struct prefix *)p;
889:
890: voi = ospf_if_new (ospf, vi, co->address);
891: if (voi == NULL)
892: {
893: if (IS_DEBUG_OSPF_EVENT)
894: zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
895: return NULL;
896: }
897: voi->connected = co;
898: voi->vl_data = vl_data;
899: voi->ifp->mtu = OSPF_VL_MTU;
900: voi->type = OSPF_IFTYPE_VIRTUALLINK;
901:
902: vlink_count++;
903: if (IS_DEBUG_OSPF_EVENT)
904: zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
905: if (IS_DEBUG_OSPF_EVENT)
906: zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);
907:
908: area_id.s_addr = 0;
909: area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
910: voi->area = area;
911:
912: if (IS_DEBUG_OSPF_EVENT)
913: zlog_debug ("ospf_vl_new(): set associated area to the backbone");
914:
915: ospf_nbr_add_self (voi);
916: ospf_area_add_if (voi->area, voi);
917:
918: ospf_if_stream_set (voi);
919:
920: if (IS_DEBUG_OSPF_EVENT)
921: zlog_debug ("ospf_vl_new(): Stop");
922: return voi;
923: }
924:
925: static void
926: ospf_vl_if_delete (struct ospf_vl_data *vl_data)
927: {
928: struct interface *ifp = vl_data->vl_oi->ifp;
929: vl_data->vl_oi->address->u.prefix4.s_addr = 0;
930: vl_data->vl_oi->address->prefixlen = 0;
931: ospf_if_free (vl_data->vl_oi);
932: if_delete (ifp);
933: vlink_count--;
934: }
935:
936: /* Look up vl_data for given peer, optionally qualified to be in the
937: * specified area. NULL area returns first found..
938: */
939: struct ospf_vl_data *
940: ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area,
941: struct in_addr vl_peer)
942: {
943: struct ospf_vl_data *vl_data;
944: struct listnode *node;
945:
946: if (IS_DEBUG_OSPF_EVENT)
947: {
948: zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer));
949: if (area)
950: zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id));
951: }
952:
953: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
954: {
955: if (IS_DEBUG_OSPF_EVENT)
956: zlog_debug ("%s: VL %s, peer %s", __func__,
957: vl_data->vl_oi->ifp->name,
958: inet_ntoa (vl_data->vl_peer));
959:
960: if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
961: continue;
962:
963: if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer))
964: return vl_data;
965: }
966:
967: return NULL;
968: }
969:
970: static void
971: ospf_vl_shutdown (struct ospf_vl_data *vl_data)
972: {
973: struct ospf_interface *oi;
974:
975: if ((oi = vl_data->vl_oi) == NULL)
976: return;
977:
978: oi->address->u.prefix4.s_addr = 0;
979: oi->address->prefixlen = 0;
980:
981: UNSET_FLAG (oi->ifp->flags, IFF_UP);
982: /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
983: OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
984: }
985:
986: void
987: ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
988: {
989: listnode_add (ospf->vlinks, vl_data);
990: #ifdef HAVE_SNMP
991: ospf_snmp_vl_add (vl_data);
992: #endif /* HAVE_SNMP */
993: }
994:
995: void
996: ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
997: {
998: ospf_vl_shutdown (vl_data);
999: ospf_vl_if_delete (vl_data);
1000:
1001: #ifdef HAVE_SNMP
1002: ospf_snmp_vl_delete (vl_data);
1003: #endif /* HAVE_SNMP */
1004: listnode_delete (ospf->vlinks, vl_data);
1005:
1006: ospf_vl_data_free (vl_data);
1007: }
1008:
1009: static int
1010: ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
1011: {
1012: int changed = 0;
1013: struct ospf_interface *voi;
1014: struct listnode *node;
1015: struct vertex_parent *vp = NULL;
1016: int i;
1017: struct router_lsa *rl;
1018:
1019: voi = vl_data->vl_oi;
1020:
1021: if (voi->output_cost != v->distance)
1022: {
1023:
1024: voi->output_cost = v->distance;
1025: changed = 1;
1026: }
1027:
1028: for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
1029: {
1030: vl_data->nexthop.oi = vp->nexthop->oi;
1031: vl_data->nexthop.router = vp->nexthop->router;
1032:
1033: if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
1034: &vl_data->nexthop.oi->address->u.prefix4))
1035: changed = 1;
1036:
1037: voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4;
1038: voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen;
1039:
1040: break; /* We take the first interface. */
1041: }
1042:
1043: rl = (struct router_lsa *)v->lsa;
1044:
1045: /* use SPF determined backlink index in struct vertex
1046: * for virtual link destination address
1047: */
1048: if (vp && vp->backlink >= 0)
1049: {
1050: if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
1051: &rl->link[vp->backlink].link_data))
1052: changed = 1;
1053: vl_data->peer_addr = rl->link[vp->backlink].link_data;
1054: }
1055: else
1056: {
1057: /* This is highly odd, there is no backlink index
1058: * there should be due to the ospf_spf_has_link() check
1059: * in SPF. Lets warn and try pick a link anyway.
1060: */
1061: zlog_warn ("ospf_vl_set_params: No backlink for %s!",
1062: vl_data->vl_oi->ifp->name);
1063: for (i = 0; i < ntohs (rl->links); i++)
1064: {
1065: switch (rl->link[i].type)
1066: {
1067: case LSA_LINK_TYPE_VIRTUALLINK:
1068: if (IS_DEBUG_OSPF_EVENT)
1069: zlog_debug ("found back link through VL");
1070: case LSA_LINK_TYPE_TRANSIT:
1071: case LSA_LINK_TYPE_POINTOPOINT:
1072: if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
1073: &rl->link[i].link_data))
1074: changed = 1;
1075: vl_data->peer_addr = rl->link[i].link_data;
1076: }
1077: }
1078: }
1079:
1080: if (IS_DEBUG_OSPF_EVENT)
1081: zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__,
1082: vl_data->vl_oi->ifp->name,
1083: inet_ntoa(vl_data->peer_addr),
1084: voi->output_cost,
1085: (changed ? " " : " un"));
1086:
1087: return changed;
1088: }
1089:
1090:
1091: void
1092: ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
1093: struct vertex *v)
1094: {
1095: struct ospf *ospf = area->ospf;
1096: struct listnode *node;
1097: struct ospf_vl_data *vl_data;
1098: struct ospf_interface *oi;
1099:
1100: if (IS_DEBUG_OSPF_EVENT)
1101: {
1102: zlog_debug ("ospf_vl_up_check(): Start");
1103: zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
1104: zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
1105: }
1106:
1107: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
1108: {
1109: if (IS_DEBUG_OSPF_EVENT)
1110: {
1111: zlog_debug ("%s: considering VL, %s in area %s", __func__,
1112: vl_data->vl_oi->ifp->name,
1113: inet_ntoa (vl_data->vl_area_id));
1114: zlog_debug ("%s: peer ID: %s", __func__,
1115: inet_ntoa (vl_data->vl_peer));
1116: }
1117:
1118: if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
1119: IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
1120: {
1121: oi = vl_data->vl_oi;
1122: SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
1123:
1124: if (IS_DEBUG_OSPF_EVENT)
1125: zlog_debug ("ospf_vl_up_check(): this VL matched");
1126:
1127: if (oi->state == ISM_Down)
1128: {
1129: if (IS_DEBUG_OSPF_EVENT)
1130: zlog_debug ("ospf_vl_up_check(): VL is down, waking it up");
1131: SET_FLAG (oi->ifp->flags, IFF_UP);
1132: OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp);
1133: }
1134:
1135: if (ospf_vl_set_params (vl_data, v))
1136: {
1137: if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
1138: zlog_debug ("ospf_vl_up_check: VL cost change,"
1139: " scheduling router lsa refresh");
1140: if (ospf->backbone)
1141: ospf_router_lsa_update_area (ospf->backbone);
1142: else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
1143: zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
1144: }
1145: }
1146: }
1147: }
1148:
1149: void
1150: ospf_vl_unapprove (struct ospf *ospf)
1151: {
1152: struct listnode *node;
1153: struct ospf_vl_data *vl_data;
1154:
1155: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
1156: UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
1157: }
1158:
1159: void
1160: ospf_vl_shut_unapproved (struct ospf *ospf)
1161: {
1162: struct listnode *node, *nnode;
1163: struct ospf_vl_data *vl_data;
1164:
1165: for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
1166: if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
1167: ospf_vl_shutdown (vl_data);
1168: }
1169:
1170: int
1171: ospf_full_virtual_nbrs (struct ospf_area *area)
1172: {
1173: if (IS_DEBUG_OSPF_EVENT)
1174: {
1175: zlog_debug ("counting fully adjacent virtual neighbors in area %s",
1176: inet_ntoa (area->area_id));
1177: zlog_debug ("there are %d of them", area->full_vls);
1178: }
1179:
1180: return area->full_vls;
1181: }
1182:
1183: int
1184: ospf_vls_in_area (struct ospf_area *area)
1185: {
1186: struct listnode *node;
1187: struct ospf_vl_data *vl_data;
1188: int c = 0;
1189:
1190: for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
1191: if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
1192: c++;
1193:
1194: return c;
1195: }
1196:
1197:
1198: struct crypt_key *
1199: ospf_crypt_key_new ()
1200: {
1201: return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
1202: }
1203:
1204: void
1205: ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
1206: {
1207: listnode_add (crypt, ck);
1208: }
1209:
1210: struct crypt_key *
1211: ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id)
1212: {
1213: struct listnode *node;
1214: struct crypt_key *ck;
1215:
1216: for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck))
1217: if (ck->key_id == key_id)
1218: return ck;
1219:
1220: return NULL;
1221: }
1222:
1223: int
1224: ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id)
1225: {
1226: struct listnode *node, *nnode;
1227: struct crypt_key *ck;
1228:
1229: for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck))
1230: {
1231: if (ck->key_id == key_id)
1232: {
1233: listnode_delete (auth_crypt, ck);
1234: XFREE (MTYPE_OSPF_CRYPT_KEY, ck);
1235: return 1;
1236: }
1237: }
1238:
1239: return 0;
1240: }
1241:
1242: u_char
1243: ospf_default_iftype(struct interface *ifp)
1244: {
1245: if (if_is_pointopoint (ifp))
1246: return OSPF_IFTYPE_POINTOPOINT;
1247: else if (if_is_loopback (ifp))
1248: return OSPF_IFTYPE_LOOPBACK;
1249: else
1250: return OSPF_IFTYPE_BROADCAST;
1251: }
1252:
1253: void
1254: ospf_if_init ()
1255: {
1256: /* Initialize Zebra interface data structure. */
1257: if_init ();
1258: om->iflist = iflist;
1259: if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
1260: if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
1261: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>