Annotation of embedaddon/quagga/ospfd/ospf_zebra.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Zebra connect library for OSPFd
! 3: * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, 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 it
! 8: * under the terms of the GNU General Public License as published by the
! 9: * Free Software Foundation; either version 2, or (at your option) any
! 10: * 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 "command.h"
! 27: #include "network.h"
! 28: #include "prefix.h"
! 29: #include "routemap.h"
! 30: #include "table.h"
! 31: #include "stream.h"
! 32: #include "memory.h"
! 33: #include "zclient.h"
! 34: #include "filter.h"
! 35: #include "plist.h"
! 36: #include "log.h"
! 37:
! 38: #include "ospfd/ospfd.h"
! 39: #include "ospfd/ospf_interface.h"
! 40: #include "ospfd/ospf_ism.h"
! 41: #include "ospfd/ospf_asbr.h"
! 42: #include "ospfd/ospf_asbr.h"
! 43: #include "ospfd/ospf_abr.h"
! 44: #include "ospfd/ospf_lsa.h"
! 45: #include "ospfd/ospf_dump.h"
! 46: #include "ospfd/ospf_route.h"
! 47: #include "ospfd/ospf_zebra.h"
! 48: #ifdef HAVE_SNMP
! 49: #include "ospfd/ospf_snmp.h"
! 50: #endif /* HAVE_SNMP */
! 51:
! 52: /* Zebra structure to hold current status. */
! 53: struct zclient *zclient = NULL;
! 54:
! 55: /* For registering threads. */
! 56: extern struct thread_master *master;
! 57: struct in_addr router_id_zebra;
! 58:
! 59: /* Router-id update message from zebra. */
! 60: static int
! 61: ospf_router_id_update_zebra (int command, struct zclient *zclient,
! 62: zebra_size_t length)
! 63: {
! 64: struct ospf *ospf;
! 65: struct prefix router_id;
! 66: zebra_router_id_update_read(zclient->ibuf,&router_id);
! 67:
! 68: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 69: {
! 70: char buf[128];
! 71: prefix2str(&router_id, buf, sizeof(buf));
! 72: zlog_debug("Zebra rcvd: router id update %s", buf);
! 73: }
! 74:
! 75: router_id_zebra = router_id.u.prefix4;
! 76:
! 77: ospf = ospf_lookup ();
! 78:
! 79: if (ospf != NULL)
! 80: ospf_router_id_update (ospf);
! 81:
! 82: return 0;
! 83: }
! 84:
! 85: /* Inteface addition message from zebra. */
! 86: static int
! 87: ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
! 88: {
! 89: struct interface *ifp;
! 90:
! 91: ifp = zebra_interface_add_read (zclient->ibuf);
! 92:
! 93: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 94: zlog_debug ("Zebra: interface add %s index %d flags %llx metric %d mtu %d",
! 95: ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
! 96: ifp->metric, ifp->mtu);
! 97:
! 98: assert (ifp->info);
! 99:
! 100: if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
! 101: {
! 102: SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
! 103: IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
! 104: }
! 105:
! 106: ospf_if_update (NULL, ifp);
! 107:
! 108: #ifdef HAVE_SNMP
! 109: ospf_snmp_if_update (ifp);
! 110: #endif /* HAVE_SNMP */
! 111:
! 112: return 0;
! 113: }
! 114:
! 115: static int
! 116: ospf_interface_delete (int command, struct zclient *zclient,
! 117: zebra_size_t length)
! 118: {
! 119: struct interface *ifp;
! 120: struct stream *s;
! 121: struct route_node *rn;
! 122:
! 123: s = zclient->ibuf;
! 124: /* zebra_interface_state_read() updates interface structure in iflist */
! 125: ifp = zebra_interface_state_read (s);
! 126:
! 127: if (ifp == NULL)
! 128: return 0;
! 129:
! 130: if (if_is_up (ifp))
! 131: zlog_warn ("Zebra: got delete of %s, but interface is still up",
! 132: ifp->name);
! 133:
! 134: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 135: zlog_debug
! 136: ("Zebra: interface delete %s index %d flags %lld metric %d mtu %d",
! 137: ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
! 138:
! 139: #ifdef HAVE_SNMP
! 140: ospf_snmp_if_delete (ifp);
! 141: #endif /* HAVE_SNMP */
! 142:
! 143: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
! 144: if (rn->info)
! 145: ospf_if_free ((struct ospf_interface *) rn->info);
! 146:
! 147: ifp->ifindex = IFINDEX_INTERNAL;
! 148: return 0;
! 149: }
! 150:
! 151: static struct interface *
! 152: zebra_interface_if_lookup (struct stream *s)
! 153: {
! 154: char ifname_tmp[INTERFACE_NAMSIZ];
! 155:
! 156: /* Read interface name. */
! 157: stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
! 158:
! 159: /* And look it up. */
! 160: return if_lookup_by_name_len(ifname_tmp,
! 161: strnlen(ifname_tmp, INTERFACE_NAMSIZ));
! 162: }
! 163:
! 164: static int
! 165: ospf_interface_state_up (int command, struct zclient *zclient,
! 166: zebra_size_t length)
! 167: {
! 168: struct interface *ifp;
! 169: struct ospf_interface *oi;
! 170: struct route_node *rn;
! 171:
! 172: ifp = zebra_interface_if_lookup (zclient->ibuf);
! 173:
! 174: if (ifp == NULL)
! 175: return 0;
! 176:
! 177: /* Interface is already up. */
! 178: if (if_is_operative (ifp))
! 179: {
! 180: /* Temporarily keep ifp values. */
! 181: struct interface if_tmp;
! 182: memcpy (&if_tmp, ifp, sizeof (struct interface));
! 183:
! 184: zebra_interface_if_set_value (zclient->ibuf, ifp);
! 185:
! 186: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 187: zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
! 188:
! 189: if (if_tmp.bandwidth != ifp->bandwidth)
! 190: {
! 191: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 192: zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
! 193: ifp->name, if_tmp.bandwidth, ifp->bandwidth);
! 194:
! 195: ospf_if_recalculate_output_cost (ifp);
! 196: }
! 197:
! 198: if (if_tmp.mtu != ifp->mtu)
! 199: {
! 200: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 201: zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
! 202: ifp->name, if_tmp.mtu, ifp->mtu);
! 203:
! 204: /* Must reset the interface (simulate down/up) when MTU changes. */
! 205: ospf_if_reset(ifp);
! 206: }
! 207: return 0;
! 208: }
! 209:
! 210: zebra_interface_if_set_value (zclient->ibuf, ifp);
! 211:
! 212: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 213: zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
! 214:
! 215: for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
! 216: {
! 217: if ((oi = rn->info) == NULL)
! 218: continue;
! 219:
! 220: ospf_if_up (oi);
! 221: }
! 222:
! 223: return 0;
! 224: }
! 225:
! 226: static int
! 227: ospf_interface_state_down (int command, struct zclient *zclient,
! 228: zebra_size_t length)
! 229: {
! 230: struct interface *ifp;
! 231: struct ospf_interface *oi;
! 232: struct route_node *node;
! 233:
! 234: ifp = zebra_interface_state_read (zclient->ibuf);
! 235:
! 236: if (ifp == NULL)
! 237: return 0;
! 238:
! 239: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 240: zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
! 241:
! 242: for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
! 243: {
! 244: if ((oi = node->info) == NULL)
! 245: continue;
! 246: ospf_if_down (oi);
! 247: }
! 248:
! 249: return 0;
! 250: }
! 251:
! 252: static int
! 253: ospf_interface_address_add (int command, struct zclient *zclient,
! 254: zebra_size_t length)
! 255: {
! 256: struct connected *c;
! 257:
! 258: c = zebra_interface_address_read (command, zclient->ibuf);
! 259:
! 260: if (c == NULL)
! 261: return 0;
! 262:
! 263: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 264: {
! 265: char buf[128];
! 266: prefix2str(c->address, buf, sizeof(buf));
! 267: zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
! 268: }
! 269:
! 270: ospf_if_update (NULL, c->ifp);
! 271:
! 272: #ifdef HAVE_SNMP
! 273: ospf_snmp_if_update (c->ifp);
! 274: #endif /* HAVE_SNMP */
! 275:
! 276: return 0;
! 277: }
! 278:
! 279: static int
! 280: ospf_interface_address_delete (int command, struct zclient *zclient,
! 281: zebra_size_t length)
! 282: {
! 283: struct connected *c;
! 284: struct interface *ifp;
! 285: struct ospf_interface *oi;
! 286: struct route_node *rn;
! 287: struct prefix p;
! 288:
! 289: c = zebra_interface_address_read (command, zclient->ibuf);
! 290:
! 291: if (c == NULL)
! 292: return 0;
! 293:
! 294: if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
! 295: {
! 296: char buf[128];
! 297: prefix2str(c->address, buf, sizeof(buf));
! 298: zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf);
! 299: }
! 300:
! 301: ifp = c->ifp;
! 302: p = *c->address;
! 303: p.prefixlen = IPV4_MAX_PREFIXLEN;
! 304:
! 305: rn = route_node_lookup (IF_OIFS (ifp), &p);
! 306: if (!rn)
! 307: {
! 308: connected_free (c);
! 309: return 0;
! 310: }
! 311:
! 312: assert (rn->info);
! 313: oi = rn->info;
! 314:
! 315: /* Call interface hook functions to clean up */
! 316: ospf_if_free (oi);
! 317:
! 318: #ifdef HAVE_SNMP
! 319: ospf_snmp_if_update (c->ifp);
! 320: #endif /* HAVE_SNMP */
! 321:
! 322: connected_free (c);
! 323:
! 324: return 0;
! 325: }
! 326:
! 327: void
! 328: ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
! 329: {
! 330: u_char message;
! 331: u_char distance;
! 332: u_char flags;
! 333: int psize;
! 334: struct stream *s;
! 335: struct ospf_path *path;
! 336: struct listnode *node;
! 337:
! 338: if (zclient->redist[ZEBRA_ROUTE_OSPF])
! 339: {
! 340: message = 0;
! 341: flags = 0;
! 342:
! 343: /* OSPF pass nexthop and metric */
! 344: SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
! 345: SET_FLAG (message, ZAPI_MESSAGE_METRIC);
! 346:
! 347: /* Distance value. */
! 348: distance = ospf_distance_apply (p, or);
! 349: if (distance)
! 350: SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
! 351:
! 352: /* Make packet. */
! 353: s = zclient->obuf;
! 354: stream_reset (s);
! 355:
! 356: /* Put command, type, flags, message. */
! 357: zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
! 358: stream_putc (s, ZEBRA_ROUTE_OSPF);
! 359: stream_putc (s, flags);
! 360: stream_putc (s, message);
! 361:
! 362: /* Put prefix information. */
! 363: psize = PSIZE (p->prefixlen);
! 364: stream_putc (s, p->prefixlen);
! 365: stream_write (s, (u_char *) & p->prefix, psize);
! 366:
! 367: /* Nexthop count. */
! 368: stream_putc (s, or->paths->count);
! 369:
! 370: /* Nexthop, ifindex, distance and metric information. */
! 371: for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
! 372: {
! 373: if (path->nexthop.s_addr != INADDR_ANY)
! 374: {
! 375: stream_putc (s, ZEBRA_NEXTHOP_IPV4);
! 376: stream_put_in_addr (s, &path->nexthop);
! 377: }
! 378: else
! 379: {
! 380: stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
! 381: if (path->ifindex)
! 382: stream_putl (s, path->ifindex);
! 383: else
! 384: stream_putl (s, 0);
! 385: }
! 386:
! 387: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 388: {
! 389: char buf[2][INET_ADDRSTRLEN];
! 390: zlog_debug("Zebra: Route add %s/%d nexthop %s",
! 391: inet_ntop(AF_INET, &p->prefix,
! 392: buf[0], sizeof(buf[0])),
! 393: p->prefixlen,
! 394: inet_ntop(AF_INET, &path->nexthop,
! 395: buf[1], sizeof(buf[1])));
! 396: }
! 397: }
! 398:
! 399: if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
! 400: stream_putc (s, distance);
! 401: if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
! 402: {
! 403: if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
! 404: stream_putl (s, or->cost + or->u.ext.type2_cost);
! 405: else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
! 406: stream_putl (s, or->u.ext.type2_cost);
! 407: else
! 408: stream_putl (s, or->cost);
! 409: }
! 410:
! 411: stream_putw_at (s, 0, stream_get_endp (s));
! 412:
! 413: zclient_send_message(zclient);
! 414: }
! 415: }
! 416:
! 417: void
! 418: ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
! 419: {
! 420: struct zapi_ipv4 api;
! 421: struct ospf_path *path;
! 422: struct in_addr *nexthop;
! 423: struct listnode *node, *nnode;
! 424:
! 425: if (zclient->redist[ZEBRA_ROUTE_OSPF])
! 426: {
! 427: api.type = ZEBRA_ROUTE_OSPF;
! 428: api.flags = 0;
! 429: api.message = 0;
! 430: api.ifindex_num = 0;
! 431: api.nexthop_num = 0;
! 432:
! 433: for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
! 434: {
! 435: if (path->nexthop.s_addr != INADDR_ANY)
! 436: {
! 437: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
! 438: api.nexthop_num = 1;
! 439: nexthop = &path->nexthop;
! 440: api.nexthop = &nexthop;
! 441: }
! 442: else if (if_lookup_by_index(path->ifindex))
! 443: {
! 444: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
! 445: api.ifindex_num = 1;
! 446: api.ifindex = &path->ifindex;
! 447: }
! 448: else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
! 449: {
! 450: zlog_debug("Zebra: no ifp %s %d",
! 451: inet_ntoa(p->prefix),
! 452: p->prefixlen);
! 453: }
! 454:
! 455: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
! 456:
! 457: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
! 458: {
! 459: char buf[2][INET_ADDRSTRLEN];
! 460: zlog_debug("Zebra: Route delete %s/%d nexthop %s",
! 461: inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])),
! 462: p->prefixlen,
! 463: inet_ntop(AF_INET, *api.nexthop,
! 464: buf[1], sizeof(buf[1])));
! 465: }
! 466: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
! 467: {
! 468: zlog_debug ("Zebra: Route delete %s/%d ifindex %d",
! 469: inet_ntoa (p->prefix),
! 470: p->prefixlen, *api.ifindex);
! 471: }
! 472: }
! 473: }
! 474: }
! 475:
! 476: void
! 477: ospf_zebra_add_discard (struct prefix_ipv4 *p)
! 478: {
! 479: struct zapi_ipv4 api;
! 480:
! 481: if (zclient->redist[ZEBRA_ROUTE_OSPF])
! 482: {
! 483: api.type = ZEBRA_ROUTE_OSPF;
! 484: api.flags = ZEBRA_FLAG_BLACKHOLE;
! 485: api.message = 0;
! 486: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
! 487: api.nexthop_num = 0;
! 488: api.ifindex_num = 0;
! 489:
! 490: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
! 491:
! 492: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 493: zlog_debug ("Zebra: Route add discard %s/%d",
! 494: inet_ntoa (p->prefix), p->prefixlen);
! 495: }
! 496: }
! 497:
! 498: void
! 499: ospf_zebra_delete_discard (struct prefix_ipv4 *p)
! 500: {
! 501: struct zapi_ipv4 api;
! 502:
! 503: if (zclient->redist[ZEBRA_ROUTE_OSPF])
! 504: {
! 505: api.type = ZEBRA_ROUTE_OSPF;
! 506: api.flags = ZEBRA_FLAG_BLACKHOLE;
! 507: api.message = 0;
! 508: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
! 509: api.nexthop_num = 0;
! 510: api.ifindex_num = 0;
! 511:
! 512: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
! 513:
! 514: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 515: zlog_debug ("Zebra: Route delete discard %s/%d",
! 516: inet_ntoa (p->prefix), p->prefixlen);
! 517:
! 518: }
! 519: }
! 520:
! 521: int
! 522: ospf_is_type_redistributed (int type)
! 523: {
! 524: return (DEFAULT_ROUTE_TYPE (type)) ?
! 525: zclient->default_information : zclient->redist[type];
! 526: }
! 527:
! 528: int
! 529: ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
! 530: {
! 531: int force = 0;
! 532:
! 533: if (ospf_is_type_redistributed (type))
! 534: {
! 535: if (mtype != ospf->dmetric[type].type)
! 536: {
! 537: ospf->dmetric[type].type = mtype;
! 538: force = LSA_REFRESH_FORCE;
! 539: }
! 540: if (mvalue != ospf->dmetric[type].value)
! 541: {
! 542: ospf->dmetric[type].value = mvalue;
! 543: force = LSA_REFRESH_FORCE;
! 544: }
! 545:
! 546: ospf_external_lsa_refresh_type (ospf, type, force);
! 547:
! 548: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 549: zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
! 550: ospf_redist_string(type),
! 551: metric_type (ospf, type), metric_value (ospf, type));
! 552:
! 553: return CMD_SUCCESS;
! 554: }
! 555:
! 556: ospf->dmetric[type].type = mtype;
! 557: ospf->dmetric[type].value = mvalue;
! 558:
! 559: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
! 560:
! 561: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 562: zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
! 563: ospf_redist_string(type),
! 564: metric_type (ospf, type), metric_value (ospf, type));
! 565:
! 566: ospf_asbr_status_update (ospf, ++ospf->redistribute);
! 567:
! 568: return CMD_SUCCESS;
! 569: }
! 570:
! 571: int
! 572: ospf_redistribute_unset (struct ospf *ospf, int type)
! 573: {
! 574: if (type == zclient->redist_default)
! 575: return CMD_SUCCESS;
! 576:
! 577: if (!ospf_is_type_redistributed (type))
! 578: return CMD_SUCCESS;
! 579:
! 580: zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
! 581:
! 582: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 583: zlog_debug ("Redistribute[%s]: Stop",
! 584: ospf_redist_string(type));
! 585:
! 586: ospf->dmetric[type].type = -1;
! 587: ospf->dmetric[type].value = -1;
! 588:
! 589: /* Remove the routes from OSPF table. */
! 590: ospf_redistribute_withdraw (ospf, type);
! 591:
! 592: ospf_asbr_status_update (ospf, --ospf->redistribute);
! 593:
! 594: return CMD_SUCCESS;
! 595: }
! 596:
! 597: int
! 598: ospf_redistribute_default_set (struct ospf *ospf, int originate,
! 599: int mtype, int mvalue)
! 600: {
! 601: ospf->default_originate = originate;
! 602: ospf->dmetric[DEFAULT_ROUTE].type = mtype;
! 603: ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
! 604:
! 605: if (ospf_is_type_redistributed (DEFAULT_ROUTE))
! 606: {
! 607: /* if ospf->default_originate changes value, is calling
! 608: ospf_external_lsa_refresh_default sufficient to implement
! 609: the change? */
! 610: ospf_external_lsa_refresh_default (ospf);
! 611:
! 612: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 613: zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
! 614: ospf_redist_string(DEFAULT_ROUTE),
! 615: metric_type (ospf, DEFAULT_ROUTE),
! 616: metric_value (ospf, DEFAULT_ROUTE));
! 617: return CMD_SUCCESS;
! 618: }
! 619:
! 620: zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
! 621:
! 622: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 623: zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
! 624: metric_type (ospf, DEFAULT_ROUTE),
! 625: metric_value (ospf, DEFAULT_ROUTE));
! 626:
! 627: if (ospf->router_id.s_addr == 0)
! 628: ospf->external_origin |= (1 << DEFAULT_ROUTE);
! 629: else
! 630: thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
! 631:
! 632: ospf_asbr_status_update (ospf, ++ospf->redistribute);
! 633:
! 634: return CMD_SUCCESS;
! 635: }
! 636:
! 637: int
! 638: ospf_redistribute_default_unset (struct ospf *ospf)
! 639: {
! 640: if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
! 641: return CMD_SUCCESS;
! 642:
! 643: ospf->default_originate = DEFAULT_ORIGINATE_NONE;
! 644: ospf->dmetric[DEFAULT_ROUTE].type = -1;
! 645: ospf->dmetric[DEFAULT_ROUTE].value = -1;
! 646:
! 647: zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
! 648:
! 649: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 650: zlog_debug ("Redistribute[DEFAULT]: Stop");
! 651:
! 652: ospf_asbr_status_update (ospf, --ospf->redistribute);
! 653:
! 654: return CMD_SUCCESS;
! 655: }
! 656:
! 657: static int
! 658: ospf_external_lsa_originate_check (struct ospf *ospf,
! 659: struct external_info *ei)
! 660: {
! 661: /* If prefix is multicast, then do not originate LSA. */
! 662: if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
! 663: {
! 664: zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
! 665: "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
! 666: return 0;
! 667: }
! 668:
! 669: /* Take care of default-originate. */
! 670: if (is_prefix_default (&ei->p))
! 671: if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
! 672: {
! 673: zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
! 674: "for default");
! 675: return 0;
! 676: }
! 677:
! 678: return 1;
! 679: }
! 680:
! 681: /* If connected prefix is OSPF enable interface, then do not announce. */
! 682: int
! 683: ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
! 684: {
! 685: struct listnode *node;
! 686: struct ospf_interface *oi;
! 687:
! 688:
! 689: for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
! 690: if (prefix_match (oi->address, (struct prefix *) &ei->p))
! 691: return 0;
! 692: return 1;
! 693: }
! 694:
! 695: /* return 1 if external LSA must be originated, 0 otherwise */
! 696: int
! 697: ospf_redistribute_check (struct ospf *ospf,
! 698: struct external_info *ei, int *changed)
! 699: {
! 700: struct route_map_set_values save_values;
! 701: struct prefix_ipv4 *p = &ei->p;
! 702: u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
! 703:
! 704: if (changed)
! 705: *changed = 0;
! 706:
! 707: if (!ospf_external_lsa_originate_check (ospf, ei))
! 708: return 0;
! 709:
! 710: /* Take care connected route. */
! 711: if (type == ZEBRA_ROUTE_CONNECT &&
! 712: !ospf_distribute_check_connected (ospf, ei))
! 713: return 0;
! 714:
! 715: if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
! 716: /* distirbute-list exists, but access-list may not? */
! 717: if (DISTRIBUTE_LIST (ospf, type))
! 718: if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
! 719: {
! 720: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 721: zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
! 722: ospf_redist_string(type),
! 723: inet_ntoa (p->prefix), p->prefixlen);
! 724: return 0;
! 725: }
! 726:
! 727: save_values = ei->route_map_set;
! 728: ospf_reset_route_map_set_values (&ei->route_map_set);
! 729:
! 730: /* apply route-map if needed */
! 731: if (ROUTEMAP_NAME (ospf, type))
! 732: {
! 733: int ret;
! 734:
! 735: ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
! 736: RMAP_OSPF, ei);
! 737:
! 738: if (ret == RMAP_DENYMATCH)
! 739: {
! 740: ei->route_map_set = save_values;
! 741: if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
! 742: zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
! 743: ospf_redist_string(type),
! 744: inet_ntoa (p->prefix), p->prefixlen);
! 745: return 0;
! 746: }
! 747:
! 748: /* check if 'route-map set' changed something */
! 749: if (changed)
! 750: *changed = !ospf_route_map_set_compare (&ei->route_map_set,
! 751: &save_values);
! 752: }
! 753:
! 754: return 1;
! 755: }
! 756:
! 757: /* OSPF route-map set for redistribution */
! 758: void
! 759: ospf_routemap_set (struct ospf *ospf, int type, const char *name)
! 760: {
! 761: if (ROUTEMAP_NAME (ospf, type))
! 762: free (ROUTEMAP_NAME (ospf, type));
! 763:
! 764: ROUTEMAP_NAME (ospf, type) = strdup (name);
! 765: ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
! 766: }
! 767:
! 768: void
! 769: ospf_routemap_unset (struct ospf *ospf, int type)
! 770: {
! 771: if (ROUTEMAP_NAME (ospf, type))
! 772: free (ROUTEMAP_NAME (ospf, type));
! 773:
! 774: ROUTEMAP_NAME (ospf, type) = NULL;
! 775: ROUTEMAP (ospf, type) = NULL;
! 776: }
! 777:
! 778: /* Zebra route add and delete treatment. */
! 779: static int
! 780: ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
! 781: zebra_size_t length)
! 782: {
! 783: struct stream *s;
! 784: struct zapi_ipv4 api;
! 785: unsigned long ifindex;
! 786: struct in_addr nexthop;
! 787: struct prefix_ipv4 p;
! 788: struct external_info *ei;
! 789: struct ospf *ospf;
! 790:
! 791: s = zclient->ibuf;
! 792: ifindex = 0;
! 793: nexthop.s_addr = 0;
! 794:
! 795: /* Type, flags, message. */
! 796: api.type = stream_getc (s);
! 797: api.flags = stream_getc (s);
! 798: api.message = stream_getc (s);
! 799:
! 800: /* IPv4 prefix. */
! 801: memset (&p, 0, sizeof (struct prefix_ipv4));
! 802: p.family = AF_INET;
! 803: p.prefixlen = stream_getc (s);
! 804: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
! 805:
! 806: if (IPV4_NET127(ntohl(p.prefix.s_addr)))
! 807: return 0;
! 808:
! 809: /* Nexthop, ifindex, distance, metric. */
! 810: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
! 811: {
! 812: api.nexthop_num = stream_getc (s);
! 813: nexthop.s_addr = stream_get_ipv4 (s);
! 814: }
! 815: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
! 816: {
! 817: api.ifindex_num = stream_getc (s);
! 818: /* XXX assert(api.ifindex_num == 1); */
! 819: ifindex = stream_getl (s);
! 820: }
! 821: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
! 822: api.distance = stream_getc (s);
! 823: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
! 824: api.metric = stream_getl (s);
! 825:
! 826: ospf = ospf_lookup ();
! 827: if (ospf == NULL)
! 828: return 0;
! 829:
! 830: if (command == ZEBRA_IPV4_ROUTE_ADD)
! 831: {
! 832: /* XXX|HACK|TODO|FIXME:
! 833: * Maybe we should ignore reject/blackhole routes? Testing shows that
! 834: * there is no problems though and this is only way to "summarize"
! 835: * routes in ASBR at the moment. Maybe we need just a better generalised
! 836: * solution for these types?
! 837: *
! 838: * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
! 839: * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
! 840: * return 0;
! 841: */
! 842:
! 843: ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
! 844:
! 845: if (ospf->router_id.s_addr == 0)
! 846: /* Set flags to generate AS-external-LSA originate event
! 847: for each redistributed protocols later. */
! 848: ospf->external_origin |= (1 << api.type);
! 849: else
! 850: {
! 851: if (ei)
! 852: {
! 853: if (is_prefix_default (&p))
! 854: ospf_external_lsa_refresh_default (ospf);
! 855: else
! 856: {
! 857: struct ospf_lsa *current;
! 858:
! 859: current = ospf_external_info_find_lsa (ospf, &ei->p);
! 860: if (!current)
! 861: ospf_external_lsa_originate (ospf, ei);
! 862: else if (IS_LSA_MAXAGE (current))
! 863: ospf_external_lsa_refresh (ospf, current,
! 864: ei, LSA_REFRESH_FORCE);
! 865: else
! 866: zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
! 867: inet_ntoa (p.prefix));
! 868: }
! 869: }
! 870: }
! 871: }
! 872: else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
! 873: {
! 874: ospf_external_info_delete (api.type, p);
! 875: if (is_prefix_default (&p))
! 876: ospf_external_lsa_refresh_default (ospf);
! 877: else
! 878: ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
! 879: }
! 880:
! 881: return 0;
! 882: }
! 883:
! 884:
! 885: int
! 886: ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
! 887: {
! 888: /* Lookup access-list for distribute-list. */
! 889: DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
! 890:
! 891: /* Clear previous distribute-name. */
! 892: if (DISTRIBUTE_NAME (ospf, type))
! 893: free (DISTRIBUTE_NAME (ospf, type));
! 894:
! 895: /* Set distribute-name. */
! 896: DISTRIBUTE_NAME (ospf, type) = strdup (name);
! 897:
! 898: /* If access-list have been set, schedule update timer. */
! 899: if (DISTRIBUTE_LIST (ospf, type))
! 900: ospf_distribute_list_update (ospf, type);
! 901:
! 902: return CMD_SUCCESS;
! 903: }
! 904:
! 905: int
! 906: ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
! 907: {
! 908: /* Schedule update timer. */
! 909: if (DISTRIBUTE_LIST (ospf, type))
! 910: ospf_distribute_list_update (ospf, type);
! 911:
! 912: /* Unset distribute-list. */
! 913: DISTRIBUTE_LIST (ospf, type) = NULL;
! 914:
! 915: /* Clear distribute-name. */
! 916: if (DISTRIBUTE_NAME (ospf, type))
! 917: free (DISTRIBUTE_NAME (ospf, type));
! 918:
! 919: DISTRIBUTE_NAME (ospf, type) = NULL;
! 920:
! 921: return CMD_SUCCESS;
! 922: }
! 923:
! 924: /* distribute-list update timer. */
! 925: static int
! 926: ospf_distribute_list_update_timer (struct thread *thread)
! 927: {
! 928: struct route_node *rn;
! 929: struct external_info *ei;
! 930: struct route_table *rt;
! 931: struct ospf_lsa *lsa;
! 932: int type, default_refresh = 0;
! 933: struct ospf *ospf;
! 934:
! 935: ospf = ospf_lookup ();
! 936: if (ospf == NULL)
! 937: return 0;
! 938:
! 939: ospf->t_distribute_update = NULL;
! 940:
! 941: zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
! 942:
! 943: /* foreach all external info. */
! 944: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
! 945: {
! 946: rt = EXTERNAL_INFO (type);
! 947: if (!rt)
! 948: continue;
! 949: for (rn = route_top (rt); rn; rn = route_next (rn))
! 950: if ((ei = rn->info) != NULL)
! 951: {
! 952: if (is_prefix_default (&ei->p))
! 953: default_refresh = 1;
! 954: else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
! 955: ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
! 956: else
! 957: ospf_external_lsa_originate (ospf, ei);
! 958: }
! 959: }
! 960: if (default_refresh)
! 961: ospf_external_lsa_refresh_default (ospf);
! 962: return 0;
! 963: }
! 964:
! 965: #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
! 966:
! 967: /* Update distribute-list and set timer to apply access-list. */
! 968: void
! 969: ospf_distribute_list_update (struct ospf *ospf, int type)
! 970: {
! 971: struct route_table *rt;
! 972:
! 973: /* External info does not exist. */
! 974: if (!(rt = EXTERNAL_INFO (type)))
! 975: return;
! 976:
! 977: /* If exists previously invoked thread, then let it continue. */
! 978: if (ospf->t_distribute_update)
! 979: return;
! 980:
! 981: /* Set timer. */
! 982: ospf->t_distribute_update =
! 983: thread_add_timer (master, ospf_distribute_list_update_timer,
! 984: (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
! 985: }
! 986:
! 987: /* If access-list is updated, apply some check. */
! 988: static void
! 989: ospf_filter_update (struct access_list *access)
! 990: {
! 991: struct ospf *ospf;
! 992: int type;
! 993: int abr_inv = 0;
! 994: struct ospf_area *area;
! 995: struct listnode *node;
! 996:
! 997: /* If OSPF instatnce does not exist, return right now. */
! 998: ospf = ospf_lookup ();
! 999: if (ospf == NULL)
! 1000: return;
! 1001:
! 1002: /* Update distribute-list, and apply filter. */
! 1003: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
! 1004: {
! 1005: if (ROUTEMAP (ospf, type) != NULL)
! 1006: {
! 1007: /* if route-map is not NULL it may be using this access list */
! 1008: ospf_distribute_list_update (ospf, type);
! 1009: continue;
! 1010: }
! 1011:
! 1012: /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
! 1013: * but no distribute list. */
! 1014: if (type == ZEBRA_ROUTE_MAX)
! 1015: break;
! 1016:
! 1017: if (DISTRIBUTE_NAME (ospf, type))
! 1018: {
! 1019: /* Keep old access-list for distribute-list. */
! 1020: struct access_list *old = DISTRIBUTE_LIST (ospf, type);
! 1021:
! 1022: /* Update access-list for distribute-list. */
! 1023: DISTRIBUTE_LIST (ospf, type) =
! 1024: access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
! 1025:
! 1026: /* No update for this distribute type. */
! 1027: if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
! 1028: continue;
! 1029:
! 1030: /* Schedule distribute-list update timer. */
! 1031: if (DISTRIBUTE_LIST (ospf, type) == NULL ||
! 1032: strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
! 1033: ospf_distribute_list_update (ospf, type);
! 1034: }
! 1035: }
! 1036:
! 1037: /* Update Area access-list. */
! 1038: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
! 1039: {
! 1040: if (EXPORT_NAME (area))
! 1041: {
! 1042: EXPORT_LIST (area) = NULL;
! 1043: abr_inv++;
! 1044: }
! 1045:
! 1046: if (IMPORT_NAME (area))
! 1047: {
! 1048: IMPORT_LIST (area) = NULL;
! 1049: abr_inv++;
! 1050: }
! 1051: }
! 1052:
! 1053: /* Schedule ABR tasks -- this will be changed -- takada. */
! 1054: if (IS_OSPF_ABR (ospf) && abr_inv)
! 1055: ospf_schedule_abr_task (ospf);
! 1056: }
! 1057:
! 1058: /* If prefix-list is updated, do some updates. */
! 1059: void
! 1060: ospf_prefix_list_update (struct prefix_list *plist)
! 1061: {
! 1062: struct ospf *ospf;
! 1063: int type;
! 1064: int abr_inv = 0;
! 1065: struct ospf_area *area;
! 1066: struct listnode *node;
! 1067:
! 1068: /* If OSPF instatnce does not exist, return right now. */
! 1069: ospf = ospf_lookup ();
! 1070: if (ospf == NULL)
! 1071: return;
! 1072:
! 1073: /* Update all route-maps which are used as redistribution filters.
! 1074: * They might use prefix-list.
! 1075: */
! 1076: for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
! 1077: {
! 1078: if (ROUTEMAP (ospf, type) != NULL)
! 1079: {
! 1080: /* If route-map is not NULL it may be using this prefix list */
! 1081: ospf_distribute_list_update (ospf, type);
! 1082: continue;
! 1083: }
! 1084: }
! 1085:
! 1086: /* Update area filter-lists. */
! 1087: for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
! 1088: {
! 1089: /* Update filter-list in. */
! 1090: if (PREFIX_NAME_IN (area))
! 1091: if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
! 1092: {
! 1093: PREFIX_LIST_IN (area) =
! 1094: prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
! 1095: abr_inv++;
! 1096: }
! 1097:
! 1098: /* Update filter-list out. */
! 1099: if (PREFIX_NAME_OUT (area))
! 1100: if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
! 1101: {
! 1102: PREFIX_LIST_IN (area) =
! 1103: prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
! 1104: abr_inv++;
! 1105: }
! 1106: }
! 1107:
! 1108: /* Schedule ABR task. */
! 1109: if (IS_OSPF_ABR (ospf) && abr_inv)
! 1110: ospf_schedule_abr_task (ospf);
! 1111: }
! 1112:
! 1113: static struct ospf_distance *
! 1114: ospf_distance_new (void)
! 1115: {
! 1116: return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
! 1117: }
! 1118:
! 1119: static void
! 1120: ospf_distance_free (struct ospf_distance *odistance)
! 1121: {
! 1122: XFREE (MTYPE_OSPF_DISTANCE, odistance);
! 1123: }
! 1124:
! 1125: int
! 1126: ospf_distance_set (struct vty *vty, struct ospf *ospf,
! 1127: const char *distance_str,
! 1128: const char *ip_str,
! 1129: const char *access_list_str)
! 1130: {
! 1131: int ret;
! 1132: struct prefix_ipv4 p;
! 1133: u_char distance;
! 1134: struct route_node *rn;
! 1135: struct ospf_distance *odistance;
! 1136:
! 1137: ret = str2prefix_ipv4 (ip_str, &p);
! 1138: if (ret == 0)
! 1139: {
! 1140: vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
! 1141: return CMD_WARNING;
! 1142: }
! 1143:
! 1144: distance = atoi (distance_str);
! 1145:
! 1146: /* Get OSPF distance node. */
! 1147: rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
! 1148: if (rn->info)
! 1149: {
! 1150: odistance = rn->info;
! 1151: route_unlock_node (rn);
! 1152: }
! 1153: else
! 1154: {
! 1155: odistance = ospf_distance_new ();
! 1156: rn->info = odistance;
! 1157: }
! 1158:
! 1159: /* Set distance value. */
! 1160: odistance->distance = distance;
! 1161:
! 1162: /* Reset access-list configuration. */
! 1163: if (odistance->access_list)
! 1164: {
! 1165: free (odistance->access_list);
! 1166: odistance->access_list = NULL;
! 1167: }
! 1168: if (access_list_str)
! 1169: odistance->access_list = strdup (access_list_str);
! 1170:
! 1171: return CMD_SUCCESS;
! 1172: }
! 1173:
! 1174: int
! 1175: ospf_distance_unset (struct vty *vty, struct ospf *ospf,
! 1176: const char *distance_str,
! 1177: const char *ip_str, char
! 1178: const *access_list_str)
! 1179: {
! 1180: int ret;
! 1181: struct prefix_ipv4 p;
! 1182: u_char distance;
! 1183: struct route_node *rn;
! 1184: struct ospf_distance *odistance;
! 1185:
! 1186: ret = str2prefix_ipv4 (ip_str, &p);
! 1187: if (ret == 0)
! 1188: {
! 1189: vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
! 1190: return CMD_WARNING;
! 1191: }
! 1192:
! 1193: distance = atoi (distance_str);
! 1194:
! 1195: rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
! 1196: if (!rn)
! 1197: {
! 1198: vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
! 1199: return CMD_WARNING;
! 1200: }
! 1201:
! 1202: odistance = rn->info;
! 1203:
! 1204: if (odistance->access_list)
! 1205: free (odistance->access_list);
! 1206: ospf_distance_free (odistance);
! 1207:
! 1208: rn->info = NULL;
! 1209: route_unlock_node (rn);
! 1210: route_unlock_node (rn);
! 1211:
! 1212: return CMD_SUCCESS;
! 1213: }
! 1214:
! 1215: void
! 1216: ospf_distance_reset (struct ospf *ospf)
! 1217: {
! 1218: struct route_node *rn;
! 1219: struct ospf_distance *odistance;
! 1220:
! 1221: for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
! 1222: if ((odistance = rn->info) != NULL)
! 1223: {
! 1224: if (odistance->access_list)
! 1225: free (odistance->access_list);
! 1226: ospf_distance_free (odistance);
! 1227: rn->info = NULL;
! 1228: route_unlock_node (rn);
! 1229: }
! 1230: }
! 1231:
! 1232: u_char
! 1233: ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
! 1234: {
! 1235: struct ospf *ospf;
! 1236:
! 1237: ospf = ospf_lookup ();
! 1238: if (ospf == NULL)
! 1239: return 0;
! 1240:
! 1241: if (ospf->distance_intra)
! 1242: if (or->path_type == OSPF_PATH_INTRA_AREA)
! 1243: return ospf->distance_intra;
! 1244:
! 1245: if (ospf->distance_inter)
! 1246: if (or->path_type == OSPF_PATH_INTER_AREA)
! 1247: return ospf->distance_inter;
! 1248:
! 1249: if (ospf->distance_external)
! 1250: if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
! 1251: || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
! 1252: return ospf->distance_external;
! 1253:
! 1254: if (ospf->distance_all)
! 1255: return ospf->distance_all;
! 1256:
! 1257: return 0;
! 1258: }
! 1259:
! 1260: void
! 1261: ospf_zebra_init ()
! 1262: {
! 1263: /* Allocate zebra structure. */
! 1264: zclient = zclient_new ();
! 1265: zclient_init (zclient, ZEBRA_ROUTE_OSPF);
! 1266: zclient->router_id_update = ospf_router_id_update_zebra;
! 1267: zclient->interface_add = ospf_interface_add;
! 1268: zclient->interface_delete = ospf_interface_delete;
! 1269: zclient->interface_up = ospf_interface_state_up;
! 1270: zclient->interface_down = ospf_interface_state_down;
! 1271: zclient->interface_address_add = ospf_interface_address_add;
! 1272: zclient->interface_address_delete = ospf_interface_address_delete;
! 1273: zclient->ipv4_route_add = ospf_zebra_read_ipv4;
! 1274: zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
! 1275:
! 1276: access_list_add_hook (ospf_filter_update);
! 1277: access_list_delete_hook (ospf_filter_update);
! 1278: prefix_list_add_hook (ospf_prefix_list_update);
! 1279: prefix_list_delete_hook (ospf_prefix_list_update);
! 1280: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>