Exemplo n.º 1
0
/* Update external reachability info of area for a given level
 * and prefix, using the given redistribution settings. */
static void
isis_redist_update_ext_reach(struct isis_area *area, int level,
                             struct isis_redist *redist, struct prefix *p,
                             struct isis_ext_info *info)
{
  struct isis_ext_info area_info;
  route_map_result_t map_ret;

  memcpy(&area_info, info, sizeof(area_info));
  if (redist->metric != 0xffffffff)
    area_info.metric = redist->metric;

  if (redist->map_name)
    {
      map_ret = route_map_apply(redist->map, p, RMAP_ISIS, &area_info);
      if (map_ret == RMAP_DENYMATCH)
        area_info.distance = 255;
    }

  /* Allow synthesized default routes only on always orignate */
  if (area_info.origin == DEFAULT_ROUTE
      && redist->redist != DEFAULT_ORIGINATE_ALWAYS)
    area_info.distance = 255;

  if (area_info.distance < 255)
    isis_redist_install(area, level, p, &area_info);
  else
    isis_redist_uninstall(area, level, p);
}
Exemplo n.º 2
0
void
ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
                             u_int nexthop_num, struct in6_addr *nexthop)
{
  int ret;
  struct ospf6_route troute;
  struct ospf6_external_info tinfo;
  struct ospf6_route *route, *match;
  struct ospf6_external_info *info;
  struct prefix prefix_id;
  struct route_node *node;
  char pbuf[64], ibuf[16];
  struct listnode *lnode, *lnnode;
  struct ospf6_area *oa;

  if (! ospf6_zebra_is_redistribute (type))
    return;

  if (IS_OSPF6_DEBUG_ASBR)
    {
      prefix2str (prefix, pbuf, sizeof (pbuf));
      zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
    }

  /* if route-map was specified but not found, do not advertise */
  if (ospf6->rmap[type].name)
    {
      if (ospf6->rmap[type].map == NULL)
        ospf6_asbr_routemap_update (NULL);
      if (ospf6->rmap[type].map == NULL)
        {
          zlog_warn ("route-map \"%s\" not found, suppress redistributing",
                     ospf6->rmap[type].name);
          return;
        }
    }

  /* apply route-map */
  if (ospf6->rmap[type].map)
    {
      memset (&troute, 0, sizeof (troute));
      memset (&tinfo, 0, sizeof (tinfo));
      troute.route_option = &tinfo;

      ret = route_map_apply (ospf6->rmap[type].map, prefix,
                             RMAP_OSPF6, &troute);
      if (ret == RMAP_DENYMATCH)
        {
          if (IS_OSPF6_DEBUG_ASBR)
            zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
          return;
        }
    }

  match = ospf6_route_lookup (prefix, ospf6->external_table);
  if (match)
    {
      info = match->route_option;

      /* copy result of route-map */
      if (ospf6->rmap[type].map)
        {
          if (troute.path.metric_type)
            match->path.metric_type = troute.path.metric_type;
          if (troute.path.cost)
            match->path.cost = troute.path.cost;
          if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
            memcpy (&info->forwarding, &tinfo.forwarding,
                    sizeof (struct in6_addr));
        }

      info->type = type;
      match->nexthop[0].ifindex = ifindex;
      if (nexthop_num && nexthop)
        memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));

      /* create/update binding in external_id_table */
      prefix_id.family = AF_INET;
      prefix_id.prefixlen = 32;
      prefix_id.u.prefix4.s_addr = htonl (info->id);
      node = route_node_get (ospf6->external_id_table, &prefix_id);
      node->info = match;

      if (IS_OSPF6_DEBUG_ASBR)
        {
          inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
          zlog_debug ("Advertise as AS-External Id:%s", ibuf);
        }

      match->path.origin.id = htonl (info->id);
      ospf6_as_external_lsa_originate (match);
      return;
    }

  /* create new entry */
  route = ospf6_route_create ();
  route->type = OSPF6_DEST_TYPE_NETWORK;
  memcpy (&route->prefix, prefix, sizeof (struct prefix));

  info = (struct ospf6_external_info *)
    XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
  route->route_option = info;
  info->id = ospf6->external_id++;

  /* copy result of route-map */
  if (ospf6->rmap[type].map)
    {
      if (troute.path.metric_type)
        route->path.metric_type = troute.path.metric_type;
      if (troute.path.cost)
        route->path.cost = troute.path.cost;
      if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
        memcpy (&info->forwarding, &tinfo.forwarding,
                sizeof (struct in6_addr));
    }

  info->type = type;
  route->nexthop[0].ifindex = ifindex;
  if (nexthop_num && nexthop)
    memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));

  /* create/update binding in external_id_table */
  prefix_id.family = AF_INET;
  prefix_id.prefixlen = 32;
  prefix_id.u.prefix4.s_addr = htonl (info->id);
  node = route_node_get (ospf6->external_id_table, &prefix_id);
  node->info = route;

  route = ospf6_route_add (route, ospf6->external_table);
  route->route_option = info;

  if (IS_OSPF6_DEBUG_ASBR)
    {
      inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
      zlog_debug ("Advertise as AS-External Id:%s", ibuf);
    }

  route->path.origin.id = htonl (info->id);
  ospf6_as_external_lsa_originate (route);

  /* Router-Bit (ASBR Flag) may have to be updated */
  for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
    OSPF6_ROUTER_LSA_SCHEDULE (oa);
}