void k5_plugin_free_context(krb5_context context) { int i; for (i = 0; i < PLUGIN_NUM_INTERFACES; i++) free_mapping_list(context->plugins[i].modules); memset(context->plugins, 0, sizeof(context->plugins)); }
/* Expand *list_inout to contain the mappings from modstrs, followed by the * existing built-in module mappings. */ static krb5_error_code make_full_list(krb5_context context, char **modstrs, struct plugin_mapping ***list_inout) { krb5_error_code ret = 0; size_t count, pos, i, j; struct plugin_mapping **list, **mp; char **mod; /* Allocate space for all of the modules plus a null terminator. */ for (count = 0; modstrs[count] != NULL; count++); for (mp = *list_inout; mp != NULL && *mp != NULL; mp++, count++); list = calloc(count + 1, sizeof(*list)); if (list == NULL) return ENOMEM; /* Parse each profile module entry and store it in the list. */ for (mod = modstrs, pos = 0; *mod != NULL; mod++, pos++) { ret = parse_modstr(context, *mod, &list[pos]); if (ret != 0) { free_mapping_list(list); return ret; } } /* Cannibalize the old list of built-in modules. */ for (mp = *list_inout; mp != NULL && *mp != NULL; mp++, pos++) list[pos] = *mp; assert(pos == count); /* Filter out duplicates, preferring earlier entries to later ones. */ for (i = 0, pos = 0; i < count; i++) { for (j = 0; j < pos; j++) { if (strcmp(list[i]->modname, list[j]->modname) == 0) { free_plugin_mapping(list[i]); break; } } if (j == pos) list[pos++] = list[i]; } list[pos] = NULL; free(*list_inout); *list_inout = list; return 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_link_status_change( lispd_iface_elt *iface, int new_status) { lispd_mapping_list *map_list = NULL; if (iface->status == new_status){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_link_status_change: The detected change of status doesn't affect"); return; } if (iface->status_changed == TRUE){ iface->status_changed = FALSE; }else{ iface->status_changed = TRUE; } // Change status of the interface iface->status = new_status; /* * If the affected interface is the default control or output iface, recalculate it */ if (default_ctrl_iface_v4 == iface || default_ctrl_iface_v6 == iface){ lispd_log_msg(LISP_LOG_DEBUG_2,"Default control interface down (%s). Recalculate new control interface", iface->iface_name); set_default_ctrl_ifaces(); } if ((default_ctrl_iface_v4 == NULL && iface->ipv4_address->afi != AF_UNSPEC) || (default_ctrl_iface_v6 == NULL && iface->ipv6_address->afi != AF_UNSPEC)){ lispd_log_msg(LISP_LOG_DEBUG_2,"Recalculate new control interface"); set_default_ctrl_ifaces(); } if (default_out_iface_v4 == iface || default_out_iface_v6 == iface){ lispd_log_msg(LISP_LOG_DEBUG_2,"Default output interface down (%s). Recalculate new output interface", iface->iface_name); set_default_output_ifaces(); } if ((default_out_iface_v4 == NULL && iface->ipv4_address->afi != AF_UNSPEC) || (default_out_iface_v6 == NULL && iface->ipv6_address->afi != AF_UNSPEC)){ lispd_log_msg(LISP_LOG_DEBUG_2,"Recalculate new data interface"); set_default_output_ifaces(); } iface_balancing_vectors_calc(iface); /* Check if the interface is behind NAT */ if(nat_aware==TRUE){ if (iface->status == UP && iface->ipv4_address != NULL){ map_list = get_mappings_from_iface(iface); restart_info_request_process(map_list,iface->ipv4_address); free_mapping_list(map_list,FALSE); } } /* 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); }
void process_new_gateway ( lisp_addr_t gateway, lispd_iface_elt *iface ) { lisp_addr_t **gw_addr = NULL; int afi = AF_UNSPEC; lispd_mapping_list *map_list = NULL; switch(gateway.afi){ case AF_INET: gw_addr = &(iface->ipv4_gateway); afi = AF_INET; iface->ipv4_changed = TRUE; break; case AF_INET6: gw_addr = &(iface->ipv6_gateway); afi = AF_INET6; iface->ipv6_changed = TRUE; break; default: return; } if (*gw_addr == NULL){ // The default gateway of this interface is not deffined yet *gw_addr = clone_lisp_addr(&gateway); if (*gw_addr == NULL){ free (*gw_addr); *gw_addr = NULL; return; } }else{ copy_lisp_addr(*gw_addr,&gateway); } #ifndef VPNAPI add_route(afi,iface->iface_index,NULL,NULL,*gw_addr,0,100,iface->iface_index); #endif #ifdef VPNAPI if (iface->status != UP){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_new_gateway: Probably the interface %s is UP " "but we didn't receive netlink indicating this. Change %s status to UP", iface->iface_name,iface->iface_name); iface->status = UP; /* * If we don't have default control or output iface, recalculate it */ if ((default_ctrl_iface_v4 == NULL && iface->ipv4_address->afi != AF_UNSPEC) || (default_ctrl_iface_v6 == NULL && iface->ipv6_address->afi != AF_UNSPEC)){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_new_gateway: Recalculate new control interface"); set_default_ctrl_ifaces(); } if ((default_out_iface_v4 == NULL && iface->ipv4_address->afi != AF_UNSPEC) || (default_out_iface_v6 == NULL && iface->ipv6_address->afi != AF_UNSPEC)){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_new_gateway: Recalculate new data interface"); set_default_output_ifaces(); } } if (gateway.afi == AF_INET){ reset_socket(ipv4_data_input_fd); reset_socket(ipv4_control_input_fd); }else{ reset_socket(ipv6_data_input_fd); reset_socket(ipv6_control_input_fd); } #endif /* Check if the interface is behind NAT */ if(nat_aware==TRUE){ if (iface->status == UP && iface->ipv4_address != NULL){ map_list = get_mappings_from_iface(iface); restart_info_request_process(map_list,iface->ipv4_address); free_mapping_list(map_list,FALSE); } } /* 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); }
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; lispd_mapping_list *map_list = NULL; int aux_afi = 0; /* 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); #ifndef VPNAPI /* 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(iface->out_socket_v4,AF_INET,&new_addr,0); break; case AF_INET6: bind_socket(iface->out_socket_v6,AF_INET6,&new_addr,0); break; } #endif return; } #ifndef VPNAPI /* * 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(iface->out_socket_v4,AF_INET,&new_addr,0); break; case AF_INET6: bind_socket(iface->out_socket_v6,AF_INET6,&new_addr,0); break; } #endif 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; } /* Check if the new address is behind NAT */ if(nat_aware==TRUE){ if (iface->status == UP && new_addr.afi == AF_INET){ map_list = get_mappings_from_iface(iface); restart_info_request_process(map_list,iface->ipv4_address); free_mapping_list(map_list,FALSE); } } /* 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); }