25. More Info Https://ThesisScientist.com
}
NS_INLINE rt_table_t *NS_CLASS rt_table_update_timeout(rt_table_t * rt,
u_int32_t lifetime)
{
struct timeval new_timeout;
if (!rt)
return NULL;
if (rt->state == VALID) {
gettimeofday(&new_timeout, NULL);
timeval_add_msec(&new_timeout, lifetime);
if (timeval_diff(&rt->rt_timer.timeout, &new_timeout) < 0)
timer_set_timeout(&rt->rt_timer, lifetime);
} else
timer_set_timeout(&rt->rt_timer, lifetime);
return rt;
}
/* Update route timeouts in response to an incoming or outgoing data packet. */
void NS_CLASS rt_table_update_route_timeouts(rt_table_t * fwd_rt,
rt_table_t * rev_rt)
{
rt_table_t *next_hop_rt = NULL;
if (fwd_rt && fwd_rt->state == VALID) {
if (llfeedback || fwd_rt->flags & RT_INET_DEST ||
fwd_rt->hcnt != 1 || fwd_rt->hello_timer.used)
rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);
next_hop_rt = rt_table_find(fwd_rt->next_hop);
if (next_hop_rt && next_hop_rt->state == VALID &&
next_hop_rt->dest_addr.s_addr != fwd_rt->dest_addr.s_addr &&
(llfeedback || fwd_rt->hello_timer.used))
rt_table_update_timeout(next_hop_rt,
ACTIVE_ROUTE_TIMEOUT);
}
if (rev_rt && rev_rt->state == VALID) {
if (llfeedback || rev_rt->hcnt != 1 || rev_rt->hello_timer.used)
rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);
next_hop_rt = rt_table_find(rev_rt->next_hop);
if (next_hop_rt && next_hop_rt->state == VALID && rev_rt &&
next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr &&
26. More Info Https://ThesisScientist.com
(llfeedback || rev_rt->hello_timer.used))
rt_table_update_timeout(next_hop_rt,
ACTIVE_ROUTE_TIMEOUT);
rt_table_t *NS_CLASS rt_table_find(struct in_addr dest_addr)
{
hash_value hash;
unsigned int index;
list_t *pos;
if (rt_tbl.num_entries == 0)
return NULL;
/* Calculate index */
index = hashing(&dest_addr, &hash);
/* Handle collisions: */
list_foreach(pos, &rt_tbl.tbl[index]) {
rt_table_t *rt = (rt_table_t *) pos;
if (rt->hash != hash)
continue;
if (memcmp(&dest_addr, &rt->dest_addr, sizeof(struct in_addr))
== 0)
return rt;
}
return NULL;
}
rt_table_t *NS_CLASS rt_table_find_gateway()
{
rt_table_t *gw = NULL;
int i;
for (i = 0; i < RT_TABLESIZE; i++) {
list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt = (rt_table_t *) pos;
if (rt->flags & RT_GATEWAY && rt->state == VALID) {
if (!gw || rt->hcnt < gw->hcnt)
gw = rt;
}
}
}
return gw;
}
#ifdef CONFIG_GATEWAY
int NS_CLASS rt_table_update_inet_rt(rt_table_t * gw, u_int32_t life)
{
int n = 0;
27. More Info Https://ThesisScientist.com
int i;
if (!gw)
return -1;
for (i = 0; i < RT_TABLESIZE; i++) {
list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt = (rt_table_t *) pos;
if (rt->flags & RT_INET_DEST && rt->state == VALID) {
rt_table_update(rt, gw->dest_addr, gw->hcnt, 0,
life, VALID, rt->flags);
n++;
}
}
}
return n;
}
#endif /* CONFIG_GATEWAY_DISABLED */
/* Route expiry and Deletion. */
int NS_CLASS rt_table_invalidate(rt_table_t * rt)
{
struct timeval now;
gettimeofday(&now, NULL);
if (rt == NULL)
return -1;
/* If the route is already invalidated, do nothing... */
if (rt->state == INVALID) {
DEBUG(LOG_DEBUG, 0, "Route %s already invalidated!!!",
ip_to_str(rt->dest_addr));
return -1;
}
if (rt->hello_timer.used) {
DEBUG(LOG_DEBUG, 0, "last HELLO: %ld",
timeval_diff(&now, &rt->last_hello_time));
}
/* Remove any pending, but now obsolete timers. */
timer_remove(&rt->rt_timer);
timer_remove(&rt->hello_timer);
timer_remove(&rt->ack_timer);
/* Mark the route as invalid */
rt->state = INVALID;
rt_tbl.num_active--;
rt->hello_cnt = 0;
/* When the lifetime of a route entry expires, increase the sequence
number for that entry. */
28. More Info Https://ThesisScientist.com
seqno_incr(rt->dest_seqno);
rt->last_hello_time.tv_sec = 0;
rt->last_hello_time.tv_usec = 0;
#ifndef NS_PORT
nl_send_del_route_msg(rt->dest_addr, rt->next_hop, rt->hcnt);
#endif
#ifdef CONFIG_GATEWAY
if (rt->flags & RT_GATEWAY) {
int i;
rt_table_t *gw = rt_table_find_gateway();
for (i = 0; i < RT_TABLESIZE; i++) {
list_t *pos;
list_foreach(pos, &rt_tbl.tbl[i]) {
rt_table_t *rt2 = (rt_table_t *) pos;
if (rt2->state == VALID
&& (rt2->flags & RT_INET_DEST)
&& (rt2->next_hop.s_addr ==
rt->dest_addr.s_addr)) {
if (0) {
DEBUG(LOG_DEBUG, 0,
"Invalidated GW %s but found new GW %s for
%s",
ip_to_str(rt->dest_addr),
ip_to_str(gw->dest_addr),
ip_to_str(rt2->
dest_addr));
rt_table_update(rt2,
gw->dest_addr,
gw->hcnt, 0,
timeval_diff
(&rt->rt_timer.
timeout, &now),
VALID,
rt2->flags);
} else {
rt_table_invalidate(rt2);
precursor_list_destroy(rt2);
}
}
}
}
}
#endif
if (rt->flags & RT_REPAIR) {
/* Set a timeout for the repair */
rt->rt_timer.handler = &NS_CLASS local_repair_timeout;
29. More Info Https://ThesisScientist.com
timer_set_timeout(&rt->rt_timer, ACTIVE_ROUTE_TIMEOUT);
DEBUG(LOG_DEBUG, 0, "%s kept for repairs during %u msecs",
ip_to_str(rt->dest_addr), ACTIVE_ROUTE_TIMEOUT);
} else {
/* Schedule a deletion timer */
rt->rt_timer.handler = &NS_CLASS route_delete_timeout;
timer_set_timeout(&rt->rt_timer, DELETE_PERIOD);
DEBUG(LOG_DEBUG, 0, "%s removed in %u msecs",
ip_to_str(rt->dest_addr), DELETE_PERIOD);
}
return 0;
}
void NS_CLASS rt_table_delete(rt_table_t * rt)
{
if (!rt) {
DEBUG(LOG_ERR, 0, "No route entry to delete");
return;
}
list_detach(&rt->l);
precursor_list_destroy(rt);
if (rt->state == VALID) {
#ifndef NS_PORT
nl_send_del_route_msg(rt->dest_addr, rt->next_hop, rt->hcnt);
#endif
rt_tbl.num_active--;
}
/* Make sure timers are removed... */
timer_remove(&rt->rt_timer);
timer_remove(&rt->hello_timer);
timer_remove(&rt->ack_timer);
rt_tbl.num_entries--;
free(rt);
return;
}
void NS_CLASS precursor_add(rt_table_t * rt, struct in_addr addr)
{
precursor_t *pr;
list_t *pos;
/* Sanity check */
if (!rt)
return;
list_foreach(pos, &rt->precursors) {