Beispiel #1
0
// ----- check_deflection_in_area -------------------------------------------
int check_deflection_in_area(uint16_t uOspfDomain, ospf_area_t tArea)
{
  int iIndexI, iIndexJ;
  /* Builds the set of BR that belongs to area and are on the backbone */
  SPtrArray * pBRList = ospf_domain_get_br_on_bb_in_area(uOspfDomain, tArea);
  net_node_t * pBR, * pER;
  
  /* Build all possibile couple of border router in the set. 
   * For each couple build RSPT on ER 
   * */
  for(iIndexI = 0; iIndexI < ptr_array_length(pBRList); iIndexI++) { 
    ptr_array_get_at(pBRList, iIndexI, &pBR);
    for(iIndexJ = 0; iIndexJ < ptr_array_length(pBRList); iIndexJ++) { 
      if (iIndexI == iIndexJ)
        continue;
      ptr_array_get_at(pBRList, iIndexJ, &pER);
      fprintf(stdout, "BR ");
      ip_address_dump(stdout, pBR->tAddr);
      fprintf(stdout, " - ER ");
      ip_address_dump(stdout, pER->tAddr);
      fprintf(stdout, "\n Computing rspt on ER\n");
      SRadixTree * pRspt = ospf_node_compute_rspt(pER, uOspfDomain, tArea);
      assert(pRspt != NULL);
      SSptVertex * pBRVertex = radix_tree_get_exact(pRspt, 
		                                    pBR->tAddr, 32);
      
      assert(pBRVertex != NULL);
      
      
      radix_tree_destroy(&pRspt);
    }
  }
  return 0;
}
Beispiel #2
0
/**
 * Aggregate N routes. The announced delay is the best route's delay.
 * The aggregated route has all the attribute (Next-Hop,
 * Communities, ...) of the best routes except the AS-Path which is an
 * AS-SET containing the AS-Num of all the ASes traversed by one of
 * the aggregated routes.
 */
SRoute * qos_route_aggregate(SRoutes * pRoutes, SRoute * pBestRoute)
{
  SRoute * pAggrRoute;
  int iIndex;
  SRoute * pRoute;
  SPath ** ppPaths= (SPath **) MALLOC(sizeof(SPath *)*
				      ptr_array_length(pRoutes));
  qos_delay_t tDelay;
  
  assert(routes_list_get_num(pRoutes) >= 1);

  // Aggregate Delay
  tDelay.tMean= 0;
  tDelay.uWeight= 0;
  for (iIndex= 0; iIndex < routes_list_get_num(pRoutes); iIndex++) {
    pRoute= (SRoute *) pRoutes->data[iIndex];
    tDelay.tMean+= pRoute->tDelay.uWeight*pRoute->tDelay.tMean;
    tDelay.uWeight+= pRoute->tDelay.uWeight;
    ppPaths[iIndex]= pRoute->pASPath;
  }
  tDelay.tMean= (int) (tDelay.tMean/tDelay.uWeight);

  // Aggregate Bandwidth: NOT YET IMPLEMENTED

  // Aggregate Paths
  pAggrRoute= route_copy(pBestRoute);
  pAggrRoute->tDelay= tDelay;
  pAggrRoute->tDelay.tDelay= pBestRoute->tDelay.tDelay;
  path_destroy(&pAggrRoute->pASPath);
  pAggrRoute->pASPath= path_aggregate(ppPaths, routes_list_get_num(pRoutes));
  FREE(ppPaths);

  return pAggrRoute;
}
Beispiel #3
0
// ----- check_deflection ----------------------------------------------
int check_deflection(uint16_t IGPDomainNumber, cr_info_list_t tList) {
  LOG_DEBUG("check actual deflection in domain %d\n", IGPDomainNumber);
  int iIndex;
  SCRouterInfo * pCRInfo;

  for (iIndex = 0; iIndex < ptr_array_length(tList); iIndex++){
    ptr_array_get_at(tList, iIndex, &pCRInfo);
    
    fprintf(stdout, "CRInfo BR: ");
    ip_address_dump(stdout, pCRInfo->pBR->tAddr);
    fprintf(stdout, "\n");
    fprintf(stdout, "ERInfo ER: ");
    ip_address_dump(stdout, pCRInfo->pER->tAddr);
    
    fprintf(stdout, "Compute RSPT on ER\n");
    SRadixTree * pRspt = ospf_node_compute_rspt(pCRInfo->pER, 
		                                 IGPDomainNumber, 
						 pCRInfo->tArea);
    assert(pRspt != NULL);
    SSptVertex * pBRVertex = radix_tree_get_exact(pRspt, 
		                                  pCRInfo->pBR->tAddr, 32);
    assert(pBRVertex != NULL);
    csource_check_deflection(pBRVertex, pCRInfo); 
    radix_tree_destroy(&pRspt);
    
        
    //fprintf(stdout, "--- Per ogni dest in CRInfo\n");
    //fprintf(stdout, "------- Trova route in routing table in foglia\n");
    //fprintf(stdout, "------- if (advRouter(route) == ER(CRInfo) deflection!\n");
  }
return 0;
}
Beispiel #4
0
// -----[ cli_enum_as_level_domains ]--------------------------------
as_level_domain_t * cli_enum_as_level_domains(const char * text,
					      int state)
{
  static as_level_topo_t * topo= NULL;
  static unsigned int index= 0;
  char str_asn[ASN_STR_LEN];
  as_level_domain_t * domain;

  if (state == 0) {
    topo= aslevel_get_topo();
    if (topo == NULL)
      return NULL;
    index= 0;
  }

  while (index < ptr_array_length(topo->domains)) {
    domain= (as_level_domain_t *) topo->domains->data[index];
    assert(snprintf(str_asn, ASN_STR_LEN, "%u", domain->asn) >= 0);
    index++;
    if (!strncmp(text, str_asn, strlen(text)))
      return domain;
  }

  return NULL;
}
Beispiel #5
0
void _qos_test()
{
  SRoute * pRoute1;
  SRoute * pRoute2;
  SRoute * pRoute3;
  SRoutes * pRoutes;
  SRoute * pAggrRoute;
  SPrefix sPrefix;
  int iIndex;

  sPrefix.tNetwork= 256;
  sPrefix.uMaskLen= 24;

  pRoute1= route_create(sPrefix, NULL, 1, ROUTE_ORIGIN_IGP);
  pRoute2= route_create(sPrefix, NULL, 2, ROUTE_ORIGIN_IGP);
  pRoute3= route_create(sPrefix, NULL, 3, ROUTE_ORIGIN_IGP);

  pRoute1->tDelay.tDelay= 5;
  pRoute1->tDelay.tMean= 5;
  pRoute1->tDelay.uWeight= 1;

  pRoute2->tDelay.tDelay= 5;
  pRoute2->tDelay.tMean= 7.5;
  pRoute2->tDelay.uWeight= 2;

  pRoute3->tDelay.tDelay= 10;
  pRoute3->tDelay.tMean= 10;
  pRoute3->tDelay.uWeight= 1;

  fprintf(stdout, "route-delay-compare: %d\n",
	  qos_route_compare_delay(&pRoute1, &pRoute2, 0));

  route_path_append(pRoute1, 1);
  route_path_append(pRoute2, 2);
  route_path_append(pRoute3, 3);

  pRoutes= ptr_array_create_ref(0);
  ptr_array_append(pRoutes, pRoute1);
  ptr_array_append(pRoutes, pRoute2);
  ptr_array_append(pRoutes, pRoute3);
  _array_sort((SArray *) pRoutes, qos_route_compare_delay);

  for (iIndex= 0; iIndex < ptr_array_length(pRoutes); iIndex++) {
    fprintf(stdout, "*** ");
    route_dump(stdout, (SRoute *) pRoutes->data[iIndex]);
    fprintf(stdout, "\n");
  }

  pAggrRoute= qos_route_aggregate(pRoutes, pRoute1);

  route_dump(stdout, pAggrRoute); fprintf(stdout, "\n");

  routes_list_destroy(&pRoutes);
  route_destroy(&pRoute1);
  route_destroy(&pRoute2);
  route_destroy(&pRoute3);
  route_destroy(&pAggrRoute);
}
Beispiel #6
0
// -----[ aslevel_topo_num_edges ]---------------------------------
unsigned int aslevel_topo_num_edges(as_level_topo_t * topo)
{
  unsigned int num_edges= 0;
  unsigned int index;
  as_level_domain_t * domain;

  ASLEVEL_TOPO_FOREACH_DOMAIN(topo, index, domain) {
    num_edges+= ptr_array_length(domain->neighbors);
  }
Beispiel #7
0
static int _find_object(OBJECT obj, struct marshal_state *ms) {
  int i;
  return -1;
  for(i = 0; i < ptr_array_length(ms->objects); i++) {
    if(obj == (OBJECT)ptr_array_get_index(ms->objects, i)) {
      return i;
    }
  }
  
  return -1;
}
Beispiel #8
0
// ----- build_critical_destination_list ---------------------------------------
int build_critical_destination_list(SCRouterInfo * pCRInfo)
{
 LOG_DEBUG("bcdl on ER "); 
 ip_address_dump(stdout, pCRInfo->pER->tAddr);
 fprintf(stdout, " area %d BR ", pCRInfo->tArea);
 ip_address_dump(stdout, pCRInfo->pBR->tAddr);
 fprintf(stdout, "\n");
 if (OSPF_rt_for_each(pCRInfo->pER->pOspfRT, build_cd_for_each, pCRInfo) 
		                                                == OSPF_SUCCESS)
   return ptr_array_length(pCRInfo->tCDList);
 return 0;
}
Beispiel #9
0
/**
 *  Visit the revers shorthes path tree starting from pVertex to its soon.
 *  
 */
void csource_check_deflection(SSptVertex * pVertex, SCRouterInfo * pCRInfo){
  SSptVertex * pSon;
  int iLeafIdx;
  if (spt_vertex_is_router(pVertex) && 
       (spt_vertex_to_router(pVertex)->tAddr != pCRInfo->pBR->tAddr)) {
    SCDestInfo * pCDInfo;
    int iDestIdx;
    SPrefix vertex_id = spt_vertex_get_id(pVertex);
    fprintf(stdout, "Visit ");
    ip_prefix_dump(stdout, vertex_id);
    fprintf(stdout, "\nCritical dest list: \n");
    for (iDestIdx = 0; iDestIdx < ptr_array_length(pCRInfo->tCDList); 
		                                                   iDestIdx++){
      SOSPFRouteInfo * pCDRoute;
      ptr_array_get_at(pCRInfo->tCDList, iDestIdx, &pCDInfo);
      ip_prefix_dump(stdout, *pCDInfo);
      fprintf(stdout, "\n");

      pCDRoute = OSPF_rt_find_exact(spt_vertex_to_router(pVertex)->pOspfRT, 
	  	                    *pCDInfo, NET_ROUTE_IGP, OSPF_NO_AREA);
      assert(pCDRoute != NULL);
      
      int iNHIdx;
      SOSPFNextHop * pNH;
      for (iNHIdx = 0; iNHIdx < ptr_array_length(pCDRoute->aNextHops); iNHIdx++)      {
        ptr_array_get_at(pCDRoute->aNextHops, iNHIdx, &pNH);
	if (pNH->tAdvRouterAddr != 0)
	  ip_prefix_dump(stdout, pCDRoute->sPrefix);
	if (pNH->tAdvRouterAddr == pCRInfo->pER->tAddr)
          fprintf(stdout, "Trovata route con deflection!");
      }   
    } 
  }
  //visit children
  for (iLeafIdx = 0; iLeafIdx < ptr_array_length(pVertex->sons); iLeafIdx++){
    ptr_array_get_at(pVertex->sons, iLeafIdx, &pSon);
    csource_check_deflection(pSon, pCRInfo); 
  }
}
Beispiel #10
0
const char * quark_to_string(quark q)
{
  const char *retval;
  if (q == 0) return NULL;
  mutex_lock();
  if (quark_init_if_needed() || q >= ptr_array_length(quark_string_index))
  {
    mutex_unlock();
    return NULL;
  }
  retval = ptr_array_get_index(quark_string_index, q);
  mutex_unlock();
  return retval;
}
Beispiel #11
0
/**
 * Check if the given route is
 *   - learned through an iBGP session
 * or
 *   - has an aggregate which contains a route learned through an iBGP
 *     session
 */
int qos_route_is_ibgp(SBGPRouter * pRouter, SRoute * pRoute)
{
  int iIndex;

  // Best route learned from iBGP ?
  if (route_peer_get(pRoute)->uRemoteAS == pRouter->uNumber)
    return 1;

  // Route in the aggregate learned from iBGP ?
  if (pRoute->pAggrRoute != NULL) {
    for (iIndex= 0; iIndex < ptr_array_length(pRoute->pAggrRoutes); iIndex++)
      if (route_peer_get((SRoute *) pRoute->pAggrRoutes->data[iIndex])->uRemoteAS
	  == pRouter->uNumber)
	return 1;
  }

  return 0;
}
Beispiel #12
0
quark quark_from_static_string(const char *string)
{
  if (string == NULL) return 0;
  mutex_lock();
  if (!quark_init_if_needed())
  {
    uintptr_t value = (uintptr_t)hashtable_search(quark_string_hash, string);
    if (value != 0)
    {
      mutex_unlock();
      return value;
    }
  }
  if (!ptr_array_append(quark_string_index, string))
  { 
    mutex_unlock();
    return QUARK_NOT_FOUND;
  }
  size_t index = ptr_array_length(quark_string_index) - 1;
  hashtable_insert(quark_string_hash, (char *)string, (void*) index);
  mutex_unlock();
  return index;
}
Beispiel #13
0
// ----- ospf_build_cd_for_each ---------------------------------------------
int build_cd_for_each(uint32_t uKey, uint8_t uKeyLen, void * pItem, 
		                                              void * pContext){ 
  SCRouterInfo * pCtx = (SCRouterInfo *) pContext;
  SOSPFRouteInfoList * pRIList = (SOSPFRouteInfoList *) pItem;
  SOSPFRouteInfo * pRIExitRouter = NULL;// = ospf_ri_list_get_route(pRIList);
  SOSPFRouteInfo * pRIBorderRouter;
  SPrefix sRoutePrefix;
  sRoutePrefix.tNetwork = (net_addr_t) uKey;
  sRoutePrefix.uMaskLen = uKeyLen;
  int iIndex;

  for (iIndex = 0; iIndex < ptr_array_length(pRIList); iIndex++){
    ptr_array_get_at(pRIList, iIndex, &pRIExitRouter);
    if (ospf_ri_route_type_is(pRIExitRouter, NET_ROUTE_IGP))
      break;
    else{
      pRIExitRouter = NULL;
    }
  }
  
  if (pRIExitRouter != NULL && 
      ospf_route_is_adver_in_area(pRIExitRouter, pCtx->tArea)) {
    
    pRIBorderRouter = OSPF_rt_find_exact(pCtx->pBR->pOspfRT, 
		                  sRoutePrefix, NET_ROUTE_ANY, pCtx->tArea);
    if (pRIBorderRouter == NULL){

        _cd_list_add(pCtx->tCDList, sRoutePrefix);
    }
    else if (ospf_ri_get_cost(pRIExitRouter) + pCtx->tRCost_BR_ER < 
		                         ospf_ri_get_cost(pRIBorderRouter)){
        _cd_list_add(pCtx->tCDList, sRoutePrefix);
    } 
  }

  return OSPF_SUCCESS;
}
Beispiel #14
0
/**
 * Select one route with the following rules:
 *
 *   - prefer largest Delay-interval
 *   - prefer shortest AS-PATH
 *   - final tie-break
 *
 * Must go to the end of the function to select a unique best route,
 * but keep N good routes to aggregate
 */
void qos_decision_process_tie_break(SBGPRouter * pRouter, SRoutes * pRoutes,
				    unsigned int uNumRoutes)
{
  int iIndex;
  SRoute * pCurrentRoute, * pRoute;

  // *** lowest delay, then largest interval ***
  if (ptr_array_length(pRoutes) < 1)
    return;
  pCurrentRoute= (SRoute *) pRoutes->data[0];
  for (iIndex= 0; iIndex < ptr_array_length(pRoutes)-1; iIndex++) {
    pRoute= (SRoute *) pRoutes->data[iIndex+1];
    if ((pCurrentRoute->tDelay.tDelay != pRoute->tDelay.tDelay) ||
	(_qos_delay_interval(pCurrentRoute->tDelay) !=
	 _qos_delay_interval(pRoute->tDelay))) {
      iIndex++;
      while (ptr_array_length(pRoutes) > iIndex) {
	ptr_array_remove_at(pRoutes, iIndex);
      }
    }
    pCurrentRoute= pRoute;
  }

  // *** shortest AS-PATH ***
  dp_rule_shortest_path(pRoutes);
  if (ptr_array_length(pRoutes) <= uNumRoutes)
    return;

  // *** eBGP over iBGP ***
  dp_rule_ebgp_over_ibgp(pRouter, pRoutes);
  if (ptr_array_length(pRoutes) <= uNumRoutes)
    return;

  // *** nearest NEXT-HOP (lowest IGP-cost) ***
  dp_rule_nearest_next_hop(pRouter, pRoutes);
  if (ptr_array_length(pRoutes) <= uNumRoutes)
    return;

  dp_rule_final(pRouter, pRoutes);
}
Beispiel #15
0
// -----[ aslevel_topo_num_nodes ]---------------------------------
unsigned int aslevel_topo_num_nodes(as_level_topo_t * topo)
{
  return ptr_array_length(topo->domains);
}
Beispiel #16
0
/**
 * Let M be the number of routes which we want to keep for
 * aggregation (M = BGP_OPTIONS_QOS_AGGR_LIMIT).
 *
 * Order the routes lexicographically:
 *   - first, lowest delay
 *   - then longest interval
 *
 * Find the highest P < M such that
 *   delay(R[P]) != delay(R[P+1])
 * or such that
 *   (delay(R[P]) == delay(R[P+1])) and (interval(R[P]) < interval(R[P+1]))
 *   
 * Select the P first routes as candidates for aggregation
 *
 * Use the remaining tie-break rules to select at most M-P additional
 * routes as candidates for aggregation
 *
 * Run the decision process on the P first rules to find which one is
 * the best one.
 */
int qos_decision_process_delay(SBGPRouter * pRouter, SRoutes * pRoutes,
			       unsigned int uNumRoutes)
{
  int iIndex, iIndexLast;
  SRoute * pRoute, * pCurrentRoute;
  SRoutes * pAggrRoutes/*, * pOthRoutes*/;

  AS_LOG_DEBUG(pRouter, " > qos_decision_process_delay\n");

  assert(uNumRoutes >= 1);

  // Sort routes based on (delay, delay_interval)
  _array_sort((SArray *) pRoutes, qos_route_compare_delay);

  // If there are more routes than can be aggregated, select a subset
  if (routes_list_get_num(pRoutes) > uNumRoutes) {

    // Find the higher P < M...
    iIndexLast= 0;
    pCurrentRoute= (SRoute *) pRoutes->data[0];
    for (iIndex= 0; (iIndex < ptr_array_length(pRoutes)-1) &&
	   (iIndex < uNumRoutes); iIndex++) {
      pRoute= (SRoute *) pRoutes->data[iIndex+1];
      if ((pCurrentRoute->tDelay.tDelay != pRoute->tDelay.tDelay) ||
	  (_qos_delay_interval(pCurrentRoute->tDelay) !=
	   _qos_delay_interval(pRoute->tDelay)))
	iIndexLast= iIndex;
      pCurrentRoute= pRoute;
    }

    _array_trim((SArray *) pRoutes, iIndexLast+1);

    // Tie-break for the N-P last routes in order to find additional
    // aggregatable routes (optional)
    /*
    pOthRoutes= (SPtrArray *) _array_sub((SArray *) pRoutes,
					 iIndexLast+1,
					 ptr_array_length(pRoutes)-1);
    qos_decision_process_tie_break(pAS, pOthRoutes,
				   uNumRoutes-iIndexLast-1);

    _array_add_all((SArray *) pAggrRoutes, (SArray  *) pOthRoutes);
    _array_destroy((SArray **) &pOthRoutes);
    */

  }

  pAggrRoutes= (SRoutes *) _array_copy((SArray *) pRoutes);

  // Find best route
  qos_decision_process_tie_break(pRouter, pRoutes, 1);

  assert(ptr_array_length(pRoutes) <= 1);

  // Attach the list of aggregatable routes to the best route
  if (ptr_array_length(pRoutes) == 1) {
    ((SRoute *) pRoutes->data[0])->pAggrRoutes= pAggrRoutes;
    ((SRoute *) pRoutes->data[0])->pAggrRoute=
      qos_route_aggregate(pAggrRoutes, (SRoute *) pRoutes->data[0]);
  } else
    routes_list_destroy(&pAggrRoutes);

  AS_LOG_DEBUG(pRouter, " < qos_decision_process_delay\n");
    
  return 0;
}
Beispiel #17
0
/**
 * Disseminate route to Adj-RIB-Outs.
 *
 * If there is no best route, then
 *   - if a route was previously announced, send an explicit withdraw
 *   - otherwise do nothing
 *
 * If there is one best route, then send an update. If a route was
 * previously announced, it will be implicitly withdrawn.
 */
void qos_decision_process_disseminate(SBGPRouter * pRouter, SPrefix sPrefix,
				      SRoute * pRoute)
{
#define QOS_REDISTRIBUTE_NOT  0
#define QOS_REDISTRIBUTE_BEST 1
#define QOS_REDISTRIBUTE_EBGP 2

  int iIndex, iIndex2;
  SPeer * pPeer;
  SRoutes * pAggrRoutes= NULL;
  SRoute * pEBGPRoute= NULL;
  int iRedistributionType;
  int iAggregateIBGP;

  AS_LOG_DEBUG(pRouter, " > qos_decision_process_disseminate.begin\n");

  iAggregateIBGP= qos_route_is_ibgp(pRouter, pRoute);

  if (pRoute->pAggrRoute != NULL) {
    pAggrRoutes= pRoute->pAggrRoutes;
    pEBGPRoute= pRoute->pEBGPRoute;
    pRoute= pRoute->pAggrRoute;
  }

  for (iIndex= 0; iIndex < ptr_array_length(pRouter->pPeers); iIndex++) {
    pPeer= (SPeer *) pRouter->pPeers->data[iIndex];

    iRedistributionType= QOS_REDISTRIBUTE_BEST;

    // If one route of the aggregate was learned through the iBGP,
    // prevent the redistribution to all the iBGP peer.
    // Announce the eBGP route if it exists
    if ((pPeer->uRemoteAS == pRouter->uNumber) &&
	(iAggregateIBGP)) {
      if (pEBGPRoute != NULL)
	iRedistributionType= QOS_REDISTRIBUTE_EBGP;
      else
	iRedistributionType= QOS_REDISTRIBUTE_NOT;
    }

    // If the route is an aggregate, check every peer which has
    // announced a route in the aggregate and prevent the
    // redistribution
    if ((iRedistributionType != QOS_REDISTRIBUTE_NOT) &&
	(pAggrRoutes != NULL)) {
      for (iIndex2= 0; iIndex2 < ptr_array_length(pAggrRoutes); iIndex2++)
	if (((SRoute *) pAggrRoutes->data[iIndex2])->tNextHop ==
	    pPeer->tAddr) {
	  iRedistributionType= QOS_REDISTRIBUTE_NOT;
	  break;
	}
    }

    switch (iRedistributionType) {
    case QOS_REDISTRIBUTE_BEST:
      LOG_DEBUG("\tredistribution allowed to %d:", pPeer->uRemoteAS);
      LOG_ENABLED_DEBUG()
	ip_address_dump(log_get_stream(pMainLog), pPeer->tAddr);
      LOG_DEBUG("\n");
      qos_decision_process_disseminate_to_peer(pRouter, sPrefix, pRoute,
					       pPeer);
      break;
    case QOS_REDISTRIBUTE_EBGP:
      LOG_DEBUG("\tredistribution of eBGP allowed to %d:", pPeer->uRemoteAS);
      LOG_ENABLED_DEBUG()
	ip_address_dump(log_get_stream(pMainLog), pPeer->tAddr);
      LOG_DEBUG("\n");
      qos_decision_process_disseminate_to_peer(pRouter, sPrefix, pEBGPRoute,
					       pPeer);      
      break;
    default:
      LOG_DEBUG("\tredistribution refused to %d:", pPeer->uRemoteAS);
      LOG_ENABLED_DEBUG()
	ip_address_dump(log_get_stream(pMainLog), pPeer->tAddr);
      LOG_DEBUG("\n");
      qos_decision_process_disseminate_to_peer(pRouter, sPrefix, NULL,
					       pPeer);
    }
  }

  AS_LOG_DEBUG(pRouter, " < qos_decision_process_disseminate.end\n");

}
Beispiel #18
0
// ----- build_critical_routers_list -------------------------------------------
int build_critical_routers_list(uint16_t uOspfDomain,
                                    ospf_area_t tArea, cr_info_list_t * tCRList) {
  int iIndexI, iIndexJ;
  SOSPFRouteInfo * pRouteIJArea, * pRouteIJBackbone;
  *tCRList = _cr_info_list_create();
  SCRouterInfo * pCRInfo;
  /* Builds the set of BR that belongs to area and are on the backbone */
  SPtrArray * pBRList = ospf_domain_get_br_on_bb_in_area(uOspfDomain, tArea);
  net_node_t * pBRI, *pBRJ;
  SPrefix sPrefix;
  
  /* Build all possibile couple of border router in the set. 
   * For each couple check if condition 1 is verified
   * If is verified check condition 2, too.
   * */
  for(iIndexI = 0; iIndexI < ptr_array_length(pBRList); iIndexI++){ 
    ptr_array_get_at(pBRList, iIndexI, &pBRI);
    for(iIndexJ = 0; iIndexJ < ptr_array_length(pBRList); iIndexJ++){ 
      if (iIndexI == iIndexJ)
        continue;
      ptr_array_get_at(pBRList, iIndexJ, &pBRJ);
      sPrefix.tNetwork = ospf_node_get_id(pBRJ);
      sPrefix.uMaskLen = 32;
      pRouteIJArea = OSPF_rt_find_exact(pBRI->pOspfRT, sPrefix,
		                        NET_ROUTE_IGP, tArea);

      /* If BR1 has not a route towards BR2 in area tArea this wants 
       * to say that there is a partition in the area. In this case no
       * deflection is possibile because there not will be a source that
       * has BR1 on its path towards BR2, if BR2.
       * */
      if (pRouteIJArea == NULL)
	continue;
      
      pRouteIJBackbone = OSPF_rt_find_exact(pBRI->pOspfRT, sPrefix, 
		                            NET_ROUTE_IGP, BACKBONE_AREA);
      /* If BR1 has not a route towards BR2 in backbone this wants 
       * to say that there is a partition in backbone.
       * Deflection can be possibile if BR2 will be choosen 
       * as exit router to exit area for some couple source-destination
       * where source has BR1 on the path towards BR2.
       * This happends because BR2 announces destination in area tArea
       * but BR1 has not a route towards it because he does not consider
       * summary in area != backbone.
       *
       * If we assume that when a route does not exist in a routing table
       * it has a cost infinite, condition 1 we try to verify is still
       * verified.
       * */
      if (pRouteIJBackbone == NULL) {      
	fprintf(stdout, "partizione nel backbone - verificata la cond 1\n");
	pCRInfo = _crouter_info_create(pBRI, pBRJ,
			               ospf_ri_get_cost(pRouteIJArea), tArea);
	int iRes =build_critical_destination_list(pCRInfo);
	fprintf(stdout, "Returned %d", iRes);
	if (iRes)   
	  _cr_info_list_add(*tCRList, pCRInfo);
	else
	  _crouter_info_destroy(&pCRInfo);
        continue;
      }   
      
      /* Checking condition 2. 
       * If it's true computing critical destination list for this 
       * couple of routers and adding them to critical routers list. 
       * */
      if (ospf_ri_get_cost(pRouteIJArea) < ospf_ri_get_cost(pRouteIJBackbone))
        fprintf(stdout, "Verificata condizione 1\n");
        pCRInfo = _crouter_info_create(pBRI, pBRJ,
			               ospf_ri_get_cost(pRouteIJArea), tArea);
        
	int iRes =build_critical_destination_list(pCRInfo); 
	fprintf(stdout, "Returned %d", iRes);
        if (iRes)   
	  _cr_info_list_add(*tCRList, pCRInfo);
	else
	  _crouter_info_destroy(&pCRInfo);
    }
  }
  return ptr_array_length(*tCRList);
}
Beispiel #19
0
/**
 * Phase I - Calculate degree of preference (LOCAL_PREF) for each
 *           single route. Operate on separate Adj-RIB-Ins.
 *           This phase is carried by 'peer_handle_message' (peer.c).
 *
 * Phase II - Selection of best route on the basis of the degree of
 *            preference and then on tie-breaking rules (AS-Path
 *            length, Origin, MED, ...).
 *
 * Phase III - Dissemination of routes.
 *
 * In our implementation, we distinguish two main cases:
 * - a withdraw has been received from a peer for a given prefix. In
 * this case, if the best route towards this prefix was received by
 * the given peer, the complete decision process has to be
 * run. Otherwise, nothing more is done (the route has been removed
 * from the peer's Adj-RIB-In by 'peer_handle_message');
 * - an update has been received. The complete decision process has to
 * be run.
 */
int qos_decision_process(SBGPRouter * pRouter, SPeer * pOriginPeer,
			 SPrefix sPrefix)
{
#ifndef __EXPERIMENTAL_WALTON__
  SRoutes * pRoutes= routes_list_create();
  SRoutes * pEBGPRoutes= routes_list_create();
  int iIndex;
  SPeer * pPeer;
  SRoute * pRoute, * pOldRoute;

  AS_LOG_DEBUG(pRouter, " > qos_decision_process.begin\n");

  LOG_DEBUG("\t<-peer: AS%d\n", pOriginPeer->uRemoteAS);

  pOldRoute= rib_find_exact(pRouter->pLocRIB, sPrefix);
  LOG_DEBUG("\tbest: ");
  LOG_ENABLED_DEBUG() route_dump(log_get_stream(pMainLog), pOldRoute);
  LOG_DEBUG("\n");

  // *** lock all Adj-RIB-Ins ***

  // Build list of eligible routes and list of eligible eBGP routes
  for (iIndex= 0; iIndex < ptr_array_length(pRouter->pPeers); iIndex++) {
    pPeer= (SPeer*) pRouter->pPeers->data[iIndex];
    pRoute= rib_find_exact(pPeer->pAdjRIBIn, sPrefix);
    if ((pRoute != NULL) &&
	(route_flag_get(pRoute, ROUTE_FLAG_FEASIBLE))) {
      assert(ptr_array_append(pRoutes, pRoute) >= 0);
      LOG_DEBUG("\teligible: ");
      LOG_ENABLED_DEBUG() route_dump(log_get_stream(pMainLog), pRoute);
      LOG_DEBUG("\n");
      if (route_peer_get(pRoute)->uRemoteAS != pRouter->uNumber)
	assert(ptr_array_append(pEBGPRoutes, pRoute) >= 0);
    }
  }

  // Keep routes with highest degree of preference
  if (ptr_array_length(pRoutes) > 1)
    as_decision_process_dop(pRouter, pRoutes);

  // Tie-break
  if (ptr_array_length(pRoutes) > 1)
    qos_decision_process_delay(pRouter, pRoutes, BGP_OPTIONS_QOS_AGGR_LIMIT);

  assert(ptr_array_length(pRoutes) <= 1);

  if (ptr_array_length(pRoutes) == 1) {

    LOG_DEBUG("\tselected: ");
    LOG_ENABLED_DEBUG()
      route_dump(log_get_stream(pMainLog), (SRoute *) pRoutes->data[0]);
    LOG_DEBUG("\n");

    // Carry aggregated route ?
    if (((SRoute *) pRoutes->data[0])->pAggrRoute != NULL) {
      LOG_DEBUG("\taggregated: ");
      LOG_ENABLED_DEBUG()
	route_dump(log_get_stream(pMainLog),
		    ((SRoute *) pRoutes->data[0])->pAggrRoute);

      LOG_DEBUG("\n");
    }

    // If best route is iBGP or aggregate contains an iBGP route, then
    // find the best eBGP route (and aggregate: optional)
    if (qos_route_is_ibgp(pRouter, (SRoute *) pRoutes->data[0])) {

      // Keep eBGP routes with highest degree of preference
      if (ptr_array_length(pEBGPRoutes) > 1)
	as_decision_process_dop(pRouter, pEBGPRoutes);

      // Tie-break for eBGP routes
      if (ptr_array_length(pEBGPRoutes) > 1)
	qos_decision_process_delay(pRouter, pEBGPRoutes,
				   BGP_OPTIONS_QOS_AGGR_LIMIT);

      assert(ptr_array_length(pRoutes) <= 1);

      if (ptr_array_length(pEBGPRoutes) == 1)
	((SRoute *) pRoutes->data[0])->pEBGPRoute=
	  (SRoute *) pEBGPRoutes->data[0];

    }

    route_copy_count++;
    pRoute= route_copy((SRoute *) pRoutes->data[0]);
    route_flag_set(pRoute, ROUTE_FLAG_BEST, 1);
    
    LOG_DEBUG("\tnew best: ");
    LOG_ENABLED_DEBUG() route_dump(log_get_stream(pMainLog), pRoute);
    LOG_DEBUG("\n");
    
    // New/updated route
    // => install in Loc-RIB
    // => advertise to peers
    if ((pOldRoute == NULL) || !route_equals(pOldRoute, pRoute)) {
      if (pOldRoute != NULL)
	route_flag_set(pOldRoute, ROUTE_FLAG_BEST, 0);
      assert(rib_add_route(pRouter->pLocRIB, pRoute) == 0);
      qos_decision_process_disseminate(pRouter, sPrefix, pRoute);
    } else {
      route_destroy(&pRoute);
      pRoute= pOldRoute;
    }
  } else if (ptr_array_length(pRoutes) == 0) {
    LOG_DEBUG("no best\n");
    // If a route towards this prefix was previously installed, then
    // withdraw it. Otherwise, do nothing...
    if (pOldRoute != NULL) {
      //LOG_DEBUG("there was a previous best-route\n");
      rib_remove_route(pRouter->pLocRIB, sPrefix);
      //LOG_DEBUG("previous best-route removed\n");
      route_flag_set(pOldRoute, ROUTE_FLAG_BEST, 0);
      // Withdraw should ideally only be sent to peers that already
      // have received this route. Since we do not maintain
      // Adj-RIB-Outs, the 'withdraw' message is sent to all peers...
      qos_decision_process_disseminate(pRouter, sPrefix, NULL);
    }
  }

  // *** unlock all Adj-RIB-Ins ***
  
  routes_list_destroy(&pRoutes);
  routes_list_destroy(&pEBGPRoutes);
  
  AS_LOG_DEBUG(pRouter, " < qos_decision_process.end\n");
#endif
  return 0;
}