Пример #1
0
/* Check area border router status. */
void
ospf_check_abr_status (struct ospf *ospf)
{
  struct ospf_area *area;
  listnode node;
  int bb_configured = 0;
  int bb_act_attached = 0;
  int areas_configured = 0;
  int areas_act_attached = 0;
  u_char new_flags = ospf->flags;

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

  for (node = listhead (ospf->areas); node; nextnode (node))
    {
      area = getdata (node);

      if (listcount (area->oiflist)) 
	{
	  areas_configured++;
	  
	  if (OSPF_IS_AREA_BACKBONE (area))
 	    bb_configured = 1;
	}

      if (ospf_area_actively_attached (area))
	{
	  areas_act_attached++;
	  
	  if (OSPF_IS_AREA_BACKBONE (area))
            bb_act_attached = 1;
	}
    }

  if (IS_DEBUG_OSPF_EVENT)
    {
      zlog_info ("ospf_check_abr_status(): looked through areas");
      zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured);
      zlog_info ("ospf_check_abr_status(): bb_act_attached: %d",
		 bb_act_attached);
      zlog_info ("ospf_check_abr_status(): areas_configured: %d",
		 areas_configured);
      zlog_info ("ospf_check_abr_status(): areas_act_attached: %d",
		 areas_act_attached);
    }

  switch (ospf->abr_type)
    {
    case OSPF_ABR_SHORTCUT:
    case OSPF_ABR_STAND:
      if (areas_act_attached > 1)
	SET_FLAG (new_flags, OSPF_FLAG_ABR);
      else
	UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
      break;

    case OSPF_ABR_IBM:
      if ((areas_act_attached > 1) && bb_configured)
	SET_FLAG (new_flags, OSPF_FLAG_ABR);
      else
	UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
      break;

    case OSPF_ABR_CISCO:
      if ((areas_configured > 1) && bb_act_attached)
	SET_FLAG (new_flags, OSPF_FLAG_ABR);
      else
	UNSET_FLAG (new_flags, OSPF_FLAG_ABR);
      break;
    default:
      break;
    }

  if (new_flags != ospf->flags)
    {
      ospf_spf_calculate_schedule (ospf);
      if (IS_DEBUG_OSPF_EVENT)
	zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags);
      ospf->flags = new_flags;
      OSPF_TIMER_ON (ospf->t_router_lsa_update,
		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
    }
}
Пример #2
0
static void
isis_zebra_route_add_ipv4 (struct prefix *prefix,
			   struct isis_route_info *route_info)
{
  u_char message, flags;
  int psize;
  struct stream *stream;
  struct isis_nexthop *nexthop;
  struct listnode *node;

  if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
    return;

  if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
    {
      message = 0;
      flags = 0;

      SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
      SET_FLAG (message, ZAPI_MESSAGE_METRIC);
#if 0
      SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
#endif

      stream = zclient->obuf;
      stream_reset (stream);
      zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
      /* type */
      stream_putc (stream, ZEBRA_ROUTE_ISIS);
      /* flags */
      stream_putc (stream, flags);
      /* message */
      stream_putc (stream, message);
      /* SAFI */
      stream_putw (stream, SAFI_UNICAST);
      /* prefix information */
      psize = PSIZE (prefix->prefixlen);
      stream_putc (stream, prefix->prefixlen);
      stream_write (stream, (u_char *) & prefix->u.prefix4, psize);

      stream_putc (stream, listcount (route_info->nexthops));

      /* Nexthop, ifindex, distance and metric information */
      for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
	{
	  /* FIXME: can it be ? */
	  if (nexthop->ip.s_addr != INADDR_ANY)
	    {
	      stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
	      stream_put_in_addr (stream, &nexthop->ip);
	    }
	  else
	    {
	      stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
	      stream_putl (stream, nexthop->ifindex);
	    }
	}
#if 0
      if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
	stream_putc (stream, route_info->depth);
#endif
      if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
	stream_putl (stream, route_info->cost);

      stream_putw_at (stream, 0, stream_get_endp (stream));
      zclient_send_message(zclient);
      SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
      UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
    }
Пример #3
0
/* Send ECMP routes to zebra. */
static void
ripng_zebra_ipv6_send (struct route_node *rp, u_char cmd)
{
  static struct in6_addr **nexthops = NULL;
  static unsigned int *ifindexes = NULL;
  static unsigned int nexthops_len = 0;

  struct list *list = (struct list *)rp->info;
  struct zapi_ipv6 api;
  struct listnode *listnode = NULL;
  struct ripng_info *rinfo = NULL;
  int count = 0;

  if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIPNG], VRF_DEFAULT))
    {
      api.vrf_id = VRF_DEFAULT;
      api.type = ZEBRA_ROUTE_RIPNG;
      api.flags = 0;
      api.message = 0;
      api.safi = SAFI_UNICAST;

      if (nexthops_len < listcount (list))
        {
          nexthops_len = listcount (list);
          nexthops = XREALLOC (MTYPE_TMP, nexthops,
                               nexthops_len * sizeof (struct in6_addr *));
          ifindexes = XREALLOC (MTYPE_TMP, ifindexes,
                                nexthops_len * sizeof (unsigned int));
        }

      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
      for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
        {
          nexthops[count] = &rinfo->nexthop;
          ifindexes[count] = rinfo->ifindex;
          count++;
          if (cmd == ZEBRA_IPV6_ROUTE_ADD)
            SET_FLAG (rinfo->flags, RIPNG_RTF_FIB);
          else
            UNSET_FLAG (rinfo->flags, RIPNG_RTF_FIB);
        }

      api.nexthop = nexthops;
      api.nexthop_num = count;
      api.ifindex = ifindexes;
      api.ifindex_num = count;

      rinfo = listgetdata (listhead (list));

      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = rinfo->metric;

      zapi_ipv6_route (cmd, zclient,
                       (struct prefix_ipv6 *)&rp->p, &api);

      if (IS_RIPNG_DEBUG_ZEBRA)
        {
          if (ripng->ecmp)
            zlog_debug ("%s: %s/%d nexthops %d",
                        (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \
                            "Install into zebra" : "Delete from zebra",
                        inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen, count);
          else
            zlog_debug ("%s: %s/%d",
                        (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \
                            "Install into zebra" : "Delete from zebra",
                        inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen);
        }
    }
Пример #4
0
    if (listnode_lookup (parent->children, vertex) == NULL)
      listnode_add (parent->children, vertex);
  }

  if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) {
    for (ALL_LIST_ELEMENTS_RO (parent->Adj_N, node, parent_adj))
      listnode_add (vertex->Adj_N, parent_adj);
  } else if (adj) {
    listnode_add (vertex->Adj_N, adj);
  }

#ifdef EXTREME_DEBUG
  zlog_debug ("ISIS-Spf: add to TENT %s %s %s depth %d dist %d adjcount %d",
              print_sys_hostname (vertex->N.id),
	      vtype2string (vertex->type), vid2string (vertex, buff),
	      vertex->depth, vertex->d_N, listcount(vertex->Adj_N));
#endif /* EXTREME_DEBUG */

  if (list_isempty (spftree->tents))
    {
      listnode_add (spftree->tents, vertex);
      return vertex;
    }

  /* XXX: This cant use the standard ALL_LIST_ELEMENTS macro */
  for (node = listhead (spftree->tents); node; node = listnextnode (node))
    {
      v = listgetdata (node);
      if (v->d_N > vertex->d_N)
	{
	  list_add_node_prev (spftree->tents, node, vertex);
Пример #5
0
unsigned int
number_of_listeners (void)
{
  return listcount(sm->listen_sockets);
}
Пример #6
0
static void
bgp_dump_routes_index_table(struct bgp *bgp)
{
  struct peer *peer;
  struct listnode *node;
  uint16_t peerno = 0;
  struct stream *obuf;

  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  /* MRT header */
  bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE);

  /* Collector BGP ID */
  stream_put_in_addr (obuf, &bgp->router_id);

  /* View name */
  if(bgp->name)
    {
      stream_putw (obuf, strlen(bgp->name));
      stream_put(obuf, bgp->name, strlen(bgp->name));
    }
  else
    {
      stream_putw(obuf, 0);
    }

  /* Peer count */
  stream_putw (obuf, listcount(bgp->peer));

  /* Walk down all peers */
  for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
    {

      /* Peer's type */
      if (sockunion_family(&peer->su) == AF_INET)
        {
          stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
        }
#ifdef HAVE_IPV6
      else if (sockunion_family(&peer->su) == AF_INET6)
        {
          stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
        }
#endif /* HAVE_IPV6 */

      /* Peer's BGP ID */
      stream_put_in_addr (obuf, &peer->remote_id);

      /* Peer's IP address */
      if (sockunion_family(&peer->su) == AF_INET)
        {
          stream_put_in_addr (obuf, &peer->su.sin.sin_addr);
        }
#ifdef HAVE_IPV6
      else if (sockunion_family(&peer->su) == AF_INET6)
        {
          stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr,
                        IPV6_MAX_BYTELEN);
        }
#endif /* HAVE_IPV6 */

      /* Peer's AS number. */
      /* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */
      stream_putl (obuf, peer->as);

      /* Store the peer number for this peer */
      peer->table_dump_index = peerno;
      peerno++;
    }

  bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);

  fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
  fflush (bgp_dump_routes.fp);
}
Пример #7
0
int
area_net_title (struct isis_area *area, const u_char *net_title)
{
  struct area_addr *addr;
  struct area_addr *addrp;
  struct listnode *node;

  u_char buff[255];

  if (!area)
    {
      Log(LOG_WARNING, "WARN ( %s/core/ISIS ): Can't find ISIS instance\n", config.name);
      return TRUE;
    }

  /* We check that we are not over the maximal number of addresses */
  if (listcount (area->area_addrs) >= isis->max_area_addrs)
    {
      Log(LOG_WARNING, "WARN ( %s/core/ISIS ): Maximum of area addresses (%d) already reached\n",
	       config.name, isis->max_area_addrs);
      return TRUE;
    }

  addr = calloc(1, sizeof (struct area_addr));
  addr->addr_len = dotformat2buff (buff, net_title);
  memcpy (addr->area_addr, buff, addr->addr_len);
  if (addr->addr_len < 8 || addr->addr_len > 20)
    {
      Log(LOG_WARNING, "WARN ( %s/core/ISIS ): area address must be at least 8..20 octets long (%d)\n",
		 config.name, addr->addr_len);
      free(addr);
      return TRUE;
    }

  if (isis->sysid_set == 0)
    {
      /*
       * First area address - get the SystemID for this router
       */
      memcpy (isis->sysid, GETSYSID (addr, ISIS_SYS_ID_LEN), ISIS_SYS_ID_LEN);
      isis->sysid_set = 1;
      Log(LOG_DEBUG, "DEBUG ( %s/core/ISIS ): Router has SystemID %s\n", config.name, sysid_print (isis->sysid));
    }
  else
    {
      /*
       * Check that the SystemID portions match
       */
      if (memcmp (isis->sysid, GETSYSID (addr, ISIS_SYS_ID_LEN),
		  ISIS_SYS_ID_LEN))
	{
	  Log(LOG_WARNING, "WARN ( %s/core/ISIS ): System ID must not change when defining additional area addresses\n", config.name);
	  free(addr);
	  return TRUE;
	}

      /* now we see that we don't already have this address */
      for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp))
	{
	  if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) != (addr->addr_len))
	    continue;
	  if (!memcmp (addrp->area_addr, addr->area_addr, addr->addr_len))
	    {
	      free(addr);
	      return FALSE;	/* silent fail */
	    }
	}

    }
  /*
   * Forget the systemID part of the address
   */
  addr->addr_len -= (ISIS_SYS_ID_LEN + 1);
  isis_listnode_add (area->area_addrs, addr);

  /* Only now we can safely generate our LSPs for this area */
  if (listcount (area->area_addrs) > 0)
    {
      lsp_l1_generate (area);
      lsp_l2_generate (area);
    }

  return FALSE;
}
Пример #8
0
int
isis_dr_elect (struct isis_circuit *circuit, int level)
{
  struct list *adjdb;
  struct listnode *node;
  struct isis_adjacency *adj, *adj_dr = NULL;
  struct list *list = list_new ();
  u_char own_prio;
  int biggest_prio = -1;
  int cmp_res, retval = ISIS_OK;

  own_prio = circuit->priority[level - 1];
  adjdb = circuit->u.bc.adjdb[level - 1];

  if (!adjdb)
    {
      zlog_warn ("isis_dr_elect() adjdb == NULL");
      list_delete (list);
      return ISIS_WARNING;
    }
  isis_adj_build_up_list (adjdb, list);

  /*
   * Loop the adjacencies and find the one with the biggest priority
   */
  for (ALL_LIST_ELEMENTS_RO (list, node, adj))
    {
      /* clear flag for show output */
      adj->dis_record[level - 1].dis = ISIS_IS_NOT_DIS;
      adj->dis_record[level - 1].last_dis_change = time (NULL);

      if (adj->prio[level - 1] > biggest_prio)
	{
	  biggest_prio = adj->prio[level - 1];
	  adj_dr = adj;
	}
      else if (adj->prio[level - 1] == biggest_prio)
	{
	  /*
	   * Comparison of MACs breaks a tie
	   */
	  if (adj_dr)
	    {
	      cmp_res = memcmp (adj_dr->snpa, adj->snpa, ETH_ALEN);
	      if (cmp_res < 0)
		{
		  adj_dr = adj;
		}
	      if (cmp_res == 0)
		zlog_warn
		  ("isis_dr_elect(): multiple adjacencies with same SNPA");
	    }
	  else
	    {
	      adj_dr = adj;
	    }
	}
    }

  if (!adj_dr)
    {
      /*
       * Could not find the DR - means we are alone. Resign if we were DR.
       */
      if (circuit->u.bc.is_dr[level - 1])
        retval = isis_dr_resign (circuit, level);
      list_delete (list);
      return retval;
    }

  /*
   * Now we have the DR adjacency, compare it to self
   */
  if (adj_dr->prio[level - 1] < own_prio ||
      (adj_dr->prio[level - 1] == own_prio &&
       memcmp (adj_dr->snpa, circuit->u.bc.snpa, ETH_ALEN) < 0))
    {
      adj_dr->dis_record[level - 1].dis = ISIS_IS_NOT_DIS;
      adj_dr->dis_record[level - 1].last_dis_change = time (NULL);

      /* rotate the history log */
      for (ALL_LIST_ELEMENTS_RO (list, node, adj))
        isis_check_dr_change (adj, level);

      /* We are the DR, commence DR */
      if (circuit->u.bc.is_dr[level - 1] == 0 && listcount (list) > 0)
        retval = isis_dr_commence (circuit, level);
    }
Пример #9
0
/* Call when interface TE Link parameters are modified */
void
isis_link_params_update (struct isis_circuit *circuit, struct interface *ifp)
{
  int i;
  struct prefix_ipv4 *addr;
  struct mpls_te_circuit *mtc;

  /* Sanity Check */
  if ((circuit == NULL) || (ifp == NULL))
      return;

  zlog_info ("MPLS-TE: Initialize circuit parameters for interface %s", ifp->name);
  
  /* Check if MPLS TE Circuit context has not been already created */
  if (circuit->mtc == NULL)
      circuit->mtc = mpls_te_circuit_new();

  mtc = circuit->mtc;

  /* Fulfil MTC TLV from ifp TE Link parameters */
  if (HAS_LINK_PARAMS(ifp))
    {
      mtc->status = enable;
      /* STD_TE metrics */
      if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP))
        set_circuitparams_admin_grp (mtc, ifp->link_params->admin_grp);
      else
        SUBTLV_TYPE(mtc->admin_grp) = 0;

      /* If not already set, register local IP addr from ip_addr list if it exists */
      if (SUBTLV_TYPE(mtc->local_ipaddr) == 0)
        {
          if (circuit->ip_addrs != NULL && listcount(circuit->ip_addrs) != 0)
            {
              addr = (struct prefix_ipv4 *)listgetdata ((struct listnode *)listhead (circuit->ip_addrs));
              set_circuitparams_local_ipaddr (mtc, addr->prefix);
            }
        }

      /* If not already set, try to determine Remote IP addr if circuit is P2P */
      if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0) && (circuit->circ_type == CIRCUIT_T_P2P))
        {
          struct isis_adjacency *adj = circuit->u.p2p.neighbor;
          if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0)
            {
              struct in_addr *ip_addr;
              ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs));
              set_circuitparams_rmt_ipaddr (mtc, *ip_addr);
            }
        }

      if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW))
        set_circuitparams_max_bw (mtc, ifp->link_params->max_bw);
      else
        SUBTLV_TYPE(mtc->max_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW))
        set_circuitparams_max_rsv_bw (mtc, ifp->link_params->max_rsv_bw);
      else
        SUBTLV_TYPE(mtc->max_rsv_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW))
        for (i = 0; i < MAX_CLASS_TYPE; i++)
          set_circuitparams_unrsv_bw (mtc, i, ifp->link_params->unrsv_bw[i]);
      else
        SUBTLV_TYPE(mtc->unrsv_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_TE))
        set_circuitparams_te_metric(mtc, ifp->link_params->te_metric);
      else
        SUBTLV_TYPE(mtc->te_metric) = 0;

      /* TE metric Extensions */
      if (IS_PARAM_SET(ifp->link_params, LP_DELAY))
        set_circuitparams_av_delay(mtc, ifp->link_params->av_delay, 0);
      else
        SUBTLV_TYPE(mtc->av_delay) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY))
        set_circuitparams_mm_delay(mtc, ifp->link_params->min_delay, ifp->link_params->max_delay, 0);
      else
        SUBTLV_TYPE(mtc->mm_delay) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR))
        set_circuitparams_delay_var(mtc, ifp->link_params->delay_var);
      else
        SUBTLV_TYPE(mtc->delay_var) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS))
        set_circuitparams_pkt_loss(mtc, ifp->link_params->pkt_loss, 0);
      else
        SUBTLV_TYPE(mtc->pkt_loss) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_RES_BW))
        set_circuitparams_res_bw(mtc, ifp->link_params->res_bw);
      else
        SUBTLV_TYPE(mtc->res_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW))
        set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw);
      else
        SUBTLV_TYPE(mtc->ava_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_USE_BW))
        set_circuitparams_use_bw(mtc, ifp->link_params->use_bw);
      else
        SUBTLV_TYPE(mtc->use_bw) = 0;

      /* INTER_AS */
      if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS))
        set_circuitparams_inter_as(mtc, ifp->link_params->rmt_ip, ifp->link_params->rmt_as);
      else
        /* reset inter-as TE params */
        unset_circuitparams_inter_as (mtc);

      /* Compute total length of SUB TLVs */
      mtc->length = subtlvs_len(mtc);

    }
  else
    mtc->status = disable;

  /* Finally Update LSP */
#if 0
  if (IS_MPLS_TE(isisMplsTE) && circuit->area)
       lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
#endif
  return;
}