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>