Annotation of embedaddon/quagga/ospfd/ospf_interface.c, revision 1.1
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:
! 395: struct ospf_interface *
! 396: ospf_if_lookup_by_local_addr (struct ospf *ospf,
! 397: struct interface *ifp, struct in_addr address)
! 398: {
! 399: struct listnode *node;
! 400: struct ospf_interface *oi;
! 401:
! 402: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
! 403: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
! 404: {
! 405: if (ifp && oi->ifp != ifp)
! 406: continue;
! 407:
! 408: if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
! 409: return oi;
! 410: }
! 411:
! 412: return NULL;
! 413: }
! 414:
! 415: struct ospf_interface *
! 416: ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
! 417: {
! 418: struct listnode *node;
! 419: struct ospf_interface *oi;
! 420:
! 421: /* Check each Interface. */
! 422: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
! 423: {
! 424: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
! 425: {
! 426: struct prefix ptmp;
! 427:
! 428: prefix_copy (&ptmp, CONNECTED_PREFIX(oi->connected));
! 429: apply_mask (&ptmp);
! 430: if (prefix_same (&ptmp, (struct prefix *) p))
! 431: return oi;
! 432: }
! 433: }
! 434: return NULL;
! 435: }
! 436:
! 437: /* determine receiving interface by ifp and source address */
! 438: struct ospf_interface *
! 439: ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
! 440: struct interface *ifp)
! 441: {
! 442: struct route_node *rn;
! 443: struct prefix_ipv4 addr;
! 444: struct ospf_interface *oi, *match;
! 445:
! 446: addr.family = AF_INET;
! 447: addr.prefix = src;
! 448: addr.prefixlen = IPV4_MAX_BITLEN;
! 449:
! 450: match = NULL;
! 451:
! 452: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
! 453: {
! 454: oi = rn->info;
! 455:
! 456: if (!oi) /* oi can be NULL for PtP aliases */
! 457: continue;
! 458:
! 459: if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
! 460: continue;
! 461:
! 462: if (if_is_loopback (oi->ifp))
! 463: continue;
! 464:
! 465: if (prefix_match (CONNECTED_PREFIX(oi->connected),
! 466: (struct prefix *) &addr))
! 467: {
! 468: if ( (match == NULL) ||
! 469: (match->address->prefixlen < oi->address->prefixlen)
! 470: )
! 471: match = oi;
! 472: }
! 473: }
! 474:
! 475: return match;
! 476: }
! 477:
! 478: void
! 479: ospf_if_stream_set (struct ospf_interface *oi)
! 480: {
! 481: /* set output fifo queue. */
! 482: if (oi->obuf == NULL)
! 483: oi->obuf = ospf_fifo_new ();
! 484: }
! 485:
! 486: void
! 487: ospf_if_stream_unset (struct ospf_interface *oi)
! 488: {
! 489: struct ospf *ospf = oi->ospf;
! 490:
! 491: if (oi->obuf)
! 492: {
! 493: ospf_fifo_free (oi->obuf);
! 494: oi->obuf = NULL;
! 495:
! 496: if (oi->on_write_q)
! 497: {
! 498: listnode_delete (ospf->oi_write_q, oi);
! 499: if (list_isempty(ospf->oi_write_q))
! 500: OSPF_TIMER_OFF (ospf->t_write);
! 501: oi->on_write_q = 0;
! 502: }
! 503: }
! 504: }
! 505:
! 506:
! 507: static struct ospf_if_params *
! 508: ospf_new_if_params (void)
! 509: {
! 510: struct ospf_if_params *oip;
! 511:
! 512: oip = XCALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));
! 513:
! 514: if (!oip)
! 515: return NULL;
! 516:
! 517: UNSET_IF_PARAM (oip, output_cost_cmd);
! 518: UNSET_IF_PARAM (oip, transmit_delay);
! 519: UNSET_IF_PARAM (oip, retransmit_interval);
! 520: UNSET_IF_PARAM (oip, passive_interface);
! 521: UNSET_IF_PARAM (oip, v_hello);
! 522: UNSET_IF_PARAM (oip, fast_hello);
! 523: UNSET_IF_PARAM (oip, v_wait);
! 524: UNSET_IF_PARAM (oip, priority);
! 525: UNSET_IF_PARAM (oip, type);
! 526: UNSET_IF_PARAM (oip, auth_simple);
! 527: UNSET_IF_PARAM (oip, auth_crypt);
! 528: UNSET_IF_PARAM (oip, auth_type);
! 529:
! 530: oip->auth_crypt = list_new ();
! 531:
! 532: oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
! 533:
! 534: return oip;
! 535: }
! 536:
! 537: void
! 538: ospf_del_if_params (struct ospf_if_params *oip)
! 539: {
! 540: list_delete (oip->auth_crypt);
! 541: XFREE (MTYPE_OSPF_IF_PARAMS, oip);
! 542: }
! 543:
! 544: void
! 545: ospf_free_if_params (struct interface *ifp, struct in_addr addr)
! 546: {
! 547: struct ospf_if_params *oip;
! 548: struct prefix_ipv4 p;
! 549: struct route_node *rn;
! 550:
! 551: p.family = AF_INET;
! 552: p.prefixlen = IPV4_MAX_PREFIXLEN;
! 553: p.prefix = addr;
! 554: rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
! 555: if (!rn || !rn->info)
! 556: return;
! 557:
! 558: oip = rn->info;
! 559: route_unlock_node (rn);
! 560:
! 561: if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
! 562: !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
! 563: !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
! 564: !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
! 565: !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
! 566: !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) &&
! 567: !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
! 568: !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
! 569: !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
! 570: !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
! 571: !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
! 572: listcount (oip->auth_crypt) == 0 &&
! 573: ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
! 574: {
! 575: ospf_del_if_params (oip);
! 576: rn->info = NULL;
! 577: route_unlock_node (rn);
! 578: }
! 579: }
! 580:
! 581: struct ospf_if_params *
! 582: ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
! 583: {
! 584: struct prefix_ipv4 p;
! 585: struct route_node *rn;
! 586:
! 587: p.family = AF_INET;
! 588: p.prefixlen = IPV4_MAX_PREFIXLEN;
! 589: p.prefix = addr;
! 590:
! 591: rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
! 592:
! 593: if (rn)
! 594: {
! 595: route_unlock_node (rn);
! 596: return rn->info;
! 597: }
! 598:
! 599: return NULL;
! 600: }
! 601:
! 602: struct ospf_if_params *
! 603: ospf_get_if_params (struct interface *ifp, struct in_addr addr)
! 604: {
! 605: struct prefix_ipv4 p;
! 606: struct route_node *rn;
! 607:
! 608: p.family = AF_INET;
! 609: p.prefixlen = IPV4_MAX_PREFIXLEN;
! 610: p.prefix = addr;
! 611:
! 612: rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
! 613:
! 614: if (rn->info == NULL)
! 615: rn->info = ospf_new_if_params ();
! 616: else
! 617: route_unlock_node (rn);
! 618:
! 619: return rn->info;
! 620: }
! 621:
! 622: void
! 623: ospf_if_update_params (struct interface *ifp, struct in_addr addr)
! 624: {
! 625: struct route_node *rn;
! 626: struct ospf_interface *oi;
! 627:
! 628: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
! 629: {
! 630: if ((oi = rn->info) == NULL)
! 631: continue;
! 632:
! 633: if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
! 634: oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
! 635: }
! 636: }
! 637:
! 638: int
! 639: ospf_if_new_hook (struct interface *ifp)
! 640: {
! 641: int rc = 0;
! 642:
! 643: ifp->info = XCALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
! 644:
! 645: IF_OIFS (ifp) = route_table_init ();
! 646: IF_OIFS_PARAMS (ifp) = route_table_init ();
! 647:
! 648: IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
! 649:
! 650: SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
! 651: IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
! 652:
! 653: SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
! 654: IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
! 655:
! 656: SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
! 657: IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
! 658:
! 659: IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
! 660:
! 661: SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
! 662: IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
! 663:
! 664: SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello);
! 665: IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
! 666:
! 667: SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
! 668: IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
! 669:
! 670: SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
! 671: memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
! 672:
! 673: SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
! 674: IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
! 675:
! 676: #ifdef HAVE_OPAQUE_LSA
! 677: rc = ospf_opaque_new_if (ifp);
! 678: #endif /* HAVE_OPAQUE_LSA */
! 679: return rc;
! 680: }
! 681:
! 682: static int
! 683: ospf_if_delete_hook (struct interface *ifp)
! 684: {
! 685: int rc = 0;
! 686: struct route_node *rn;
! 687: #ifdef HAVE_OPAQUE_LSA
! 688: rc = ospf_opaque_del_if (ifp);
! 689: #endif /* HAVE_OPAQUE_LSA */
! 690:
! 691: route_table_finish (IF_OIFS (ifp));
! 692:
! 693: for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
! 694: if (rn->info)
! 695: ospf_del_if_params (rn->info);
! 696: route_table_finish (IF_OIFS_PARAMS (ifp));
! 697:
! 698: ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp));
! 699: XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
! 700: ifp->info = NULL;
! 701:
! 702: return rc;
! 703: }
! 704:
! 705: int
! 706: ospf_if_is_enable (struct ospf_interface *oi)
! 707: {
! 708: if (!if_is_loopback (oi->ifp))
! 709: if (if_is_up (oi->ifp))
! 710: return 1;
! 711:
! 712: return 0;
! 713: }
! 714:
! 715: void
! 716: ospf_if_set_multicast(struct ospf_interface *oi)
! 717: {
! 718: if ((oi->state > ISM_Loopback) &&
! 719: (oi->type != OSPF_IFTYPE_LOOPBACK) &&
! 720: (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
! 721: (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
! 722: {
! 723: /* The interface should belong to the OSPF-all-routers group. */
! 724: if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) &&
! 725: (ospf_if_add_allspfrouters(oi->ospf, oi->address,
! 726: oi->ifp->ifindex) >= 0))
! 727: /* Set the flag only if the system call to join succeeded. */
! 728: OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
! 729: }
! 730: else
! 731: {
! 732: /* The interface should NOT belong to the OSPF-all-routers group. */
! 733: if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
! 734: {
! 735: /* Only actually drop if this is the last reference */
! 736: if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
! 737: ospf_if_drop_allspfrouters (oi->ospf, oi->address,
! 738: oi->ifp->ifindex);
! 739: /* Unset the flag regardless of whether the system call to leave
! 740: the group succeeded, since it's much safer to assume that
! 741: we are not a member. */
! 742: OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS);
! 743: }
! 744: }
! 745:
! 746: if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
! 747: (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
! 748: ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
! 749: (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
! 750: {
! 751: /* The interface should belong to the OSPF-designated-routers group. */
! 752: if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) &&
! 753: (ospf_if_add_alldrouters(oi->ospf, oi->address,
! 754: oi->ifp->ifindex) >= 0))
! 755: /* Set the flag only if the system call to join succeeded. */
! 756: OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
! 757: }
! 758: else
! 759: {
! 760: /* The interface should NOT belong to the OSPF-designated-routers group */
! 761: if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
! 762: {
! 763: /* drop only if last reference */
! 764: if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
! 765: ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
! 766:
! 767: /* Unset the flag regardless of whether the system call to leave
! 768: the group succeeded, since it's much safer to assume that
! 769: we are not a member. */
! 770: OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
! 771: }
! 772: }
! 773: }
! 774:
! 775: int
! 776: ospf_if_up (struct ospf_interface *oi)
! 777: {
! 778: if (oi == NULL)
! 779: return 0;
! 780:
! 781: if (oi->type == OSPF_IFTYPE_LOOPBACK)
! 782: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
! 783: else
! 784: {
! 785: struct ospf *ospf = ospf_lookup ();
! 786: if (ospf != NULL)
! 787: ospf_adjust_sndbuflen (ospf, oi->ifp->mtu);
! 788: else
! 789: zlog_warn ("%s: ospf_lookup() returned NULL", __func__);
! 790: ospf_if_stream_set (oi);
! 791: OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
! 792: }
! 793:
! 794: return 1;
! 795: }
! 796:
! 797: int
! 798: ospf_if_down (struct ospf_interface *oi)
! 799: {
! 800: if (oi == NULL)
! 801: return 0;
! 802:
! 803: OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
! 804: /* Shutdown packet reception and sending */
! 805: ospf_if_stream_unset (oi);
! 806:
! 807: return 1;
! 808: }
! 809:
! 810:
! 811: /* Virtual Link related functions. */
! 812:
! 813: struct ospf_vl_data *
! 814: ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
! 815: {
! 816: struct ospf_vl_data *vl_data;
! 817:
! 818: vl_data = XCALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
! 819:
! 820: vl_data->vl_peer.s_addr = vl_peer.s_addr;
! 821: vl_data->vl_area_id = area->area_id;
! 822: vl_data->format = area->format;
! 823:
! 824: return vl_data;
! 825: }
! 826:
! 827: void
! 828: ospf_vl_data_free (struct ospf_vl_data *vl_data)
! 829: {
! 830: XFREE (MTYPE_OSPF_VL_DATA, vl_data);
! 831: }
! 832:
! 833: u_int vlink_count = 0;
! 834:
! 835: struct ospf_interface *
! 836: ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
! 837: {
! 838: struct ospf_interface * voi;
! 839: struct interface * vi;
! 840: char ifname[INTERFACE_NAMSIZ + 1];
! 841: struct ospf_area *area;
! 842: struct in_addr area_id;
! 843: struct connected *co;
! 844: struct prefix_ipv4 *p;
! 845:
! 846: if (IS_DEBUG_OSPF_EVENT)
! 847: zlog_debug ("ospf_vl_new(): Start");
! 848: if (vlink_count == OSPF_VL_MAX_COUNT)
! 849: {
! 850: if (IS_DEBUG_OSPF_EVENT)
! 851: zlog_debug ("ospf_vl_new(): Alarm: "
! 852: "cannot create more than OSPF_MAX_VL_COUNT virtual links");
! 853: return NULL;
! 854: }
! 855:
! 856: if (IS_DEBUG_OSPF_EVENT)
! 857: zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");
! 858:
! 859: snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
! 860: vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
! 861: co = connected_new ();
! 862: co->ifp = vi;
! 863: listnode_add (vi->connected, co);
! 864:
! 865: p = prefix_ipv4_new ();
! 866: p->family = AF_INET;
! 867: p->prefix.s_addr = 0;
! 868: p->prefixlen = 0;
! 869:
! 870: co->address = (struct prefix *)p;
! 871:
! 872: voi = ospf_if_new (ospf, vi, co->address);
! 873: if (voi == NULL)
! 874: {
! 875: if (IS_DEBUG_OSPF_EVENT)
! 876: zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
! 877: return NULL;
! 878: }
! 879: voi->connected = co;
! 880: voi->vl_data = vl_data;
! 881: voi->ifp->mtu = OSPF_VL_MTU;
! 882: voi->type = OSPF_IFTYPE_VIRTUALLINK;
! 883:
! 884: vlink_count++;
! 885: if (IS_DEBUG_OSPF_EVENT)
! 886: zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
! 887: if (IS_DEBUG_OSPF_EVENT)
! 888: zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);
! 889:
! 890: area_id.s_addr = 0;
! 891: area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
! 892: voi->area = area;
! 893:
! 894: if (IS_DEBUG_OSPF_EVENT)
! 895: zlog_debug ("ospf_vl_new(): set associated area to the backbone");
! 896:
! 897: ospf_nbr_add_self (voi);
! 898: ospf_area_add_if (voi->area, voi);
! 899:
! 900: ospf_if_stream_set (voi);
! 901:
! 902: if (IS_DEBUG_OSPF_EVENT)
! 903: zlog_debug ("ospf_vl_new(): Stop");
! 904: return voi;
! 905: }
! 906:
! 907: static void
! 908: ospf_vl_if_delete (struct ospf_vl_data *vl_data)
! 909: {
! 910: struct interface *ifp = vl_data->vl_oi->ifp;
! 911: vl_data->vl_oi->address->u.prefix4.s_addr = 0;
! 912: vl_data->vl_oi->address->prefixlen = 0;
! 913: ospf_if_free (vl_data->vl_oi);
! 914: if_delete (ifp);
! 915: vlink_count--;
! 916: }
! 917:
! 918: /* Look up vl_data for given peer, optionally qualified to be in the
! 919: * specified area. NULL area returns first found..
! 920: */
! 921: struct ospf_vl_data *
! 922: ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area,
! 923: struct in_addr vl_peer)
! 924: {
! 925: struct ospf_vl_data *vl_data;
! 926: struct listnode *node;
! 927:
! 928: if (IS_DEBUG_OSPF_EVENT)
! 929: {
! 930: zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer));
! 931: if (area)
! 932: zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id));
! 933: }
! 934:
! 935: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
! 936: {
! 937: if (IS_DEBUG_OSPF_EVENT)
! 938: zlog_debug ("%s: VL %s, peer %s", __func__,
! 939: vl_data->vl_oi->ifp->name,
! 940: inet_ntoa (vl_data->vl_peer));
! 941:
! 942: if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
! 943: continue;
! 944:
! 945: if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer))
! 946: return vl_data;
! 947: }
! 948:
! 949: return NULL;
! 950: }
! 951:
! 952: static void
! 953: ospf_vl_shutdown (struct ospf_vl_data *vl_data)
! 954: {
! 955: struct ospf_interface *oi;
! 956:
! 957: if ((oi = vl_data->vl_oi) == NULL)
! 958: return;
! 959:
! 960: oi->address->u.prefix4.s_addr = 0;
! 961: oi->address->prefixlen = 0;
! 962:
! 963: UNSET_FLAG (oi->ifp->flags, IFF_UP);
! 964: /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
! 965: OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
! 966: }
! 967:
! 968: void
! 969: ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
! 970: {
! 971: listnode_add (ospf->vlinks, vl_data);
! 972: #ifdef HAVE_SNMP
! 973: ospf_snmp_vl_add (vl_data);
! 974: #endif /* HAVE_SNMP */
! 975: }
! 976:
! 977: void
! 978: ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
! 979: {
! 980: ospf_vl_shutdown (vl_data);
! 981: ospf_vl_if_delete (vl_data);
! 982:
! 983: #ifdef HAVE_SNMP
! 984: ospf_snmp_vl_delete (vl_data);
! 985: #endif /* HAVE_SNMP */
! 986: listnode_delete (ospf->vlinks, vl_data);
! 987:
! 988: ospf_vl_data_free (vl_data);
! 989: }
! 990:
! 991: static int
! 992: ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
! 993: {
! 994: int changed = 0;
! 995: struct ospf_interface *voi;
! 996: struct listnode *node;
! 997: struct vertex_parent *vp = NULL;
! 998: int i;
! 999: struct router_lsa *rl;
! 1000:
! 1001: voi = vl_data->vl_oi;
! 1002:
! 1003: if (voi->output_cost != v->distance)
! 1004: {
! 1005:
! 1006: voi->output_cost = v->distance;
! 1007: changed = 1;
! 1008: }
! 1009:
! 1010: for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
! 1011: {
! 1012: vl_data->nexthop.oi = vp->nexthop->oi;
! 1013: vl_data->nexthop.router = vp->nexthop->router;
! 1014:
! 1015: if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
! 1016: &vl_data->nexthop.oi->address->u.prefix4))
! 1017: changed = 1;
! 1018:
! 1019: voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4;
! 1020: voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen;
! 1021:
! 1022: break; /* We take the first interface. */
! 1023: }
! 1024:
! 1025: rl = (struct router_lsa *)v->lsa;
! 1026:
! 1027: /* use SPF determined backlink index in struct vertex
! 1028: * for virtual link destination address
! 1029: */
! 1030: if (vp && vp->backlink >= 0)
! 1031: {
! 1032: if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
! 1033: &rl->link[vp->backlink].link_data))
! 1034: changed = 1;
! 1035: vl_data->peer_addr = rl->link[vp->backlink].link_data;
! 1036: }
! 1037: else
! 1038: {
! 1039: /* This is highly odd, there is no backlink index
! 1040: * there should be due to the ospf_spf_has_link() check
! 1041: * in SPF. Lets warn and try pick a link anyway.
! 1042: */
! 1043: zlog_warn ("ospf_vl_set_params: No backlink for %s!",
! 1044: vl_data->vl_oi->ifp->name);
! 1045: for (i = 0; i < ntohs (rl->links); i++)
! 1046: {
! 1047: switch (rl->link[i].type)
! 1048: {
! 1049: case LSA_LINK_TYPE_VIRTUALLINK:
! 1050: if (IS_DEBUG_OSPF_EVENT)
! 1051: zlog_debug ("found back link through VL");
! 1052: case LSA_LINK_TYPE_TRANSIT:
! 1053: case LSA_LINK_TYPE_POINTOPOINT:
! 1054: if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
! 1055: &rl->link[i].link_data))
! 1056: changed = 1;
! 1057: vl_data->peer_addr = rl->link[i].link_data;
! 1058: }
! 1059: }
! 1060: }
! 1061:
! 1062: if (IS_DEBUG_OSPF_EVENT)
! 1063: zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__,
! 1064: vl_data->vl_oi->ifp->name,
! 1065: inet_ntoa(vl_data->peer_addr),
! 1066: voi->output_cost,
! 1067: (changed ? " " : " un"));
! 1068:
! 1069: return changed;
! 1070: }
! 1071:
! 1072:
! 1073: void
! 1074: ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
! 1075: struct vertex *v)
! 1076: {
! 1077: struct ospf *ospf = area->ospf;
! 1078: struct listnode *node;
! 1079: struct ospf_vl_data *vl_data;
! 1080: struct ospf_interface *oi;
! 1081:
! 1082: if (IS_DEBUG_OSPF_EVENT)
! 1083: {
! 1084: zlog_debug ("ospf_vl_up_check(): Start");
! 1085: zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
! 1086: zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
! 1087: }
! 1088:
! 1089: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
! 1090: {
! 1091: if (IS_DEBUG_OSPF_EVENT)
! 1092: {
! 1093: zlog_debug ("%s: considering VL, %s in area %s", __func__,
! 1094: vl_data->vl_oi->ifp->name,
! 1095: inet_ntoa (vl_data->vl_area_id));
! 1096: zlog_debug ("%s: peer ID: %s", __func__,
! 1097: inet_ntoa (vl_data->vl_peer));
! 1098: }
! 1099:
! 1100: if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
! 1101: IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
! 1102: {
! 1103: oi = vl_data->vl_oi;
! 1104: SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
! 1105:
! 1106: if (IS_DEBUG_OSPF_EVENT)
! 1107: zlog_debug ("ospf_vl_up_check(): this VL matched");
! 1108:
! 1109: if (oi->state == ISM_Down)
! 1110: {
! 1111: if (IS_DEBUG_OSPF_EVENT)
! 1112: zlog_debug ("ospf_vl_up_check(): VL is down, waking it up");
! 1113: SET_FLAG (oi->ifp->flags, IFF_UP);
! 1114: OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp);
! 1115: }
! 1116:
! 1117: if (ospf_vl_set_params (vl_data, v))
! 1118: {
! 1119: if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
! 1120: zlog_debug ("ospf_vl_up_check: VL cost change,"
! 1121: " scheduling router lsa refresh");
! 1122: if (ospf->backbone)
! 1123: ospf_router_lsa_update_area (ospf->backbone);
! 1124: else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
! 1125: zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
! 1126: }
! 1127: }
! 1128: }
! 1129: }
! 1130:
! 1131: void
! 1132: ospf_vl_unapprove (struct ospf *ospf)
! 1133: {
! 1134: struct listnode *node;
! 1135: struct ospf_vl_data *vl_data;
! 1136:
! 1137: for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
! 1138: UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
! 1139: }
! 1140:
! 1141: void
! 1142: ospf_vl_shut_unapproved (struct ospf *ospf)
! 1143: {
! 1144: struct listnode *node, *nnode;
! 1145: struct ospf_vl_data *vl_data;
! 1146:
! 1147: for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
! 1148: if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
! 1149: ospf_vl_shutdown (vl_data);
! 1150: }
! 1151:
! 1152: int
! 1153: ospf_full_virtual_nbrs (struct ospf_area *area)
! 1154: {
! 1155: if (IS_DEBUG_OSPF_EVENT)
! 1156: {
! 1157: zlog_debug ("counting fully adjacent virtual neighbors in area %s",
! 1158: inet_ntoa (area->area_id));
! 1159: zlog_debug ("there are %d of them", area->full_vls);
! 1160: }
! 1161:
! 1162: return area->full_vls;
! 1163: }
! 1164:
! 1165: int
! 1166: ospf_vls_in_area (struct ospf_area *area)
! 1167: {
! 1168: struct listnode *node;
! 1169: struct ospf_vl_data *vl_data;
! 1170: int c = 0;
! 1171:
! 1172: for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
! 1173: if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
! 1174: c++;
! 1175:
! 1176: return c;
! 1177: }
! 1178:
! 1179:
! 1180: struct crypt_key *
! 1181: ospf_crypt_key_new ()
! 1182: {
! 1183: return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
! 1184: }
! 1185:
! 1186: void
! 1187: ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
! 1188: {
! 1189: listnode_add (crypt, ck);
! 1190: }
! 1191:
! 1192: struct crypt_key *
! 1193: ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id)
! 1194: {
! 1195: struct listnode *node;
! 1196: struct crypt_key *ck;
! 1197:
! 1198: for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck))
! 1199: if (ck->key_id == key_id)
! 1200: return ck;
! 1201:
! 1202: return NULL;
! 1203: }
! 1204:
! 1205: int
! 1206: ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id)
! 1207: {
! 1208: struct listnode *node, *nnode;
! 1209: struct crypt_key *ck;
! 1210:
! 1211: for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck))
! 1212: {
! 1213: if (ck->key_id == key_id)
! 1214: {
! 1215: listnode_delete (auth_crypt, ck);
! 1216: XFREE (MTYPE_OSPF_CRYPT_KEY, ck);
! 1217: return 1;
! 1218: }
! 1219: }
! 1220:
! 1221: return 0;
! 1222: }
! 1223:
! 1224: u_char
! 1225: ospf_default_iftype(struct interface *ifp)
! 1226: {
! 1227: if (if_is_pointopoint (ifp))
! 1228: return OSPF_IFTYPE_POINTOPOINT;
! 1229: else if (if_is_loopback (ifp))
! 1230: return OSPF_IFTYPE_LOOPBACK;
! 1231: else
! 1232: return OSPF_IFTYPE_BROADCAST;
! 1233: }
! 1234:
! 1235: void
! 1236: ospf_if_init ()
! 1237: {
! 1238: /* Initialize Zebra interface data structure. */
! 1239: if_init ();
! 1240: om->iflist = iflist;
! 1241: if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
! 1242: if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
! 1243: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>