示例#1
0
void activate_interface_address(
    lispd_iface_elt     *iface,
    lisp_addr_t         new_address)
{
    lispd_iface_mappings_list       *mapping_list               = NULL;
    lispd_mapping_elt               *mapping                    = NULL;
    lispd_locators_list             **not_init_locators_list    = NULL;
    lispd_locators_list             **locators_list             = NULL;
    lispd_locator_elt               *locator                    = NULL;

    switch(new_address.afi) {
    case AF_INET:
        iface->out_socket_v4 = open_device_binded_raw_socket(iface->iface_name,AF_INET);
        bind_socket_src_address(iface->out_socket_v4, &new_address);
        break;
    case AF_INET6:
        iface->out_socket_v6 = open_device_binded_raw_socket(iface->iface_name,AF_INET6);
        bind_socket_src_address(iface->out_socket_v6, &new_address);
        break;
    }

    mapping_list = iface->head_mappings_list;
    /*
     * Activate the locator for each mapping associated with the interface
     */
    while (mapping_list != NULL) {
        mapping = mapping_list->mapping;
        lispd_log_msg(LISP_LOG_DEBUG_2,"Activating locator %s associated to the EID %s/%d\n",
                      get_char_from_lisp_addr_t(new_address),
                      get_char_from_lisp_addr_t(mapping->eid_prefix),
                      mapping->eid_prefix_length);
        not_init_locators_list = &(((lcl_mapping_extended_info *)mapping->extended_info)->head_not_init_locators_list);
        locator = extract_locator_from_list (not_init_locators_list, new_address);
        if (locator != NULL) {
            switch(new_address.afi) {
            case AF_INET:
                mapping_list->use_ipv4_address = TRUE;
                locators_list = &mapping->head_v4_locators_list;
                break;
            case AF_INET6:
                mapping_list->use_ipv6_address = TRUE;
                locators_list = &mapping->head_v6_locators_list;
                break;
            }
            /* Add the activated locator */
            if (add_locator_to_list (locators_list,locator) == GOOD) {
                mapping->locator_count = mapping->locator_count + 1;
            } else {
                free_locator(locator);
            }
        } else {
            lispd_log_msg(LISP_LOG_DEBUG_1,"activate_interface_address: No locator with address %s has been found"
                          " in the not init locators list of the mapping %s/%d. Is priority equal to -1 for this EID and afi?",
                          get_char_from_lisp_addr_t(new_address),
                          get_char_from_lisp_addr_t(mapping->eid_prefix),
                          mapping->eid_prefix_length);
        }
        mapping_list = mapping_list->next;
    }
}
示例#2
0
int process_not_authoritative_reply(
        lispd_referral_cache_entry              *referral_entry,
        lispd_pending_referral_cache_entry      *pending_referral_entry)
{
    lispd_log_msg(LISP_LOG_DEBUG_2,"process_not_authoritative_reply: Node %s is not authoritative for the requested prefix %s/%d. "
            "Asking next ddt node.", get_char_from_lisp_addr_t(referral_entry->src_inf_ddt_node_locator_addr),
            get_char_from_lisp_addr_t(pending_referral_entry->map_cache_entry->mapping->eid_prefix),
            pending_referral_entry->map_cache_entry->mapping->eid_prefix_length);

    err = try_next_referral_node_or_go_through_root (pending_referral_entry);
    if (err != GOOD){
        if (err == ERR_DST_ADDR){
            err = activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix,
                    referral_entry->mapping->eid_prefix_length,1,MAPPING_ACT_NO_ACTION);
            if (err != GOOD){
                del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix,
                        pending_referral_entry->map_cache_entry->mapping->eid_prefix_length);
            }
        }
        remove_pending_referral_cache_entry_from_list(pending_referral_entry);
    }
    free_referral_cache_entry(referral_entry);

    return (err);
}
示例#3
0
int build_and_send_map_reply_msg(
        lispd_mapping_elt   *requested_mapping,
        lisp_addr_t         *src_rloc_addr,
        lisp_addr_t         *dst_rloc_addr,
        uint16_t            dport,
        uint64_t            nonce,
        map_reply_opts      opts)
{
    uint8_t         *map_reply_pkt      = NULL;
    int             map_reply_pkt_len   = 0;
    int             result              = 0;

    lispd_log_msg(LISP_LOG_DEBUG_2,"Build Map Reply Packet");

    /* Build the packet */
    if (opts.rloc_probe == TRUE){
        map_reply_pkt = build_map_reply_pkt(requested_mapping, src_rloc_addr, opts, nonce, &map_reply_pkt_len);
    }
    else{
        map_reply_pkt = build_map_reply_pkt(requested_mapping, NULL, opts, nonce, &map_reply_pkt_len);
    }
    if (map_reply_pkt == NULL){
        lispd_log_msg(LISP_LOG_DEBUG_1,"build_and_send_map_reply_msg: Couldn't send Map-Reply for requested EID %s/%d ",
                get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                requested_mapping->eid_prefix_length);
        return (BAD);
    }

    err = send_control_msg(map_reply_pkt,
            map_reply_pkt_len,
            src_rloc_addr,
            dst_rloc_addr,
            LISP_CONTROL_PORT,
            dport);
    free (map_reply_pkt);


    if (err == GOOD){
        if (opts.rloc_probe == TRUE){
            lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Reply packet for %s/%d probing local locator %s",
                    get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                    requested_mapping->eid_prefix_length,
                    get_char_from_lisp_addr_t(*src_rloc_addr));
        }else{
            lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Reply packet for %s/%d",
                    get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                    requested_mapping->eid_prefix_length);
        }
        result = GOOD;
    }else {
        if (opts.rloc_probe == TRUE){
            lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't build/send Probe Reply!");
        }else{
            lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't build/send Map-Reply!");
        }
        result = BAD;
    }

    return (result);
}
示例#4
0
int send_udp_ctrl_packet(
        lisp_addr_t *dst_addr,
        uint16_t    src_port,
        uint16_t    dst_port,
        void        *packet,
        int         packet_len)
{
    switch (dst_addr->afi){
    case AF_INET:
        if (default_ctrl_iface_v4 != NULL){
            err = send_udp_ipv4_packet(default_ctrl_iface_v4->ipv4_address,dst_addr,src_port,dst_port,(void *)packet,packet_len);
        }else{
            LISPD_LOG(LISP_LOG_DEBUG_1,"No local RLOC compatible with the afi of the destinaion locator %s",
                    get_char_from_lisp_addr_t(*dst_addr));
            err = BAD;
        }
        break;
    case AF_INET6:
        if (default_ctrl_iface_v6 != NULL){
            err = send_udp_ipv6_packet(default_ctrl_iface_v6->ipv6_address,dst_addr,src_port,dst_port,(void *)packet,packet_len);
        }else{
            LISPD_LOG(LISP_LOG_DEBUG_1,"No local RLOC compatible with the afi of the destination locator %s",
                    get_char_from_lisp_addr_t(*dst_addr));
            err = BAD;
        }
        break;
    }
    return err;
}
示例#5
0
int send_map_request_miss(timer *t, void *arg)
{
    timer_map_request_argument *argument = (timer_map_request_argument *)arg;
    lispd_map_cache_entry *map_cache_entry = argument->map_cache_entry;
    nonces_list *nonces = map_cache_entry->nonces;
    lisp_addr_t *dst_rloc = NULL;

    if (nonces == NULL){
        nonces = new_nonces_list();
        if (nonces==NULL){
            lispd_log_msg(LISP_LOG_WARNING,"Send_map_request_miss: Unable to allocate memory for nonces.");
            return (BAD);
        }
        map_cache_entry->nonces = nonces;
    }

    if (nonces->retransmits - 1 < map_request_retries ){

        if (map_cache_entry->request_retry_timer == NULL){
            map_cache_entry->request_retry_timer = create_timer (MAP_REQUEST_RETRY_TIMER);
        }

        if (nonces->retransmits > 0){
            lispd_log_msg(LISP_LOG_DEBUG_1,"Retransmiting Map Request for EID: %s (%d retries)",
                    get_char_from_lisp_addr_t(map_cache_entry->mapping->eid_prefix),
                    nonces->retransmits);
        }

        /* Get the RLOC of the Map Resolver to be used */
        dst_rloc = get_map_resolver();

        if ((dst_rloc == NULL) || (build_and_send_map_request_msg(
                map_cache_entry->mapping,
                &(argument->src_eid),
                dst_rloc,
                1,
                0,
                0,
                0,
                &nonces->nonce[nonces->retransmits]))==BAD){
            lispd_log_msg (LISP_LOG_DEBUG_1, "send_map_request_miss: Couldn't send map request for a new map cache entry");

        }

        nonces->retransmits ++;
        start_timer(map_cache_entry->request_retry_timer, LISPD_INITIAL_MRQ_TIMEOUT,
                send_map_request_miss, (void *)argument);

    }else{
        lispd_log_msg(LISP_LOG_DEBUG_1,"No Map Reply fot EID %s/%d after %d retries. Removing map cache entry ...",
                        get_char_from_lisp_addr_t(map_cache_entry->mapping->eid_prefix),
                        map_cache_entry->mapping->eid_prefix_length,
                        nonces->retransmits -1);
        del_map_cache_entry_from_db(map_cache_entry->mapping->eid_prefix,
                map_cache_entry->mapping->eid_prefix_length);

    }
    return GOOD;
}
示例#6
0
/*
 * 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");
    }
}
示例#7
0
int forward_native(
        char            *packet_buf,
        int             pckt_length )
{

    int             ret                        = 0;
    int             output_socket              = 0;
    int             packet_afi                 = 0;

    packet_afi = get_afi_from_packet((uint8_t *)packet_buf);
    output_socket = get_default_output_socket(packet_afi);


    if (output_socket == -1){
        lispd_log_msg(LISP_LOG_DEBUG_2, "fordward_native: No output interface for afi %d",packet_afi);
        return (BAD);
    }


    lispd_log_msg(LISP_LOG_DEBUG_3, "Fordwarding native for destination %s",
            get_char_from_lisp_addr_t(extract_dst_addr_from_packet(packet_buf)));

    ret = send_packet(output_socket,packet_buf,pckt_length);

    return (ret);

}
示例#8
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);
    }
}
示例#9
0
/*
 * Restart from root all pending referrals which its previous referral has expired.
 * @param expired_referral_cache Referral cache entry that has expired
 */
void reset_pending_referrals_with_expired_previous_referral(lispd_referral_cache_entry *expired_referral_cache)
{
    lispd_pending_referral_cache_list   *pending_referrals      = pening_referrals_list;
    lispd_pending_referral_cache_entry  *pending_referral_entry = NULL;

    while (pending_referrals != NULL){
        if (pending_referrals->pending_referral_cache_entry->previous_referral == expired_referral_cache){
            pending_referral_entry = pending_referrals->pending_referral_cache_entry;
            pending_referral_entry->previous_referral = get_root_referral_cache(pending_referral_entry->map_cache_entry->mapping->eid_prefix.afi);
            pending_referral_entry->tried_locators = 0;
            pending_referral_entry->request_through_root = TRUE;
            if (pending_referral_entry->nonces != NULL){
                free(pending_referral_entry->nonces);
                pending_referral_entry->nonces = NULL;
            }
            if (pending_referral_entry->ddt_request_retry_timer != NULL){
                stop_timer(pending_referral_entry->ddt_request_retry_timer);
                pending_referral_entry->ddt_request_retry_timer = NULL;
            }
            lispd_log_msg(LISP_LOG_DEBUG_1,"reset_pending_referrals_with_expired_previous_referral: Resetting of pending referral cache "
                    "%s/%d due to expiration of its parent referral node. Restart from root",
                    get_char_from_lisp_addr_t(pending_referral_entry->map_cache_entry->mapping->eid_prefix),
                    pending_referral_entry->map_cache_entry->mapping->eid_prefix_length);
            err = send_ddt_map_request_miss(NULL,(void *)pending_referral_entry);
        }
        pending_referrals = pending_referrals->next;
    }
}
示例#10
0
void *pkt_fill_mapping_record(
    lispd_pkt_mapping_record_t              *rec,
    lispd_mapping_elt                       *mapping,
    lisp_addr_t                             *probed_rloc)
{
    int                                     cpy_len             = 0;
    lispd_pkt_mapping_record_locator_t      *loc_ptr            = NULL;
    lispd_locators_list                     *locators_list[2]   = {NULL,NULL};
    lispd_locator_elt                       *locator            = NULL;
    int                                     ctr                 = 0;

    if ((rec == NULL) || (mapping == NULL))
        return NULL;

    rec->ttl                    = htonl(DEFAULT_MAP_REGISTER_TIMEOUT);
    rec->locator_count          = mapping->locator_count;
    rec->eid_prefix_length      = mapping->eid_prefix_length;
    rec->action                 = 0;
    rec->authoritative          = 1;
    rec->version_hi             = 0;
    rec->version_low            = 0;

    loc_ptr = (lispd_pkt_mapping_record_locator_t *)pkt_fill_eid(&(rec->eid_prefix_afi), mapping);

    if (loc_ptr == NULL){
        return NULL;
    }

    locators_list[0] = mapping->head_v4_locators_list;
    locators_list[1] = mapping->head_v6_locators_list;
    for (ctr = 0 ; ctr < 2 ; ctr++){
        while (locators_list[ctr]) {
            locator              = locators_list[ctr]->locator;
            loc_ptr->priority    = locator->priority;
            loc_ptr->weight      = locator->weight;
            loc_ptr->mpriority   = locator->mpriority;
            loc_ptr->mweight     = locator->mweight;
            loc_ptr->local       = 1;
            if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){
                loc_ptr->probed  = 1;
            }
            loc_ptr->reachable   = *(locator->state);
            loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL));

            if ((cpy_len = copy_addr((void *) CO(loc_ptr,
                    sizeof(lispd_pkt_mapping_record_locator_t)), locator->locator_addr, 0)) == 0) {
                LISPD_LOG(LISP_LOG_DEBUG_3, "copy_addr failed for locator %s",
                        get_char_from_lisp_addr_t(*(locator->locator_addr)));
                return(NULL);
            }

            loc_ptr = (lispd_pkt_mapping_record_locator_t *)
                            CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len));
            locators_list[ctr] = locators_list[ctr]->next;
        }
    }
    return (void *)loc_ptr;
}
示例#11
0
int process_map_reply_probe_locator(
        uint8_t                 **offset,
        lispd_mapping_elt       *mapping,
        uint64_t                nonce,
        lispd_locator_elt       **locator)
{
    lispd_pkt_mapping_record_locator_t  *pkt_locator    = NULL;
    lispd_locator_elt                   *aux_locator    = NULL;
    uint8_t                             *cur_ptr        = NULL;


    *locator = NULL;
    cur_ptr = *offset;
    pkt_locator = (lispd_pkt_mapping_record_locator_t *)(cur_ptr);

    cur_ptr = (uint8_t *)&(pkt_locator->locator_afi);

    /* Extract locator from packet */
    aux_locator = new_rmt_locator (&cur_ptr,UP,
            pkt_locator->priority, pkt_locator->weight,
            pkt_locator->mpriority, pkt_locator->mweight);

    if (aux_locator != NULL){
        /* If the locator of the packed is probed, search the structure of the locator that represents the locator of tha packet */
        if (pkt_locator->probed == TRUE){
            *locator = get_locator_from_mapping(mapping, aux_locator->locator_addr);
            if (*locator == NULL){
                lispd_log_msg(LISP_LOG_DEBUG_2,"get_map_reply_locator_from_mapping: The locator %s is not found in the mapping %s/%d",
                        get_char_from_lisp_addr_t(*(aux_locator->locator_addr)),
                        get_char_from_lisp_addr_t(mapping->eid_prefix),
                        mapping->eid_prefix_length);
                return (ERR_NO_EXIST);
            }
        }
    }else{
        if (err != ERR_AFI_LCAF_TYPE){

            return (err);
        }
    }

    *offset = cur_ptr;
    return (GOOD);
}
示例#12
0
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);
}
示例#13
0
void set_default_ctrl_ifaces()
{
    default_ctrl_iface_v4 = get_any_output_iface(AF_INET);

    if (default_ctrl_iface_v4 != NULL) {
       lispd_log_msg(LISP_LOG_DEBUG_2,"Default IPv4 control iface %s: %s\n",
               default_ctrl_iface_v4->iface_name, get_char_from_lisp_addr_t(*(default_ctrl_iface_v4->ipv4_address)));
    }

    default_ctrl_iface_v6 = get_any_output_iface(AF_INET6);
    if (default_ctrl_iface_v6 != NULL) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"Default IPv6 control iface %s: %s\n",
                default_ctrl_iface_v6->iface_name, get_char_from_lisp_addr_t(*(default_ctrl_iface_v6->ipv6_address)));
    }

    // XXX alopez If no output interface found exit --> To be modified when iface management implemented
    if (!default_ctrl_iface_v4 && !default_ctrl_iface_v6){
        lispd_log_msg(LISP_LOG_ERR,"NO CONTROL IFACE: all the locators are down");
    }
}
示例#14
0
/*
 * 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);
    }
}
示例#15
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);
    }
}
示例#16
0
/*
 * Add a locator into the locators list of the mapping.
 */
int add_locator_to_mapping(
        lispd_mapping_elt           *mapping,
        lispd_locator_elt           *locator)
{
    int result = GOOD;

    switch (locator->locator_addr->afi){
    case AF_INET:
        err = add_locator_to_list (&(mapping->head_v4_locators_list), locator);
        break;
    case AF_INET6:
        err = add_locator_to_list (&(mapping->head_v6_locators_list), locator);
        break;
    case AF_UNSPEC:
        err = add_locator_to_list (&(((lcl_mapping_extended_info *)(mapping->extended_info))->head_not_init_locators_list), locator);
        if (err == GOOD){
            // The locator_count should not be incremented
            return (GOOD);
        }
    }

    if (err == GOOD){
        mapping->locator_count++;
        lispd_log_msg(LISP_LOG_DEBUG_3, "add_locator_to_mapping: The locator %s has been added to the EID %s/%d.",
                get_char_from_lisp_addr_t(*(locator->locator_addr)),
                get_char_from_lisp_addr_t(mapping->eid_prefix),
                mapping->eid_prefix_length);
        result = GOOD;
    }else if (err == ERR_EXIST){
        lispd_log_msg(LISP_LOG_DEBUG_3, "add_locator_to_mapping: The locator %s already exists for the EID %s/%d.",
                get_char_from_lisp_addr_t(*(locator->locator_addr)),
                get_char_from_lisp_addr_t(mapping->eid_prefix),
                mapping->eid_prefix_length);
        result = GOOD;
    }else{
        result = BAD;
    }

    return (result);
}
示例#17
0
 int process_map_request_record(
         uint8_t **cur_ptr,
         lisp_addr_t *local_rloc,
         lisp_addr_t *remote_rloc,
         uint16_t dst_port,
         uint8_t rloc_probe,
         uint64_t nonce)
 {
     lispd_pkt_map_request_eid_prefix_record_t  *record                 = NULL;
     lispd_mapping_elt                          *requested_mapping      = NULL;
     lispd_mapping_elt                          *mapping                = NULL;
     map_reply_opts                             opts;
     lisp_addr_t                                aux_eid_prefix;
     int                                        aux_eid_prefix_length   = 0;
     int                                        aux_iid                 = -1;

     /* Get the requested EID prefix */
     record = (lispd_pkt_map_request_eid_prefix_record_t *)*cur_ptr;
     /* Auxiliar lispd_mapping_elt created to be filled with pkt_process_eid_afi */
     requested_mapping = new_local_mapping(aux_eid_prefix, aux_eid_prefix_length, aux_iid);
     if (requested_mapping == NULL){
         return (BAD);
     }
     *cur_ptr = (uint8_t *)&(record->eid_prefix_afi);
     if ((err=pkt_process_eid_afi(cur_ptr, requested_mapping))!=GOOD){
         lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_request_record: Requested EID could not be processed");
         free_mapping_elt (requested_mapping, TRUE);
         return (err);
     }
     requested_mapping->eid_prefix_length = record->eid_prefix_length;

     /* Check the existence of the requested EID */
     /*  We don't use prefix mask and use by default 32 or 128*/
     mapping = lookup_eid_in_db(requested_mapping->eid_prefix);
     if (!mapping){
         lispd_log_msg(LISP_LOG_DEBUG_1,"The requested EID doesn't belong to this node: %s/%d",
                 get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                 requested_mapping->eid_prefix_length);
         free_mapping_elt (requested_mapping, TRUE);
         return (BAD);
     }
     free_mapping_elt (requested_mapping, TRUE);

     /* Set flags for Map-Reply */
     opts.send_rec   = 1;
     opts.echo_nonce = 0;
     opts.rloc_probe = rloc_probe;

     err = build_and_send_map_reply_msg(mapping, local_rloc, remote_rloc, dst_port, nonce, opts);

     return (err);
 }
示例#18
0
int fordward_to_petr(
        char                    *original_packet,
        int                     original_packet_length,
        lispd_mapping_elt       *src_mapping,
        packet_tuple            tuple)
{
    lispd_locator_elt       *outer_src_locator  = NULL;
    lispd_locator_elt       *outer_dst_locator  = NULL;
    char                    *encap_packet       = NULL;
    int                     encap_packet_size   = 0;
    int                     output_socket       = 0;

    if (proxy_etrs == NULL){
        lispd_log_msg(LISP_LOG_DEBUG_3, "fordward_to_petr: Proxy-etr not found");
        return (BAD);
    }

    if ((select_src_rmt_locators_from_balancing_locators_vec (
                src_mapping,
                proxy_etrs->mapping,
                tuple,
                &outer_src_locator,
                &outer_dst_locator)) != GOOD){
        lispd_log_msg(LISP_LOG_DEBUG_3, "fordward_to_petr: No Proxy-etr compatible with local locators afi");
        return (BAD);
    }

    if (encapsulate_packet(original_packet,
            original_packet_length,
            outer_src_locator->locator_addr,
            outer_dst_locator->locator_addr,
            LISP_DATA_PORT,
            LISP_DATA_PORT,
            0,
            &encap_packet,
            &encap_packet_size) != GOOD){
        return (BAD);
    }

    output_socket = ((lcl_locator_extended_info *)(outer_src_locator->extended_info))->out_socket;

    if (send_packet (output_socket,encap_packet,encap_packet_size ) != GOOD){
        free (encap_packet );
        return (BAD);
    }

    lispd_log_msg(LISP_LOG_DEBUG_3, "Fordwarded eid %s to petr",get_char_from_lisp_addr_t(extract_dst_addr_from_packet(original_packet)));
    free (encap_packet );

    return (GOOD);
}
int add_route(
        int                 afi,
        uint32_t            ifindex,
        lisp_addr_t         *dest,
        lisp_addr_t         *src,
        lisp_addr_t         *gw,
        uint32_t            prefix_len,
        uint32_t            metric,
        uint32_t            table)
{
    int result = BAD;
    result = modify_route(RTM_NEWROUTE, afi,ifindex, dest, src, gw, prefix_len, metric, table);
    if (result == GOOD){
        lispd_log_msg(LISP_LOG_DEBUG_1, "add_route: added route to the system: src addr: %s, dst prefix:%s/%d, gw: %s, table: %d",
                (src != NULL) ? get_char_from_lisp_addr_t(*src) : "-",
                (dest != NULL) ? get_char_from_lisp_addr_t(*dest) : "-",
                prefix_len,
                (gw != NULL) ? get_char_from_lisp_addr_t(*gw) : "-",
                table);
    }

    return (result);
}
示例#20
0
/*
 * Remove a referral and all its offspring
 */
int referral_expiry(
        timer   *t,
        void    *arg)
{
    lispd_referral_cache_entry *referral_entry = (lispd_referral_cache_entry *)arg;

    lispd_log_msg(LISP_LOG_DEBUG_1,"referral_expiry: The referral entry with prefix %s/%d has expired. "
            "Removing it and all its offspring", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix),
            referral_entry->mapping->eid_prefix_length);

    remove_referral_cache_entry_from_parent_node(referral_entry);
    del_referral_cache_entry_from_db(referral_entry);
    dump_referral_cache_db(LISP_LOG_DEBUG_3);
    return (GOOD);
}
示例#21
0
int process_ms_not_registered_reply(
        lispd_referral_cache_entry              *referral_entry,
        lispd_pending_referral_cache_entry      *pending_referral_entry)
{
    lispd_referral_cache_entry              *db_referral_entry = NULL;

    db_referral_entry = lookup_referral_cache_exact(
            referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES);

    /* Add referral cache entry to database */
    if (db_referral_entry == NULL){
        if (add_referral_cache_entry_to_db(referral_entry) != GOOD){
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_not_registered_reply: Coudn't add referral cache entry for prefix %s/%d",
                    get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length);
            free_referral_cache_entry(referral_entry);
            remove_pending_referral_cache_entry_from_list(pending_referral_entry);
            return (BAD);
        }
        add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry);
        pending_referral_entry->previous_referral = referral_entry;
    }else{
        /* Entry already exist. Replace it with the new data. Valid if the previous entry was a ms ack or ms not registered ack */
        update_referral_cache_data(db_referral_entry, referral_entry);
        free_referral_cache_entry(referral_entry);
        referral_entry = db_referral_entry;
    }
    /* Try with the next ddt node*/
    pending_referral_entry->tried_locators = pending_referral_entry->tried_locators + 1;
    lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_not_registered_reply: Receive a MS_NOT_REGISTERED referral. Trying next node");
    err = send_ddt_map_request_miss(NULL,(void *)pending_referral_entry);
    /* If we asked to all MS where prefix is delegated and all reply  MS_NOT_REGISTERED, remove entry from pending list
     * and activate map cache*/
    if (err == ERR_DST_ADDR){
        lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_not_registered_reply: Tried all noedes. Activate negative map reply");
        if (activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix,
                referral_entry->mapping->eid_prefix_length,referral_entry->ttl,MAPPING_ACT_NO_ACTION) != GOOD){
            del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix,
                    pending_referral_entry->map_cache_entry->mapping->eid_prefix_length);
        }
        remove_pending_referral_cache_entry_from_list(pending_referral_entry);
        /* Program expiry time */
        program_referral_expiry_timer(referral_entry);
    }
    return (GOOD);
}
示例#22
0
int process_ms_ack_reply(
        lispd_referral_cache_entry              *referral_entry,
        lispd_pending_referral_cache_entry      *pending_referral_entry)
{
    lispd_referral_cache_entry              *db_referral_entry = NULL;

    db_referral_entry = lookup_referral_cache_exact(
            referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES);

    /* Add referral cache entry to database */
    if (db_referral_entry == NULL){
        if (add_referral_cache_entry_to_db(referral_entry) != GOOD){
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_ack_reply: Coudn't add referral cache entry for prefix %s/%d",
                    get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length);
            free_referral_cache_entry(referral_entry);
            remove_pending_referral_cache_entry_from_list(pending_referral_entry);
            return (BAD);
        }
        add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry);
    }else{
        /* Entry already exist. Replace it with the new data. Valid if the previous entry was a ms ack or ms not registered ack */
        update_referral_cache_data(db_referral_entry, referral_entry);
        free_referral_cache_entry(referral_entry);
        referral_entry = db_referral_entry;
    }

    /* Program expiry time */
    program_referral_expiry_timer(referral_entry);
    /* Finish process and remove the pending referral cache from the list */
    if (pending_referral_entry->map_cache_entry->active == TRUE){
        // We have received a map reply
        remove_pending_referral_cache_entry_from_list(pending_referral_entry);
    }
    else{
        if (pending_referral_entry->ddt_request_retry_timer == NULL){
            pending_referral_entry->ddt_request_retry_timer = create_timer (DDT_MAP_REQ_RETRY_MS_ACK_TIMER);
        }
        pending_referral_entry->previous_referral = referral_entry;
        start_timer(pending_referral_entry->ddt_request_retry_timer, LISPD_INITIAL_MRQ_TIMEOUT,
                send_map_request_ddt_map_reply_miss, (void *)pending_referral_entry);
    }

    return (GOOD);
}
示例#23
0
void dump_servers(
        lispd_addr_list_t   *list,
        const char          *list_name,
        int                 log_level)
{ 
    lispd_addr_list_t   *iterator = 0;

    if (!list)
        return;

    lispd_log_msg(log_level, "************* %13s ***************", list_name);
    lispd_log_msg(log_level, "|               Locator (RLOC)            |");

    iterator = list;
    while (iterator) {
        lispd_log_msg(log_level,"| %39s |", get_char_from_lisp_addr_t(*(iterator->address)));
        iterator = iterator->next;
    }
}
示例#24
0
int process_delegation_hole_reply(
        lispd_referral_cache_entry              *referral_entry,
        lispd_pending_referral_cache_entry      *pending_referral_entry)
{

    lispd_referral_cache_entry              *db_referral_entry = NULL;

    db_referral_entry = lookup_referral_cache_exact(
            referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES);

    if (db_referral_entry != NULL && db_referral_entry->act_entry_type != DELEGATION_HOLE){
        del_referral_cache_entry_from_db(db_referral_entry);
        db_referral_entry = NULL;
    }
    if (db_referral_entry == NULL){
        /* Add referral cache entry to database */

        if (add_referral_cache_entry_to_db(referral_entry) != GOOD){
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_delegation_hole_reply: Coudn't add referral cache entry for prefix %s/%d",
                    get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length);
            free_referral_cache_entry(referral_entry);
            remove_pending_referral_cache_entry_from_list(pending_referral_entry);
            return (BAD);
        }
        add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry);
    }else{
        /* Entry already exist. Replace it with the new data.*/
        update_referral_cache_data(db_referral_entry, referral_entry);
        free_referral_cache_entry(referral_entry);
        referral_entry = db_referral_entry;
    }
    /*Remove entry from pending list and activate map cache*/
    if (activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix,
            referral_entry->mapping->eid_prefix_length,referral_entry->ttl,MAPPING_ACT_NO_ACTION)!=GOOD){
        del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix,
                           pending_referral_entry->map_cache_entry->mapping->eid_prefix_length);
    }
    remove_pending_referral_cache_entry_from_list(pending_referral_entry);
    /* Program expiry time */
    program_referral_expiry_timer(referral_entry);
    return(GOOD);
}
示例#25
0
void process_nl_del_address (struct nlmsghdr *nlh)
{
    struct ifaddrmsg    *ifa            = NULL;
    struct rtattr       *rth            = NULL;
    int                 iface_index     = 0;
    int                 rt_length       = 0;
    lispd_iface_elt     *iface          = NULL;
    lisp_addr_t         new_addr;
    char                iface_name[IF_NAMESIZE];

    ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh);
    iface_index = ifa->ifa_index;

    iface = get_interface_from_index(iface_index);

    if (iface == NULL) {
        if_indextoname(iface_index, iface_name);
        lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_add_address: the netlink message is not for any interface associated with RLOCs (%s)",
                      iface_name);
        return;
    }
    rth = IFA_RTA (ifa);

    rth = IFA_RTA (ifa);
    rt_length = IFA_PAYLOAD (nlh);
    for (; rt_length && RTA_OK (rth, rt_length); rth = RTA_NEXT (rth,rt_length))
    {
        if (rth->rta_type == IFA_ADDRESS) {
            if (ifa->ifa_family == AF_INET) {
                memcpy (&(new_addr.address),(struct in_addr *)RTA_DATA(rth),sizeof(struct in_addr));
                new_addr.afi = AF_INET;
            } else if (ifa->ifa_family == AF_INET6) {
                memcpy (&(new_addr.address),(struct in6_addr *)RTA_DATA(rth),sizeof(struct in6_addr));
                new_addr.afi = AF_INET6;
            }
            break;
        }
    }
    /* Actions to be done when address is removed */
    lispd_log_msg(LISP_LOG_DEBUG_2,"   deleted address: %s\n", get_char_from_lisp_addr_t(new_addr));
}
/*
 * This function deletes a specific ip rule to
 * kernel's rule list
 */
int del_rule(
        int         afi,
        int         if_index,
        uint8_t     table,
        uint32_t    priority,
        uint8_t     type,
        lisp_addr_t *src_addr,
        int         src_plen,
        lisp_addr_t *dst_addr,
        int         dst_plen,
        int         flags)
{
    int result = BAD;
    result = modify_rule(afi, if_index, RTM_DELRULE, table,priority, type, src_addr, src_plen, dst_addr, dst_plen, flags);
    if (result == GOOD){
        lispd_log_msg(LISP_LOG_DEBUG_1, "del_rule: Removed rule for source routing of src addr: %s",
                get_char_from_lisp_addr_t(*src_addr));
    }

    return (result);
}
示例#27
0
int remove_pending_referral_cache_entry_from_list(lispd_pending_referral_cache_entry *pending_referral)
{
    lispd_pending_referral_cache_list       *list_elt           = NULL;
    lispd_pending_referral_cache_list       *prev_list_elt      = NULL;
    uint8_t                                 entry_found         = FALSE;
    uint8_t                                 result              = FALSE;

    list_elt = pening_referrals_list;

    while (list_elt != NULL){
        if (list_elt->pending_referral_cache_entry == pending_referral){
            if (prev_list_elt == NULL){
                pening_referrals_list = list_elt->next;
            }else{
                prev_list_elt->next = list_elt->next;
            }
            entry_found = TRUE;
            break;
        }
        prev_list_elt = list_elt;
        list_elt = list_elt->next;
    }

    if (entry_found == TRUE){
        free (list_elt);
        result = GOOD;
    }else{
        lispd_log_msg(LISP_LOG_DEBUG_1,"remove_pending_referral_cache_entry_from_list: The entry %s/%d has not been found"
                " in the list of pending referral cache entries", get_char_from_lisp_addr_t(pending_referral->map_cache_entry->mapping->eid_prefix),
                pending_referral->map_cache_entry->mapping->eid_prefix_length);
        result = BAD;
    }
    free_pending_referral_cache_entry(pending_referral);

    return (result);
}
示例#28
0
/*
 * Add a locator to a locators list
 */
int add_locator_to_list (
        lispd_locators_list         **list,
        lispd_locator_elt           *locator)
{
    lispd_locators_list     *locator_list           = NULL,
                            *aux_locator_list_prev  = NULL,
                            *aux_locator_list_next  = NULL;
    int                     cmp                     = 0;

    if ((locator_list = malloc(sizeof(lispd_locators_list))) == NULL) {
        LISPD_LOG(LISP_LOG_WARNING, "Unable to allocate memory for lispd_locator_list: %s", strerror(errno));
        return(ERR_MALLOC);
    }

    locator_list->next = NULL;
    locator_list->locator = locator;
    if (locator->locator_type == LOCAL_LOCATOR &&
            locator->locator_addr->afi != AF_UNSPEC){ /* If it's a local initialized locator, we should store it in order*/
        if (*list == NULL){
            *list = locator_list;
        }else{
            aux_locator_list_prev = NULL;
            aux_locator_list_next = *list;
            while (aux_locator_list_next != NULL){
                if (locator->locator_addr->afi == AF_INET){
                    cmp = memcmp(&(locator->locator_addr->address.ip),&(aux_locator_list_next->locator->locator_addr->address.ip),sizeof(struct in_addr));
                } else {
                    cmp = memcmp(&(locator->locator_addr->address.ipv6),&(aux_locator_list_next->locator->locator_addr->address.ipv6),sizeof(struct in6_addr));
                }
                if (cmp < 0){
                    break;
                }
                if (cmp == 0){
                    LISPD_LOG(LISP_LOG_DEBUG_3, "The locator %s already exists.",
                            get_char_from_lisp_addr_t(*(locator->locator_addr)));
                    free (locator_list);
                    return (ERR_EXIST);
                }
                aux_locator_list_prev = aux_locator_list_next;
                aux_locator_list_next = aux_locator_list_next->next;
            }
            if (aux_locator_list_prev == NULL){
                locator_list->next = aux_locator_list_next;
                *list = locator_list;
            }else{
                aux_locator_list_prev->next = locator_list;
                locator_list->next = aux_locator_list_next;
            }
        }
    }else{ /* Remote locators and not initialized local locators */
        if (*list == NULL){
            *list = locator_list;
        }else{
            aux_locator_list_prev = *list;
            while (aux_locator_list_prev->next != NULL){
                aux_locator_list_prev = aux_locator_list_prev->next;
            }
            aux_locator_list_prev->next = locator_list;
        }
    }

    return (GOOD);
}
示例#29
0
int process_map_reply_probe_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;
    lispd_locator_elt                       *aux_locator            = NULL;
    lispd_locator_elt                       *locator                = NULL;
    rmt_locator_extended_info               *rmt_locator_ext_inf    = NULL;
    lispd_locators_list                     *locators_list[2]       = {NULL,NULL};
    lisp_addr_t                             aux_eid_prefix;
    int                                     aux_eid_prefix_length   = 0;
    int                                     aux_iid                 = 0;
    int                                     ctr                     = 0;
    int                                     locators_probed         = 0;

    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_probe_record:  Error processing the EID of the map reply record");
        free_mapping_elt(mapping);
        return (BAD);
    }
    mapping->eid_prefix_length = record->eid_prefix_length;

    if (record->locator_count != 0 ){
        /* 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_probe_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 instane id.*/
        if (cache_entry->mapping->iid != mapping->iid){
            lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_probe_record:  Instance ID of the map reply doesn't match with the map cache entry");
            free_mapping_elt(mapping);
            return (BAD);
        }


        /* Free auxiliar mapping used to search the map cache entry*/
        free_mapping_elt(mapping);

        /*
         * Check probed locators of the list. Only one locator can be probed per message
         */
        for (ctr=0 ; ctr < record->locator_count ; ctr++){
            err = process_map_reply_probe_locator (cur_ptr, cache_entry->mapping, nonce, &locator);
            if (err == ERR_MALLOC){
                return (BAD);
            }
            if (locator == NULL){ // The current locator is not probed
                continue;
            }
            rmt_locator_ext_inf = (rmt_locator_extended_info *)(locator->extended_info);
            /* Check the nonce of the message match with the one stored in the structure of the locator */
            if ((check_nonce(rmt_locator_ext_inf->rloc_probing_nonces,nonce)) == GOOD){
                free(rmt_locator_ext_inf->rloc_probing_nonces);
                rmt_locator_ext_inf->rloc_probing_nonces = NULL;
                if (locators_probed == 0){
                    aux_locator = locator;
                    locators_probed ++;
                }else{
                    lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: Invalid Map-Reply Probe. Only one locator can be probed per message");
                    return (BAD);
                }
            }else{
                lispd_log_msg(LISP_LOG_DEBUG_1,"The nonce of the Map-Reply Probe doesn't match the nonce of the generated Map-Request Probe. Discarding message ...");
                return (BAD);
            }
        }
        locator = aux_locator;
        if (locator ==  NULL){
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: Invalid Map-Reply Probe. No probed locator of the received message matches with the "
                    "locators of the mapping  stored in the map cahce database.");
            return (BAD);
        }
        lispd_log_msg(LISP_LOG_DEBUG_1,"Map-Reply probe reachability to RLOC %s of the EID cache entry %s/%d",
                    get_char_from_lisp_addr_t(*(locator->locator_addr)),
                    get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix),
                    cache_entry->mapping->eid_prefix_length);

    }else{ // Probe of a negative map cache -> proxy-etr
        if(proxy_etrs != NULL && compare_lisp_addr_t(&(mapping->eid_prefix),&(proxy_etrs->mapping->eid_prefix)) == 0){
            cache_entry = proxy_etrs;
            locators_list[0] = proxy_etrs->mapping->head_v4_locators_list;
            locators_list[1] = proxy_etrs->mapping->head_v6_locators_list;

            for (ctr=0 ; ctr < 2 ; ctr++){
                while (locators_list[ctr]!=NULL){
                    aux_locator = locators_list[ctr]->locator;
                    rmt_locator_ext_inf = (rmt_locator_extended_info *)(aux_locator->extended_info);
                    if ((check_nonce(rmt_locator_ext_inf->rloc_probing_nonces,nonce)) == GOOD){
                        free (rmt_locator_ext_inf->rloc_probing_nonces);
                        rmt_locator_ext_inf->rloc_probing_nonces = NULL;
                        locator = aux_locator;
                        break;
                    }
                    locators_list[ctr] = locators_list[ctr]->next;
                }
                if (locator != NULL){
                    break;
                }
            }
            if (locator == NULL){
                lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: The nonce of the Negative Map-Reply Probe don't match any nonce of Proxy-ETR locators");
                free_mapping_elt(mapping);
                return (BAD);
            }
            free_mapping_elt(mapping);
        }else{
            lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: The received negative Map-Reply Probe has not been requested: %s/%d",
                    get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length);
            free_mapping_elt(mapping);
            return (BAD);
        }

        lispd_log_msg(LISP_LOG_DEBUG_1,"Map-Reply probe reachability to the PETR with RLOC %s",
                    get_char_from_lisp_addr_t(*(locator->locator_addr)));
    }



    if (*(locator->state) == DOWN){
        *(locator->state) = UP;

        lispd_log_msg(LISP_LOG_DEBUG_1,"Map-Reply Probe received for locator %s -> Locator state changes to UP",
                           get_char_from_lisp_addr_t(*(locator->locator_addr)));

        /* [re]Calculate balancing locator vectors  if it has been a change of status*/
        calculate_balancing_vectors (
                cache_entry->mapping,
                &(((rmt_mapping_extended_info *)cache_entry->mapping->extended_info)->rmt_balancing_locators_vecs));
    }
    /*
     * Reprogramming timers of rloc probing
     */
    rmt_locator_ext_inf = (rmt_locator_extended_info *)(locator->extended_info);
    if (rmt_locator_ext_inf->probe_timer == NULL){
       lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: The received Map-Reply Probe was not requested");
       return (BAD);
    }

    start_timer(rmt_locator_ext_inf->probe_timer, rloc_probe_interval, (timer_callback)rloc_probing,rmt_locator_ext_inf->probe_timer->cb_argument);
    if (record->locator_count != 0 ){
        lispd_log_msg(LISP_LOG_DEBUG_2,"Reprogramed RLOC probing of the locator %s of the EID %s/%d in %d seconds",
                get_char_from_lisp_addr_t(*(locator->locator_addr)),
                get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix),
                cache_entry->mapping->eid_prefix_length, rloc_probe_interval);
    }else{
        lispd_log_msg(LISP_LOG_DEBUG_2,"Reprogramed RLOC probing of the locator %s (PETR) in %d seconds",
                get_char_from_lisp_addr_t(*(locator->locator_addr)), rloc_probe_interval);
    }

    return (GOOD);
}
示例#30
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);
}