/* * Extract the locator from a locators list that match with the address. * The locator is removed from the list */ lispd_locator_elt *extract_locator_from_list( lispd_locators_list **head_locator_list, lisp_addr_t addr) { lispd_locator_elt *locator = NULL; lispd_locators_list *locator_list = NULL; lispd_locators_list *prev_locator_list_elt = NULL; locator_list = *head_locator_list; while (locator_list != NULL){ if (compare_lisp_addr_t(locator_list->locator->locator_addr,&addr)==0){ locator = locator_list->locator; /* Extract the locator from the list */ if (prev_locator_list_elt != NULL){ prev_locator_list_elt->next = locator_list->next; }else{ *head_locator_list = locator_list->next; } free (locator_list); break; } prev_locator_list_elt = locator_list; locator_list = locator_list->next; } return (locator); }
/* * If prefix b is contained in prefix a, then return TRUE. Otherwise return FALSE. * If both prefixs are the same it also returns TRUE */ int is_prefix_b_part_of_a ( lisp_addr_t a_prefix, int a_prefix_length, lisp_addr_t b_prefix, int b_prefix_length) { lisp_addr_t a_network_addr; lisp_addr_t b_network_addr_prefix_a; if (a_prefix.afi != b_prefix.afi){ return FALSE; } if (a_prefix_length > b_prefix_length){ return FALSE; } a_network_addr = get_network_address(a_prefix, a_prefix_length); b_network_addr_prefix_a = get_network_address(b_prefix, a_prefix_length); if (compare_lisp_addr_t (&a_network_addr, &b_network_addr_prefix_a) == 0){ return (TRUE); }else{ return (FALSE); } }
void *pkt_fill_mapping_record( lispd_pkt_mapping_record_t *rec, lispd_mapping_elt *mapping, lisp_addr_t *probed_rloc) { int cpy_len = 0; lispd_pkt_mapping_record_locator_t *loc_ptr = NULL; lispd_locators_list *locators_list[2] = {NULL,NULL}; lispd_locator_elt *locator = NULL; int ctr = 0; if ((rec == NULL) || (mapping == NULL)) return NULL; rec->ttl = htonl(DEFAULT_MAP_REGISTER_TIMEOUT); rec->locator_count = mapping->locator_count; rec->eid_prefix_length = mapping->eid_prefix_length; rec->action = 0; rec->authoritative = 1; rec->version_hi = 0; rec->version_low = 0; loc_ptr = (lispd_pkt_mapping_record_locator_t *)pkt_fill_eid(&(rec->eid_prefix_afi), mapping); if (loc_ptr == NULL){ return NULL; } locators_list[0] = mapping->head_v4_locators_list; locators_list[1] = mapping->head_v6_locators_list; for (ctr = 0 ; ctr < 2 ; ctr++){ while (locators_list[ctr]) { locator = locators_list[ctr]->locator; loc_ptr->priority = locator->priority; loc_ptr->weight = locator->weight; loc_ptr->mpriority = locator->mpriority; loc_ptr->mweight = locator->mweight; loc_ptr->local = 1; if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){ loc_ptr->probed = 1; } loc_ptr->reachable = *(locator->state); loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL)); if ((cpy_len = copy_addr((void *) CO(loc_ptr, sizeof(lispd_pkt_mapping_record_locator_t)), locator->locator_addr, 0)) == 0) { LISPD_LOG(LISP_LOG_DEBUG_3, "copy_addr failed for locator %s", get_char_from_lisp_addr_t(*(locator->locator_addr))); return(NULL); } loc_ptr = (lispd_pkt_mapping_record_locator_t *) CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len)); locators_list[ctr] = locators_list[ctr]->next; } } return (void *)loc_ptr; }
lispd_pending_referral_cache_entry *lookup_pending_referral_cache_entry_by_eid ( lisp_addr_t eid_prefix, int eid_prefix_length) { lispd_pending_referral_cache_entry *pending_referral = NULL; lispd_mapping_elt *mapping = NULL; lispd_pending_referral_cache_list *aux_list = pening_referrals_list; while (aux_list != NULL){ mapping = aux_list->pending_referral_cache_entry->map_cache_entry->mapping; if (compare_lisp_addr_t (&(mapping->eid_prefix), &eid_prefix) == 0 && mapping->eid_prefix_length == eid_prefix_length){ pending_referral = aux_list->pending_referral_cache_entry; break; } aux_list = aux_list->next; } return (pending_referral); }
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); }
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); }
int process_info_reply_msg( uint8_t *packet, lisp_addr_t local_rloc) { uint8_t *ptr = packet; uint8_t lisp_type = 0; uint8_t reply = 0; uint64_t nonce = 0; uint16_t key_id = 0; uint16_t auth_data_len = 0; uint8_t *auth_data_pos = NULL; uint32_t ttl = 0; uint8_t eid_mask_len = 0; lisp_addr_t eid_prefix = {.afi=AF_UNSPEC}; uint16_t ms_udp_port = 0; uint16_t etr_udp_port = 0; uint32_t info_reply_hdr_len = 0; uint32_t lcaf_addr_len = 0; uint32_t pckt_len = 0; uint16_t *lcaf_afi = NULL; lisp_addr_t global_etr_rloc = {.afi=AF_UNSPEC}; lisp_addr_t ms_rloc = {.afi=AF_UNSPEC}; lisp_addr_t private_etr_rloc = {.afi=AF_UNSPEC}; lispd_rtr_locators_list *rtr_locators_list = NULL; lispd_mapping_elt *mapping = NULL; lispd_locator_elt *locator = NULL; lcl_locator_extended_info *lcl_locator_ext_inf = NULL; char rtrs_list_str[2000]; int rtrs_list_str_size = 0; lispd_rtr_locators_list *aux_rtr_locators_list = NULL; uint8_t is_behind_nat = FALSE; /* * Get source port and address. */ err = extract_info_nat_header(ptr, &lisp_type, &reply, &nonce, &key_id, &auth_data_len, &auth_data_pos, &ttl, &eid_mask_len, &eid_prefix, &info_reply_hdr_len); if (err != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Couldn't process Info Reply message"); return (BAD); } ptr = CO(ptr,info_reply_hdr_len); lcaf_afi = (uint16_t *)ptr; if ( ntohs(*lcaf_afi) != LISP_AFI_LCAF){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Malformed packet"); return (BAD); } ptr = CO(ptr,FIELD_AFI_LEN); /* Extract Info-Reply body fields */ err = extract_nat_lcaf_data(ptr, &ms_udp_port, &etr_udp_port, &global_etr_rloc, &ms_rloc, &private_etr_rloc, &rtr_locators_list, &lcaf_addr_len); if (err == BAD) { lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Error extracting packet data"); return (BAD); } /* Leave only RTR with same afi as the local rloc where we received the message */ remove_rtr_locators_with_afi_different_to(&rtr_locators_list, local_rloc.afi); lcaf_addr_len = lcaf_addr_len + FIELD_AFI_LEN; /* Print the extracted information of the message */ if (is_loggable(LISP_LOG_DEBUG_2)){ aux_rtr_locators_list = rtr_locators_list; rtrs_list_str[0] = '\0'; while (aux_rtr_locators_list != NULL){ sprintf(rtrs_list_str + rtrs_list_str_size, " %s ", get_char_from_lisp_addr_t(aux_rtr_locators_list->locator->address)); rtrs_list_str_size = rtrs_list_str_size + strlen(rtrs_list_str); aux_rtr_locators_list = aux_rtr_locators_list->next; } lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply message data->" "Nonce: %s , KeyID: %hu ,TTL: %u , EID-prefix: %s/%hhu , " "MS UDP Port Number: %hu , ETR UDP Port Number: %hu , Global ETR RLOC Address: %s , " "MS RLOC Address: %s , Private ETR RLOC Address: %s, RTR RLOC Compatible list: %s", get_char_from_nonce(nonce), key_id, ttl, get_char_from_lisp_addr_t(eid_prefix),eid_mask_len, ms_udp_port, etr_udp_port, get_char_from_lisp_addr_t(global_etr_rloc), get_char_from_lisp_addr_t(ms_rloc),get_char_from_lisp_addr_t(private_etr_rloc),rtrs_list_str); } /* Checking the nonce */ if (check_nonce(nat_ir_nonce,nonce) == GOOD ){ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct nonce field checking "); free(nat_ir_nonce); nat_ir_nonce = NULL; }else{ lispd_log_msg(LISP_LOG_DEBUG_1, "Info-Reply: Error checking nonce field. No Info Request generated with nonce: %s", get_char_from_nonce (nonce)); return (BAD); } /* Check authentication data */ pckt_len = info_reply_hdr_len + lcaf_addr_len; if(BAD == check_auth_field(key_id, map_servers->key, (void *) packet, pckt_len, auth_data_pos)){ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Error checking auth data field"); return(BAD); }else{ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct auth data field checking"); } // TODO Select the best RTR from the list retrieved from the Info-Reply /* Check if behind NAT */ switch (compare_lisp_addr_t(&global_etr_rloc, &local_rloc)) { case 0: is_behind_nat = FALSE; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is not behind NAT"); break; case 1: case 2: is_behind_nat = TRUE; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is behind NAT"); break; case -1: is_behind_nat = UNKNOWN; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: Unknown state"); break; } if (is_behind_nat == TRUE){ if (rtr_locators_list == NULL){ lispd_log_msg(LISP_LOG_WARNING, "process_info_reply_msg: The interface with IP address %s is behind NAT" " but there is no RTR compatible with local AFI", get_char_from_lisp_addr_t(local_rloc)); } mapping = lookup_eid_exact_in_db(eid_prefix, eid_mask_len); if (mapping == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply is not for any local EID"); return (BAD); } locator = get_locator_from_mapping(mapping,local_rloc); if (locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply received in the wrong locator"); return (BAD); } lcl_locator_ext_inf = (lcl_locator_extended_info *)locator->extended_info; if (lcl_locator_ext_inf->rtr_locators_list != NULL){ free_rtr_list(lcl_locator_ext_inf->rtr_locators_list); } lcl_locator_ext_inf->rtr_locators_list = rtr_locators_list; if (nat_status == NO_NAT || nat_status == PARTIAL_NAT){ nat_status = PARTIAL_NAT; }else{ nat_status = FULL_NAT; } }else{ if (nat_status == FULL_NAT || nat_status == PARTIAL_NAT){ nat_status = PARTIAL_NAT; }else{ nat_status = NO_NAT; } } /* If we are behind NAT, the program timer to send Info Request after TTL minutes */ if (is_behind_nat == TRUE){ if (info_reply_ttl_timer == NULL) { info_reply_ttl_timer = create_timer(INFO_REPLY_TTL_TIMER); } start_timer(info_reply_ttl_timer, ttl*60, info_request, (void *)mapping); lispd_log_msg(LISP_LOG_DEBUG_1, "Reprogrammed info request in %d minutes",ttl); }else{ stop_timer(info_reply_ttl_timer); info_reply_ttl_timer = NULL; } /* Once we know the NAT state we send a Map-Register */ map_register(NULL,NULL); return (GOOD); }
uint8_t *pkt_fill_mapping_record( lispd_pkt_mapping_record_t *rec, lispd_mapping_elt *mapping, lisp_addr_t *probed_rloc) { uint8_t *cur_ptr = NULL; int cpy_len = 0; lispd_pkt_mapping_record_locator_t *loc_ptr = NULL; lispd_locators_list *locators_list[2] = {NULL,NULL}; lispd_locator_elt *locator = NULL; lcl_locator_extended_info *lct_extended_info = NULL; lisp_addr_t *itr_address = NULL; int ctr = 0; if ((rec == NULL) || (mapping == NULL)){ return NULL; } rec->ttl = htonl(DEFAULT_MAP_REGISTER_TIMEOUT); rec->locator_count = mapping->locator_count; rec->eid_prefix_length = mapping->eid_prefix_length; rec->action = 0; rec->authoritative = 1; rec->version_hi = 0; rec->version_low = 0; cur_ptr = (uint8_t *)&(rec->eid_prefix_afi); cur_ptr = pkt_fill_eid(cur_ptr, mapping); loc_ptr = (lispd_pkt_mapping_record_locator_t *)cur_ptr; if (loc_ptr == NULL){ return NULL; } locators_list[0] = mapping->head_v4_locators_list; locators_list[1] = mapping->head_v6_locators_list; for (ctr = 0 ; ctr < 2 ; ctr++){ while (locators_list[ctr]) { locator = locators_list[ctr]->locator; if (*(locator->state) == UP){ loc_ptr->priority = locator->priority; }else{ /* If the locator is DOWN, set the priority to 255 -> Locator should not be used */ loc_ptr->priority = UNUSED_RLOC_PRIORITY; } loc_ptr->weight = locator->weight; loc_ptr->mpriority = locator->mpriority; loc_ptr->mweight = locator->mweight; loc_ptr->local = 1; if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){ loc_ptr->probed = 1; } loc_ptr->reachable = *(locator->state); loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL)); lct_extended_info = (lcl_locator_extended_info *)(locator->extended_info); if (lct_extended_info->rtr_locators_list != NULL){ itr_address = &(lct_extended_info->rtr_locators_list->locator->address); }else{ itr_address = locator->locator_addr; } if ((cpy_len = copy_addr((void *) CO(loc_ptr, sizeof(lispd_pkt_mapping_record_locator_t)), itr_address, 0)) == 0) { lispd_log_msg(LISP_LOG_DEBUG_3, "pkt_fill_mapping_record: copy_addr failed for locator %s", get_char_from_lisp_addr_t(*(locator->locator_addr))); return(NULL); } loc_ptr = (lispd_pkt_mapping_record_locator_t *) CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len)); locators_list[ctr] = locators_list[ctr]->next; } } return ((void *)loc_ptr); }