--- embedaddon/mrouted/route.c 2012/02/21 23:10:48 1.1.1.1 +++ embedaddon/mrouted/route.c 2013/07/21 23:59:22 1.1.1.2 @@ -259,9 +259,8 @@ void add_neighbor_to_routes(vifi_t vifi, u_int index) void delete_neighbor_from_routes(u_int32 addr, vifi_t vifi, u_int index) { struct rtentry *r; - struct uvif *v; + struct uvif *v = &uvifs[vifi]; - v = &uvifs[vifi]; for (r = routing_table; r != NULL; r = r->rt_next) { if (r->rt_metric != UNREACHABLE) { if (r->rt_parent == vifi && r->rt_gateway == addr) { @@ -273,11 +272,10 @@ void delete_neighbor_from_routes(u_int32 addr, vifi_t } else if (r->rt_dominants[vifi] == addr) { VIFM_SET(vifi, r->rt_children); r->rt_dominants[vifi] = 0; - if ((uvifs[vifi].uv_flags & VIFF_NOFLOOD) || - AVOID_TRANSIT(vifi, r)) - NBRM_CLRMASK(r->rt_subordinates, uvifs[vifi].uv_nbrmap); + if ((v->uv_flags & VIFF_NOFLOOD) || AVOID_TRANSIT(vifi, r)) + NBRM_CLRMASK(r->rt_subordinates, v->uv_nbrmap); else - NBRM_SETMASK(r->rt_subordinates, uvifs[vifi].uv_nbrmap); + NBRM_SETMASK(r->rt_subordinates, v->uv_nbrmap); update_table_entry(r, r->rt_gateway); } else if (NBRM_ISSET(index, r->rt_subordinates)) { NBRM_CLR(index, r->rt_subordinates); @@ -295,10 +293,14 @@ void delete_neighbor_from_routes(u_int32 addr, vifi_t * beginning for each update; this relies on having the route reports in * a single message be in the same order as the route entries in the routing * table. + * + * find_route() expects rtp to be the preceding entry in the linked list + * where route insertion takes place. We need to be able to insert routes + * before at the list head (routing table). */ void start_route_updates(void) { - rtp = routing_table; + rtp = NULL; } @@ -315,7 +317,11 @@ static int find_route(u_int32 origin, u_int32 mask) { struct rtentry *r; - r = rtp; + /* + * If rtp is NULL, we are preceding routing_table, so our first search + * candidate should be the routing_table. + */ + r = rtp ? rtp : routing_table; while (r != NULL) { if (origin == r->rt_origin && mask == r->rt_originmask) { rtp = r; @@ -386,8 +392,16 @@ static void create_route(u_int32 origin, u_int32 mask) rt_end = this; rtp->rt_next = this; } else { + if (routing_table) { + /* Change existing head to this */ + this->rt_next = routing_table; + routing_table->rt_prev = this; + } + else { + /* this is the first route entry that exists */ + rt_end = this; + } routing_table = this; - rt_end = this; } rtp = this; @@ -1233,11 +1247,9 @@ static int report_chunk(int which_routes, struct rtent int datalen = 0; int width = 0; u_int32 mask = 0; - u_int32 src; int admetric = v->uv_admetric; int metric; - src = v->uv_lcl_addr; p = send_buf + MIN_IP_HEADER_LEN + IGMP_MINLEN; for (r = start_rt; r != routing_table; r = r->rt_prev) {