Annotation of embedaddon/quagga/ospfd/ospf_asbr.c, revision 1.1.1.3

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: 
1.1.1.3 ! misho      47: 
1.1       misho      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: 
1.1.1.3 ! misho      99: 
1.1       misho     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;
1.1.1.3 ! misho     125:   values->nexthop.s_addr = -1;
1.1       misho     126: }
                    127: 
                    128: int
                    129: ospf_route_map_set_compare (struct route_map_set_values *values1,
                    130:                            struct route_map_set_values *values2)
                    131: {
                    132:   return values1->metric == values2->metric &&
                    133:     values1->metric_type == values2->metric_type;
                    134: }
                    135: 
                    136: /* Add an External info for AS-external-LSA. */
                    137: struct external_info *
                    138: ospf_external_info_add (u_char type, struct prefix_ipv4 p,
1.1.1.3 ! misho     139:                        ifindex_t ifindex, struct in_addr nexthop)
1.1       misho     140: {
                    141:   struct external_info *new;
                    142:   struct route_node *rn;
                    143: 
                    144:   /* Initialize route table. */
                    145:   if (EXTERNAL_INFO (type) == NULL)
                    146:     EXTERNAL_INFO (type) = route_table_init ();
                    147: 
                    148:   rn = route_node_get (EXTERNAL_INFO (type), (struct prefix *) &p);
                    149:   /* If old info exists, -- discard new one or overwrite with new one? */
                    150:   if (rn)
                    151:     if (rn->info)
                    152:       {
                    153:        route_unlock_node (rn);
                    154:        zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
                    155:                   ospf_redist_string(type),
                    156:                   inet_ntoa (p.prefix), p.prefixlen);
                    157:        /* XFREE (MTYPE_OSPF_TMP, rn->info); */
                    158:        return rn->info;
                    159:       }
                    160: 
                    161:   /* Create new External info instance. */
                    162:   new = ospf_external_info_new (type);
                    163:   new->p = p;
                    164:   new->ifindex = ifindex;
                    165:   new->nexthop = nexthop;
                    166:   new->tag = 0;
                    167: 
1.1.1.3 ! misho     168:   if (rn)
        !           169:     rn->info = new;
1.1       misho     170: 
                    171:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
                    172:     zlog_debug ("Redistribute[%s]: %s/%d external info created.",
                    173:               ospf_redist_string(type),
                    174:               inet_ntoa (p.prefix), p.prefixlen);
                    175:   return new;
                    176: }
                    177: 
                    178: void
                    179: ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
                    180: {
                    181:   struct route_node *rn;
                    182: 
                    183:   rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
                    184:   if (rn)
                    185:     {
                    186:       ospf_external_info_free (rn->info);
                    187:       rn->info = NULL;
                    188:       route_unlock_node (rn);
                    189:       route_unlock_node (rn);
                    190:     }
                    191: }
                    192: 
                    193: struct external_info *
                    194: ospf_external_info_lookup (u_char type, struct prefix_ipv4 *p)
                    195: {
                    196:   struct route_node *rn;
                    197:   rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) p);
                    198:   if (rn)
                    199:     {
                    200:       route_unlock_node (rn);
                    201:       if (rn->info)
                    202:        return rn->info;
                    203:     }
                    204: 
                    205:   return NULL;
                    206: }
                    207: 
                    208: struct ospf_lsa *
                    209: ospf_external_info_find_lsa (struct ospf *ospf,
                    210:                             struct prefix_ipv4 *p)
                    211: {
                    212:   struct ospf_lsa *lsa;
                    213:   struct as_external_lsa *al;
                    214:   struct in_addr mask, id;
                    215: 
                    216:   lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
                    217:                                p->prefix, ospf->router_id);
                    218: 
                    219:   if (!lsa)
                    220:     return NULL;
                    221: 
                    222:   al = (struct as_external_lsa *) lsa->data;
                    223: 
                    224:   masklen2ip (p->prefixlen, &mask);
                    225: 
                    226:   if (mask.s_addr != al->mask.s_addr)
                    227:     {
                    228:       id.s_addr = p->prefix.s_addr | (~mask.s_addr);
                    229:       lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
                    230:                                   id, ospf->router_id);
                    231:       if (!lsa)
                    232:        return NULL;
                    233:     }
                    234: 
                    235:   return lsa;
                    236: }
                    237: 
1.1.1.3 ! misho     238: 
1.1       misho     239: /* Update ASBR status. */
                    240: void
                    241: ospf_asbr_status_update (struct ospf *ospf, u_char status)
                    242: {
                    243:   zlog_info ("ASBR[Status:%d]: Update", status);
                    244: 
                    245:   /* ASBR on. */
                    246:   if (status)
                    247:     {
                    248:       /* Already ASBR. */
                    249:       if (IS_OSPF_ASBR (ospf))
                    250:        {
                    251:          zlog_info ("ASBR[Status:%d]: Already ASBR", status);
                    252:          return;
                    253:        }
                    254:       SET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
                    255:     }
                    256:   else
                    257:     {
                    258:       /* Already non ASBR. */
                    259:       if (! IS_OSPF_ASBR (ospf))
                    260:        {
                    261:          zlog_info ("ASBR[Status:%d]: Already non ASBR", status);
                    262:          return;
                    263:        }
                    264:       UNSET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
                    265:     }
                    266: 
                    267:   /* Transition from/to status ASBR, schedule timer. */
1.1.1.3 ! misho     268:   ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_STATUS_CHANGE);
1.1       misho     269:   ospf_router_lsa_update (ospf);
                    270: }
                    271: 
                    272: void
                    273: ospf_redistribute_withdraw (struct ospf *ospf, u_char type)
                    274: {
                    275:   struct route_node *rn;
                    276:   struct external_info *ei;
                    277: 
                    278:   /* Delete external info for specified type. */
                    279:   if (EXTERNAL_INFO (type))
                    280:     for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
                    281:       if ((ei = rn->info))
                    282:        if (ospf_external_info_find_lsa (ospf, &ei->p))
                    283:          {
                    284:            if (is_prefix_default (&ei->p) &&
                    285:                ospf->default_originate != DEFAULT_ORIGINATE_NONE)
                    286:              continue;
                    287:            ospf_external_lsa_flush (ospf, type, &ei->p,
                    288:                                     ei->ifindex /*, ei->nexthop */);
1.1.1.2   misho     289: 
                    290:            ospf_external_info_free (ei);
                    291:            route_unlock_node (rn);
                    292:            rn->info = NULL;
1.1       misho     293:          }
                    294: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>