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);
}
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);
}
Example #3
0
void
ospf6_spf_table_finish (struct ospf6_route_table *result_table)
{
  struct ospf6_route *route;
  struct ospf6_vertex *v;
  for (route = ospf6_route_head (result_table); route;
       route = ospf6_route_next (route))
  {
    v = (struct ospf6_vertex *) route->route_option;
    ospf6_vertex_delete (v);
    ospf6_route_remove (route, result_table);
  }
}
Example #4
0
/* Make new area structure */
struct ospf6_area *
ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
{
  struct ospf6_area *oa;
  struct ospf6_route *route;

  oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));

  inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
  oa->area_id = area_id;
  oa->if_list = list_new ();

  oa->lsdb = ospf6_lsdb_create (oa);
  oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
  oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
  oa->lsdb_self = ospf6_lsdb_create (oa);

  oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
  oa->spf_table->scope = oa;
  oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
  oa->route_table->scope = oa;
  oa->route_table->hook_add = ospf6_area_route_hook_add;
  oa->route_table->hook_remove = ospf6_area_route_hook_remove;

  oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
  oa->range_table->scope = oa;
  oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
  oa->summary_prefix->scope = oa;
  oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
  oa->summary_router->scope = oa;

  /* set default options */
  OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
  OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
  OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);

  oa->ospf6 = o;
  listnode_add_sort (o->area_list, oa);

  /* import athoer area's routes as inter-area routes */
  for (route = ospf6_route_head (o->route_table); route;
       route = ospf6_route_next (route))
    ospf6_abr_originate_summary_to_area (route, oa);

  return oa;
}
Example #5
0
static void
ospf6_asbr_redistribute_unset (int type)
{
  struct ospf6_route *route;
  struct ospf6_external_info *info;

  ospf6_zebra_no_redistribute (type);

  for (route = ospf6_route_head (ospf6->external_table); route;
       route = ospf6_route_next (route))
    {
      info = route->route_option;
      if (info->type != type)
        continue;

      ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
                                      &route->prefix);
    }
}
Example #6
0
static u_char *
ospfv3AreaEntry (struct variable *v, oid *name, size_t *length,
                 int exact, size_t *var_len, WriteMethod **write_method)
{
  struct ospf6_area *oa, *area = NULL;
  struct ospf6_lsa *lsa = NULL;
  u_int32_t area_id = 0;
  u_int32_t count;
  u_int16_t sum;
  struct listnode *node;
  unsigned int len;
  char a[16];
  struct ospf6_route *ro;

  if (ospf6 == NULL)
    return NULL;

  if (smux_header_table(v, name, length, exact, var_len, write_method)
      == MATCH_FAILED)
    return NULL;

  len = *length - v->namelen;
  len = (len >= 1 ? sizeof 1 : 0);
  if (exact && len != 1)
    return NULL;
  if (len)
    area_id  = htonl (name[v->namelen]);

  inet_ntop (AF_INET, &area_id, a, sizeof (a));
  zlog_debug ("SNMP access by area: %s, exact=%d len=%d length=%lu",
	      a, exact, len, (u_long)*length);

  for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
    {
      if (area == NULL)
        {
          if (len == 0) /* return first area entry */
            area = oa;
          else if (exact && ntohl (oa->area_id) == ntohl (area_id))
            area = oa;
          else if (ntohl (oa->area_id) > ntohl (area_id))
            area = oa;
        }
    }

  if (area == NULL)
    return NULL;

  *length = v->namelen + 1;
  name[v->namelen] = ntohl (area->area_id);

  inet_ntop (AF_INET, &area->area_id, a, sizeof (a));
  zlog_debug ("SNMP found area: %s, exact=%d len=%d length=%lu",
	      a, exact, len, (u_long)*length);

  switch (v->magic)
    {
    case OSPFv3IMPORTASEXTERN:
      /* No NSSA support */
      return SNMP_INTEGER (IS_AREA_STUB(area)?2:1);
    case OSPFv3AREASPFRUNS:
      return SNMP_INTEGER (area->spf_calculation);
    case OSPFv3AREABDRRTRCOUNT:
    case OSPFv3AREAASBDRRTRCOUNT:
      count = 0;
      for (ro = ospf6_route_head (ospf6->brouter_table); ro;
	   ro = ospf6_route_next (ro))
        {
          if (ntohl (ro->path.area_id) != ntohl (area->area_id)) continue;
          if (v->magic == OSPFv3AREABDRRTRCOUNT &&
              CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_B))
            count++;
          if (v->magic == OSPFv3AREAASBDRRTRCOUNT &&
              CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_E))
            count++;
        }
      return SNMP_INTEGER (count);
    case OSPFv3AREASCOPELSACOUNT:
      return SNMP_INTEGER (area->lsdb->count);
    case OSPFv3AREASCOPELSACKSUMSUM:
      for (sum = 0, lsa = ospf6_lsdb_head (area->lsdb);
	   lsa;
	   lsa = ospf6_lsdb_next (lsa))
	sum += ntohs (lsa->header->checksum);
      return SNMP_INTEGER (sum);
    case OSPFv3AREASUMMARY:
      return SNMP_INTEGER (2); /* sendAreaSummary */
    case OSPFv3AREAROWSTATUS:
      return SNMP_INTEGER (1); /* Active */
    case OSPFv3AREASTUBMETRIC:
    case OSPFv3AREANSSATRANSLATORROLE:
    case OSPFv3AREANSSATRANSLATORSTATE:
    case OSPFv3AREANSSATRANSLATORSTABINTERVAL:
    case OSPFv3AREANSSATRANSLATOREVENTS:
    case OSPFv3AREASTUBMETRICTYPE:
    case OSPFv3AREATEENABLED:
      /* Not implemented. */
      return NULL;
    }
  return NULL;
}
Example #7
0
static int
ospf6_spf_calculation_thread (struct thread *t)
{
  struct ospf6_area *oa;
  struct ospf6 *ospf6;
  struct timeval start, end, runtime;
  struct listnode *node;
  struct ospf6_route *route;
  int areas_processed = 0;
  char rbuf[32];

  ospf6 = (struct ospf6 *)THREAD_ARG (t);
  ospf6->t_spf_calc = NULL;

  /* execute SPF calculation */
  quagga_gettime (QUAGGA_CLK_MONOTONIC, &start);

  for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa))
    {

      if (oa == ospf6->backbone)
	continue;

      if (IS_OSPF6_DEBUG_SPF (PROCESS))
	zlog_debug ("SPF calculation for Area %s", oa->name);
      if (IS_OSPF6_DEBUG_SPF (DATABASE))
	ospf6_spf_log_database (oa);

      ospf6_spf_calculation (ospf6->router_id, oa->spf_table, oa);
      ospf6_intra_route_calculation (oa);
      ospf6_intra_brouter_calculation (oa);

      areas_processed++;
    }

  if (ospf6->backbone)
    {
      if (IS_OSPF6_DEBUG_SPF (PROCESS))
	zlog_debug ("SPF calculation for Backbone area %s",
		    ospf6->backbone->name);
      if (IS_OSPF6_DEBUG_SPF (DATABASE))
	ospf6_spf_log_database(ospf6->backbone);

      ospf6_spf_calculation(ospf6->router_id, ospf6->backbone->spf_table,
			    ospf6->backbone);
      ospf6_intra_route_calculation(ospf6->backbone);
      ospf6_intra_brouter_calculation(ospf6->backbone);
      areas_processed++;
    }

  /* Redo summaries if required */
  for (route = ospf6_route_head (ospf6->route_table); route;
       route = ospf6_route_next (route))
    ospf6_abr_originate_summary(route);

  quagga_gettime (QUAGGA_CLK_MONOTONIC, &end);
  timersub (&end, &start, &runtime);

  ospf6->ts_spf_duration = runtime;

  ospf6_spf_reason_string(ospf6->spf_reason, rbuf, sizeof(rbuf));

  if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME))
    zlog_debug ("SPF runtime: %lld sec %lld usec",
		(long long)runtime.tv_sec, (long long)runtime.tv_usec);

  zlog_info("SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, "
	    "Reason: %s\n", areas_processed,
	    (long long)runtime.tv_sec, (long long)runtime.tv_usec,
	    rbuf);
  ospf6->last_spf_reason = ospf6->spf_reason;
  ospf6_reset_spf_reason(ospf6);
  return 0;
}