int process_map_request_record( uint8_t **cur_ptr, lisp_addr_t *local_rloc, lisp_addr_t *remote_rloc, uint16_t dst_port, uint8_t rloc_probe, uint64_t nonce) { lispd_pkt_map_request_eid_prefix_record_t *record = NULL; lispd_mapping_elt *requested_mapping = NULL; lispd_mapping_elt *mapping = NULL; map_reply_opts opts; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = -1; /* Get the requested EID prefix */ record = (lispd_pkt_map_request_eid_prefix_record_t *)*cur_ptr; /* Auxiliar lispd_mapping_elt created to be filled with pkt_process_eid_afi */ requested_mapping = new_local_mapping(aux_eid_prefix, aux_eid_prefix_length, aux_iid); if (requested_mapping == NULL){ return (BAD); } *cur_ptr = (uint8_t *)&(record->eid_prefix_afi); if ((err=pkt_process_eid_afi(cur_ptr, requested_mapping))!=GOOD){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_request_record: Requested EID could not be processed"); free_mapping_elt (requested_mapping, TRUE); return (err); } requested_mapping->eid_prefix_length = record->eid_prefix_length; /* Check the existence of the requested EID */ /* We don't use prefix mask and use by default 32 or 128*/ mapping = lookup_eid_in_db(requested_mapping->eid_prefix); if (!mapping){ lispd_log_msg(LISP_LOG_DEBUG_1,"The requested EID doesn't belong to this node: %s/%d", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length); free_mapping_elt (requested_mapping, TRUE); return (BAD); } free_mapping_elt (requested_mapping, TRUE); /* Set flags for Map-Reply */ opts.send_rec = 1; opts.echo_nonce = 0; opts.rloc_probe = rloc_probe; err = build_and_send_map_reply_msg(mapping, local_rloc, remote_rloc, dst_port, nonce, opts); return (err); }
void free_referral_cache_entry_recursive(lispd_referral_cache_entry *referral_cache_entry) { free_mapping_elt (referral_cache_entry->mapping); if (referral_cache_entry->expiry_ddt_cache_timer != NULL){ stop_timer(referral_cache_entry->expiry_ddt_cache_timer); } remove_referral_cache_entry_from_parent_node(referral_cache_entry); free_lispd_referral_cache_list(referral_cache_entry->children_nodes); free (referral_cache_entry); }
/* * Generates a clone of a lispd_mapping_elt. Parameters like timers or nonces are not cloned */ lispd_mapping_elt *copy_mapping_elt(lispd_mapping_elt *elt) { lispd_mapping_elt *mapping = NULL; mapping = new_mapping(elt->eid_prefix,elt->eid_prefix_length,elt->iid); if (mapping == NULL){ return (NULL); } mapping->locator_count = elt->locator_count; if (elt->head_v4_locators_list != NULL){ mapping->head_v4_locators_list = copy_locators_list(elt->head_v4_locators_list); if (mapping->head_v4_locators_list == NULL){ free_mapping_elt(mapping); return (NULL); } } if(elt->head_v6_locators_list != NULL){ mapping->head_v6_locators_list = copy_locators_list(elt->head_v6_locators_list); if (mapping->head_v6_locators_list == NULL){ free_mapping_elt(mapping); return(NULL); } } if (elt->extended_info != NULL){ if (mapping->mapping_type == LOCAL_MAPPING){ mapping->extended_info = (void *)copy_lcl_mapping_extended_info((lcl_mapping_extended_info *)elt->extended_info); if (mapping->extended_info == NULL){ free_mapping_elt(mapping); return(NULL); } calculate_balancing_vectors (mapping,&(((lcl_mapping_extended_info *)mapping->extended_info)->outgoing_balancing_locators_vecs)); }else{ mapping->extended_info = (void *)copy_rmt_mapping_extended_info((rmt_mapping_extended_info *)elt->extended_info); if (mapping->extended_info == NULL){ free_mapping_elt(mapping); return(NULL); } calculate_balancing_vectors (mapping,&(((rmt_mapping_extended_info *)mapping->extended_info)->rmt_balancing_locators_vecs)); } } return (mapping); }
/* * Copy from the src referral cache to the dst referral cache the following data: mapping, act and ttl * @param dst_referral Destination of the data to be copied. The timer should be restarted outside this function * @param src_referral Source of the data to be copied * @return GOOD if finish correctly or an error code otherwise */ int update_referral_cache_data( lispd_referral_cache_entry *dst_referral, lispd_referral_cache_entry *src_referral) { free_mapping_elt (dst_referral->mapping); dst_referral->mapping = copy_mapping_elt(src_referral->mapping); if (dst_referral->mapping == NULL){ return (BAD); } dst_referral->act_entry_type = src_referral->act_entry_type; dst_referral->ttl = src_referral->ttl; return (GOOD); }
void free_referral_cache_entry(lispd_referral_cache_entry *referral_cache_entry) { lispd_referral_cache_list *list_elt = referral_cache_entry->children_nodes; lispd_referral_cache_list *aux_list_elt = NULL; free_mapping_elt (referral_cache_entry->mapping); /* We remove the list of childs (lispd_referral_cache_list) but not the childs (lispd_referral_cache_entry)*/ while (list_elt != NULL){ aux_list_elt = list_elt->next; free(aux_list_elt); list_elt = aux_list_elt; } if (referral_cache_entry->expiry_ddt_cache_timer != NULL){ stop_timer(referral_cache_entry->expiry_ddt_cache_timer); } free (referral_cache_entry); }
/* * Generates a mapping with the local extended info */ lispd_mapping_elt *new_local_mapping( lisp_addr_t eid_prefix, uint8_t eid_prefix_length, int iid) { lispd_mapping_elt *mapping = NULL; if ((mapping = new_mapping (eid_prefix, eid_prefix_length, iid)) == NULL){ return (NULL); } mapping->mapping_type = LOCAL_MAPPING; mapping->extended_info = (void *)new_lcl_mapping_extended_info(); if (mapping->extended_info == NULL){ free_mapping_elt(mapping); return (NULL); } return (mapping); }
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); }
int process_map_reply_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; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = 0; int ctr = 0; uint8_t is_new_mapping = FALSE; 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_record: Error processing the EID of the map reply record"); free_mapping_elt(mapping); return (BAD); } mapping->eid_prefix_length = record->eid_prefix_length; /* * Check if the map replay corresponds to a not active map cache */ cache_entry = lookup_nonce_in_no_active_map_caches(mapping->eid_prefix.afi, nonce); if (cache_entry != NULL){ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Instance ID of the map reply doesn't match with the inactive map cache entry"); free_mapping_elt(mapping); return (BAD); } /* * If the eid prefix of the received map reply doesn't match the inactive map cache entry (x.x.x.x/32 or x:x:x:x:x:x:x:x/128),then * we remove the inactie entry from the database and store it again with the correct eix prefix (for instance /24). */ if (cache_entry->mapping->eid_prefix_length != mapping->eid_prefix_length){ if (change_map_cache_prefix_in_db(mapping->eid_prefix, mapping->eid_prefix_length, cache_entry) != GOOD){ free_mapping_elt(mapping); return (BAD); } } cache_entry->active = 1; stop_timer(cache_entry->request_retry_timer); cache_entry->request_retry_timer = NULL; lispd_log_msg(LISP_LOG_DEBUG_2," Activating map cache entry %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); is_new_mapping = TRUE; } /* If the nonce is not found in the no active cache enties, then it should be an active cache entry */ else { /* 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_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 the found map cache entry contain the nonce of the map reply*/ if (check_nonce(cache_entry->nonces,nonce)==BAD){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: The nonce of the Map-Reply doesn't match the nonce of the generated Map-Request. Discarding message ..."); free_mapping_elt(mapping); return (BAD); }else { free(cache_entry->nonces); cache_entry->nonces = NULL; } /* Stop timer of Map Requests retransmits */ if (cache_entry->smr_inv_timer != NULL){ stop_timer(cache_entry->smr_inv_timer); cache_entry->smr_inv_timer = NULL; } /* Check instane id.*/ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Instance ID of the map reply doesn't match with the map cache entry"); free_mapping_elt(mapping); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_2," A map cache entry already exists for %s/%d, replacing locators list of this entry", get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length); free_locator_list(cache_entry->mapping->head_v4_locators_list); free_locator_list(cache_entry->mapping->head_v6_locators_list); cache_entry->mapping->head_v4_locators_list = NULL; cache_entry->mapping->head_v6_locators_list = NULL; free_mapping_elt(mapping); } cache_entry->actions = record->action; cache_entry->ttl = ntohl(record->ttl); cache_entry->active_witin_period = 1; cache_entry->timestamp = time(NULL); //locator_count updated when adding the processed locators /* Generate the locators */ for (ctr=0 ; ctr < record->locator_count ; ctr++){ if ((process_map_reply_locator (cur_ptr, cache_entry->mapping)) != GOOD){ return(BAD); } } if (is_loggable(LISP_LOG_DEBUG_2)){ dump_map_cache_entry(cache_entry, LISP_LOG_DEBUG_2); } /* [re]Calculate balancing locator vectors if it is not a negative map reply*/ if (cache_entry->mapping->locator_count != 0){ calculate_balancing_vectors ( cache_entry->mapping, &(((rmt_mapping_extended_info *)cache_entry->mapping->extended_info)->rmt_balancing_locators_vecs)); } /* * Reprogramming timers */ /* Expiration cache timer */ if (!cache_entry->expiry_cache_timer){ cache_entry->expiry_cache_timer = create_timer (EXPIRE_MAP_CACHE_TIMER); } start_timer(cache_entry->expiry_cache_timer, cache_entry->ttl*60, (timer_callback)map_cache_entry_expiration, (void *)cache_entry); lispd_log_msg(LISP_LOG_DEBUG_1,"The map cache entry %s/%d will expire in %d minutes.", get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length, cache_entry->ttl); /* RLOC probing timer */ if (is_new_mapping == TRUE && rloc_probe_interval != 0){ programming_rloc_probing(cache_entry); } return (TRUE); }
int process_map_referral_record( uint8_t **offset, uint64_t nonce) { uint8_t *cur_ptr = NULL; lispd_pkt_referral_mapping_record_t *record = NULL; lispd_referral_cache_entry *referral_entry = NULL; lispd_referral_cache_entry *previous_referral_entry = NULL; lispd_mapping_elt *referral_mapping = NULL; lispd_pending_referral_cache_entry *pending_referral_entry = NULL; lispd_map_cache_entry *map_cache_entry = NULL; lisp_addr_t ddt_node_locator_addr = {.afi=AF_UNSPEC}; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = 0; int ctr = 0; int result = GOOD; int detected_loop = FALSE; cur_ptr = *offset; record = (lispd_pkt_referral_mapping_record_t *)(cur_ptr); pending_referral_entry = lookup_pending_referral_cache_entry_by_nonce (nonce); if (pending_referral_entry == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_referral_record: The nonce of the Map-Referral doesn't match the nonce of any generated Map-Request. Discarding message ..."); free_mapping_elt(referral_mapping); return (BAD); }else { if (pending_referral_entry->previous_referral->act_entry_type == MS_NOT_REGISTERED){ previous_referral_entry = pending_referral_entry->previous_referral->parent_node; ddt_node_locator_addr = get_ddt_locator_addr_at_position(pending_referral_entry->previous_referral->parent_node, ctrl_supported_afi, pending_referral_entry->tried_locators); }else{ previous_referral_entry = pending_referral_entry->previous_referral; ddt_node_locator_addr = get_ddt_locator_addr_at_position(pending_referral_entry->previous_referral, ctrl_supported_afi, pending_referral_entry->tried_locators); } } free(pending_referral_entry->nonces); pending_referral_entry->nonces = NULL; /* Stop the timer to not retry to send the map request */ stop_timer(pending_referral_entry->ddt_request_retry_timer); pending_referral_entry->ddt_request_retry_timer = NULL; /* Fill a auxiliar mapping with the information of the packet */ referral_mapping = new_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid); if (referral_mapping == NULL){ return (BAD); } cur_ptr = (uint8_t *)&(record->eid_prefix_afi); if (pkt_process_eid_afi(&cur_ptr,referral_mapping) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_referral_record: Error processing the EID of the map reply record"); free_mapping_elt(referral_mapping); return (BAD); } referral_mapping->eid_prefix_length = record->eid_prefix_length; /* Check that the requested EID belongs to the returned prefix in the referral */ if (is_prefix_b_part_of_a ( referral_mapping->eid_prefix, referral_mapping->eid_prefix_length, pending_referral_entry->map_cache_entry->mapping->eid_prefix, pending_referral_entry->map_cache_entry->mapping->eid_prefix_length) == FALSE){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_referral_record: The requested EID doesn't belong to the prefix received " "in the map referral: EID: %s - received prefix: %s/%d", get_char_from_lisp_addr_t(pending_referral_entry->map_cache_entry->mapping->eid_prefix), get_char_from_lisp_addr_t(referral_mapping->eid_prefix),referral_mapping->eid_prefix_length); err = try_next_referral_node_or_go_through_root (pending_referral_entry); if (err != GOOD){ if (err == ERR_DST_ADDR){ err = activate_negative_map_cache (pending_referral_entry->map_cache_entry, pending_referral_entry->map_cache_entry->mapping->eid_prefix, pending_referral_entry->map_cache_entry->mapping->eid_prefix_length, 1,MAPPING_ACT_NO_ACTION); if (err != GOOD){ del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix, pending_referral_entry->map_cache_entry->mapping->eid_prefix_length); } } remove_pending_referral_cache_entry_from_list(pending_referral_entry); } free_mapping_elt(referral_mapping); return (BAD); } /* * Avoid loops: * - Check that the returned referral has a more specific prefix than the previous referral * - If received referral is: MS_REFERRAL or NODE_REFERRAL, Check that its prefix is diferent from the previous one. */ if (is_prefix_b_part_of_a ( previous_referral_entry->mapping->eid_prefix, previous_referral_entry->mapping->eid_prefix_length, referral_mapping->eid_prefix, referral_mapping->eid_prefix_length) == FALSE){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_referral_record: Loop detected in the ddt process-> " "received prefix: %s/%d - previous prefix: %s/%d. Trying next ddt node", get_char_from_lisp_addr_t(referral_mapping->eid_prefix),referral_mapping->eid_prefix_length, get_char_from_lisp_addr_t(previous_referral_entry->mapping->eid_prefix), previous_referral_entry->mapping->eid_prefix_length); detected_loop = TRUE; }else if ((previous_referral_entry->mapping->eid_prefix_length == referral_mapping->eid_prefix_length) && (record->action == NODE_REFERRAL || record->action == MS_REFERRAL)){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_referral_record: Loop detected in the ddt process-> " "%s message contains same prefix as last referral iteration : %s/%d", (record->action == NODE_REFERRAL ? "Node referral" : "MS referral"), get_char_from_lisp_addr_t(referral_mapping->eid_prefix), referral_mapping->eid_prefix_length); detected_loop = TRUE; } if ( detected_loop == TRUE){ /* Try with the next ddt node*/ err = try_next_referral_node_or_go_through_root (pending_referral_entry); if (err != GOOD){ if (err == ERR_DST_ADDR){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_referral_record: Loop detected in the ddt process-> " "error in the ddt tree"); err = activate_negative_map_cache (pending_referral_entry->map_cache_entry, previous_referral_entry->mapping->eid_prefix, previous_referral_entry->mapping->eid_prefix_length, 1,MAPPING_ACT_NO_ACTION); if (err != GOOD){ del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix, pending_referral_entry->map_cache_entry->mapping->eid_prefix_length); } } remove_pending_referral_cache_entry_from_list(pending_referral_entry); } free_mapping_elt(referral_mapping); return (BAD); } map_cache_entry = pending_referral_entry->map_cache_entry; if (map_cache_entry->mapping->iid != referral_mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_referral_record: Instance ID of the map referral doesn't match with the pending referral cache entry"); free_mapping_elt(referral_mapping); remove_pending_referral_cache_entry_from_list(pending_referral_entry); return (BAD); } /* Create the referral cache entry */ referral_entry = new_referral_cache_entry(referral_mapping, record->action, ntohl(record->ttl)); referral_entry->src_inf_ddt_node_locator_addr = ddt_node_locator_addr; /* Get the locators list */ for (ctr=0 ; ctr < record->locator_count ; ctr++){ if ((process_map_referral_locator (&cur_ptr, referral_entry->mapping)) != GOOD){ return(BAD); } } lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_referral_record:Answer from %s : Authoritative: %d , Incomplete: %d", get_char_from_lisp_addr_t(referral_entry->src_inf_ddt_node_locator_addr),record->authoritative,record->incomplete); dump_referral_cache_entry(referral_entry,LISP_LOG_DEBUG_2); switch (referral_entry->act_entry_type){ case NODE_REFERRAL: result = process_node_referral_reply(referral_entry,pending_referral_entry); break; case MS_REFERRAL: result = process_ms_referral_reply(referral_entry,pending_referral_entry); break; case MS_ACK: result = process_ms_ack_reply(referral_entry,pending_referral_entry); break; case MS_NOT_REGISTERED: result = process_ms_not_registered_reply(referral_entry,pending_referral_entry); break; case DELEGATION_HOLE: result = process_delegation_hole_reply(referral_entry,pending_referral_entry); break; case NOT_AUTHORITATIVE: result = process_not_authoritative_reply(referral_entry,pending_referral_entry); break; default: lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_referral_record: Referral record %s/%d with not supported action: %d", get_char_from_lisp_addr_t(referral_mapping->eid_prefix),referral_mapping->eid_prefix_length,referral_entry->act_entry_type); result = BAD; break; } return (result); }
int process_map_request_msg( uint8_t *packet, lisp_addr_t *local_rloc, uint16_t dst_port) { lispd_mapping_elt *source_mapping = NULL; lispd_map_cache_entry *map_cache_entry = NULL; lisp_addr_t itr_rloc[32]; lisp_addr_t *remote_rloc = NULL; int itr_rloc_count = 0; int itr_rloc_afi = 0; uint8_t *cur_ptr = NULL; int len = 0; lispd_pkt_map_request_t *msg = NULL; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = -1; int i = 0; /* If the packet is an Encapsulated Map Request, verify checksum and remove the inner IP header */ if (((lisp_encap_control_hdr_t *) packet)->type == LISP_ENCAP_CONTROL_TYPE) { if ((err = process_encapsulated_map_request_headers(packet,&len,&dst_port)) != GOOD){ return (BAD); } msg = (lispd_pkt_map_request_t *) CO(packet, len); } else if (((lispd_pkt_map_request_t *) packet)->type == LISP_MAP_REQUEST) { msg = (lispd_pkt_map_request_t *) packet; } else return(BAD); //we should never reach this return() /* * Source EID is optional in general, but required for SMRs */ /* Auxiliar lispd_mapping_elt created to be filled with pkt_process_eid_afi */ source_mapping = new_local_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid); if (source_mapping == NULL){ return (BAD); } cur_ptr = (uint8_t *)&(msg->source_eid_afi); if (pkt_process_eid_afi(&cur_ptr, source_mapping) != GOOD){ free_mapping_elt(source_mapping, FALSE); return (BAD); } /* If packet is a Solicit Map Request, process it */ if (source_mapping->eid_prefix.afi != 0 && msg->solicit_map_request) { /* * Lookup the map cache entry that match with the source EID prefix of the message */ map_cache_entry = lookup_map_cache(source_mapping->eid_prefix); if (map_cache_entry == NULL){ free_mapping_elt(source_mapping, FALSE); return (BAD); } /* * Check IID of the received Solicit Map Request match the IID of the map cache */ if (map_cache_entry->mapping->iid != source_mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_request_msg: The IID of the received Solicit Map Request doesn't match the IID of " "the entry in the map cache"); free_mapping_elt(source_mapping, FALSE); return (BAD); } /* Free source_mapping once we have a valid map cache entry */ free_mapping_elt(source_mapping, FALSE); /* * Only accept a solicit map request for an EID prefix ->If node which generates the message * has more than one locator, it probably will generate a solicit map request for each one. * Only the first one is considered. * If map_cache_entry->nonces is different of null, we have already received a solicit map request */ if (map_cache_entry->nonces == NULL){ solicit_map_request_reply(NULL,(void *)map_cache_entry); } /* Return here only if RLOC probe bit is not set */ if (!msg->rloc_probe){ return(GOOD); } } /* Get the array of ITR-RLOCs */ itr_rloc_count = msg->additional_itr_rloc_count + 1; for (i = 0; i < itr_rloc_count; i++) { itr_rloc_afi = lisp2inetafi(ntohs(*(uint16_t *)cur_ptr)); cur_ptr = CO(cur_ptr, sizeof(uint16_t)); memcpy(&(itr_rloc[i].address), cur_ptr, get_addr_len(itr_rloc_afi)); itr_rloc[i].afi = itr_rloc_afi; cur_ptr = CO(cur_ptr, get_addr_len(itr_rloc_afi)); // Select the first accessible rloc from the ITR-RLOC list if (remote_rloc == NULL){ if (local_rloc != NULL && itr_rloc[i].afi == local_rloc->afi){ remote_rloc = &itr_rloc[i]; } } } if (remote_rloc == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_request_msg: Couldn't generate map replay - " "No supported afi in the list of ITR-RLOCS"); return (BAD); } /* Process record and send Map Reply for each one */ for (i = 0; i < msg->record_count; i++) { process_map_request_record(&cur_ptr, local_rloc, remote_rloc, dst_port, msg->rloc_probe, msg->nonce); } return(GOOD); }