Ejemplo n.º 1
0
/*
 * Generates a clone of a lispd_mapping_elt. Parameters like timers or nonces are not cloned
 */
lispd_mapping_elt *copy_mapping_elt(lispd_mapping_elt *elt)
{
    lispd_mapping_elt *mapping = NULL;
    mapping = new_mapping(elt->eid_prefix,elt->eid_prefix_length,elt->iid);
    if (mapping == NULL){
        return (NULL);
    }
    mapping->locator_count = elt->locator_count;
    if (elt->head_v4_locators_list != NULL){
        mapping->head_v4_locators_list = copy_locators_list(elt->head_v4_locators_list);
        if (mapping->head_v4_locators_list == NULL){
            free_mapping_elt(mapping);
            return (NULL);
        }
    }
    if(elt->head_v6_locators_list != NULL){
        mapping->head_v6_locators_list = copy_locators_list(elt->head_v6_locators_list);
        if (mapping->head_v6_locators_list == NULL){
            free_mapping_elt(mapping);
            return(NULL);
        }
    }
    if (elt->extended_info != NULL){
        if (mapping->mapping_type == LOCAL_MAPPING){
            mapping->extended_info = (void *)copy_lcl_mapping_extended_info((lcl_mapping_extended_info *)elt->extended_info);
            if (mapping->extended_info == NULL){
                free_mapping_elt(mapping);
                return(NULL);
            }
            calculate_balancing_vectors (mapping,&(((lcl_mapping_extended_info *)mapping->extended_info)->outgoing_balancing_locators_vecs));
        }else{
            mapping->extended_info = (void *)copy_rmt_mapping_extended_info((rmt_mapping_extended_info *)elt->extended_info);
            if (mapping->extended_info == NULL){
                free_mapping_elt(mapping);
                return(NULL);
            }
            calculate_balancing_vectors (mapping,&(((rmt_mapping_extended_info *)mapping->extended_info)->rmt_balancing_locators_vecs));
        }
    }

    return (mapping);
}
Ejemplo n.º 2
0
void iface_balancing_vectors_calc(lispd_iface_elt  *iface)
{
    lispd_iface_mappings_list   *mapping_list       = NULL;
    lcl_mapping_extended_info   *lcl_extended_info  = NULL;

    mapping_list = iface->head_mappings_list;
    while (mapping_list != NULL){
        lcl_extended_info = (lcl_mapping_extended_info *)(mapping_list->mapping->extended_info);
        calculate_balancing_vectors (
                mapping_list->mapping,
                &(lcl_extended_info->outgoing_balancing_locators_vecs));
        mapping_list = mapping_list->next;
    }
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
int main(int argc, char **argv) 
{
    lisp_addr_t *tun_v4_addr;
    lisp_addr_t *tun_v6_addr;
    char *tun_dev_name = TUN_IFACE_NAME;

#ifdef ROUTER
#ifdef OPENWRT
    lispd_log_msg(LISP_LOG_INFO,"LISPmob compiled for openWRT xTR\n");
#else
    lispd_log_msg(LISP_LOG_INFO,"LISPmob compiled for linux xTR\n");
#endif
#else
    lispd_log_msg(LISP_LOG_INFO,"LISPmob compiled for mobile node\n");
#endif


    /*
     *  Check for superuser privileges
     */

    if (geteuid()) {
        lispd_log_msg(LISP_LOG_INFO,"Running %s requires superuser privileges! Exiting...\n", LISPD);
        exit_cleanup();
    }

    /*
     *  Initialize the random number generator
     */

    iseed = (unsigned int) time (NULL);
    srandom(iseed);

    /*
     * Set up signal handlers
     */

    signal(SIGHUP,  signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGINT,  signal_handler);
    signal(SIGQUIT, signal_handler);


    /*
     *  set up databases
     */

    db_init();
    map_cache_init();


    /*
     *  Parse command line options
     */

    handle_lispd_command_line(argc, argv);



    /*
     *  see if we need to daemonize, and if so, do it
     */

    if (daemonize) {
        lispd_log_msg(LISP_LOG_DEBUG_1, "Starting the daemonizing process");
        if ((pid = fork()) < 0) {
            exit_cleanup();
        }
        umask(0);
        if (pid > 0)
            exit_cleanup();
        if ((sid = setsid()) < 0)
            exit_cleanup();
        if ((chdir("/")) < 0)
            exit_cleanup();
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
    }


    /*
     *  create timers
     */

    if (build_timers_event_socket(&timers_fd) == 0)
    {
        lispd_log_msg(LISP_LOG_CRIT, " Error programing the timer signal. Exiting...");
        exit_cleanup();
    }
    init_timers();




    /*
     *  Parse config file. Format of the file depends on the node: Linux Box or OpenWRT router
     */

#ifdef OPENWRT
    if (config_file == NULL){
        config_file = "/etc/config/lispd";
    }
    handle_uci_lispd_config_file(config_file);
#else
    if (config_file == NULL){
        config_file = "/etc/lispd.conf";
    }
    handle_lispd_config_file(config_file);
#endif

    if (map_servers == NULL){
        lispd_log_msg(LISP_LOG_CRIT, "No Map Server configured. Exiting...");
        exit_cleanup();
    }

    if (map_resolvers == NULL){
        lispd_log_msg(LISP_LOG_CRIT, "No Map Resolver configured. Exiting...");
        exit_cleanup();
    }

    if (proxy_etrs == NULL){
        lispd_log_msg(LISP_LOG_WARNING, "No Proxy-ETR defined. Packets to non-LISP destinations will be "
                "forwarded natively (no LISP encapsulation). This may prevent mobility in some scenarios.");
        sleep(3);
    }else{
        calculate_balancing_vectors (
                proxy_etrs->mapping,
                &(((rmt_mapping_extended_info *)(proxy_etrs->mapping->extended_info))->rmt_balancing_locators_vecs));
    }


    /*
     * Select the default rlocs for output data packets and output control packets
     */

    set_default_output_ifaces();

    set_default_ctrl_ifaces();


    /*
     * Create tun interface
     */

    create_tun(tun_dev_name,
            TUN_RECEIVE_SIZE,
            TUN_MTU,
            &tun_receive_fd,
            &tun_ifindex,
            &tun_receive_buf);


    /*
     * Assign address to the tun interface
     * Assign route to 0.0.0.0/1 and 128.0.0.0/1 via tun interface
     *                 ::/1      and 8000::/1
     */

#ifdef ROUTER
    tun_v4_addr = get_main_eid(AF_INET);
    if (tun_v4_addr != NULL){
        tun_v4_addr = (lisp_addr_t *)malloc(sizeof(lisp_addr_t));
        get_lisp_addr_from_char(TUN_LOCAL_V4_ADDR,tun_v4_addr);
    }
    tun_v6_addr = get_main_eid(AF_INET6);
    if (tun_v6_addr != NULL){
        tun_v6_addr = (lisp_addr_t *)malloc(sizeof(lisp_addr_t));
        get_lisp_addr_from_char(TUN_LOCAL_V6_ADDR,tun_v6_addr);
    }
#else
    tun_v4_addr = get_main_eid(AF_INET);
    tun_v6_addr = get_main_eid(AF_INET6);
#endif

    tun_bring_up_iface(tun_dev_name);
    if (tun_v4_addr != NULL){
        tun_add_eid_to_iface(*tun_v4_addr,tun_dev_name);
        set_tun_default_route_v4();
    }
    if (tun_v6_addr != NULL){
        tun_add_eid_to_iface(*tun_v6_addr,tun_dev_name);
        set_tun_default_route_v6();
    }
#ifdef ROUTER
    if (tun_v4_addr != NULL){
        free(tun_v4_addr);
    }
    if (tun_v6_addr != NULL){
        free(tun_v6_addr);
    }
#endif
    /*
     * Generate receive sockets for control (4342) and data port (4341)
     */

    if (default_rloc_afi == -1 || default_rloc_afi == AF_INET){
        ipv4_control_input_fd = open_control_input_socket(AF_INET);
        ipv4_data_input_fd = open_data_input_socket(AF_INET);
    }

    if (default_rloc_afi == -1 || default_rloc_afi == AF_INET6){
        ipv6_control_input_fd = open_control_input_socket(AF_INET6);
        ipv6_data_input_fd = open_data_input_socket(AF_INET6);
    }

    /*
     * Create net_link socket to receive notifications of changes of RLOC status.
     */
    netlink_fd = opent_netlink_socket();

    lispd_log_msg(LISP_LOG_INFO,"LISPmob (0.3.3): 'lispd' started...");

    /*
     * Request to dump the routing tables to obtain the gatways when processing the netlink messages
     */

    request_route_table(RT_TABLE_MAIN, AF_INET);
    process_netlink_msg(netlink_fd);
    request_route_table(RT_TABLE_MAIN, AF_INET6);
    process_netlink_msg(netlink_fd);

    /*
     *  Register to the Map-Server(s)
     */

    map_register (NULL,NULL);

    /*
     * SMR proxy-ITRs list to be updated with new mappings
     */

    init_smr(NULL,NULL);

    /*
     * RLOC Probing proxy ETRs
     */
    programming_petr_rloc_probing();


    event_loop();

    lispd_log_msg(LISP_LOG_INFO, "Exiting...");         /* event_loop returned bad */
    closelog();
    return(0);
}