void NS_CLASS route_expire_timeout(void *arg) { rt_table_t *rt; rt = (rt_table_t *) arg; if (!rt) { log(LOG_WARNING, 0, __FUNCTION__, "arg was NULL, ignoring timeout!"); return; } DEBUG(LOG_DEBUG, 0, "Route %s DOWN, seqno=%d", ip_to_str(rt->dest_addr), rt->dest_seqno); rt_table_invalidate(rt); precursor_list_destroy(rt); return; }
void rerr_process(RERR * rerr, int rerrlen, u_int32_t ip_src, u_int32_t ip_dst) { RERR *new_rerr = NULL; rt_table_t *entry; u_int32_t rerr_dest, rerr_dest_seqno; int i; RERR_udest *udest; #ifdef DEBUG log(LOG_DEBUG, 0, "rerr_process: ip_src=%s", ip_to_str(ip_src)); log_pkt_fields((AODV_msg *) rerr); #endif if (rerrlen < RERR_CALC_SIZE(rerr)) { log(LOG_WARNING, 0, "rerr_process: IP data too short (%u bytes) from %s to %s. Should be %d bytes.", rerrlen, ip_to_str(ip_src), ip_to_str(ip_dst), RERR_CALC_SIZE(rerr)); return; } /* Check which destinations that are unreachable. */ udest = RERR_UDEST_FIRST(rerr); while (rerr->dest_count) { rerr_dest = ntohl(udest->dest_addr); rerr_dest_seqno = ntohl(udest->dest_seqno); #ifdef DEBUG log(LOG_DEBUG, 0, "rerr_process: unreachable dest=%s seqno=%ld", ip_to_str(rerr_dest), rerr_dest_seqno); #endif if ((entry = rt_table_find_active(rerr_dest)) != NULL && memcmp(&entry->next_hop, &ip_src, sizeof(u_int32_t)) == 0) { /* (a) updates the corresponding destination sequence number with the Destination Sequence Number in the packet, and */ /* UGLY HACK: we decrement the seqno by one here, since it will be incremented upon calling rt_table_invalidate() below... */ entry->dest_seqno = rerr_dest_seqno - 1; /* (d) check precursor list for emptiness. If not empty, include the destination as an unreachable destination in the RERR... */ if (entry->precursors != NULL) { if (new_rerr == NULL) new_rerr = rerr_create(0, entry->dest_addr, entry->dest_seqno); else rerr_add_udest(new_rerr, entry->dest_addr, entry->dest_seqno); } #ifdef DEBUG log(LOG_DEBUG, 0, "rerr_process: removing rte %s - WAS IN RERR!!", ip_to_str(rerr_dest)); #endif /* Invalidate route: Hop count -> INFTY */ rt_table_invalidate(entry); } udest = RERR_UDEST_NEXT(udest); rerr->dest_count--; } /* End while() */ /* If a RERR was created, then send it now... */ /* FIXME: Unicast if possible... And send on only those interfaces where it is necessary. */ if (new_rerr) { for (i = 0; i < MAX_NR_INTERFACES; i++) { if (!DEV_NR(i).enabled) continue; aodv_socket_send((AODV_msg *) new_rerr, AODV_BROADCAST, RERR_CALC_SIZE(rerr), 1, &DEV_NR(i)); } } }
void route_expire_timeout(void *arg) { rt_table_t *rt_entry; #ifdef DEBUG u_int32_t now = get_currtime(); #endif rt_entry = (rt_table_t *)arg; if(rt_entry == NULL) { log(LOG_WARNING, 0, "route_expire_timer: arg was NULL, ignoring timeout!"); return; } #ifdef DEBUG log(LOG_DEBUG, 0, "route_expire_timeout: %s curT=%lu exp=%lu", ip_to_str(rt_entry->dest_addr), now, rt_entry->expire); #endif /* If hopcount = 1, this is a direct neighbor and a link break has occured. Send a RERR with the incremented sequence number */ if(rt_entry->hcnt == 1) { RERR *rerr; rt_table_t *u_entry; int i; #ifdef DEBUG log(LOG_DEBUG, 0, "route_expire_timeout: LINK FAILURE for %s, seqno=%d", ip_to_str(rt_entry->dest_addr), rt_entry->dest_seqno); #endif /* Create a route error msg */ rerr = rerr_create(0, rt_entry->dest_addr, rt_entry->dest_seqno); /* Check the routing table for entries which have the unreachable destination (dest) as next hop. These entries (destinations) cannot be reached either since dest is down. They should therefore also be included in the RERR. */ for(i = 0; i < RT_TABLESIZE; i++) { for (u_entry = routing_table[i]; u_entry != NULL; u_entry = u_entry->next) { if ((u_entry->next_hop == rt_entry->dest_addr) && (u_entry->dest_addr != rt_entry->dest_addr)) { if(u_entry->precursors != NULL) { rerr_add_udest(rerr, u_entry->dest_addr, u_entry->dest_seqno); #ifdef DEBUG log(LOG_DEBUG, 0, "route_expire_timeout: Added %s as unreachable, seqno=%d", ip_to_str(u_entry->dest_addr), u_entry->dest_seqno); #endif rerr->dest_count++; } rt_table_invalidate(u_entry); } } } /* FIXME: Check if we should unicast the RERR. This check does not catch all cases when we could unicast (like when several unreachable destinations have the same precursor). */ if(rerr->dest_count == 1 && rt_entry->precursors != NULL && rt_entry->precursors->next == NULL) aodv_socket_send((AODV_msg *)rerr, rt_entry->precursors->neighbor, RERR_CALC_SIZE(rerr), 1); else if(rerr->dest_count > 1 && (rt_entry->precursors != NULL)) aodv_socket_send((AODV_msg *)rerr, AODV_BROADCAST, RERR_CALC_SIZE(rerr), 1); #ifdef DEBUG else log(LOG_DEBUG, 0, "route_expire_timeout: No precursors, dropping RERR"); #endif } /* Now also invalidate the entry of the link that broke... */ rt_table_invalidate(rt_entry); }