📄 routing_table.c
字号:
/***************************************************************************** * * Copyright (C) 2001 Uppsala University and Ericsson AB. * Copyright (C) 2003 Simon Fraser University and NewMIC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: Erik Nordstr鰉, <erik.nordstrom@it.uu.se> * : Peter Lee <peter.lee@shaw.ca> * *****************************************************************************/#ifdef NS_PORT#include "aodv-uu.h"#else#include <time.h>#include "routing_table.h"#include "aodv_timeout.h"#include "aodv_rerr.h"#include "aodv_socket.h"#include "k_route.h"#include "timer_queue.h"#include "defs.h"#include "debug.h"#include "params.h"//PL:#ifdef _IPV6#include "ipv6_utils.h"#endif /* _IPV6 */#endif /* NS_PORT *///PL:#ifdef _IPV6static unsigned int hashing(struct in6_addr * addr, hash_value * hash);#elsestatic unsigned int hashing(u_int32_t * addr, hash_value * hash);#endif#ifndef NS_PORT#ifdef _IPV6static void rt_table_remove_precursor(struct in6_addr dest_addr);#elsestatic void rt_table_remove_precursor(u_int32_t dest_addr);#endif /* _IPV6 */#endifvoid NS_CLASS rt_table_init(){ int i; /* We do a for loop here... NS does not like us to use memset() */ for (i = 0; i < RT_TABLESIZE; i++) routing_table[i] = NULL;}void NS_CLASS rt_table_destroy(){ int i; rt_table_t *rt_entry, *tmp; for (i = 0; i < RT_TABLESIZE; i++) { rt_entry = routing_table[i]; while (rt_entry != NULL) { /* Destroy and free memory used by precursor list for this entry */ DEBUG(LOG_INFO, 0, "routing_table_destroy: Clearing bucket %d", i); precursor_list_destroy(rt_entry);#ifndef NS_PORT //PL: plen is 128 IPv6 and 0 is the netmask for IPv4#ifdef _IPV6 //printf("1. rt_entry->last_hcnt = %d\n", rt_entry->last_hcnt); if (rt_entry->hcnt != INFTY && k_del_rte(rt_entry->dest_addr, rt_entry->next_hop, 128, rt_entry->ifindex, rt_entry->hcnt + 1) < 0) log(LOG_WARNING, errno, "rt_table_destroy: Could not delete kernel route!");#else if (rt_entry->hcnt != INFTY && k_del_rte(rt_entry->dest_addr, 0, 0) < 0) log(LOG_WARNING, errno, "rt_table_destroy: Could not delete kernel route!");#endif /* _IPV6 */#endif tmp = rt_entry; rt_entry = rt_entry->next; /* Free memory used by this route entry */ free(tmp); } }}/* Calculate a hash value and table index given a key... *///PL:#ifdef _IPV6unsigned int hashing(struct in6_addr * addr, hash_value * hash){ /* hashing function from /usr/src/linux/include/net/addrconf.h look like this:static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr){ __u32 word; word = addr->s6_addr[2] ^ addr->s6_addr32[3]; word ^= (word>>16); word ^= (word >> 8); return ((word ^ (word >> 4)) & 0x0f);} */ *hash = addr->s6_addr[2] ^ addr->s6_addr32[3]; *hash ^= (*hash >> 16); *hash ^= (*hash >> 8); return(( (*hash) ^ (*hash >> 4) ) & RT_TABLEMASK);}#elseunsigned int hashing(u_int32_t * addr, hash_value * hash){ /* *hash = (*addr & 0x7fffffff); */ *hash = *addr; return (*hash & RT_TABLEMASK);}#endif /* _IPV6 *///PL:#ifdef _IPV6rt_table_t *NS_CLASS rt_table_insert(struct in6_addr dest_addr, struct in6_addr next, u_int8_t hops, u_int32_t seqno, u_int32_t life, u_int16_t flags, unsigned int ifindex)#elsert_table_t *NS_CLASS rt_table_insert(u_int32_t dest_addr, u_int32_t next, u_int8_t hops, u_int32_t seqno, u_int32_t life, u_int16_t flags, unsigned int ifindex)#endif{ rt_table_t *rt_entry; hash_value hash; unsigned int index; /* Calculate hash key */ index = hashing(&dest_addr, &hash); rt_entry = routing_table[index]; //PL:#ifdef _IPV6 DEBUG(LOG_INFO, 0, "rt_table_insert: Inserting %s into bucket %d", ip6_to_str(dest_addr), index);#else DEBUG(LOG_INFO, 0, "rt_table_insert: Inserting %s into bucket %d", ip_to_str(dest_addr), index);#endif /* _IPV6 */ if (rt_entry != NULL) DEBUG(LOG_INFO, 0, "rt_table_insert: Collision in bucket %d detected!", index); /* Check if we already have an entry for dest_addr */ while (rt_entry != NULL) { //PL:#ifdef _IPV6 if (memcmp(&rt_entry->dest_addr, &dest_addr, sizeof(struct in6_addr)) == 0) { DEBUG(LOG_INFO, 0, "rt_table_insert: %s already exist in routing table!!!", ip6_to_str(dest_addr)); return NULL; }#else if (memcmp(&rt_entry->dest_addr, &dest_addr, sizeof(u_int32_t)) == 0) { DEBUG(LOG_INFO, 0, "rt_table_insert: %s already exist in routing table!!!", ip_to_str(dest_addr)); return NULL; }#endif /* _IPV6 */ rt_entry = rt_entry->next; } if ((rt_entry = (rt_table_t *) malloc(sizeof(rt_table_t))) == NULL) { fprintf(stderr, "rt_table_insert: Malloc failed!\n"); exit(-1); } memset(rt_entry, 0, sizeof(rt_table_t)); //PL:#ifdef _IPV6 memcpy(&rt_entry->dest_addr, &dest_addr, sizeof(struct in6_addr)); memcpy(&rt_entry->next_hop, &next, sizeof(struct in6_addr)); memcpy(&rt_entry->hash, &hash, sizeof(hash_value));#else rt_entry->dest_addr = dest_addr; rt_entry->next_hop = next; rt_entry->hash = hash;#endif /* _IPV6 */ rt_entry->dest_seqno = seqno; rt_entry->flags = flags; rt_entry->hcnt = hops; rt_entry->ifindex = ifindex; rt_entry->last_hcnt = 0; rt_entry->last_life = life; rt_entry->precursors = NULL; /* Initialize timers */ rt_entry->rt_timer.handler = &NS_CLASS route_expire_timeout; rt_entry->rt_timer.data = rt_entry; rt_entry->ack_timer.handler = &NS_CLASS rrep_ack_timeout; rt_entry->ack_timer.data = rt_entry; rt_entry->hello_timer.handler = &NS_CLASS hello_timeout; rt_entry->hello_timer.data = rt_entry; rt_entry->last_hello_time.tv_sec = 0; rt_entry->last_hello_time.tv_usec = 0; rt_entry->hello_cnt = 0; /* Insert first in bucket... */ rt_entry->next = routing_table[index]; routing_table[index] = rt_entry; if (hops == INFTY) { rt_entry->rt_timer.handler = &NS_CLASS route_delete_timeout; life = DELETE_PERIOD; }#ifndef NS_PORT else { /* Add route to kernel routing table ... */ //PL: plen is 128 IPv6 and 0 is the netmask for IPv4#ifdef _IPV6 if (k_add_rte(dest_addr, next, 128, hops, rt_entry->ifindex) < 0)#else if (k_add_rte(dest_addr, next, 0, hops, rt_entry->ifindex) < 0)#endif /* _IPV6 */ { log(LOG_WARNING, errno, "rt_table_insert: Could not add kernel route!"); //PL: need to set the bucket back to NULL!! routing_table[index] = NULL; //return NULL; } }#endif //PL:#ifdef _IPV6 DEBUG(LOG_INFO, 0, "rt_table_insert: New timer for %s, life=%d", ip6_to_str(rt_entry->dest_addr), life);#else DEBUG(LOG_INFO, 0, "rt_table_insert: New timer for %s, life=%d", ip_to_str(rt_entry->dest_addr), life);#endif /* _IPV6 */ timer_add_msec(&rt_entry->rt_timer, life); return rt_entry;}//PL:#ifdef _IPV6rt_table_t *NS_CLASS rt_table_update(rt_table_t * rt_entry, struct in6_addr next, u_int8_t hops, u_int32_t seqno, u_int32_t newlife, u_int16_t flags)#elsert_table_t *NS_CLASS rt_table_update(rt_table_t * rt_entry, u_int32_t next, u_int8_t hops, u_int32_t seqno, u_int32_t newlife, u_int16_t flags)#endif /* _IPV6 */{ unsigned int metric; /* If this previously was an expired route, but will now be active again we must add it to the kernel routing table... */ //PL: debug /*********** For debug purpose *********/ /* DEBUG(LOG_DEBUG, 0, "rt_table_update: rt_entry->dest_addr = %s, rt_entry->next_hop = %s, next = %s, hops = %d", ip6_to_str(rt_entry->dest_addr), ip6_to_str(rt_entry->next_hop), ip6_to_str(next), hops); */ if (rt_entry->hcnt == INFTY && hops != INFTY) { rt_entry->rt_timer.handler = &NS_CLASS route_expire_timeout;#ifndef NS_PORT //PL: plen is 128 IPv6 and 0 is the netmask for IPv4#ifdef _IPV6 if (k_add_rte(rt_entry->dest_addr, next, 128, hops, rt_entry->ifindex) < 0)#else if (k_add_rte(rt_entry->dest_addr, next, 0, hops, rt_entry->ifindex) < 0)#endif /* _IPV6 */ log(LOG_WARNING, errno, "rt_table_update 1: Could not add kernel route!"); else DEBUG(LOG_INFO, 0, "rt_table_update 2: Added kernel route for expired %s", ip6_to_str(rt_entry->dest_addr));#endif } //PL:#ifdef _IPV6 else if ( (memcmp(&rt_entry->next_hop, &ipv6_default_addr, sizeof(struct in6_addr)) != 0) && (memcmp(&rt_entry->next_hop, &next, sizeof(struct in6_addr)) != 0) ) { DEBUG(LOG_INFO, 0, "rt_table_update 3: rt_entry->nxt_addr=%s, next=%s", ip6_to_str(rt_entry->next_hop), ip6_to_str(next));#else else if (rt_entry->next_hop != 0 && rt_entry->next_hop != next) { DEBUG(LOG_INFO, 0, "rt_table_update 4: rt_entry->nxt_addr=%s, next=%s", ip_to_str(rt_entry->next_hop), ip_to_str(next));#endif /* _IPV6 */ precursor_list_destroy(rt_entry);#ifndef NS_PORT#ifdef _IPV6 //printf("2. rt_entry->last_hcnt = %d\n", rt_entry->last_hcnt); if (rt_entry->last_hcnt == INFTY) metric = rt_entry->last_hcnt + 1; //PL: else metric = rt_entry->hcnt; if (k_del_rte(rt_entry->dest_addr,rt_entry->next_hop, 128, rt_entry->ifindex, metric) < 0) log(LOG_WARNING, errno, "rt_table_update 5: Could not update kernel route!"); else { if (k_add_rte(rt_entry->dest_addr, next, 128, hops,rt_entry->ifindex) < 0) log(LOG_WARNING, errno, "rt_table_update 6: Could not update kernel route!"); }#else if (k_chg_rte(rt_entry->dest_addr, next, 0, hops, rt_entry->ifindex) < 0) log(LOG_WARNING, errno, "rt_table_update - call k_chg_rte: Could not update kernel route!");#endif /* _IPV6 */#endif /* NS_PORT */ } rt_entry->dest_seqno = seqno; rt_entry->last_life = newlife; rt_entry->flags = flags; //PL:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -