Annotation of embedaddon/quagga/ospfd/ospf_asbr.c, revision 1.1
1.1 ! misho 1: /*
! 2: * OSPF AS Boundary Router functions.
! 3: * Copyright (C) 1999, 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 Free
! 19: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
! 20: * 02111-1307, USA.
! 21: */
! 22:
! 23: #include <zebra.h>
! 24:
! 25: #include "thread.h"
! 26: #include "memory.h"
! 27: #include "linklist.h"
! 28: #include "prefix.h"
! 29: #include "if.h"
! 30: #include "table.h"
! 31: #include "vty.h"
! 32: #include "filter.h"
! 33: #include "log.h"
! 34:
! 35: #include "ospfd/ospfd.h"
! 36: #include "ospfd/ospf_interface.h"
! 37: #include "ospfd/ospf_asbr.h"
! 38: #include "ospfd/ospf_lsa.h"
! 39: #include "ospfd/ospf_lsdb.h"
! 40: #include "ospfd/ospf_neighbor.h"
! 41: #include "ospfd/ospf_spf.h"
! 42: #include "ospfd/ospf_flood.h"
! 43: #include "ospfd/ospf_route.h"
! 44: #include "ospfd/ospf_zebra.h"
! 45: #include "ospfd/ospf_dump.h"
! 46:
! 47:
! 48: /* Remove external route. */
! 49: void
! 50: ospf_external_route_remove (struct ospf *ospf, struct prefix_ipv4 *p)
! 51: {
! 52: struct route_node *rn;
! 53: struct ospf_route *or;
! 54:
! 55: rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p);
! 56: if (rn)
! 57: if ((or = rn->info))
! 58: {
! 59: zlog_info ("Route[%s/%d]: external path deleted",
! 60: inet_ntoa (p->prefix), p->prefixlen);
! 61:
! 62: /* Remove route from zebra. */
! 63: if (or->type == OSPF_DESTINATION_NETWORK)
! 64: ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or);
! 65:
! 66: ospf_route_free (or);
! 67: rn->info = NULL;
! 68:
! 69: route_unlock_node (rn);
! 70: route_unlock_node (rn);
! 71: return;
! 72: }
! 73:
! 74: zlog_info ("Route[%s/%d]: no such external path",
! 75: inet_ntoa (p->prefix), p->prefixlen);
! 76: }
! 77:
! 78: /* Lookup external route. */
! 79: struct ospf_route *
! 80: ospf_external_route_lookup (struct ospf *ospf,
! 81: struct prefix_ipv4 *p)
! 82: {
! 83: struct route_node *rn;
! 84:
! 85: rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p);
! 86: if (rn)
! 87: {
! 88: route_unlock_node (rn);
! 89: if (rn->info)
! 90: return rn->info;
! 91: }
! 92:
! 93: zlog_warn ("Route[%s/%d]: lookup, no such prefix",
! 94: inet_ntoa (p->prefix), p->prefixlen);
! 95:
! 96: return NULL;
! 97: }
! 98:
! 99:
! 100: /* Add an External info for AS-external-LSA. */
! 101: struct external_info *
! 102: ospf_external_info_new (u_char type)
! 103: {
! 104: struct external_info *new;
! 105:
! 106: new = (struct external_info *)
! 107: XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info));
! 108: new->type = type;
! 109:
! 110: ospf_reset_route_map_set_values (&new->route_map_set);
! 111: return new;
! 112: }
! 113:
! 114: static void
! 115: ospf_external_info_free (struct external_info *ei)
! 116: {
! 117: XFREE (MTYPE_OSPF_EXTERNAL_INFO, ei);
! 118: }
! 119:
! 120: void
! 121: ospf_reset_route_map_set_values (struct route_map_set_values *values)
! 122: {
! 123: values->metric = -1;
! 124: values->metric_type = -1;
! 125: }
! 126:
! 127: int
! 128: ospf_route_map_set_compare (struct route_map_set_values *values1,
! 129: struct route_map_set_values *values2)
! 130: {
! 131: return values1->metric == values2->metric &&
! 132: values1->metric_type == values2->metric_type;
! 133: }
! 134:
! 135: /* Add an External info for AS-external-LSA. */
! 136: struct external_info *
! 137: ospf_external_info_add (u_char type, struct prefix_ipv4 p,
! 138: unsigned int ifindex, struct in_addr nexthop)
! 139: {
! 140: struct external_info *new;
! 141: struct route_node *rn;
! 142:
! 143: /* Initialize route table. */
! 144: if (EXTERNAL_INFO (type) == NULL)
! 145: EXTERNAL_INFO (type) = route_table_init ();
! 146:
! 147: rn = route_node_get (EXTERNAL_INFO (type), (struct prefix *) &p);
! 148: /* If old info exists, -- discard new one or overwrite with new one? */
! 149: if (rn)
! 150: if (rn->info)
! 151: {
! 152: route_unlock_node (rn);
! 153: zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
! 154: ospf_redist_string(type),
! 155: inet_ntoa (p.prefix), p.prefixlen);
! 156: /* XFREE (MTYPE_OSPF_TMP, rn->info); */
! 157: return rn->info;
! 158: }
! 159:
! 160: /* Create new External info instance. */
! 161: new = ospf_external_info_new (type);
! 162: new->p = p;
! 163: new->ifindex = ifindex;
! 164: new->nexthop = nexthop;
! 165: new->tag = 0;
! 166:
! 167: rn->info = new;
! 168:
! 169: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
! 170: zlog_debug ("Redistribute[%s]: %s/%d external info created.",
! 171: ospf_redist_string(type),
! 172: inet_ntoa (p.prefix), p.prefixlen);
! 173: return new;
! 174: }
! 175:
! 176: void
! 177: ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
! 178: {
! 179: struct route_node *rn;
! 180:
! 181: rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
! 182: if (rn)
! 183: {
! 184: ospf_external_info_free (rn->info);
! 185: rn->info = NULL;
! 186: route_unlock_node (rn);
! 187: route_unlock_node (rn);
! 188: }
! 189: }
! 190:
! 191: struct external_info *
! 192: ospf_external_info_lookup (u_char type, struct prefix_ipv4 *p)
! 193: {
! 194: struct route_node *rn;
! 195: rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) p);
! 196: if (rn)
! 197: {
! 198: route_unlock_node (rn);
! 199: if (rn->info)
! 200: return rn->info;
! 201: }
! 202:
! 203: return NULL;
! 204: }
! 205:
! 206: struct ospf_lsa *
! 207: ospf_external_info_find_lsa (struct ospf *ospf,
! 208: struct prefix_ipv4 *p)
! 209: {
! 210: struct ospf_lsa *lsa;
! 211: struct as_external_lsa *al;
! 212: struct in_addr mask, id;
! 213:
! 214: lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
! 215: p->prefix, ospf->router_id);
! 216:
! 217: if (!lsa)
! 218: return NULL;
! 219:
! 220: al = (struct as_external_lsa *) lsa->data;
! 221:
! 222: masklen2ip (p->prefixlen, &mask);
! 223:
! 224: if (mask.s_addr != al->mask.s_addr)
! 225: {
! 226: id.s_addr = p->prefix.s_addr | (~mask.s_addr);
! 227: lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
! 228: id, ospf->router_id);
! 229: if (!lsa)
! 230: return NULL;
! 231: }
! 232:
! 233: return lsa;
! 234: }
! 235:
! 236:
! 237: /* Update ASBR status. */
! 238: void
! 239: ospf_asbr_status_update (struct ospf *ospf, u_char status)
! 240: {
! 241: zlog_info ("ASBR[Status:%d]: Update", status);
! 242:
! 243: /* ASBR on. */
! 244: if (status)
! 245: {
! 246: /* Already ASBR. */
! 247: if (IS_OSPF_ASBR (ospf))
! 248: {
! 249: zlog_info ("ASBR[Status:%d]: Already ASBR", status);
! 250: return;
! 251: }
! 252: SET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
! 253: }
! 254: else
! 255: {
! 256: /* Already non ASBR. */
! 257: if (! IS_OSPF_ASBR (ospf))
! 258: {
! 259: zlog_info ("ASBR[Status:%d]: Already non ASBR", status);
! 260: return;
! 261: }
! 262: UNSET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
! 263: }
! 264:
! 265: /* Transition from/to status ASBR, schedule timer. */
! 266: ospf_spf_calculate_schedule (ospf);
! 267: ospf_router_lsa_update (ospf);
! 268: }
! 269:
! 270: void
! 271: ospf_redistribute_withdraw (struct ospf *ospf, u_char type)
! 272: {
! 273: struct route_node *rn;
! 274: struct external_info *ei;
! 275:
! 276: /* Delete external info for specified type. */
! 277: if (EXTERNAL_INFO (type))
! 278: for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
! 279: if ((ei = rn->info))
! 280: if (ospf_external_info_find_lsa (ospf, &ei->p))
! 281: {
! 282: if (is_prefix_default (&ei->p) &&
! 283: ospf->default_originate != DEFAULT_ORIGINATE_NONE)
! 284: continue;
! 285: ospf_external_lsa_flush (ospf, type, &ei->p,
! 286: ei->ifindex /*, ei->nexthop */);
! 287: ospf_external_info_delete (type, ei->p);
! 288: }
! 289: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>