Пример #1
0
void
ospf6_abr_enable_area (struct ospf6_area *area)
{
  struct ospf6_area *oa;
  struct ospf6_route *ro;
  struct listnode *node, *nnode;

  for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
    {
      /* update B bit for each area */
      OSPF6_ROUTER_LSA_SCHEDULE (oa);

      /* install other area's configured address range */
      if (oa != area)
        {
          for (ro = ospf6_route_head (oa->range_table); ro;
               ro = ospf6_route_next (ro))
            {
              if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
                ospf6_abr_originate_summary_to_area (ro, area);
            }
        }
    }

  /* install calculated routes to border routers */
  for (ro = ospf6_route_head (area->ospf6->brouter_table); ro;
       ro = ospf6_route_next (ro))
    ospf6_abr_originate_summary_to_area (ro, area);

  /* install calculated routes to network (may be rejected by ranges) */
  for (ro = ospf6_route_head (area->ospf6->route_table); ro;
       ro = ospf6_route_next (ro))
    ospf6_abr_originate_summary_to_area (ro, area);
}
Пример #2
0
static void ospf6_neighbor_state_change(u_char next_state, struct ospf6_neighbor * on)
{
  u_char prev_state;

  prev_state = on->state;
  on->state = next_state;

  if(prev_state == next_state)
    return;

  if(IS_OSPF6_SIBLING_DEBUG_NEIGHBOR)
  {
    zlog_debug("Neighbor state change %s: [%s]->[%s]", on->name, ospf6_neighbor_state_str[prev_state], ospf6_neighbor_state_str[next_state]);
  }

  if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
  {
    struct ospf6_area_hostnum * ah = calloc(1, sizeof(struct ospf6_area_hostnum));

    ah->oa = on->ospf6_if->area;
    ah->hostnum = on->ospf6_if->ctrl_client->hostnum;

    OSPF6_ROUTER_LSA_SCHEDULE (ah);
    if(on->ospf6_if->state == OSPF6_INTERFACE_DR)
    {
//       OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
    }
//    OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
  }
}
Пример #3
0
void
ospf6_abr_disable_area (struct ospf6_area *area)
{
  struct ospf6_area *oa;
  struct ospf6_route *ro;
  struct ospf6_lsa *old;
  struct listnode *node, *nnode;

  /* Withdraw all summary prefixes previously originated */
  for (ro = ospf6_route_head (area->summary_prefix); ro;
       ro = ospf6_route_next (ro))
    {
      old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
                               area->ospf6->router_id, area->lsdb);
      if (old)
        ospf6_lsa_purge (old);
      ospf6_route_remove (ro, area->summary_prefix);
    }

  /* Withdraw all summary router-routes previously originated */
  for (ro = ospf6_route_head (area->summary_router); ro;
       ro = ospf6_route_next (ro))
    {
      old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
                               area->ospf6->router_id, area->lsdb);
      if (old)
        ospf6_lsa_purge (old);
      ospf6_route_remove (ro, area->summary_router);
    }

  /* Schedule Router-LSA for each area (ABR status may change) */
  for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
    /* update B bit for each area */
    OSPF6_ROUTER_LSA_SCHEDULE (oa);
}
Пример #4
0
static void
ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
{
    u_char prev_state;

    prev_state = oi->state;
    oi->state = next_state;

    if (prev_state == next_state)
        return;

    /* log */
    if (IS_OSPF6_DEBUG_INTERFACE)
    {
        zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name,
                    ospf6_interface_state_str[prev_state],
                    ospf6_interface_state_str[next_state]);
    }
    oi->state_change++;

    if ((prev_state == OSPF6_INTERFACE_DR ||
            prev_state == OSPF6_INTERFACE_BDR) &&
            (next_state != OSPF6_INTERFACE_DR &&
             next_state != OSPF6_INTERFACE_BDR))
        ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
    if ((prev_state != OSPF6_INTERFACE_DR &&
            prev_state != OSPF6_INTERFACE_BDR) &&
            (next_state == OSPF6_INTERFACE_DR ||
             next_state == OSPF6_INTERFACE_BDR))
        ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP);

    OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
    if (next_state == OSPF6_INTERFACE_DOWN)
    {
        OSPF6_NETWORK_LSA_EXECUTE (oi);
        OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
        OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
    }
    else if (prev_state == OSPF6_INTERFACE_DR ||
             next_state == OSPF6_INTERFACE_DR)
    {
        OSPF6_NETWORK_LSA_SCHEDULE (oi);
        OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
        OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
    }

#ifdef HAVE_SNMP
    /* Terminal state or regression */
    if ((next_state == OSPF6_INTERFACE_POINTTOPOINT) ||
            (next_state == OSPF6_INTERFACE_DROTHER) ||
            (next_state == OSPF6_INTERFACE_BDR) ||
            (next_state == OSPF6_INTERFACE_DR) ||
            (next_state < prev_state))
        ospf6TrapIfStateChange (oi);
#endif

}
Пример #5
0
static void
ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
{
  u_char prev_state;

  prev_state = on->state;
  on->state = next_state;

  if (prev_state == next_state)
    return;

  gettimeofday (&on->last_changed, (struct timezone *) NULL);

  /* log */
  if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
    {
      zlog_info ("Neighbor state change %s: [%s]->[%s]", on->name,
                 ospf6_neighbor_state_str[prev_state],
                 ospf6_neighbor_state_str[next_state]);
    }

  if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
    {
      OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
      if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
        {
          OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
          OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
        }
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
    }

#ifdef XXX
  if (prev_state == NBS_FULL || next_state == NBS_FULL)
    nbs_full_change (on->ospf6_interface);

  /* check for LSAs that already reached MaxAge */
  if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
       prev_state == OSPF6_NEIGHBOR_LOADING) &&
      (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
       next_state != OSPF6_NEIGHBOR_LOADING))
    {
      ospf6_maxage_remover ();
    }
#endif /*XXX*/

}
Пример #6
0
static void
ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
{
  u_char prev_state;

  prev_state = oi->state;
  oi->state = next_state;

  if (prev_state == next_state)
    return;

  /* log */
  if (IS_OSPF6_DEBUG_INTERFACE)
    {
      zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name,
		  ospf6_interface_state_str[prev_state],
		  ospf6_interface_state_str[next_state]);
    }

  if ((prev_state == OSPF6_INTERFACE_DR ||
       prev_state == OSPF6_INTERFACE_BDR) &&
      (next_state != OSPF6_INTERFACE_DR &&
       next_state != OSPF6_INTERFACE_BDR))
    ospf6_leave_alldrouters (oi->interface->ifindex);
  if ((prev_state != OSPF6_INTERFACE_DR &&
       prev_state != OSPF6_INTERFACE_BDR) &&
      (next_state == OSPF6_INTERFACE_DR ||
       next_state == OSPF6_INTERFACE_BDR))
//    ospf6_join_alldrouters (oi->interface->ifindex);
      thread_add_event (master, rospf6_join_alldrouters_send, oi, 0);

  OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
  if (next_state == OSPF6_INTERFACE_DOWN)
    {
      OSPF6_NETWORK_LSA_EXECUTE (oi);
      OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
    }
  else if (prev_state == OSPF6_INTERFACE_DR ||
           next_state == OSPF6_INTERFACE_DR)
    {
      OSPF6_NETWORK_LSA_SCHEDULE (oi);
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
    }
}
Пример #7
0
static void
ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
{
  u_char prev_state;

  prev_state = oi->state;
  oi->state = next_state;

  if (prev_state == next_state)
    return;

  /* log */
  if (IS_OSPF6_DEBUG_INTERFACE)
    {
      zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name,
		  ospf6_interface_state_str[prev_state],
		  ospf6_interface_state_str[next_state]);
    }

  if ((prev_state == OSPF6_INTERFACE_DR ||
       prev_state == OSPF6_INTERFACE_BDR) &&
      (next_state != OSPF6_INTERFACE_DR &&
       next_state != OSPF6_INTERFACE_BDR))
    ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
  if ((prev_state != OSPF6_INTERFACE_DR &&
       prev_state != OSPF6_INTERFACE_BDR) &&
      (next_state == OSPF6_INTERFACE_DR ||
       next_state == OSPF6_INTERFACE_BDR))
    ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP);

  OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
  if (next_state == OSPF6_INTERFACE_DOWN)
    {
      OSPF6_NETWORK_LSA_EXECUTE (oi);
      OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
    }
  else if (prev_state == OSPF6_INTERFACE_DR ||
           next_state == OSPF6_INTERFACE_DR)
    {
      OSPF6_NETWORK_LSA_SCHEDULE (oi);
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
      OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
    }
}
Пример #8
0
void
ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
{
  struct ospf6_route *match;
  struct ospf6_external_info *info = NULL;
  struct route_node *node;
  struct ospf6_lsa *lsa;
  struct prefix prefix_id;
  char pbuf[64], ibuf[16];
  struct listnode *lnode, *lnnode;
  struct ospf6_area *oa;

  match = ospf6_route_lookup (prefix, ospf6->external_table);
  if (match == NULL)
    {
      if (IS_OSPF6_DEBUG_ASBR)
        {
          prefix2str (prefix, pbuf, sizeof (pbuf));
          zlog_debug ("No such route %s to withdraw", pbuf);
        }
      return;
    }

  info = match->route_option;
  assert (info);

  if (info->type != type)
    {
      if (IS_OSPF6_DEBUG_ASBR)
        {
          prefix2str (prefix, pbuf, sizeof (pbuf));
          zlog_debug ("Original protocol mismatch: %s", pbuf);
        }
      return;
    }

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

  lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
                           htonl (info->id), ospf6->router_id, ospf6->lsdb);
  if (lsa)
    ospf6_lsa_purge (lsa);

  /* remove 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_lookup (ospf6->external_id_table, &prefix_id);
  assert (node);
  node->info = NULL;
  route_unlock_node (node);

  ospf6_route_remove (match, ospf6->external_table);
  XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);

  /* Router-Bit (ASBR Flag) may have to be updated */
  for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
    OSPF6_ROUTER_LSA_SCHEDULE (oa);
}
Пример #9
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);
}