Exemplo n.º 1
0
void
ospf_abr_process_network_rt (struct ospf *ospf,
			     struct route_table *rt)
{
  struct ospf_area *area;
  struct ospf_route *or;
  struct route_node *rn;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_network_rt(): Start");

  for (rn = route_top (rt); rn; rn = route_next (rn))
    {
      if ((or = rn->info) == NULL)
	continue;

      if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt(): area %s no longer exists",
		       inet_ntoa (or->u.std.area_id));
	  continue;
	}

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_process_network_rt(): this is a route to %s/%d",
		   inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
      if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt(): "
		       "this is an External router, skipping");
	  continue;
	}

      if (or->cost >= OSPF_LS_INFINITY)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt():"
		       " this route's cost is infinity, skipping");
	  continue;
	}

      if (or->type == OSPF_DESTINATION_DISCARD)
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt():"
		       " this is a discard entry, skipping");
	  continue;
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !ospf_abr_should_announce (ospf, &rn->p, or))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info("ospf_abr_process_network_rt(): denied by export-list");
	  continue;
	}

      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !ospf_abr_plist_out_check (area, or, &rn->p))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info("ospf_abr_process_network_rt(): denied by prefix-list");
	  continue;
	}

      if ((or->path_type == OSPF_PATH_INTER_AREA) &&
          !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_info ("ospf_abr_process_network_rt():"
		       " this is route is not backbone one, skipping");
	  continue;
	}


      if ((ospf->abr_type == OSPF_ABR_CISCO) ||
          (ospf->abr_type == OSPF_ABR_IBM))

	if (!ospf_act_bb_connection (ospf) &&
	    or->path_type != OSPF_PATH_INTRA_AREA)
	  {
	    if (IS_DEBUG_OSPF_EVENT)
	      zlog_info ("ospf_abr_process_network_rt(): ALT ABR: "
			 "No BB connection, skip not intra-area routes");
	    continue;
	  }

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_process_network_rt(): announcing");
      ospf_abr_announce_network (ospf, rn, or);
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_network_rt(): Stop");
}
Exemplo n.º 2
0
static void
ospf_update_network_route (struct ospf *ospf,
			   struct route_table *rt, 
                           struct route_table *rtrs,
                           struct summary_lsa *lsa,
                           struct prefix_ipv4 *p,
                           struct ospf_area *area)
{
  struct route_node *rn;
  struct ospf_route *or, *abr_or, *new_or;
  struct prefix_ipv4 abr;
  u_int32_t cost;

  abr.family = AF_INET;
  abr.prefix =lsa->header.adv_router;
  abr.prefixlen = IPV4_MAX_BITLEN;
  apply_mask_ipv4 (&abr);

  abr_or = ospf_find_abr_route (rtrs, &abr, area);

  if (abr_or == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_update_network_route(): can't find a route to the ABR");
      return;
    }

  cost = abr_or->cost + GET_METRIC (lsa->metric);

  rn = route_node_lookup (rt, (struct prefix *) p);

  if (! rn)
    {
      if (ospf->abr_type != OSPF_ABR_SHORTCUT)
        return; /* Standard ABR can update only already installed
                   backbone paths                                       */
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_update_network_route(): "
		   "Allowing Shortcut ABR to add new route");
      new_or = ospf_route_new ();
      new_or->type = OSPF_DESTINATION_NETWORK;
      new_or->id = lsa->header.id;
      new_or->mask = lsa->mask;
      new_or->u.std.options = lsa->header.options;
      new_or->u.std.origin = (struct lsa_header *) lsa;
      new_or->cost = cost;
      new_or->u.std.area_id = area->area_id;
      new_or->u.std.external_routing = area->external_routing;
      new_or->path_type = OSPF_PATH_INTER_AREA;
      ospf_route_add (rt, p, new_or, abr_or);

      return;
    }
  else
    {
      route_unlock_node (rn);
      if (rn->info == NULL)
        return;
    }

  or = rn->info;

  if (or->path_type != OSPF_PATH_INTRA_AREA &&
      or->path_type != OSPF_PATH_INTER_AREA)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_update_network_route(): ERR: path type is wrong");
      return;
    }

  if (ospf->abr_type == OSPF_ABR_SHORTCUT)
    {
      if (or->path_type == OSPF_PATH_INTRA_AREA &&
	  !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("ospf_update_network_route(): Shortcut: "
		       "this intra-area path is not backbone");
	  return;
	}
    }
  else   /* Not Shortcut ABR */
    {
      if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  if (IS_DEBUG_OSPF_EVENT)
	    zlog_debug ("ospf_update_network_route(): "
		       "route is not BB-associated");
	  return; /* We can update only BB routes */
	}
    }

  if (or->cost < cost)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_update_network_route(): new route is worse");
      return;
    }

  if (or->cost == cost)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_update_network_route(): "
		   "new route is same distance, adding nexthops");
      ospf_route_copy_nexthops (or, abr_or->paths);
    }

  if (or->cost > cost)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_update_network_route(): "
		   "new route is better, overriding nexthops");
      ospf_route_subst_nexthops (or, abr_or->paths);
      or->cost = cost;

      if ((ospf->abr_type == OSPF_ABR_SHORTCUT) &&
	  !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	{
	  or->path_type = OSPF_PATH_INTER_AREA;
	  or->u.std.area_id = area->area_id;
	  or->u.std.external_routing = area->external_routing;
          /* Note that we can do this only in Shortcut ABR mode,
             because standard ABR must leave the route type and area
             unchanged
          */
        }
    }
}
Exemplo n.º 3
0
void
ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
{
  struct ospf_route *or;
  struct route_node *rn;
  struct list *l;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_router_rt(): Start");

  for (rn = route_top (rt); rn; rn = route_next (rn))
    {
      listnode node;
      char flag = 0;
      struct ospf_route *best = NULL;

      if (rn->info == NULL)
	continue;

      l = rn->info;

      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_abr_process_router_rt(): this is a route to %s",
		   inet_ntoa (rn->p.u.prefix4));

      for (node = listhead (l); node; nextnode (node))
	{
	  or = getdata (node);
	  if (or == NULL)
	    continue;

	  if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): area %s no longer exists",
			   inet_ntoa (or->u.std.area_id));
	      continue;
	    }


	  if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL))
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): "
			   "This is not an ASBR, skipping");
	      continue;
	    }

	  if (!flag)
	    {
	      best = ospf_find_asbr_route (ospf, rt,
					   (struct prefix_ipv4 *) &rn->p);
	      flag = 1;
	    }
	  
	  if (best == NULL)
	    continue;
	
	  if (or != best)
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): "
			   "This route is not the best among possible, skipping");
	      continue;
	    }
	
	  if (or->path_type == OSPF_PATH_INTER_AREA &&
	      !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id))
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): "
			   "This route is not a backbone one, skipping");
	      continue;
	    }

	  if (or->cost >= OSPF_LS_INFINITY)
	    {
	      if (IS_DEBUG_OSPF_EVENT)
		zlog_info ("ospf_abr_process_router_rt(): "
			   "This route has LS_INFINITY metric, skipping");
	      continue;
	    }

	  if (ospf->abr_type == OSPF_ABR_CISCO
	      || ospf->abr_type == OSPF_ABR_IBM)
	    if (!ospf_act_bb_connection (ospf)
		&& or->path_type != OSPF_PATH_INTRA_AREA)
	      {
		if (IS_DEBUG_OSPF_EVENT)
		  zlog_info("ospf_abr_process_network_rt(): ALT ABR: "
			    "No BB connection, skip not intra-area routes");
		continue;
	      }

	  ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or);

	}

    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("ospf_abr_process_router_rt(): Stop");
}