static void bce_delete(struct bcentry *bce, int flush) { pthread_rwlock_wrlock(&bce->lock); if (bce->type != BCE_DAD) { del_task(&bce->tqe); if (bce->type != BCE_NONCE_BLOCK) xfrm_del_bce(&bce->our_addr, &bce->peer_addr); } if (bce->cleanup) bce->cleanup(bce); if (!flush && (bce->type == BCE_CACHED || bce->type == BCE_CACHE_DYING)) { struct timespec minlft; if (!rr_cn_nonce_lft(bce->nonce_hoa, &minlft)) { bce->type = BCE_NONCE_BLOCK; add_task_abs(&minlft, &bce->tqe, _expire); pthread_rwlock_unlock(&bce->lock); return; } } bcache_count--; hash_delete(&bc_hash, &bce->our_addr, &bce->peer_addr); pthread_rwlock_unlock(&bce->lock); bcache_free(bce); }
/* Adds bul entry to both hashes and adds a timer for expiry / resend. Caller must fill all non-private fields of bule */ int bul_add(struct bulentry *bule) { int ret = 0; struct timespec timer_expire; struct home_addr_info *hai = bule->home; assert(bule && tsisset(bule->lifetime) && hai); if ((ret = hash_add(&bul_hash, bule, &bule->hoa, &bule->peer_addr)) < 0) return ret; if ((ret = hash_add(&hai->bul, bule, NULL, &bule->peer_addr)) < 0) goto bul_free; clock_gettime(CLOCK_REALTIME, &bule->lastsent); if (bule->type == BUL_ENTRY) { if ((ret = pre_bu_bul_update(bule)) < 0) goto home_bul_free; } else if (bule->type == NON_MIP_CN_ENTRY) { if (bule->flags & IP6_MH_BU_HOME) { if (xfrm_block_hoa(hai) < 0) goto home_bul_free; } } tsadd(bule->delay, bule->lastsent, timer_expire); dbg("Adding bule\n"); dbg_func(bule, dump_bule); add_task_abs(&timer_expire, &bule->tqe, bule->callback); return 0; home_bul_free: hash_delete(&hai->bul, &bule->hoa, &bule->peer_addr); bul_free: hash_delete(&bul_hash, &bule->hoa, &bule->peer_addr); return ret; }
/* * need to be separated into two phase: * phase 1: before sending BU * add policy/state for BU * phase 2: after sending BU * add policy/state for RO */ void bul_update_timer(struct bulentry *bule) { struct timespec timer_expire; tsadd(bule->delay, bule->lastsent, timer_expire); dbg("Updating timer\n"); dbg_func(bule, dump_bule); add_task_abs(&timer_expire, &bule->tqe, bule->callback); }
//--------------------------------------------------------------------------------------------------------------------- void pmip_timer_retrans_pbu_handler(struct tq_elem *tqe) { int mutex_return_code; mutex_return_code = pthread_rwlock_wrlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_wrlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } printf("-------------------------------------\n"); if (!task_interrupted()) { pmip_entry_t *e = tq_data(tqe, pmip_entry_t, tqe); mutex_return_code = pthread_rwlock_wrlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_wrlock(&e->lock) %s\n", strerror(mutex_return_code)); } dbg("Retransmissions counter : %d\n", e->n_rets_counter); if (e->n_rets_counter == 0) { free_iov_data((struct iovec *) &e->mh_vec, e->iovlen); dbg("No PBA received from LMA....\n"); dbg("Abort Trasmitting the PBU....\n"); mutex_return_code = pthread_rwlock_unlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&e->lock) %s\n", strerror(mutex_return_code)); } pmip_bce_delete(e); } else { //Decrement the N trasnmissions counter. e->n_rets_counter--; struct in6_addr_bundle addrs; addrs.src = &conf.OurAddress; addrs.dst = &conf.LmaAddress; //sends a PBU dbg("Send PBU again....\n"); // INCREMENT SEQ NUMBER OF PBU e->seqno_out = get_new_pbu_sequence_number(); ((struct ip6_mh_binding_update *)(e->mh_vec[0].iov_base))->ip6mhbu_seqno = htons(e->seqno_out); pmip_mh_send(&addrs, e->mh_vec, e->iovlen, e->link); //add a new task for PBU retransmission. struct timespec expires; clock_gettime(CLOCK_REALTIME, &e->add_time); tsadd(e->add_time, conf.RetransmissionTimeOut, expires); add_task_abs(&expires, &e->tqe, pmip_timer_retrans_pbu_handler); dbg("PBU Retransmissions timer is triggered again....\n"); mutex_return_code = pthread_rwlock_unlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&e->lock) %s\n", strerror(mutex_return_code)); } } } mutex_return_code = pthread_rwlock_unlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } }
//--------------------------------------------------------------------------------------------------------------------- int pmip_cache_start(pmip_entry_t * bce) { dbg("PMIP cache start is initialized add task pmip_timer_bce_expired_handler in %d seconds\n", bce->lifetime.tv_sec); struct timespec expires; clock_gettime(CLOCK_REALTIME, &bce->add_time); tsadd(bce->add_time, bce->lifetime, expires); add_task_abs(&expires, &bce->tqe, pmip_timer_bce_expired_handler); return 0; }
static int __bcache_start(struct bcentry *bce) { struct timespec expires, tmp; tssub(bce->lifetime, CN_BRR_BEFORE_EXPIRY_TS, tmp); clock_gettime(CLOCK_REALTIME, &bce->add_time); tsadd(bce->add_time, bce->type == BCE_HOMEREG ? bce->lifetime : tmp, expires); add_task_abs(&expires, &bce->tqe, _expire); xfrm_add_bce(&bce->our_addr, &bce->peer_addr, &bce->coa, 0); return 0; }
//--------------------------------------------------------------------------------------------------------------------- int pmip_cache_start(pmip_entry_t * bce) { /* AnhKhuong _add */ // if (is_lma()) return 0; /* AnhKhuong _end */ //dbg("PMIP cache start is initialized.. \n"); struct timespec expires; clock_gettime(CLOCK_REALTIME, &bce->add_time); tsadd(bce->add_time, bce->lifetime, expires); add_task_abs(&expires, &bce->tqe, pmip_timer_bce_expired_handler); return 0; }
int bcache_update_expire(struct bcentry *bce) { struct timespec expires; clock_gettime(CLOCK_REALTIME, &bce->add_time); if (bce->type == BCE_HOMEREG) expires = bce->lifetime; else { bce->type = BCE_CACHED; tssub(bce->lifetime, CN_BRR_BEFORE_EXPIRY_TS, expires); } tsadd(expires, bce->add_time, expires); add_task_abs(&expires, &bce->tqe, _expire); xfrm_add_bce(&bce->our_addr, &bce->peer_addr, &bce->coa, 1); return 0; }
//--------------------------------------------------------------------------------------------------------------------- void pmip_timer_bce_expired_handler(struct tq_elem *tqe) { int mutex_return_code; mutex_return_code = pthread_rwlock_wrlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_wrlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } printf("-------------------------------------\n"); if (!task_interrupted()) { pmip_entry_t *e = tq_data(tqe, pmip_entry_t, tqe); mutex_return_code = pthread_rwlock_wrlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_wrlock(&e->lock) %s\n", strerror(mutex_return_code)); } dbg("Retransmissions counter : %d\n", e->n_rets_counter); if (e->n_rets_counter == 0) { dbg("Retransmissions counter expired\n"); free_iov_data((struct iovec *) &e->mh_vec, e->iovlen); if (is_mag()) { //++e->seqno_out; dbg("Calling deregistration\n"); mag_dereg(e, 1); pmipcache_release_entry(e); pmip_bce_delete(e); return; } //Delete existing route for the deleted MN if (is_ha()) { lma_dereg(e, 0, 0); pmipcache_release_entry(e); pmip_bce_delete(e); return; } mutex_return_code = pthread_rwlock_unlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } return; } if (is_mag()) { dbg("Send NS for Neighbour Reachability for:%x:%x:%x:%x:%x:%x:%x:%x iif=%d\n", NIP6ADDR(&e->mn_hw_address), e->link); //Create NS for Reachability test! //ndisc_send_ns(e->link, &conf.MagAddressIngress[0], solicited_mcast(&e->mn_suffix), get_mn_addr(e)); ndisc_send_ns(e->link, get_mn_addr(e)); struct timespec expires; clock_gettime(CLOCK_REALTIME, &e->add_time); tsadd(e->add_time, conf.RetransmissionTimeOut, expires); // Add a new task for deletion of entry if No Na is received. add_task_abs(&expires, &e->tqe, pmip_timer_bce_expired_handler); dbg("Start the Timer for Retransmission/Deletion ....\n"); //Decrements the Retransmissions counter. e->n_rets_counter--; mutex_return_code = pthread_rwlock_unlock(&e->lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&e->lock) %s\n", strerror(mutex_return_code)); } } if (is_ha()) { lma_dereg(e, 0, 0); pmipcache_release_entry(e); pmip_bce_delete(e); return; } } mutex_return_code = pthread_rwlock_unlock(&pmip_lock); if (mutex_return_code != 0) { dbg("pthread_rwlock_unlock(&pmip_lock) %s\n", strerror(mutex_return_code)); } }