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; } }
void process_nl_new_link (struct nlmsghdr *nlh) { struct ifinfomsg *ifi = NULL; lispd_iface_elt *iface = NULL; int iface_index = 0; uint8_t status = UP; char iface_name[IF_NAMESIZE]; uint32_t old_iface_index = 0; ifi = (struct ifinfomsg *) NLMSG_DATA (nlh); iface_index = ifi->ifi_index; iface = get_interface_from_index(iface_index); if (iface == NULL) { /* * In some OS when a virtual interface is removed and added again, the index of the interface change. * Search lispd_iface_elt by the interface name and update the index. */ if (if_indextoname(iface_index, iface_name) != NULL) { iface = get_interface(iface_name); } if (iface == NULL) { lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_new_link: the netlink message is not for any interface associated with RLOCs (%s)", iface_name); return; } else { old_iface_index = iface->iface_index; iface->iface_index = iface_index; lispd_log_msg(LISP_LOG_DEBUG_2,"process_nl_new_link: The new index of the interface %s is: %d. Updating tables", iface_name, iface->iface_index); /* Update routing tables and reopen sockets*/ if (iface->ipv4_address->afi != AF_UNSPEC) { del_rule(AF_INET,0,old_iface_index,old_iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0); add_rule(AF_INET,0,iface_index,iface_index,RTN_UNICAST,iface->ipv4_address,32,NULL,0,0); close(iface->out_socket_v4); iface->out_socket_v4 = open_device_binded_raw_socket(iface->iface_name,AF_INET); bind_socket_src_address(iface->out_socket_v4,iface->ipv4_address); } if (iface->ipv6_address->afi != AF_UNSPEC) { del_rule(AF_INET6,0,old_iface_index,old_iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0); add_rule(AF_INET6,0,iface_index,iface_index,RTN_UNICAST,iface->ipv6_address,128,NULL,0,0); close(iface->out_socket_v6); iface->out_socket_v6 = open_device_binded_raw_socket(iface->iface_name,AF_INET6); bind_socket_src_address(iface->out_socket_v6,iface->ipv6_address); } } } if ((ifi->ifi_flags & IFF_RUNNING) != 0) { lispd_log_msg(LISP_LOG_DEBUG_1, "process_nl_new_link: Interface %s changes its status to UP",iface->iface_name); status = UP; } else { lispd_log_msg(LISP_LOG_DEBUG_1, "process_nl_new_link: Interface %s changes its status to DOWN",iface->iface_name); status = DOWN; } process_link_status_change (iface, status); }
lispd_iface_elt *add_interface(char *iface_name) { lispd_iface_list_elt *iface_list = NULL; lispd_iface_list_elt *aux_iface_list = NULL; lispd_iface_elt *iface = NULL; /* Creating the new interface*/ if ((iface_list = malloc(sizeof(lispd_iface_list_elt)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"add_interface: Unable to allocate memory for iface_list_elt: %s", strerror(errno)); return(NULL); } if ((iface = malloc(sizeof(lispd_iface_elt)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"add_interface: Unable to allocate memory for iface_elt: %s", strerror(errno)); free(iface_list); return(NULL); } if ((iface->ipv4_address = (lisp_addr_t *)malloc(sizeof(lisp_addr_t)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"add_interface: Unable to allocate memory for lisp_addr_t: %s", strerror(errno)); free(iface_list); free(iface); return(NULL); } if ((iface->ipv6_address = (lisp_addr_t *)malloc(sizeof(lisp_addr_t)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"add_interface: Unable to allocate memory for lisp_addr_t: %s", strerror(errno)); free(iface_list); free(iface->ipv4_address); free(iface); return(NULL); } memset(iface->ipv4_address,0,sizeof(lisp_addr_t)); memset(iface->ipv6_address,0,sizeof(lisp_addr_t)); iface->iface_name = malloc(strlen(iface_name) + 1); // XXX Must free elsewhere strcpy(iface->iface_name, iface_name); iface->iface_index = if_nametoindex(iface_name); if (iface->iface_index != 0){ err = lispd_get_iface_address(iface_name, iface->ipv4_address, AF_INET); if (err == GOOD){ iface->out_socket_v4 = open_device_binded_raw_socket(iface->iface_name,AF_INET); }else { iface->ipv4_address->afi = AF_UNSPEC; iface->out_socket_v4 = -1; } err = lispd_get_iface_address(iface_name, iface->ipv6_address, AF_INET6); if (err == GOOD){ iface->out_socket_v6 = open_device_binded_raw_socket(iface->iface_name,AF_INET6); }else { iface->ipv6_address->afi = AF_UNSPEC; iface->out_socket_v6 = -1; } }else{ iface->ipv4_address->afi = AF_UNSPEC; iface->out_socket_v4 = -1; iface->ipv6_address->afi = AF_UNSPEC; iface->out_socket_v6 = -1; } if ( iface->ipv4_address->afi == AF_UNSPEC && iface->ipv6_address->afi == AF_UNSPEC){ iface->status = DOWN; }else{ iface->status = UP; } iface->head_mappings_list = NULL; iface->status_changed = FALSE; iface->ipv4_changed = FALSE; iface->ipv6_changed = FALSE; iface_list->iface = iface; iface_list->next = NULL; /* Add iface to the list */ if (!head_interface_list){ head_interface_list = iface_list; }else { aux_iface_list = head_interface_list; while (aux_iface_list->next) aux_iface_list = aux_iface_list->next; aux_iface_list->next = iface_list; } lispd_log_msg(LISP_LOG_DEBUG_2,"add_interface: Interface %s with interface index %d added to interfaces lists", iface_name, iface->iface_index); return (iface); }