Exemple #1
0
int process_map_reply(uint8_t *packet)
{
    lispd_pkt_map_reply_t       *mrp;
    uint64_t                    nonce;
    //uint8_t                     rloc_probe;
    int                         record_count;
    int                         ctr;

    mrp = (lispd_pkt_map_reply_t *)packet;
    nonce = mrp->nonce;
    record_count = mrp->record_count;

    lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply: Nonce of the Map Reply is: %s", get_char_from_nonce(nonce));

    packet = CO(packet, sizeof(lispd_pkt_map_reply_t));
    for (ctr=0;ctr<record_count;ctr++){
        if (mrp->rloc_probe == FALSE){
            if ((process_map_reply_record(&packet,nonce))==BAD){
                return (BAD);
            }
            if (is_loggable(LISP_LOG_DEBUG_3)){
                dump_map_cache_db(LISP_LOG_DEBUG_3);
            }
        }else{
            if ((process_map_reply_probe_record(&packet,nonce))==BAD){
                return (BAD);
            }
        }
    }
    return (TRUE);
}
/*
 * dump mapping
 */
void dump_mapping_entry(
        lispd_mapping_elt       *mapping,
        int                     log_level)
{
    lispd_locators_list         *locator_iterator_array[2]  = {NULL,NULL};
    lispd_locators_list         *locator_iterator           = NULL;
    lispd_locator_elt           *locator                    = NULL;
    int                         ctr                         = 0;

    if (is_loggable(log_level) == FALSE){
        return;
    }

    lispd_log_msg(log_level,"IDENTIFIER (EID): %s/%d (IID = %d)\n ", get_char_from_lisp_addr_t(mapping->eid_prefix),
            mapping->eid_prefix_length, mapping->iid);

    lispd_log_msg(log_level, "|               Locator (RLOC)            | Status | Priority/Weight |");

    if (mapping->locator_count > 0){
        locator_iterator_array[0] = mapping->head_v4_locators_list;
        locator_iterator_array[1] = mapping->head_v6_locators_list;
        // Loop through the locators and print each

        for (ctr = 0 ; ctr < 2 ; ctr++){
            locator_iterator = locator_iterator_array[ctr];
            while (locator_iterator != NULL) {
                locator = locator_iterator->locator;
                dump_locator (locator,log_level);
                locator_iterator = locator_iterator->next;
            }
        }
        lispd_log_msg(log_level,"\n");
    }
}
Exemple #3
0
void dump_map_servers(int log_level)
{
    lispd_map_server_list_t *ms         = NULL;
    char                    str[80];

    if (map_servers == NULL || is_loggable(log_level) == FALSE){
        return;
    }

    lispd_log_msg(log_level, "******************* Map-Servers list ********************************");
    lispd_log_msg(log_level, "|               Locator (RLOC)            |       Key Type          |");
    ms = map_servers;

    while (ms) {
        sprintf(str, "| %39s |",get_char_from_lisp_addr_t(*ms->address));
        if (ms->key_type == NO_KEY){
            sprintf(str + strlen(str),"          NONE           |");
        }else if (ms->key_type == HMAC_SHA_1_96){
            sprintf(str + strlen(str),"     HMAC-SHA-1-96       |");
        }else{
            sprintf(str + strlen(str),"    HMAC-SHA-256-128     |");
        }
        ms = ms->next;
        lispd_log_msg(log_level,"%s",str);
    }
}
Exemple #4
0
void dump_locator (
        lispd_locator_elt   *locator,
        int                 log_level)
{
    char locator_str [2000];
    if (is_loggable(log_level)){
        sprintf(locator_str, "| %39s |", get_char_from_lisp_addr_t(*(locator->locator_addr)));
        sprintf(locator_str + strlen(locator_str), "  %5s ", locator->state ? "Up" : "Down");
        sprintf(locator_str + strlen(locator_str), "|     %3d/%-3d     |", locator->priority, locator->weight);
        LISPD_LOG(log_level,"%s",locator_str);
    }
}
void dump_iface_list(int log_level)
{

    lispd_iface_list_elt        *interface_list    = head_interface_list;
    lispd_iface_mappings_list   *mapping_list      = NULL;
    char                        str[4000];

    if (head_interface_list == NULL || is_loggable(log_level) == FALSE){
        return;
    }

    sprintf(str,"*** LISP RLOC Interfaces List ***\n\n");

    while (interface_list){
        sprintf(str + strlen(str),"== %s   (%s)==\n",interface_list->iface->iface_name, interface_list->iface->status ? "Up" : "Down");
        if (interface_list->iface->ipv4_address){
            sprintf(str + strlen(str),"  IPv4 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv4_address)));
            sprintf(str + strlen(str),"    -- LIST mappings -- \n");
            mapping_list = interface_list->iface->head_mappings_list;
            while (mapping_list){
                if (mapping_list->use_ipv4_address == TRUE){
                    sprintf(str + strlen(str),"    %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix),
                            mapping_list->mapping->eid_prefix_length);
                }
                mapping_list = mapping_list->next;
            }
        }
        if (interface_list->iface->ipv6_address){
            sprintf(str + strlen(str),"  IPv6 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv6_address)));
            sprintf(str + strlen(str),"    -- LIST mappings -- \n");
            mapping_list = interface_list->iface->head_mappings_list;
            while (mapping_list){
                if (mapping_list->use_ipv6_address == TRUE){
                    sprintf(str + strlen(str),"    %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix),
                            mapping_list->mapping->eid_prefix_length);
                }
                mapping_list = mapping_list->next;
            }
        }
        interface_list = interface_list->next;
    }
    lispd_log_msg(log_level,"%s",str);
}
/*
 * Print balancing locators vector information
 */
void dump_balancing_locators_vec(
        balancing_locators_vecs     b_locators_vecs,
        lispd_mapping_elt           *mapping,
        int                         log_level)
{
    int     ctr         = 0;
    char    str[3000];

    if ( is_loggable(log_level)){
        lispd_log_msg(log_level,"Balancing locator vector for %s/%d: ",
                        get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length);

        sprintf(str,"  IPv4 locators vector (%d locators):  ",b_locators_vecs.v4_locators_vec_length);
        for (ctr = 0; ctr< b_locators_vecs.v4_locators_vec_length; ctr++){
            if (strlen(str) > 2850){
                sprintf(str + strlen(str)," ...");
                break;
            }
            sprintf(str + strlen(str)," %s  ",get_char_from_lisp_addr_t(*b_locators_vecs.v4_balancing_locators_vec[ctr]->locator_addr));
        }
        lispd_log_msg(log_level,"%s",str);
        sprintf(str,"  IPv6 locators vector (%d locators):  ",b_locators_vecs.v6_locators_vec_length);
        for (ctr = 0; ctr< b_locators_vecs.v6_locators_vec_length; ctr++){
            if (strlen(str) > 2900){
                sprintf(str + strlen(str)," ...");
                break;
            }
            sprintf(str + strlen(str)," %s  ",get_char_from_lisp_addr_t(*b_locators_vecs.v6_balancing_locators_vec[ctr]->locator_addr));
        }
        lispd_log_msg(log_level,"%s",str);
        sprintf(str,"  IPv4 & IPv6 locators vector (%d locators):  ", b_locators_vecs.locators_vec_length);
        for (ctr = 0; ctr< b_locators_vecs.locators_vec_length; ctr++){
            if (strlen(str) > 2950){
                sprintf(str + strlen(str)," ...");
                break;
            }
            sprintf(str + strlen(str)," %s  ",get_char_from_lisp_addr_t(*b_locators_vecs.balancing_locators_vec[ctr]->locator_addr));
        }
        lispd_log_msg(log_level,"%s",str);
    }
}
Exemple #7
0
void dump_proxy_etrs(int log_level)
{
    lispd_locators_list      *locator_lst_elt[2] = {NULL,NULL};
    int                      ctr                 = 0;

    if (proxy_etrs == NULL || is_loggable(log_level) == FALSE){
        return;
    }

    locator_lst_elt[0] = proxy_etrs->mapping->head_v4_locators_list;
    locator_lst_elt[1] = proxy_etrs->mapping->head_v6_locators_list;

    lispd_log_msg(log_level, "************************* Proxy ETRs List ****************************");
    lispd_log_msg(log_level, "|               Locator (RLOC)            | Status | Priority/Weight |");

    for (ctr = 0 ; ctr<2 ; ctr++){
        while (locator_lst_elt[ctr]){
            dump_locator (locator_lst_elt[ctr]->locator,log_level);
            locator_lst_elt[ctr] = locator_lst_elt[ctr]->next;
        }
    }
}
Exemple #8
0
int process_map_reply_record(uint8_t **cur_ptr, uint64_t nonce)
{
    lispd_pkt_mapping_record_t              *record                 = NULL;
    lispd_mapping_elt                       *mapping                = NULL;
    lispd_map_cache_entry                   *cache_entry            = NULL;
    lisp_addr_t                             aux_eid_prefix;
    int                                     aux_eid_prefix_length   = 0;
    int                                     aux_iid                 = 0;
    int                                     ctr                     = 0;
    uint8_t                                 is_new_mapping          = FALSE;

    record = (lispd_pkt_mapping_record_t *)(*cur_ptr);
    mapping = new_map_cache_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid);
    if (mapping == NULL){
        return (BAD);
    }
    *cur_ptr = (uint8_t *)&(record->eid_prefix_afi);
    if (!pkt_process_eid_afi(cur_ptr,mapping)){
        lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record:  Error processing the EID of the map reply record");
        free_mapping_elt(mapping);
        return (BAD);
    }
    mapping->eid_prefix_length = record->eid_prefix_length;


    /*
     * Check if the map replay corresponds to a not active map cache
     */

    cache_entry = lookup_nonce_in_no_active_map_caches(mapping->eid_prefix.afi, nonce);


    if (cache_entry != NULL){
        if (cache_entry->mapping->iid != mapping->iid){
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record:  Instance ID of the map reply doesn't match with the inactive map cache entry");
            free_mapping_elt(mapping);
            return (BAD);
        }
        /*
         * If the eid prefix of the received map reply doesn't match the inactive map cache entry (x.x.x.x/32 or x:x:x:x:x:x:x:x/128),then
         * we remove the inactie entry from the database and store it again with the correct eix prefix (for instance /24).
         */
        if (cache_entry->mapping->eid_prefix_length != mapping->eid_prefix_length){
            if (change_map_cache_prefix_in_db(mapping->eid_prefix, mapping->eid_prefix_length, cache_entry) != GOOD){
                free_mapping_elt(mapping);
                return (BAD);
            }
        }
        cache_entry->active = 1;
        stop_timer(cache_entry->request_retry_timer);
        cache_entry->request_retry_timer = NULL;
        lispd_log_msg(LISP_LOG_DEBUG_2,"  Activating map cache entry %s/%d",
                            get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length);
        free_mapping_elt(mapping);
        is_new_mapping = TRUE;
    }
    /* If the nonce is not found in the no active cache enties, then it should be an active cache entry */
    else {
        /* Serch map cache entry exist*/
        cache_entry = lookup_map_cache_exact(mapping->eid_prefix,mapping->eid_prefix_length);
        if (cache_entry == NULL){
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record:  No map cache entry found for %s/%d",
                    get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length);
            free_mapping_elt(mapping);
            return (BAD);
        }
        /* Check the found map cache entry contain the nonce of the map reply*/
        if (check_nonce(cache_entry->nonces,nonce)==BAD){
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record:  The nonce of the Map-Reply doesn't match the nonce of the generated Map-Request. Discarding message ...");
            free_mapping_elt(mapping);
            return (BAD);
        }else {
            free(cache_entry->nonces);
            cache_entry->nonces = NULL;
        }
        /* Stop timer of Map Requests retransmits */
        if (cache_entry->smr_inv_timer != NULL){
            stop_timer(cache_entry->smr_inv_timer);
            cache_entry->smr_inv_timer = NULL;
        }
        /* Check instane id.*/
        if (cache_entry->mapping->iid != mapping->iid){
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record:  Instance ID of the map reply doesn't match with the map cache entry");
            free_mapping_elt(mapping);
            return (BAD);
        }
        lispd_log_msg(LISP_LOG_DEBUG_2,"  A map cache entry already exists for %s/%d, replacing locators list of this entry",
                get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix),
                cache_entry->mapping->eid_prefix_length);
        free_locator_list(cache_entry->mapping->head_v4_locators_list);
        free_locator_list(cache_entry->mapping->head_v6_locators_list);
        cache_entry->mapping->head_v4_locators_list = NULL;
        cache_entry->mapping->head_v6_locators_list = NULL;
        free_mapping_elt(mapping);
    }
    cache_entry->actions = record->action;
    cache_entry->ttl = ntohl(record->ttl);
    cache_entry->active_witin_period = 1;
    cache_entry->timestamp = time(NULL);
    //locator_count updated when adding the processed locators

    /* Generate the locators */
    for (ctr=0 ; ctr < record->locator_count ; ctr++){
        if ((process_map_reply_locator (cur_ptr, cache_entry->mapping)) != GOOD){
            return(BAD);
        }
    }

    if (is_loggable(LISP_LOG_DEBUG_2)){
        dump_map_cache_entry(cache_entry, LISP_LOG_DEBUG_2);
    }

    /* [re]Calculate balancing locator vectors  if it is not a negative map reply*/
    if (cache_entry->mapping->locator_count != 0){
        calculate_balancing_vectors (
                cache_entry->mapping,
                &(((rmt_mapping_extended_info *)cache_entry->mapping->extended_info)->rmt_balancing_locators_vecs));
    }
    /*
     * Reprogramming timers
     */
    /* Expiration cache timer */
    if (!cache_entry->expiry_cache_timer){
        cache_entry->expiry_cache_timer = create_timer (EXPIRE_MAP_CACHE_TIMER);
    }
    start_timer(cache_entry->expiry_cache_timer, cache_entry->ttl*60, (timer_callback)map_cache_entry_expiration,
                     (void *)cache_entry);
    lispd_log_msg(LISP_LOG_DEBUG_1,"The map cache entry %s/%d will expire in %d minutes.",
            get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix),
            cache_entry->mapping->eid_prefix_length, cache_entry->ttl);

    /* RLOC probing timer */
    if (is_new_mapping == TRUE && rloc_probe_interval != 0){
        programming_rloc_probing(cache_entry);
    }
    return (TRUE);
}
void dump_referral_cache_entry(
        lispd_referral_cache_entry      *entry,
        int                             log_level)
{
    int                         ctr = 0;
    char                        str[400];
    lispd_locators_list         *locator_iterator_array[2]  = {NULL,NULL};
    lispd_locators_list         *locator_iterator           = NULL;
    lispd_locator_elt           *locator                    = NULL;

    if (is_loggable(log_level) == FALSE){
        return;
    }


    sprintf(str,"IDENTIFIER (EID): %s/%d (IID = %d), TTL: %d", get_char_from_lisp_addr_t(entry->mapping->eid_prefix),
            entry->mapping->eid_prefix_length, entry->mapping->iid, entry->ttl);

    switch (entry->act_entry_type){
    case NODE_REFERRAL:
        sprintf(str + strlen(str),"   Type: Node Referral ");
        break;
    case MS_REFERRAL:
        sprintf(str + strlen(str),"   Type: MS Referral ");
        break;
    case MS_ACK:
        sprintf(str + strlen(str),"   Type: MS ACK ");
        break;
    case MS_NOT_REGISTERED:
        sprintf(str + strlen(str),"   Type: Not Registered ");
        break;
    case DELEGATION_HOLE:
        sprintf(str + strlen(str),"   Type: Delegation hole ");
        break;
    case NOT_AUTHORITATIVE:
        sprintf(str + strlen(str),"   Type: Not authoritative ");
        break;
    default:
        sprintf(str + strlen(str),"   Type: %d ", entry->act_entry_type);
        break;
    }


    if (entry->parent_node != NULL){
        sprintf(str + strlen(str)," Parent (EID): %s/%d ", get_char_from_lisp_addr_t(entry->parent_node->mapping->eid_prefix),
                entry->parent_node->mapping->eid_prefix_length);
    }

    lispd_log_msg(log_level,"%s",str);

    if (entry->mapping->locator_count > 0){

        locator_iterator_array[0] = entry->mapping->head_v4_locators_list;
        locator_iterator_array[1] = entry->mapping->head_v6_locators_list;
        lispd_log_msg(log_level, "|               Locator (RLOC)            | Status | Priority/Weight |");
        // Loop through the locators and print each
        for (ctr = 0 ; ctr < 2 ; ctr++){
            locator_iterator = locator_iterator_array[ctr];
            while (locator_iterator != NULL) {
                locator = locator_iterator->locator;
                dump_locator(locator, log_level);
                locator_iterator = locator_iterator->next;
            }
        }
        lispd_log_msg(log_level,"\n");
    }
}
int process_info_reply_msg(
        uint8_t         *packet,
        lisp_addr_t     local_rloc)
{

    uint8_t                     *ptr                    = packet;

    uint8_t                     lisp_type               = 0;
    uint8_t                     reply                   = 0;

    uint64_t                    nonce                   = 0;
    uint16_t                    key_id                  = 0;
    uint16_t                    auth_data_len           = 0;
	uint8_t                     *auth_data_pos          = NULL;

    uint32_t                    ttl                     = 0;
    uint8_t                     eid_mask_len            = 0;
    lisp_addr_t                 eid_prefix              = {.afi=AF_UNSPEC};

    uint16_t                    ms_udp_port             = 0;
    uint16_t                    etr_udp_port            = 0;

    uint32_t                    info_reply_hdr_len      = 0;
    uint32_t                    lcaf_addr_len           = 0;
	uint32_t                    pckt_len                = 0;

	uint16_t                    *lcaf_afi               = NULL;

    lisp_addr_t                 global_etr_rloc         = {.afi=AF_UNSPEC};
    lisp_addr_t                 ms_rloc                 = {.afi=AF_UNSPEC};
    lisp_addr_t                 private_etr_rloc        = {.afi=AF_UNSPEC};
    lispd_rtr_locators_list     *rtr_locators_list      = NULL;

    lispd_mapping_elt           *mapping                = NULL;
    lispd_locator_elt           *locator                = NULL;
    lcl_locator_extended_info   *lcl_locator_ext_inf    = NULL;

    char                        rtrs_list_str[2000];
    int                         rtrs_list_str_size = 0;
    lispd_rtr_locators_list     *aux_rtr_locators_list  = NULL;

    uint8_t                     is_behind_nat           = FALSE;


    /*
     * Get source port and address.
     */

    err = extract_info_nat_header(ptr,
            &lisp_type,
            &reply,
            &nonce,
            &key_id,
            &auth_data_len,
            &auth_data_pos,
            &ttl,
            &eid_mask_len,
            &eid_prefix,
            &info_reply_hdr_len);

    if (err != GOOD){
        lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Couldn't process Info Reply message");
        return (BAD);
    }
    ptr = CO(ptr,info_reply_hdr_len);

    lcaf_afi = (uint16_t *)ptr;
    if ( ntohs(*lcaf_afi) != LISP_AFI_LCAF){
        lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Malformed packet");
        return (BAD);
    }

    ptr = CO(ptr,FIELD_AFI_LEN);
	/* Extract Info-Reply body fields */
    err = extract_nat_lcaf_data(ptr,
            &ms_udp_port,
            &etr_udp_port,
            &global_etr_rloc,
            &ms_rloc,
            &private_etr_rloc,
            &rtr_locators_list,
            &lcaf_addr_len);

    if (err == BAD) {
        lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Error extracting packet data");
        return (BAD);
    }

    /* Leave only RTR with same afi as the local rloc where we received the message */
    remove_rtr_locators_with_afi_different_to(&rtr_locators_list, local_rloc.afi);


    lcaf_addr_len = lcaf_addr_len + FIELD_AFI_LEN;



    /* Print the extracted information of the message */
    if (is_loggable(LISP_LOG_DEBUG_2)){
        aux_rtr_locators_list = rtr_locators_list;
        rtrs_list_str[0] = '\0';
        while (aux_rtr_locators_list != NULL){
            sprintf(rtrs_list_str + rtrs_list_str_size, "  %s ", get_char_from_lisp_addr_t(aux_rtr_locators_list->locator->address));
            rtrs_list_str_size = rtrs_list_str_size + strlen(rtrs_list_str);
            aux_rtr_locators_list = aux_rtr_locators_list->next;
        }
        lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply message data->"
                "Nonce: %s , KeyID: %hu ,TTL: %u , EID-prefix: %s/%hhu , "
                "MS UDP Port Number: %hu , ETR UDP Port Number: %hu , Global ETR RLOC Address: %s , "
                "MS RLOC Address: %s , Private ETR RLOC Address: %s, RTR RLOC Compatible list: %s",
                get_char_from_nonce(nonce), key_id, ttl, get_char_from_lisp_addr_t(eid_prefix),eid_mask_len,
                ms_udp_port, etr_udp_port, get_char_from_lisp_addr_t(global_etr_rloc),
                get_char_from_lisp_addr_t(ms_rloc),get_char_from_lisp_addr_t(private_etr_rloc),rtrs_list_str);
    }


    /* Checking the nonce */

    if (check_nonce(nat_ir_nonce,nonce) == GOOD ){
        lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct nonce field checking ");
        free(nat_ir_nonce);
        nat_ir_nonce = NULL;
    }else{
        lispd_log_msg(LISP_LOG_DEBUG_1, "Info-Reply: Error checking nonce field. No Info Request generated with nonce: %s",
                get_char_from_nonce (nonce));
        return (BAD);
    }

    /* Check authentication data */

    pckt_len = info_reply_hdr_len + lcaf_addr_len;

    if(BAD == check_auth_field(key_id, map_servers->key, (void *) packet, pckt_len, auth_data_pos)){
        lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Error checking auth data field");
        return(BAD);
    }else{
        lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct auth data field checking");
    }

	
	// TODO  Select the best RTR from the list retrieved from the Info-Reply


    /* Check if behind NAT */

    switch (compare_lisp_addr_t(&global_etr_rloc, &local_rloc)) {
    case 0:
        is_behind_nat = FALSE;
        lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is not behind NAT");
        break;
    case 1:
    case 2:
        is_behind_nat = TRUE;
        lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is behind NAT");
        break;
    case -1:
        is_behind_nat = UNKNOWN;
        lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: Unknown state");
        break;
    }

    if (is_behind_nat == TRUE){

        if (rtr_locators_list == NULL){
            lispd_log_msg(LISP_LOG_WARNING, "process_info_reply_msg: The interface with IP address %s is behind NAT"
                    " but there is no RTR compatible with local AFI", get_char_from_lisp_addr_t(local_rloc));
        }

        mapping = lookup_eid_exact_in_db(eid_prefix, eid_mask_len);
        if (mapping == NULL){
            lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply is not for any local EID");
            return (BAD);
        }
        locator = get_locator_from_mapping(mapping,local_rloc);
        if (locator == NULL){
            lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply received in the wrong locator");
            return (BAD);
        }

        lcl_locator_ext_inf = (lcl_locator_extended_info *)locator->extended_info;
        if (lcl_locator_ext_inf->rtr_locators_list != NULL){
            free_rtr_list(lcl_locator_ext_inf->rtr_locators_list);
        }
        lcl_locator_ext_inf->rtr_locators_list = rtr_locators_list;

        if (nat_status == NO_NAT || nat_status == PARTIAL_NAT){
            nat_status = PARTIAL_NAT;
        }else{
            nat_status = FULL_NAT;
        }
    }else{
        if (nat_status == FULL_NAT || nat_status == PARTIAL_NAT){
            nat_status = PARTIAL_NAT;
        }else{
            nat_status = NO_NAT;
        }
    }

    /* If we are behind NAT, the program timer to send Info Request after TTL minutes */
    if (is_behind_nat == TRUE){
        if (info_reply_ttl_timer == NULL) {
            info_reply_ttl_timer = create_timer(INFO_REPLY_TTL_TIMER);
        }
        start_timer(info_reply_ttl_timer, ttl*60, info_request, (void *)mapping);
        lispd_log_msg(LISP_LOG_DEBUG_1, "Reprogrammed info request in %d minutes",ttl);
    }else{
        stop_timer(info_reply_ttl_timer);
        info_reply_ttl_timer = NULL;
    }

    /* Once we know the NAT state we send a Map-Register */
    map_register(NULL,NULL);

    return (GOOD);
}