Annotation of embedaddon/quagga/ospfd/ospf_asbr.c, revision 1.1.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>