void set_default_output_ifaces()
{

    default_out_iface_v4 = get_any_output_iface(AF_INET);

    if (default_out_iface_v4 != NULL) {
       lispd_log_msg(LISP_LOG_DEBUG_2,"Default IPv4 iface %s\n",default_out_iface_v4->iface_name);
#ifdef ROUTER
       set_tun_default_route_v4();
#endif
    }
    
    default_out_iface_v6 = get_any_output_iface(AF_INET6);
    if (default_out_iface_v6 != NULL) {
       lispd_log_msg(LISP_LOG_DEBUG_2,"Default IPv6 iface %s\n",default_out_iface_v6->iface_name);
#ifdef ROUTER
       // For IPv6, the route is not updated and should be removed before adding the new one
       del_tun_default_route_v6();
       set_tun_default_route_v6();
#endif
    }

    if (!default_out_iface_v4 && !default_out_iface_v6){
        lispd_log_msg(LISP_LOG_CRIT,"NO OUTPUT IFACE: all the locators are down");
    }
}
Exemple #2
0
/*
 * Creates the routes to send the traffic to the tun interface to be encapsulated
 */
int configure_routing_to_tun()
{
    lispd_mapping_list  *list        = NULL;
    lispd_mapping_list  *list_elt    = NULL;
    lisp_addr_t         *tun_v4_addr = NULL;
    lisp_addr_t         *tun_v6_addr = NULL;
    lispd_mapping_elt   *mapping     = NULL;
    uint32_t            iface_index  = 0;


    if (tun_bring_up_iface(TUN_IFACE_NAME) != GOOD){
        return (BAD);
    }

    if (router_mode == FALSE)
    {
        /*
         * For mobile node mode, we create two /1 routes covering the full IP addresses space to route all traffic
         * generated by the node to the lispTun0 interface
         *          IPv4: 0.0.0.0/1 and 128.0.0.0/1
         *          IPv6: ::/1      and 8000::/1
         */
        tun_v4_addr = get_main_eid(AF_INET);
        tun_v6_addr = get_main_eid(AF_INET6);

        if (tun_v4_addr != NULL){
            if (tun_add_eid_to_iface(*tun_v4_addr,TUN_IFACE_NAME) != GOOD){
                return (BAD);
            }
            if (set_tun_default_route_v4() != GOOD){
                return (BAD);
            }
        }
        if (tun_v6_addr != NULL){
            if (tun_add_eid_to_iface(*tun_v6_addr,TUN_IFACE_NAME) != GOOD){
                return (BAD);
            }
            if (set_tun_default_route_v6() != GOOD){
                return (BAD);
            }
        }
    }else{
        /*
         * For router mode, add a new routing table with default route to tun interface. Using source routing,
         * We send all traffic generated by EIDs to this table
         */
        list = get_all_mappings(AF_UNSPEC);
        list_elt = list;
        /* Create rules to the new table */
        while (list_elt != NULL){
            mapping = list_elt->mapping;
            if (add_rule(mapping->eid_prefix.afi,
                        0,
                        LISP_TABLE,
                        RULE_TO_LISP_TABLE_PRIORITY,
                        RTN_UNICAST,
                        &(mapping->eid_prefix),
                        mapping->eid_prefix_length,
                        NULL,0,0)!=GOOD){
                free_mapping_list(list, FALSE);
                return (BAD);
            }
            list_elt = list_elt->next;
            if (add_rule(mapping->eid_prefix.afi,
                    0,
                    RT_TABLE_MAIN,
                    RULE_AVOID_LISP_TABLE_PRIORITY,
                    RTN_UNICAST,
                    NULL,0,
                    &(mapping->eid_prefix),
                    mapping->eid_prefix_length,
                    0)!=GOOD){
                free_mapping_list(list, FALSE);
                return (BAD);
            }
        }
        /* Add default route into the new table */
        iface_index = if_nametoindex(TUN_IFACE_NAME);
        tun_v4_addr = get_main_eid(AF_INET);
        tun_v6_addr = get_main_eid(AF_INET6);
        if (tun_v4_addr != NULL){
            add_route(AF_INET,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE);
        }
        if (tun_v6_addr != NULL){
            add_route(AF_INET6,iface_index,NULL,NULL,NULL,0,RULE_TO_LISP_TABLE_PRIORITY,LISP_TABLE);
        }

        free_mapping_list(list, FALSE);
    }
    return (GOOD);
}
void process_address_change (
    lispd_iface_elt     *iface,
    lisp_addr_t         new_addr)
{
    lisp_addr_t                 *iface_addr         = NULL;
    lispd_iface_mappings_list   *mapping_list       = NULL;
    int                         aux_afi             = 0;

    // XXX To be modified when full NAT implemented --> When Nat Aware active no IPv6 RLOCs supported
    if (nat_aware == TRUE && new_addr.afi == AF_INET6) {
        return;
    }

    /* Check if the addres is a global address*/
    if (is_link_local_addr(new_addr) == TRUE) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"precess_address_change: the extractet address from the netlink "
                      "messages is a local link address: %s discarded", get_char_from_lisp_addr_t(new_addr));
        return;
    }
    /* If default RLOC afi defined (-a 4 or 6), only accept addresses of the specified afi */
    if (default_rloc_afi != AF_UNSPEC && default_rloc_afi != new_addr.afi) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"precess_address_change: Default RLOC afi defined (-a #): Skipped %s address in iface %s",
                      (new_addr.afi == AF_INET) ? "IPv4" : "IPv6",iface->iface_name);
        return;
    }
    /*
     * Actions to be done due to a change of address: SMR
     */

    switch (new_addr.afi) {
    case AF_INET:
        iface_addr = iface->ipv4_address;
        break;
    case AF_INET6:
        iface_addr = iface->ipv6_address;
        break;
    }

    // Same address that we already have
    if (compare_lisp_addr_t(iface_addr,&new_addr)==0) {
        lispd_log_msg(LISP_LOG_DEBUG_2,"precess_address_change: The detected change of address for interface %s "
                      "doesn't affect",iface->iface_name);
        /* We must rebind the socket just in case the address is from a virtual interface who has changed its interafce number */
        switch (new_addr.afi) {
        case AF_INET:
            bind_socket_src_address(iface->out_socket_v4,&new_addr);
            break;
        case AF_INET6:
            bind_socket_src_address(iface->out_socket_v6,&new_addr);
            break;
        }

        return;
    }

    /*
     * Change source routing rules for this interface and binding
     */

    if (iface_addr->afi != AF_UNSPEC) {
        del_rule(iface_addr->afi,
                 0,
                 iface->iface_index,
                 iface->iface_index,
                 RTN_UNICAST,
                 iface_addr,
                 (iface_addr->afi == AF_INET) ? 32 : 128,
                 NULL,0,0);
    }
    add_rule(new_addr.afi,
             0,
             iface->iface_index,
             iface->iface_index,
             RTN_UNICAST,
             &new_addr,
             (new_addr.afi == AF_INET) ? 32 : 128,
             NULL,0,0);

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


    aux_afi = iface_addr->afi;
    // Update the new address
    copy_lisp_addr(iface_addr, &new_addr);


    /* The interface was down during initial configuratiopn process and now it is up. Activate address */
    if (aux_afi == AF_UNSPEC) {
        lispd_log_msg(LISP_LOG_DEBUG_1,"process_address_change: Activating the locator address %s"
                      , get_char_from_lisp_addr_t(new_addr));
        activate_interface_address(iface, new_addr);
        if (iface->status == UP) {
            iface_balancing_vectors_calc(iface);

            /*
             * If no default control and data interface, recalculate it
             */

            if ((default_ctrl_iface_v4 == NULL && new_addr.afi == AF_INET) ||
                    (default_ctrl_iface_v6 == NULL && new_addr.afi == AF_INET6)) {
                lispd_log_msg(LISP_LOG_DEBUG_2,"No default control interface. Recalculate new control interface");
                set_default_ctrl_ifaces();
            }

            if ((default_out_iface_v4 == NULL && new_addr.afi == AF_INET) ||
                    (default_out_iface_v6 == NULL && new_addr.afi == AF_INET6)) {
                lispd_log_msg(LISP_LOG_DEBUG_2,"No default output interface. Recalculate new output interface");
                set_default_output_ifaces();
            }
        }
    }

    lispd_log_msg(LISP_LOG_DEBUG_1,"precess_address_change: New address detected for interface %s -> %s",
                  iface->iface_name, get_char_from_lisp_addr_t(new_addr));

    mapping_list = iface->head_mappings_list;
    /* Sort again the locators list of the affected mappings*/
    while (mapping_list != NULL) {
        if (aux_afi != AF_UNSPEC && // When the locator is activated, it is automatically sorted
                ((new_addr.afi == AF_INET && mapping_list->use_ipv4_address == TRUE) ||
                 (new_addr.afi == AF_INET6 && mapping_list->use_ipv6_address == TRUE))) {
            sort_locators_list_elt (mapping_list->mapping, iface_addr);
        }
        mapping_list = mapping_list->next;
    }

    /* Indicate change of address in the interface */

    switch (new_addr.afi) {
    case AF_INET:
        iface->ipv4_changed = TRUE;
        break;
    case AF_INET6:
        iface->ipv6_changed = TRUE;
        break;
    }


    /* If it is compiled in router mode, then recompile default routes changing the indicated src address*/

    if (router_mode == TRUE) {
        switch (new_addr.afi) {
        case AF_INET:
            if (iface == default_out_iface_v4) {
                set_tun_default_route_v4();
            }
            break;
        case AF_INET6:
            if (iface == default_out_iface_v6) {
                del_tun_default_route_v6();
                set_tun_default_route_v6();
            }
            break;
        }
    }

    /* Check if the new address is behind NAT */

    if(nat_aware==TRUE) {
        // TODO : To be modified when implementing NAT per multiple interfaces
        nat_status = UNKNOWN;
        clear_rtr_from_locators (iface);

        if (iface->status == UP) {
            initial_info_request_process();
        } else {
            nat_aware_iface_address_change = TRUE;
        }
    }

    /* Reprograming SMR timer*/
    if (smr_timer == NULL) {
        smr_timer = create_timer (SMR_TIMER);
    }

    start_timer(smr_timer, LISPD_SMR_TIMEOUT,(timer_callback)init_smr, NULL);
}
Exemple #4
0
int main(int argc, char **argv)
{
    lisp_addr_t 		*tun_v4_addr  = NULL;
    lisp_addr_t 		*tun_v6_addr  = NULL;
    char 				*tun_dev_name = TUN_IFACE_NAME;
    uint32_t 			iseed         = 0;  /* initial random number generator */
    pid_t  				pid           = 0;    /* child pid */
    pid_t  				sid           = 0;


#ifdef OPENWRT
    lispd_log_msg(LISP_LOG_INFO,"LISPmob %s compiled for openWRT\n", LISPD_VERSION);
#else
#ifdef ANDROID
    open_log_file();
    lispd_log_msg(LISP_LOG_INFO,"LISPmob %s compiled for Android\n", LISPD_VERSION);
#else
    lispd_log_msg(LISP_LOG_INFO,"LISPmob %s compiled for Linux\n", LISPD_VERSION);
#endif
#endif

    init_globales();

#ifndef ANDROID
    /*
     *  Check for required capabilities and drop unnecssary privileges
     */

    if(check_capabilities() != GOOD) {
        exit_cleanup();
    }
#else
    /*
     * Check for superuser privileges
     */
    if (geteuid() != 0) {
        lispd_log_msg(LISP_LOG_INFO,"Running %s requires superuser privileges! Exiting...\n", LISPD);
        exit_cleanup();
    }
#endif

    /*
     *  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();
    init_referral_cache();

    /*
     *  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 process1");
        if ((pid = fork()) < 0) {
            exit_cleanup();
        }
        umask(0);
        if (pid > 0){
        	exit(EXIT_SUCCESS);
        }
        if ((sid = setsid()) < 0){
            exit_cleanup();
        }
        if ((chdir("/")) < 0){
            exit_cleanup();
        }
    }



    /*
     *  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";
    }
    err = handle_uci_lispd_config_file(config_file);
#else
    if (config_file == NULL){
        config_file = "/etc/lispd.conf";
    }
    err = handle_lispd_config_file(config_file);
#endif

    if (err != GOOD){
        lispd_log_msg(LISP_LOG_CRIT,"Wrong configuration.");
        exit_cleanup();
    }

    if (ddt_client == FALSE){
        drop_referral_cache();
    }
	
    /*
     * 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
     */

    if (router_mode == TRUE){
        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);
    }

    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();
    }
    if (router_mode == TRUE){
        if (tun_v4_addr != NULL){
            free(tun_v4_addr);
        }
        if (tun_v6_addr != NULL){
            free(tun_v6_addr);
        }
    }
    /*
     * Generate receive sockets for control (4342) and data port (4341)
     */

    if (default_rloc_afi == AF_UNSPEC || 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 == AF_UNSPEC || 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 (%s): 'lispd' started...", LISPD_VERSION);
    if (router_mode == TRUE){
        lispd_log_msg(LISP_LOG_INFO,"Running as an xTR router");
    }else{
        lispd_log_msg(LISP_LOG_INFO,"Running as a LISP mobile node");
    }

    /*
     * 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);
}
Exemple #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);
}