File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_asbr.c
Revision 1.1.1.2.2.1: download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 00:08:32 2013 UTC (10 years, 11 months ago) by misho
Branches: v0_99_22p0
Diff to: branchpoint 1.1.1.2: preferred, unified
patch0

    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:   values->nexthop.s_addr = -1;
  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,
  139: 			unsigned int ifindex, struct in_addr nexthop)
  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: 
  168:   rn->info = new;
  169: 
  170:   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
  171:     zlog_debug ("Redistribute[%s]: %s/%d external info created.",
  172: 	       ospf_redist_string(type),
  173: 	       inet_ntoa (p.prefix), p.prefixlen);
  174:   return new;
  175: }
  176: 
  177: void
  178: ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
  179: {
  180:   struct route_node *rn;
  181: 
  182:   rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
  183:   if (rn)
  184:     {
  185:       ospf_external_info_free (rn->info);
  186:       rn->info = NULL;
  187:       route_unlock_node (rn);
  188:       route_unlock_node (rn);
  189:     }
  190: }
  191: 
  192: struct external_info *
  193: ospf_external_info_lookup (u_char type, struct prefix_ipv4 *p)
  194: {
  195:   struct route_node *rn;
  196:   rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) p);
  197:   if (rn)
  198:     {
  199:       route_unlock_node (rn);
  200:       if (rn->info)
  201: 	return rn->info;
  202:     }
  203: 
  204:   return NULL;
  205: }
  206: 
  207: struct ospf_lsa *
  208: ospf_external_info_find_lsa (struct ospf *ospf,
  209: 			     struct prefix_ipv4 *p)
  210: {
  211:   struct ospf_lsa *lsa;
  212:   struct as_external_lsa *al;
  213:   struct in_addr mask, id;
  214: 
  215:   lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
  216: 				p->prefix, ospf->router_id);
  217: 
  218:   if (!lsa)
  219:     return NULL;
  220: 
  221:   al = (struct as_external_lsa *) lsa->data;
  222: 
  223:   masklen2ip (p->prefixlen, &mask);
  224: 
  225:   if (mask.s_addr != al->mask.s_addr)
  226:     {
  227:       id.s_addr = p->prefix.s_addr | (~mask.s_addr);
  228:       lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
  229: 				   id, ospf->router_id);
  230:       if (!lsa)
  231: 	return NULL;
  232:     }
  233: 
  234:   return lsa;
  235: }
  236: 
  237: 
  238: /* Update ASBR status. */
  239: void
  240: ospf_asbr_status_update (struct ospf *ospf, u_char status)
  241: {
  242:   zlog_info ("ASBR[Status:%d]: Update", status);
  243: 
  244:   /* ASBR on. */
  245:   if (status)
  246:     {
  247:       /* Already ASBR. */
  248:       if (IS_OSPF_ASBR (ospf))
  249: 	{
  250: 	  zlog_info ("ASBR[Status:%d]: Already ASBR", status);
  251: 	  return;
  252: 	}
  253:       SET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
  254:     }
  255:   else
  256:     {
  257:       /* Already non ASBR. */
  258:       if (! IS_OSPF_ASBR (ospf))
  259: 	{
  260: 	  zlog_info ("ASBR[Status:%d]: Already non ASBR", status);
  261: 	  return;
  262: 	}
  263:       UNSET_FLAG (ospf->flags, OSPF_FLAG_ASBR);
  264:     }
  265: 
  266:   /* Transition from/to status ASBR, schedule timer. */
  267:   ospf_spf_calculate_schedule (ospf);
  268:   ospf_router_lsa_update (ospf);
  269: }
  270: 
  271: void
  272: ospf_redistribute_withdraw (struct ospf *ospf, u_char type)
  273: {
  274:   struct route_node *rn;
  275:   struct external_info *ei;
  276: 
  277:   /* Delete external info for specified type. */
  278:   if (EXTERNAL_INFO (type))
  279:     for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
  280:       if ((ei = rn->info))
  281: 	if (ospf_external_info_find_lsa (ospf, &ei->p))
  282: 	  {
  283: 	    if (is_prefix_default (&ei->p) &&
  284: 		ospf->default_originate != DEFAULT_ORIGINATE_NONE)
  285: 	      continue;
  286: 	    ospf_external_lsa_flush (ospf, type, &ei->p,
  287: 				     ei->ifindex /*, ei->nexthop */);
  288: 
  289: 	    ospf_external_info_free (ei);
  290: 	    route_unlock_node (rn);
  291: 	    rn->info = NULL;
  292: 	  }
  293: }

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