Beispiel #1
0
/**
*   Activates a passive group. If the group is already
*   activated, it's reinstalled in the kernel. If
*   the route is activated, no originAddr is needed.
*/
int activateRoute(uint32_t group, uint32_t originAddr) {
    struct RouteTable*  croute;
    int result = 0;

    // Find the requested route.
    croute = findRoute(group);
    if(croute == NULL) {
        my_log(LOG_DEBUG, 0,
		"No table entry for %s [From: %s]. Inserting route.",
		inetFmt(group, s1),inetFmt(originAddr, s2));

        // Insert route, but no interfaces have yet requested it downstream.
        insertRoute(group, -1);

        // Retrieve the route from table...
        croute = findRoute(group);
    }

    if(croute != NULL) {
        // If the origin address is set, update the route data.
        if(originAddr > 0) {
            // find this origin, or an unused slot
            int i;
            for (i = 0; i < MAX_ORIGINS; i++) {
                // unused slots are at the bottom, so we can't miss this origin
                if (croute->originAddrs[i] == originAddr || croute->originAddrs[i] == 0) {
                    break;
                }
            }
            
            if (i == MAX_ORIGINS) {
                i = MAX_ORIGINS - 1;
                
                my_log(LOG_WARNING, 0, "Too many origins for route %s; replacing %s with %s",
                    inetFmt(croute->group, s1),
                    inetFmt(croute->originAddrs[i], s2),
                    inetFmt(originAddr, s3));
            }
            
            // set origin
            croute->originAddrs[i] = originAddr;
            
            // move it to the top
            while (i > 0) {
                uint32_t t = croute->originAddrs[i - 1];
                croute->originAddrs[i - 1] = croute->originAddrs[i];
                croute->originAddrs[i] = t;
                i--;
            }
        }

        // Only update kernel table if there are listeners !
        if(croute->vifBits > 0) {
            result = internUpdateKernelRoute(croute, 1);
        }
    }
    logRouteTable("Activate Route");

    return result;
}
Beispiel #2
0
/**
*   Activates a passive group. If the group is already
*   activated, it's reinstalled in the kernel. If
*   the route is activated, no originAddr is needed.
*/
int activateRoute(struct in6_addr * group, struct in6_addr * originAddr)
{
    int result = 0;
    struct RouteTable*  croute;
    struct RouteTable*  newroute;

    // Find the requested route.
    croute = findRoute(group, originAddr);
    if(croute != NULL) 
        return 0;
    croute = findRoute(group, &allzero_addr);   
    if (croute)
    {        
        newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));
        *newroute = *croute;
        newroute->originAddr = *originAddr;

        newroute->nextroute = routing_table;
        newroute->prevroute = NULL;
        routing_table->prevroute = newroute;
        routing_table = newroute;

        if( !internUpdateKernelRoute(newroute, 1) ) 
        {
            atlog(LOG_WARNING, 0, "The insertion into Kernel failed.");
            return 0;
        }
    }
    
    return 1;
}
Beispiel #3
0
bool
RibEntry::hasRoute(const Route& route)
{
  RibEntry::const_iterator it = findRoute(route);

  return it != end();
}
Beispiel #4
0
void setMyNeighbor(int* linkNeighbors){
	printf("\n--------------Start of setMyNeighbor--------------\n");
	int i,tmp;
	pthread_mutex_lock( &tableMutex );
	for (i=1; i<256; i++){
		tmp = linkNeighbors[i];
		if (tmp==0){
			neighborTable[HOSTID][i] = 1000000;
		}
		else{
			if (tmp<180)
				tmp = 180;
			else if(tmp>200){
				tmp=200;
			}

			neighborTable[HOSTID][i] = linkQualityMap[tmp-180];
		}
	}

	tableAge[HOSTID]++;
    writeMyAge();

	findRoute();

	set_beacon_counter(2);
	pthread_mutex_unlock( &tableMutex );
	
	printf("---------------End of setMyNeighbor---------------\n\n");
}
Beispiel #5
0
 vector<vector<int> > pathSum(TreeNode *root, int sum) 
 {
 	allRoute.clear();
 	route.clear();
 	if (root == NULL) {return allRoute;}
 	findRoute(root, sum);
 	return allRoute;
     
 }
Beispiel #6
0
/**
*   Returns true when the given group belongs to the given interface
*/
int interfaceInRoute(int32_t group, int Ix) {
    struct RouteTable*  croute;
    croute = findRoute(group);
    if (croute != NULL) {
        my_log(LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group);
        return BIT_TST(croute->vifBits, Ix);
    } else {
        return 0;
    }
}
Beispiel #7
0
void BcmRoute::programLpmRoute(opennsl_if_t egressId,
    const RouteNextHopEntry& fwd) {
  opennsl_l3_route_t rt;
  initL3RouteT(&rt);
  rt.l3a_intf = egressId;
  if (fwd.getNextHopSet().size() > 1) {         // multipath
    rt.l3a_flags |= OPENNSL_L3_MULTIPATH;
  }

  bool addRoute = false;
  const auto warmBootCache = hw_->getWarmBootCache();
  auto vrfAndPfx2RouteCitr = warmBootCache->findRoute(vrf_, prefix_, len_);
  if (vrfAndPfx2RouteCitr != warmBootCache->vrfAndPrefix2Route_end()) {
    // Lambda to compare if the routes are equivalent and thus we need to
    // do nothing
    auto equivalent =
      [=] (const opennsl_l3_route_t& newRoute,
           const opennsl_l3_route_t& existingRoute) {
      // Compare flags (primarily MULTIPATH vs non MULTIPATH
      // and egress id.
      return existingRoute.l3a_flags == newRoute.l3a_flags &&
      existingRoute.l3a_intf == newRoute.l3a_intf;
    };
    if (!equivalent(rt, vrfAndPfx2RouteCitr->second)) {
      VLOG (3) << "Updating route for : " << prefix_ << "/"
        << static_cast<int>(len_) << " in vrf : " << vrf_;
      // This is a change
      rt.l3a_flags |= OPENNSL_L3_REPLACE;
      addRoute = true;
    } else {
      VLOG(3) << " Route for : " << prefix_ << "/" << static_cast<int>(len_)
        << " in vrf : " << vrf_ << " already exists";
    }
  } else {
    addRoute = true;
  }
  if (addRoute) {
    if (vrfAndPfx2RouteCitr == warmBootCache->vrfAndPrefix2Route_end()) {
      VLOG (3) << "Adding route for : " << prefix_ << "/"
        << static_cast<int>(len_) << " in vrf : " << vrf_;
    }
    if (added_) {
      rt.l3a_flags |= OPENNSL_L3_REPLACE;
    }
    auto rc = opennsl_l3_route_add(hw_->getUnit(), &rt);
    bcmCheckError(rc, "failed to create a route entry for ", prefix_, "/",
        static_cast<int>(len_), " @ ", fwd, " @egress ", egressId);
    VLOG(3) << "created a route entry for " << prefix_.str() << "/"
      << static_cast<int>(len_) << " @egress " << egressId
      << " with " << fwd;
  }
  if (vrfAndPfx2RouteCitr != warmBootCache->vrfAndPrefix2Route_end()) {
    warmBootCache->programmed(vrfAndPfx2RouteCitr);
  }
}
Beispiel #8
0
	void findRoute(TreeNode* root, int sum)
	{
		if ((root->left == NULL) && (root->right == NULL) && (sum - root->val == 0))
		{
			route.push_back(root->val);
			allRoute.push_back(route);
			return;
		}
		route.push_back(root->val);
		if (root->left != NULL)
		{
			findRoute(root->left, sum - root->val);
			route.pop_back();
		}
		if (root->right != NULL)
		{
			findRoute(root->right, sum - root->val);
			route.pop_back();
		}
	}
Beispiel #9
0
int main(void)
{
    /* Previously (maximized at?) 321713 pings with a = 429 and b = COMP_NUM = 1000.
    Takes 1141 after looping order optimization.
    Always takes < COMP_NUM * 2 (and > COMP_NUM) pings after using a sorted (by
    ping(i, b)) lookup table (if ping(i, b) >= ping(a, b), i isn't included in
    the table).
    This solution uses about 5 MB of memory and malloc. Define O_N_SQR for
    the original solution (which takes about 0.3 * COMP_NUM**2 pings). */
    unsigned a = (unsigned)((0.428) * COMP_NUM);
    unsigned b = COMP_NUM;
    if (a == b) ++b;

    findRoute(a, b, COMP_NUM);
    ping(0, 0); // Print number of pings used and reset.

    findRoute(b, a, COMP_NUM);
    ping(0, 0);

    return 0;
}
Beispiel #10
0
/**
*   Ages groups in the last member check state. If the
*   route is not found, or not in this state, 0 is returned.
*/
int lastMemberGroupAge(uint32_t group) {
    struct RouteTable   *croute;

    croute = findRoute(group);
    if(croute!=NULL) {
        if(croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER) {
            return !internAgeRoute(croute);
        } else {
            return 0;
        }
    }
    return 0;
}
Beispiel #11
0
void updateTable(char* buff,int len){
	printf("\n--------------Start of updateTable--------------\n");

	int p,id,age,i;
	p=0;
	char flag;

	char unneighbor_flag;

	pthread_mutex_lock( &tableMutex );
	flag = 0;
	unneighbor_flag=0;
	while(p<len){
		id = 0x00ff & buff[p++];
		age = str2int(&buff[p]);
		p=p+4;

		if (age>tableAge[id]){
			flag = 1;
			for(i=1; i<256; i++){
				neighborTable[id][i]=1000000;
			}
		    while( (buff[p])!=0 ){
				neighborTable[id][ 0x00ff&buff[p] ]=0x00ff&buff[p+1];
				p+=2;
		    }
			tableAge[id]=age;
			printf("%d's age becomes to %d\n",id,age);
			
			if(neighborTable[id][HOSTID]<1000000&&neighborTable[HOSTID][id]<1000000){
				unneighbor_flag = 1;
			}
		}
		else{
			while( buff[p]!=0 ){
				p++;
			}
		}
		p++;
	}


	if (flag){
		findRoute();
	}
	if( unneighbor_flag ){
		set_beacon_counter(4);
	}
	pthread_mutex_unlock( &tableMutex );
	printf("---------------End of updateTable---------------\n\n");
}
Beispiel #12
0
/**
*   Should be called when a leave message is recieved, to
*   mark a route for the last member probe state.
*/
void setRouteLastMemberMode(struct in6_addr * group, struct in6_addr * src) 
{
    struct Config       *conf = getCommonConfig();
    struct RouteTable   *croute, *tmpRoute;

    croute = findRoute(group, src);
    if(croute!=NULL) 
    {
        if( !IN6_ARE_ADDR_EQUAL( src, &allzero_addr) ) 
        {
            // Check for fast leave mode...
            /*
            if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) 
            {
                // Send a leave message right away..
                sendJoinLeaveUpstream(croute, 0);
            }
            */
            // Set the routingstate to Last member check...
            croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;
            // Set the count value for expiring... (-1 since first aging)
            croute->ageValue = conf->lastMemberQueryCount;
        }
        else
        {
            tmpRoute = findNextRoute(group, NULL);
            while(tmpRoute)
            {
                // Check for fast leave mode...
                /*
                if(tmpRoute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) 
                {
                    // Send a leave message right away..
                    sendJoinLeaveUpstream(tmpRoute, 0);
                }
                */
                // Set the routingstate to Last member check...
                tmpRoute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;
                // Set the count value for expiring... (-1 since first aging)
                tmpRoute->ageValue = conf->lastMemberQueryCount;  
                if (tmpRoute->nextroute)
                    tmpRoute = findNextRoute(group, tmpRoute->nextroute);            
                else
                    break;
            }
        }
    }
}
Beispiel #13
0
/**
*   Ages groups in the last member check state. If the
*   route is not found, or not in this state, 0 is returned.
*/
int lastMemberGroupAge(struct in6_addr * group, struct in6_addr * src) 
{
    struct Config       *conf = NULL;
    struct RouteTable   *croute, *nroute;
    int i;
    
    conf = getCommonConfig();
/*
    printf("\nlastMemberGroupAge called, src = \n");
    for (i=0; i <16; i++)
        printf("%02x ",((char*)group)[i] & 255);
    printf("\n");  
    for (i=0; i <16; i++)
        printf("%02x ",((char*)src)[i] & 255);
    printf("\n");      
*/
    if( !IN6_ARE_ADDR_EQUAL( src, &allzero_addr ) ) 
    {
        croute = findRoute(group, src);
        if(croute!=NULL)
        {
            if(croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER) 
            {
                internAgeRoute(croute);
            }
        }
    }
    else
    {
        //showRoute();

        for( croute = routing_table; croute != NULL; croute = nroute )
        {        
            // Keep the next route (since current route may be removed)...
            nroute = croute->nextroute;

            // Run the aging round algorithm.
            if( croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER && 
                IN6_ARE_ADDR_EQUAL( &croute->group, group ) 
              )
            {
                // Only age routes if Last member probe is not active...
                internAgeRoute(croute);
            }
        }
    }    
    return 0;
}
Beispiel #14
0
/**
*   Should be called when a leave message is recieved, to
*   mark a route for the last member probe state.
*/
void setRouteLastMemberMode(uint32_t group) {
    struct Config       *conf = getCommonConfig();
    struct RouteTable   *croute;

    croute = findRoute(group);
    if(croute!=NULL) {
        // Check for fast leave mode...
        if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) {
            // Send a leave message right away..
            sendJoinLeaveUpstream(croute, 0);
        }
        // Set the routingstate to Last member check...
        croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;
        // Set the count value for expiring... (-1 since first aging)
        croute->ageValue = conf->lastMemberQueryCount;
    }
}
Beispiel #15
0
std::pair<RibEntry::iterator, bool>
RibEntry::insertRoute(const Route& route)
{
  iterator it = findRoute(route);

  if (it == end()) {
    if (route.flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
      m_nRoutesWithCaptureSet++;
    }

    m_routes.push_back(route);

    return std::make_pair(std::prev(m_routes.end()), true);
  }
  else {
    return std::make_pair(it, false);
  }
}
Beispiel #16
0
bool
RibEntry::insertRoute(const Route& route)
{
  iterator it = findRoute(route);

  if (it == end()) {
    if (route.flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
      m_nRoutesWithCaptureSet++;
    }

    m_routes.push_back(route);

    return true;
  }
  else {
    return false;
  }
}
Beispiel #17
0
/**
*   Should be called when a leave message is received, to
*   mark a route for the last member probe state.
*/
void setRouteLastMemberMode(uint32_t group) {
    struct Config       *conf = getCommonConfig();
    struct RouteTable   *croute;

    croute = findRoute(group);
    if(croute!=NULL) {
        // Check for fast leave mode...
        if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) {
            // Send a leave message right away only when the route has been active on only one interface
            if (numberOfInterfaces(croute) <= 1) {
                my_log(LOG_DEBUG, 0, "Leaving group %d now", group);
                sendJoinLeaveUpstream(croute, 0);
            }
        }

        // Set the routingstate to Last member check...
        croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER;

        // Set the count value for expiring... (-1 since first aging)
        croute->ageValue = conf->lastMemberQueryCount;
    }
}
Beispiel #18
0
int main()
{
    scanf ("%d%d%d%d", &N, &a, &b, &M);
    for (int u = 0; u < N; ++u)
        for (int v = 0; v < N; ++v)
            scanf("%d", &distance[u][v]);

    pingCount = 0;
    routeLength = 0;
    current = a;

    findRoute (N, a, b);

    if (current != b)
        raiseError ("Message has not reached its target");

    if (routeLength < distance[a-1][b-1] + 1)
        raiseError ("Unexpected: route is too short");

    printf ("OK\n");

    return 0;
}
Beispiel #19
0
/**
*   Adds a specified route to the routingtable.
*   If the route already exists, the existing route 
*   is updated...
*/
int insertRoute(struct in6_addr *group, struct in6_addr *src, struct sockaddr_in6 *from) 
{
    struct Config *conf = getCommonConfig();
    struct RouteTable *croute, *tmpRoute;
    //int result = 1;
/*
    int i;
    printf("insertRoute called\n");

    for (i = 0; i < 16; i ++)
        printf("%02x ", ((char*)group)[i] & 255 );
    printf("\n");

    for (i = 0; i < 16; i ++)
        printf("%02x ", ((char*)src)[i] & 255 );
    printf("\n");
*/
    

    // Sanitycheck the group adress...
    if ( !IN6_IS_ADDR_MULTICAST(group) ) 
    {
        atlog( LOG_DEBUG, 0, "Not multicast group");    
        return 0;
    }

    // Santiycheck the VIF index...
    if(from->sin6_scope_id >= MAX_MC_VIFS) 
    {
        atlog(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",
              from->sin6_scope_id,MAX_MC_VIFS);
        return 0;
    }

    // Try to find an existing route for this group...
    croute = findRoute(group, src);
    
    if(croute==NULL)
    {
        struct RouteTable*  newroute;

        /*
        IF_DEBUG atlog(LOG_DEBUG, 0, "No existing route for %s. Create new.",
                     inetFmt(group, s1));
        */

        // Create and initialize the new route table entry..
        newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));
        // Insert the route desc and clear all pointers...
        newroute->group = *group;
        newroute->originAddr = *src;
        
        newroute->nextroute  = NULL;
        newroute->prevroute  = NULL;

        // The group is not joined initially.
        newroute->upstrState = ROUTESTATE_NOTJOINED;

        // The route is not active yet, so the age is unimportant.
        newroute->ageValue    = conf->robustnessValue;
        newroute->ageActivity = 0;
        
        BIT_ZERO(newroute->ageVifBits);     // Initially we assume no listeners.

        // Set the listener flag...
        BIT_ZERO(newroute->vifBits);    // Initially no listeners...
        if(from->sin6_scope_id >= 0) 
        {
            BIT_SET(newroute->vifBits, from->sin6_scope_id);
        }

        // Check if there is a table already....
        if(routing_table == NULL) 
        {
            // No location set, so insert in on the table top.
            routing_table = newroute;
            IF_DEBUG atlog(LOG_DEBUG, 0, "No routes in table. Insert at beginning.");
        }
        else 
        {
            IF_DEBUG atlog(LOG_DEBUG, 0, "Found existing routes. Find insert location.");

            // Check if the route could be inserted at the beginning...
            if( memcmp(&routing_table->group, group, sizeof(struct in6_addr)) > 0 ) 
            {
                //IF_DEBUG atlog(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1));

                // Insert at beginning...
                newroute->nextroute = routing_table;
                newroute->prevroute = NULL;
                routing_table = newroute;

                // If the route has a next node, the previous pointer must be updated.
                if(newroute->nextroute != NULL) 
                {
                    newroute->nextroute->prevroute = newroute;
                }

            } 
            else 
            {
                // Find the location which is closest to the route.
                for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) 
                {
                    // Find insert position.
                    if( memcmp( &(croute->nextroute->group), group, sizeof(struct in6_addr) ) > 0 ) 
                        break;
                }

                //IF_DEBUG atlog(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1));
                
                // Insert after current...
                newroute->nextroute = croute->nextroute;
                newroute->prevroute = croute;
                if(croute->nextroute != NULL) 
                {
                    croute->nextroute->prevroute = newroute; 
                }
                croute->nextroute = newroute;
            }
        }

        // Set the new route as the current...
        croute = newroute;

     
        if( !IN6_ARE_ADDR_EQUAL( &croute->originAddr, &allzero_addr) ) 
        {
            // Update route in kernel...
            if( !internUpdateKernelRoute(croute, 1) ) 
            {
                atlog(LOG_WARNING, 0, "The insertion into Kernel failed.");
                return 0;
            }
        }    
    } 
    else if(from->sin6_scope_id >= 0) 
    {
        if( !IN6_ARE_ADDR_EQUAL( &croute->originAddr, &allzero_addr) ) 
        {
            // The route exists already, so just update it.
            BIT_SET(croute->vifBits, from->sin6_scope_id);
            
            // Register the VIF activity for the aging routine
            BIT_SET(croute->ageVifBits, from->sin6_scope_id);
        }
        else
        {
            tmpRoute = findNextRoute(group, NULL);
            while (tmpRoute != NULL)
            {
                // The route exists already, so just update it.
                BIT_SET(tmpRoute->vifBits, from->sin6_scope_id);
                
                // Register the VIF activity for the aging routine
                BIT_SET(tmpRoute->ageVifBits, from->sin6_scope_id);
                if (tmpRoute->nextroute)
                    tmpRoute = findNextRoute(group, tmpRoute->nextroute);  
                else
                    break;
            }
        }
    }

    // Send join message upstream, if the route has no joined flag...
    if(croute->upstrState != ROUTESTATE_JOINED)
    {
        // Send Join request upstream
        sendJoinLeaveUpstream(croute, 1);
    }

    IF_DEBUG atlogRouteTable("Insert Route");
    return 1;
}
Beispiel #20
0
void
RibEntry::eraseRoute(const Route& route)
{
  RibEntry::iterator it = findRoute(route);
  eraseRoute(it);
}
Beispiel #21
0
/**
*   Adds a specified route to the routingtable.
*   If the route already exists, the existing route 
*   is updated...
*/
int insertRoute(uint32_t group, int ifx) {
    
    struct Config *conf = getCommonConfig();
    struct RouteTable*  croute;

    // Sanitycheck the group adress...
    if( ! IN_MULTICAST( ntohl(group) )) {
        my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group. Table insert failed.",
            inetFmt(group, s1));
        return 0;
    }

    // Santiycheck the VIF index...
    //if(ifx < 0 || ifx >= MAX_MC_VIFS) {
    if(ifx >= MAX_MC_VIFS) {
        my_log(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",ifx,MAX_MC_VIFS);
        return 0;
    }

    // Try to find an existing route for this group...
    croute = findRoute(group);
    if(croute==NULL) {
        struct RouteTable*  newroute;

        my_log(LOG_DEBUG, 0, "No existing route for %s. Create new.",
                     inetFmt(group, s1));


        // Create and initialize the new route table entry..
        newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));
        // Insert the route desc and clear all pointers...
        newroute->group      = group;
        memset(newroute->originAddrs, 0, MAX_ORIGINS * sizeof(newroute->originAddrs[0]));
        newroute->nextroute  = NULL;
        newroute->prevroute  = NULL;

        // The group is not joined initially.
        newroute->upstrState = ROUTESTATE_NOTJOINED;

        // The route is not active yet, so the age is unimportant.
        newroute->ageValue    = conf->robustnessValue;
        newroute->ageActivity = 0;
        
        BIT_ZERO(newroute->ageVifBits);     // Initially we assume no listeners.

        // Set the listener flag...
        BIT_ZERO(newroute->vifBits);    // Initially no listeners...
        if(ifx >= 0) {
            BIT_SET(newroute->vifBits, ifx);
        }

        // Check if there is a table already....
        if(routing_table == NULL) {
            // No location set, so insert in on the table top.
            routing_table = newroute;
            my_log(LOG_DEBUG, 0, "No routes in table. Insert at beginning.");
        } else {

            my_log(LOG_DEBUG, 0, "Found existing routes. Find insert location.");

            // Check if the route could be inserted at the beginning...
            if(routing_table->group > group) {
                my_log(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1));

                // Insert at beginning...
                newroute->nextroute = routing_table;
                newroute->prevroute = NULL;
                routing_table = newroute;

                // If the route has a next node, the previous pointer must be updated.
                if(newroute->nextroute != NULL) {
                    newroute->nextroute->prevroute = newroute;
                }

            } else {

                // Find the location which is closest to the route.
                for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) {
                    // Find insert position.
                    if(croute->nextroute->group > group) {
                        break;
                    }
                }

                my_log(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1));
                
                // Insert after current...
                newroute->nextroute = croute->nextroute;
                newroute->prevroute = croute;
                if(croute->nextroute != NULL) {
                    croute->nextroute->prevroute = newroute; 
                }
                croute->nextroute = newroute;
            }
        }

        // Set the new route as the current...
        croute = newroute;

        // Log the cleanup in debugmode...
        my_log(LOG_INFO, 0, "Inserted route table entry for %s on VIF #%d",
            inetFmt(croute->group, s1),ifx);

    } else if(ifx >= 0) {

        // The route exists already, so just update it.
        BIT_SET(croute->vifBits, ifx);
        
        // Register the VIF activity for the aging routine
        BIT_SET(croute->ageVifBits, ifx);

        // Log the cleanup in debugmode...
        my_log(LOG_INFO, 0, "Updated route entry for %s on VIF #%d",
            inetFmt(croute->group, s1), ifx);
        
        // Update route in kernel...
        if(!internUpdateKernelRoute(croute, 1)) {
            my_log(LOG_WARNING, 0, "The insertion into Kernel failed.");
            return 0;
        }
    }

    // Send join message upstream, if the route has no joined flag...
    if(croute->upstrState != ROUTESTATE_JOINED) {
        // Send Join request upstream
        sendJoinLeaveUpstream(croute, 1);
    }

    logRouteTable("Insert Route");

    return 1;
}