//--------------------------------------------------------------------------------------------------------------------- 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)); } }
/** * _expire - expire binding cache entry **/ static void _expire(struct tq_elem *tqe) { pthread_rwlock_wrlock(&bc_lock); if (!task_interrupted()) { struct bcentry *e = tq_data(tqe, struct bcentry, tqe); pthread_rwlock_wrlock(&e->lock); if (e->type == BCE_CACHED) { /* To do: MN needs to reverse tunnel this */ mh_send_brr(&e->peer_addr, &e->our_addr); e->type = BCE_CACHE_DYING; add_task_rel(&CN_BRR_BEFORE_EXPIRY_TS, &e->tqe, _expire); pthread_rwlock_unlock(&e->lock); pthread_rwlock_unlock(&bc_lock); return; } pthread_rwlock_unlock(&e->lock); bce_delete(e, 0); } pthread_rwlock_unlock(&bc_lock); }
//--------------------------------------------------------------------------------------------------------------------- void pmip_timer_tunnel_expired_handler(struct tq_elem *tqe) { int mutex_return_code; int res; 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"); printf("-pmip_timer_tunnel_expired_handler()-\n"); printf("-------------------------------------\n"); if (!task_interrupted()) { tunnel_timer_t *tt = container_of(tqe, tunnel_timer_t, tqe); res = tunnel_del(tt->tunnel, 0, 0); tt->lifetime.tv_nsec = 0; tt->lifetime.tv_sec = 0; } 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)); } }
//--------------------------------------------------------------------------------------------------------------------- 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)); } }