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"); } }
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); }