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; } }
int process_not_authoritative_reply( lispd_referral_cache_entry *referral_entry, lispd_pending_referral_cache_entry *pending_referral_entry) { lispd_log_msg(LISP_LOG_DEBUG_2,"process_not_authoritative_reply: Node %s is not authoritative for the requested prefix %s/%d. " "Asking next ddt node.", get_char_from_lisp_addr_t(referral_entry->src_inf_ddt_node_locator_addr), get_char_from_lisp_addr_t(pending_referral_entry->map_cache_entry->mapping->eid_prefix), pending_referral_entry->map_cache_entry->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, referral_entry->mapping->eid_prefix, 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_referral_cache_entry(referral_entry); return (err); }
int build_and_send_map_reply_msg( lispd_mapping_elt *requested_mapping, lisp_addr_t *src_rloc_addr, lisp_addr_t *dst_rloc_addr, uint16_t dport, uint64_t nonce, map_reply_opts opts) { uint8_t *map_reply_pkt = NULL; int map_reply_pkt_len = 0; int result = 0; lispd_log_msg(LISP_LOG_DEBUG_2,"Build Map Reply Packet"); /* Build the packet */ if (opts.rloc_probe == TRUE){ map_reply_pkt = build_map_reply_pkt(requested_mapping, src_rloc_addr, opts, nonce, &map_reply_pkt_len); } else{ map_reply_pkt = build_map_reply_pkt(requested_mapping, NULL, opts, nonce, &map_reply_pkt_len); } if (map_reply_pkt == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"build_and_send_map_reply_msg: Couldn't send Map-Reply for requested EID %s/%d ", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length); return (BAD); } err = send_control_msg(map_reply_pkt, map_reply_pkt_len, src_rloc_addr, dst_rloc_addr, LISP_CONTROL_PORT, dport); free (map_reply_pkt); if (err == GOOD){ if (opts.rloc_probe == TRUE){ lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Reply packet for %s/%d probing local locator %s", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length, get_char_from_lisp_addr_t(*src_rloc_addr)); }else{ lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Reply packet for %s/%d", get_char_from_lisp_addr_t(requested_mapping->eid_prefix), requested_mapping->eid_prefix_length); } result = GOOD; }else { if (opts.rloc_probe == TRUE){ lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't build/send Probe Reply!"); }else{ lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't build/send Map-Reply!"); } result = BAD; } return (result); }
int send_udp_ctrl_packet( lisp_addr_t *dst_addr, uint16_t src_port, uint16_t dst_port, void *packet, int packet_len) { switch (dst_addr->afi){ case AF_INET: if (default_ctrl_iface_v4 != NULL){ err = send_udp_ipv4_packet(default_ctrl_iface_v4->ipv4_address,dst_addr,src_port,dst_port,(void *)packet,packet_len); }else{ LISPD_LOG(LISP_LOG_DEBUG_1,"No local RLOC compatible with the afi of the destinaion locator %s", get_char_from_lisp_addr_t(*dst_addr)); err = BAD; } break; case AF_INET6: if (default_ctrl_iface_v6 != NULL){ err = send_udp_ipv6_packet(default_ctrl_iface_v6->ipv6_address,dst_addr,src_port,dst_port,(void *)packet,packet_len); }else{ LISPD_LOG(LISP_LOG_DEBUG_1,"No local RLOC compatible with the afi of the destination locator %s", get_char_from_lisp_addr_t(*dst_addr)); err = BAD; } break; } return err; }
int send_map_request_miss(timer *t, void *arg) { timer_map_request_argument *argument = (timer_map_request_argument *)arg; lispd_map_cache_entry *map_cache_entry = argument->map_cache_entry; nonces_list *nonces = map_cache_entry->nonces; lisp_addr_t *dst_rloc = NULL; if (nonces == NULL){ nonces = new_nonces_list(); if (nonces==NULL){ lispd_log_msg(LISP_LOG_WARNING,"Send_map_request_miss: Unable to allocate memory for nonces."); return (BAD); } map_cache_entry->nonces = nonces; } if (nonces->retransmits - 1 < map_request_retries ){ if (map_cache_entry->request_retry_timer == NULL){ map_cache_entry->request_retry_timer = create_timer (MAP_REQUEST_RETRY_TIMER); } if (nonces->retransmits > 0){ lispd_log_msg(LISP_LOG_DEBUG_1,"Retransmiting Map Request for EID: %s (%d retries)", get_char_from_lisp_addr_t(map_cache_entry->mapping->eid_prefix), nonces->retransmits); } /* Get the RLOC of the Map Resolver to be used */ dst_rloc = get_map_resolver(); if ((dst_rloc == NULL) || (build_and_send_map_request_msg( map_cache_entry->mapping, &(argument->src_eid), dst_rloc, 1, 0, 0, 0, &nonces->nonce[nonces->retransmits]))==BAD){ lispd_log_msg (LISP_LOG_DEBUG_1, "send_map_request_miss: Couldn't send map request for a new map cache entry"); } nonces->retransmits ++; start_timer(map_cache_entry->request_retry_timer, LISPD_INITIAL_MRQ_TIMEOUT, send_map_request_miss, (void *)argument); }else{ lispd_log_msg(LISP_LOG_DEBUG_1,"No Map Reply fot EID %s/%d after %d retries. Removing map cache entry ...", get_char_from_lisp_addr_t(map_cache_entry->mapping->eid_prefix), map_cache_entry->mapping->eid_prefix_length, nonces->retransmits -1); del_map_cache_entry_from_db(map_cache_entry->mapping->eid_prefix, map_cache_entry->mapping->eid_prefix_length); } return GOOD; }
/* * dump mapping */ void dump_mapping_entry( lispd_mapping_elt *mapping, int log_level) { lispd_locators_list *locator_iterator_array[2] = {NULL,NULL}; lispd_locators_list *locator_iterator = NULL; lispd_locator_elt *locator = NULL; int ctr = 0; if (is_loggable(log_level) == FALSE){ return; } lispd_log_msg(log_level,"IDENTIFIER (EID): %s/%d (IID = %d)\n ", get_char_from_lisp_addr_t(mapping->eid_prefix), mapping->eid_prefix_length, mapping->iid); lispd_log_msg(log_level, "| Locator (RLOC) | Status | Priority/Weight |"); if (mapping->locator_count > 0){ locator_iterator_array[0] = mapping->head_v4_locators_list; locator_iterator_array[1] = mapping->head_v6_locators_list; // Loop through the locators and print each for (ctr = 0 ; ctr < 2 ; ctr++){ locator_iterator = locator_iterator_array[ctr]; while (locator_iterator != NULL) { locator = locator_iterator->locator; dump_locator (locator,log_level); locator_iterator = locator_iterator->next; } } lispd_log_msg(log_level,"\n"); } }
int forward_native( char *packet_buf, int pckt_length ) { int ret = 0; int output_socket = 0; int packet_afi = 0; packet_afi = get_afi_from_packet((uint8_t *)packet_buf); output_socket = get_default_output_socket(packet_afi); if (output_socket == -1){ lispd_log_msg(LISP_LOG_DEBUG_2, "fordward_native: No output interface for afi %d",packet_afi); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_3, "Fordwarding native for destination %s", get_char_from_lisp_addr_t(extract_dst_addr_from_packet(packet_buf))); ret = send_packet(output_socket,packet_buf,pckt_length); return (ret); }
void dump_map_servers(int log_level) { lispd_map_server_list_t *ms = NULL; char str[80]; if (map_servers == NULL || is_loggable(log_level) == FALSE){ return; } lispd_log_msg(log_level, "******************* Map-Servers list ********************************"); lispd_log_msg(log_level, "| Locator (RLOC) | Key Type |"); ms = map_servers; while (ms) { sprintf(str, "| %39s |",get_char_from_lisp_addr_t(*ms->address)); if (ms->key_type == NO_KEY){ sprintf(str + strlen(str)," NONE |"); }else if (ms->key_type == HMAC_SHA_1_96){ sprintf(str + strlen(str)," HMAC-SHA-1-96 |"); }else{ sprintf(str + strlen(str)," HMAC-SHA-256-128 |"); } ms = ms->next; lispd_log_msg(log_level,"%s",str); } }
/* * Restart from root all pending referrals which its previous referral has expired. * @param expired_referral_cache Referral cache entry that has expired */ void reset_pending_referrals_with_expired_previous_referral(lispd_referral_cache_entry *expired_referral_cache) { lispd_pending_referral_cache_list *pending_referrals = pening_referrals_list; lispd_pending_referral_cache_entry *pending_referral_entry = NULL; while (pending_referrals != NULL){ if (pending_referrals->pending_referral_cache_entry->previous_referral == expired_referral_cache){ pending_referral_entry = pending_referrals->pending_referral_cache_entry; pending_referral_entry->previous_referral = get_root_referral_cache(pending_referral_entry->map_cache_entry->mapping->eid_prefix.afi); pending_referral_entry->tried_locators = 0; pending_referral_entry->request_through_root = TRUE; if (pending_referral_entry->nonces != NULL){ free(pending_referral_entry->nonces); pending_referral_entry->nonces = NULL; } if (pending_referral_entry->ddt_request_retry_timer != NULL){ stop_timer(pending_referral_entry->ddt_request_retry_timer); pending_referral_entry->ddt_request_retry_timer = NULL; } lispd_log_msg(LISP_LOG_DEBUG_1,"reset_pending_referrals_with_expired_previous_referral: Resetting of pending referral cache " "%s/%d due to expiration of its parent referral node. Restart from root", get_char_from_lisp_addr_t(pending_referral_entry->map_cache_entry->mapping->eid_prefix), pending_referral_entry->map_cache_entry->mapping->eid_prefix_length); err = send_ddt_map_request_miss(NULL,(void *)pending_referral_entry); } pending_referrals = pending_referrals->next; } }
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; }
int process_map_reply_probe_locator( uint8_t **offset, lispd_mapping_elt *mapping, uint64_t nonce, lispd_locator_elt **locator) { lispd_pkt_mapping_record_locator_t *pkt_locator = NULL; lispd_locator_elt *aux_locator = NULL; uint8_t *cur_ptr = NULL; *locator = NULL; cur_ptr = *offset; pkt_locator = (lispd_pkt_mapping_record_locator_t *)(cur_ptr); cur_ptr = (uint8_t *)&(pkt_locator->locator_afi); /* Extract locator from packet */ aux_locator = new_rmt_locator (&cur_ptr,UP, pkt_locator->priority, pkt_locator->weight, pkt_locator->mpriority, pkt_locator->mweight); if (aux_locator != NULL){ /* If the locator of the packed is probed, search the structure of the locator that represents the locator of tha packet */ if (pkt_locator->probed == TRUE){ *locator = get_locator_from_mapping(mapping, aux_locator->locator_addr); if (*locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2,"get_map_reply_locator_from_mapping: The locator %s is not found in the mapping %s/%d", get_char_from_lisp_addr_t(*(aux_locator->locator_addr)), get_char_from_lisp_addr_t(mapping->eid_prefix), mapping->eid_prefix_length); return (ERR_NO_EXIST); } } }else{ if (err != ERR_AFI_LCAF_TYPE){ return (err); } } *offset = cur_ptr; return (GOOD); }
void dump_iface_list(int log_level) { lispd_iface_list_elt *interface_list = head_interface_list; lispd_iface_mappings_list *mapping_list = NULL; char str[4000]; if (head_interface_list == NULL || is_loggable(log_level) == FALSE){ return; } sprintf(str,"*** LISP RLOC Interfaces List ***\n\n"); while (interface_list){ sprintf(str + strlen(str),"== %s (%s)==\n",interface_list->iface->iface_name, interface_list->iface->status ? "Up" : "Down"); if (interface_list->iface->ipv4_address){ sprintf(str + strlen(str)," IPv4 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv4_address))); sprintf(str + strlen(str)," -- LIST mappings -- \n"); mapping_list = interface_list->iface->head_mappings_list; while (mapping_list){ if (mapping_list->use_ipv4_address == TRUE){ sprintf(str + strlen(str)," %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix), mapping_list->mapping->eid_prefix_length); } mapping_list = mapping_list->next; } } if (interface_list->iface->ipv6_address){ sprintf(str + strlen(str)," IPv6 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv6_address))); sprintf(str + strlen(str)," -- LIST mappings -- \n"); mapping_list = interface_list->iface->head_mappings_list; while (mapping_list){ if (mapping_list->use_ipv6_address == TRUE){ sprintf(str + strlen(str)," %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix), mapping_list->mapping->eid_prefix_length); } mapping_list = mapping_list->next; } } interface_list = interface_list->next; } lispd_log_msg(log_level,"%s",str); }
void set_default_ctrl_ifaces() { default_ctrl_iface_v4 = get_any_output_iface(AF_INET); if (default_ctrl_iface_v4 != NULL) { lispd_log_msg(LISP_LOG_DEBUG_2,"Default IPv4 control iface %s: %s\n", default_ctrl_iface_v4->iface_name, get_char_from_lisp_addr_t(*(default_ctrl_iface_v4->ipv4_address))); } default_ctrl_iface_v6 = get_any_output_iface(AF_INET6); if (default_ctrl_iface_v6 != NULL) { lispd_log_msg(LISP_LOG_DEBUG_2,"Default IPv6 control iface %s: %s\n", default_ctrl_iface_v6->iface_name, get_char_from_lisp_addr_t(*(default_ctrl_iface_v6->ipv6_address))); } // XXX alopez If no output interface found exit --> To be modified when iface management implemented if (!default_ctrl_iface_v4 && !default_ctrl_iface_v6){ lispd_log_msg(LISP_LOG_ERR,"NO CONTROL IFACE: all the locators are down"); } }
/* * Print balancing locators vector information */ void dump_balancing_locators_vec( balancing_locators_vecs b_locators_vecs, lispd_mapping_elt *mapping, int log_level) { int ctr = 0; char str[3000]; if ( is_loggable(log_level)){ lispd_log_msg(log_level,"Balancing locator vector for %s/%d: ", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); sprintf(str," IPv4 locators vector (%d locators): ",b_locators_vecs.v4_locators_vec_length); for (ctr = 0; ctr< b_locators_vecs.v4_locators_vec_length; ctr++){ if (strlen(str) > 2850){ sprintf(str + strlen(str)," ..."); break; } sprintf(str + strlen(str)," %s ",get_char_from_lisp_addr_t(*b_locators_vecs.v4_balancing_locators_vec[ctr]->locator_addr)); } lispd_log_msg(log_level,"%s",str); sprintf(str," IPv6 locators vector (%d locators): ",b_locators_vecs.v6_locators_vec_length); for (ctr = 0; ctr< b_locators_vecs.v6_locators_vec_length; ctr++){ if (strlen(str) > 2900){ sprintf(str + strlen(str)," ..."); break; } sprintf(str + strlen(str)," %s ",get_char_from_lisp_addr_t(*b_locators_vecs.v6_balancing_locators_vec[ctr]->locator_addr)); } lispd_log_msg(log_level,"%s",str); sprintf(str," IPv4 & IPv6 locators vector (%d locators): ", b_locators_vecs.locators_vec_length); for (ctr = 0; ctr< b_locators_vecs.locators_vec_length; ctr++){ if (strlen(str) > 2950){ sprintf(str + strlen(str)," ..."); break; } sprintf(str + strlen(str)," %s ",get_char_from_lisp_addr_t(*b_locators_vecs.balancing_locators_vec[ctr]->locator_addr)); } lispd_log_msg(log_level,"%s",str); } }
void dump_locator ( lispd_locator_elt *locator, int log_level) { char locator_str [2000]; if (is_loggable(log_level)){ sprintf(locator_str, "| %39s |", get_char_from_lisp_addr_t(*(locator->locator_addr))); sprintf(locator_str + strlen(locator_str), " %5s ", locator->state ? "Up" : "Down"); sprintf(locator_str + strlen(locator_str), "| %3d/%-3d |", locator->priority, locator->weight); LISPD_LOG(log_level,"%s",locator_str); } }
/* * Add a locator into the locators list of the mapping. */ int add_locator_to_mapping( lispd_mapping_elt *mapping, lispd_locator_elt *locator) { int result = GOOD; switch (locator->locator_addr->afi){ case AF_INET: err = add_locator_to_list (&(mapping->head_v4_locators_list), locator); break; case AF_INET6: err = add_locator_to_list (&(mapping->head_v6_locators_list), locator); break; case AF_UNSPEC: err = add_locator_to_list (&(((lcl_mapping_extended_info *)(mapping->extended_info))->head_not_init_locators_list), locator); if (err == GOOD){ // The locator_count should not be incremented return (GOOD); } } if (err == GOOD){ mapping->locator_count++; lispd_log_msg(LISP_LOG_DEBUG_3, "add_locator_to_mapping: The locator %s has been added to the EID %s/%d.", get_char_from_lisp_addr_t(*(locator->locator_addr)), get_char_from_lisp_addr_t(mapping->eid_prefix), mapping->eid_prefix_length); result = GOOD; }else if (err == ERR_EXIST){ lispd_log_msg(LISP_LOG_DEBUG_3, "add_locator_to_mapping: The locator %s already exists for the EID %s/%d.", get_char_from_lisp_addr_t(*(locator->locator_addr)), get_char_from_lisp_addr_t(mapping->eid_prefix), mapping->eid_prefix_length); result = GOOD; }else{ result = BAD; } return (result); }
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); }
int fordward_to_petr( char *original_packet, int original_packet_length, lispd_mapping_elt *src_mapping, packet_tuple tuple) { lispd_locator_elt *outer_src_locator = NULL; lispd_locator_elt *outer_dst_locator = NULL; char *encap_packet = NULL; int encap_packet_size = 0; int output_socket = 0; if (proxy_etrs == NULL){ lispd_log_msg(LISP_LOG_DEBUG_3, "fordward_to_petr: Proxy-etr not found"); return (BAD); } if ((select_src_rmt_locators_from_balancing_locators_vec ( src_mapping, proxy_etrs->mapping, tuple, &outer_src_locator, &outer_dst_locator)) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_3, "fordward_to_petr: No Proxy-etr compatible with local locators afi"); return (BAD); } if (encapsulate_packet(original_packet, original_packet_length, outer_src_locator->locator_addr, outer_dst_locator->locator_addr, LISP_DATA_PORT, LISP_DATA_PORT, 0, &encap_packet, &encap_packet_size) != GOOD){ return (BAD); } output_socket = ((lcl_locator_extended_info *)(outer_src_locator->extended_info))->out_socket; if (send_packet (output_socket,encap_packet,encap_packet_size ) != GOOD){ free (encap_packet ); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_3, "Fordwarded eid %s to petr",get_char_from_lisp_addr_t(extract_dst_addr_from_packet(original_packet))); free (encap_packet ); return (GOOD); }
int add_route( int afi, uint32_t ifindex, lisp_addr_t *dest, lisp_addr_t *src, lisp_addr_t *gw, uint32_t prefix_len, uint32_t metric, uint32_t table) { int result = BAD; result = modify_route(RTM_NEWROUTE, afi,ifindex, dest, src, gw, prefix_len, metric, table); if (result == GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1, "add_route: added route to the system: src addr: %s, dst prefix:%s/%d, gw: %s, table: %d", (src != NULL) ? get_char_from_lisp_addr_t(*src) : "-", (dest != NULL) ? get_char_from_lisp_addr_t(*dest) : "-", prefix_len, (gw != NULL) ? get_char_from_lisp_addr_t(*gw) : "-", table); } return (result); }
/* * Remove a referral and all its offspring */ int referral_expiry( timer *t, void *arg) { lispd_referral_cache_entry *referral_entry = (lispd_referral_cache_entry *)arg; lispd_log_msg(LISP_LOG_DEBUG_1,"referral_expiry: The referral entry with prefix %s/%d has expired. " "Removing it and all its offspring", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); remove_referral_cache_entry_from_parent_node(referral_entry); del_referral_cache_entry_from_db(referral_entry); dump_referral_cache_db(LISP_LOG_DEBUG_3); return (GOOD); }
int process_ms_not_registered_reply( lispd_referral_cache_entry *referral_entry, lispd_pending_referral_cache_entry *pending_referral_entry) { lispd_referral_cache_entry *db_referral_entry = NULL; db_referral_entry = lookup_referral_cache_exact( referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES); /* Add referral cache entry to database */ if (db_referral_entry == NULL){ if (add_referral_cache_entry_to_db(referral_entry) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_not_registered_reply: Coudn't add referral cache entry for prefix %s/%d", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); free_referral_cache_entry(referral_entry); remove_pending_referral_cache_entry_from_list(pending_referral_entry); return (BAD); } add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry); pending_referral_entry->previous_referral = referral_entry; }else{ /* Entry already exist. Replace it with the new data. Valid if the previous entry was a ms ack or ms not registered ack */ update_referral_cache_data(db_referral_entry, referral_entry); free_referral_cache_entry(referral_entry); referral_entry = db_referral_entry; } /* Try with the next ddt node*/ pending_referral_entry->tried_locators = pending_referral_entry->tried_locators + 1; lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_not_registered_reply: Receive a MS_NOT_REGISTERED referral. Trying next node"); err = send_ddt_map_request_miss(NULL,(void *)pending_referral_entry); /* If we asked to all MS where prefix is delegated and all reply MS_NOT_REGISTERED, remove entry from pending list * and activate map cache*/ if (err == ERR_DST_ADDR){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_not_registered_reply: Tried all noedes. Activate negative map reply"); if (activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length,referral_entry->ttl,MAPPING_ACT_NO_ACTION) != 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); /* Program expiry time */ program_referral_expiry_timer(referral_entry); } return (GOOD); }
int process_ms_ack_reply( lispd_referral_cache_entry *referral_entry, lispd_pending_referral_cache_entry *pending_referral_entry) { lispd_referral_cache_entry *db_referral_entry = NULL; db_referral_entry = lookup_referral_cache_exact( referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES); /* Add referral cache entry to database */ if (db_referral_entry == NULL){ if (add_referral_cache_entry_to_db(referral_entry) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_ack_reply: Coudn't add referral cache entry for prefix %s/%d", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); free_referral_cache_entry(referral_entry); remove_pending_referral_cache_entry_from_list(pending_referral_entry); return (BAD); } add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry); }else{ /* Entry already exist. Replace it with the new data. Valid if the previous entry was a ms ack or ms not registered ack */ update_referral_cache_data(db_referral_entry, referral_entry); free_referral_cache_entry(referral_entry); referral_entry = db_referral_entry; } /* Program expiry time */ program_referral_expiry_timer(referral_entry); /* Finish process and remove the pending referral cache from the list */ if (pending_referral_entry->map_cache_entry->active == TRUE){ // We have received a map reply remove_pending_referral_cache_entry_from_list(pending_referral_entry); } else{ if (pending_referral_entry->ddt_request_retry_timer == NULL){ pending_referral_entry->ddt_request_retry_timer = create_timer (DDT_MAP_REQ_RETRY_MS_ACK_TIMER); } pending_referral_entry->previous_referral = referral_entry; start_timer(pending_referral_entry->ddt_request_retry_timer, LISPD_INITIAL_MRQ_TIMEOUT, send_map_request_ddt_map_reply_miss, (void *)pending_referral_entry); } return (GOOD); }
void dump_servers( lispd_addr_list_t *list, const char *list_name, int log_level) { lispd_addr_list_t *iterator = 0; if (!list) return; lispd_log_msg(log_level, "************* %13s ***************", list_name); lispd_log_msg(log_level, "| Locator (RLOC) |"); iterator = list; while (iterator) { lispd_log_msg(log_level,"| %39s |", get_char_from_lisp_addr_t(*(iterator->address))); iterator = iterator->next; } }
int process_delegation_hole_reply( lispd_referral_cache_entry *referral_entry, lispd_pending_referral_cache_entry *pending_referral_entry) { lispd_referral_cache_entry *db_referral_entry = NULL; db_referral_entry = lookup_referral_cache_exact( referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES); if (db_referral_entry != NULL && db_referral_entry->act_entry_type != DELEGATION_HOLE){ del_referral_cache_entry_from_db(db_referral_entry); db_referral_entry = NULL; } if (db_referral_entry == NULL){ /* Add referral cache entry to database */ if (add_referral_cache_entry_to_db(referral_entry) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_delegation_hole_reply: Coudn't add referral cache entry for prefix %s/%d", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); free_referral_cache_entry(referral_entry); remove_pending_referral_cache_entry_from_list(pending_referral_entry); return (BAD); } add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry); }else{ /* Entry already exist. Replace it with the new data.*/ update_referral_cache_data(db_referral_entry, referral_entry); free_referral_cache_entry(referral_entry); referral_entry = db_referral_entry; } /*Remove entry from pending list and activate map cache*/ if (activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length,referral_entry->ttl,MAPPING_ACT_NO_ACTION)!=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); /* Program expiry time */ program_referral_expiry_timer(referral_entry); return(GOOD); }
void process_nl_del_address (struct nlmsghdr *nlh) { struct ifaddrmsg *ifa = NULL; struct rtattr *rth = NULL; int iface_index = 0; int rt_length = 0; lispd_iface_elt *iface = NULL; lisp_addr_t new_addr; char iface_name[IF_NAMESIZE]; ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh); iface_index = ifa->ifa_index; iface = get_interface_from_index(iface_index); if (iface == NULL) { if_indextoname(iface_index, iface_name); lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_add_address: the netlink message is not for any interface associated with RLOCs (%s)", iface_name); return; } rth = IFA_RTA (ifa); rth = IFA_RTA (ifa); rt_length = IFA_PAYLOAD (nlh); for (; rt_length && RTA_OK (rth, rt_length); rth = RTA_NEXT (rth,rt_length)) { if (rth->rta_type == IFA_ADDRESS) { if (ifa->ifa_family == AF_INET) { memcpy (&(new_addr.address),(struct in_addr *)RTA_DATA(rth),sizeof(struct in_addr)); new_addr.afi = AF_INET; } else if (ifa->ifa_family == AF_INET6) { memcpy (&(new_addr.address),(struct in6_addr *)RTA_DATA(rth),sizeof(struct in6_addr)); new_addr.afi = AF_INET6; } break; } } /* Actions to be done when address is removed */ lispd_log_msg(LISP_LOG_DEBUG_2," deleted address: %s\n", get_char_from_lisp_addr_t(new_addr)); }
/* * This function deletes a specific ip rule to * kernel's rule list */ int del_rule( int afi, int if_index, uint8_t table, uint32_t priority, uint8_t type, lisp_addr_t *src_addr, int src_plen, lisp_addr_t *dst_addr, int dst_plen, int flags) { int result = BAD; result = modify_rule(afi, if_index, RTM_DELRULE, table,priority, type, src_addr, src_plen, dst_addr, dst_plen, flags); if (result == GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1, "del_rule: Removed rule for source routing of src addr: %s", get_char_from_lisp_addr_t(*src_addr)); } return (result); }
int remove_pending_referral_cache_entry_from_list(lispd_pending_referral_cache_entry *pending_referral) { lispd_pending_referral_cache_list *list_elt = NULL; lispd_pending_referral_cache_list *prev_list_elt = NULL; uint8_t entry_found = FALSE; uint8_t result = FALSE; list_elt = pening_referrals_list; while (list_elt != NULL){ if (list_elt->pending_referral_cache_entry == pending_referral){ if (prev_list_elt == NULL){ pening_referrals_list = list_elt->next; }else{ prev_list_elt->next = list_elt->next; } entry_found = TRUE; break; } prev_list_elt = list_elt; list_elt = list_elt->next; } if (entry_found == TRUE){ free (list_elt); result = GOOD; }else{ lispd_log_msg(LISP_LOG_DEBUG_1,"remove_pending_referral_cache_entry_from_list: The entry %s/%d has not been found" " in the list of pending referral cache entries", get_char_from_lisp_addr_t(pending_referral->map_cache_entry->mapping->eid_prefix), pending_referral->map_cache_entry->mapping->eid_prefix_length); result = BAD; } free_pending_referral_cache_entry(pending_referral); return (result); }
/* * Add a locator to a locators list */ int add_locator_to_list ( lispd_locators_list **list, lispd_locator_elt *locator) { lispd_locators_list *locator_list = NULL, *aux_locator_list_prev = NULL, *aux_locator_list_next = NULL; int cmp = 0; if ((locator_list = malloc(sizeof(lispd_locators_list))) == NULL) { LISPD_LOG(LISP_LOG_WARNING, "Unable to allocate memory for lispd_locator_list: %s", strerror(errno)); return(ERR_MALLOC); } locator_list->next = NULL; locator_list->locator = locator; if (locator->locator_type == LOCAL_LOCATOR && locator->locator_addr->afi != AF_UNSPEC){ /* If it's a local initialized locator, we should store it in order*/ if (*list == NULL){ *list = locator_list; }else{ aux_locator_list_prev = NULL; aux_locator_list_next = *list; while (aux_locator_list_next != NULL){ if (locator->locator_addr->afi == AF_INET){ cmp = memcmp(&(locator->locator_addr->address.ip),&(aux_locator_list_next->locator->locator_addr->address.ip),sizeof(struct in_addr)); } else { cmp = memcmp(&(locator->locator_addr->address.ipv6),&(aux_locator_list_next->locator->locator_addr->address.ipv6),sizeof(struct in6_addr)); } if (cmp < 0){ break; } if (cmp == 0){ LISPD_LOG(LISP_LOG_DEBUG_3, "The locator %s already exists.", get_char_from_lisp_addr_t(*(locator->locator_addr))); free (locator_list); return (ERR_EXIST); } aux_locator_list_prev = aux_locator_list_next; aux_locator_list_next = aux_locator_list_next->next; } if (aux_locator_list_prev == NULL){ locator_list->next = aux_locator_list_next; *list = locator_list; }else{ aux_locator_list_prev->next = locator_list; locator_list->next = aux_locator_list_next; } } }else{ /* Remote locators and not initialized local locators */ if (*list == NULL){ *list = locator_list; }else{ aux_locator_list_prev = *list; while (aux_locator_list_prev->next != NULL){ aux_locator_list_prev = aux_locator_list_prev->next; } aux_locator_list_prev->next = locator_list; } } return (GOOD); }
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); }