File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_asbr.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:29 2012 UTC (11 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, HEAD
quagga

    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: 
  288: 	    ospf_external_info_free (ei);
  289: 	    route_unlock_node (rn);
  290: 	    rn->info = NULL;
  291: 	  }
  292: }

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