mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 15:47:22 +00:00
eigrpd: Fix massive memory leak
Each call into eigrp_topology_get_successors would leak the list created. As routes worked their way through the FSM we would leak memory left and right. Modify the eigrp_topology_get_successor to return NULL when there are no SUCCESORS. Clean up some dead code. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
87805f883a
commit
f6709c169b
@ -346,6 +346,9 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) {
|
|||||||
struct eigrp *eigrp = msg->eigrp;
|
struct eigrp *eigrp = msg->eigrp;
|
||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
struct list *successors = eigrp_topology_get_successor(prefix);
|
struct list *successors = eigrp_topology_get_successor(prefix);
|
||||||
|
|
||||||
|
assert(successors); // If this is NULL we have shit the bed, fun huh?
|
||||||
|
|
||||||
prefix->state = EIGRP_FSM_STATE_ACTIVE_1;
|
prefix->state = EIGRP_FSM_STATE_ACTIVE_1;
|
||||||
prefix->rdistance = prefix->distance = prefix->fdistance =
|
prefix->rdistance = prefix->distance = prefix->fdistance =
|
||||||
((struct eigrp_neighbor_entry *) successors->head->data)->distance;
|
((struct eigrp_neighbor_entry *) successors->head->data)->distance;
|
||||||
@ -359,6 +362,8 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) {
|
|||||||
eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
|
eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_delete(successors);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,6 +371,9 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) {
|
|||||||
struct eigrp *eigrp = msg->eigrp;
|
struct eigrp *eigrp = msg->eigrp;
|
||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
struct list *successors = eigrp_topology_get_successor(prefix);
|
struct list *successors = eigrp_topology_get_successor(prefix);
|
||||||
|
|
||||||
|
assert(successors); // If this is NULL somebody poked us in the eye.
|
||||||
|
|
||||||
prefix->state = EIGRP_FSM_STATE_ACTIVE_3;
|
prefix->state = EIGRP_FSM_STATE_ACTIVE_3;
|
||||||
prefix->rdistance = prefix->distance = prefix->fdistance =
|
prefix->rdistance = prefix->distance = prefix->fdistance =
|
||||||
((struct eigrp_neighbor_entry *) successors->head->data)->distance;
|
((struct eigrp_neighbor_entry *) successors->head->data)->distance;
|
||||||
@ -378,6 +386,8 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) {
|
|||||||
eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
|
eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_delete(successors);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,15 +423,21 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) {
|
|||||||
struct eigrp *eigrp = msg->eigrp;
|
struct eigrp *eigrp = msg->eigrp;
|
||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
prefix->fdistance =
|
prefix->fdistance =
|
||||||
prefix->distance =
|
prefix->distance =
|
||||||
prefix->rdistance =
|
prefix->rdistance =
|
||||||
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance;
|
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance;
|
||||||
prefix->reported_metric =
|
prefix->reported_metric =
|
||||||
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric;
|
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric;
|
||||||
if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3)
|
|
||||||
eigrp_send_reply(
|
if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) {
|
||||||
((struct eigrp_neighbor_entry *) (eigrp_topology_get_successor(
|
struct list *successors = eigrp_topology_get_successor(prefix);
|
||||||
prefix)->head->data))->adv_router, prefix);
|
|
||||||
|
assert(successors); // It's like Napolean and Waterloo
|
||||||
|
|
||||||
|
eigrp_send_reply(((struct eigrp_neighbor_entry *)successors->head->data)->adv_router, prefix);
|
||||||
|
list_delete(successors);
|
||||||
|
}
|
||||||
|
|
||||||
prefix->state = EIGRP_FSM_STATE_PASSIVE;
|
prefix->state = EIGRP_FSM_STATE_PASSIVE;
|
||||||
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
||||||
listnode_add(eigrp->topology_changes_internalIPV4,prefix);
|
listnode_add(eigrp->topology_changes_internalIPV4,prefix);
|
||||||
@ -433,17 +449,19 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) {
|
int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) {
|
||||||
|
struct list *successors = eigrp_topology_get_successor(msg->prefix);
|
||||||
|
|
||||||
|
assert(successors); // Trump and his big hands
|
||||||
|
|
||||||
msg->prefix->state =
|
msg->prefix->state =
|
||||||
msg->prefix->state == EIGRP_FSM_STATE_ACTIVE_1 ?
|
msg->prefix->state == EIGRP_FSM_STATE_ACTIVE_1 ?
|
||||||
EIGRP_FSM_STATE_ACTIVE_0 : EIGRP_FSM_STATE_ACTIVE_2;
|
EIGRP_FSM_STATE_ACTIVE_0 : EIGRP_FSM_STATE_ACTIVE_2;
|
||||||
msg->prefix->distance =
|
msg->prefix->distance = ((struct eigrp_neighbor_entry *)successors->head->data)->distance;
|
||||||
((struct eigrp_neighbor_entry *) (eigrp_topology_get_successor(
|
|
||||||
msg->prefix)->head->data))->distance;
|
|
||||||
if (!msg->prefix->rij->count) {
|
if (!msg->prefix->rij->count) {
|
||||||
(*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))(msg);
|
(*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_delete(successors);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,17 +470,22 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) {
|
|||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
prefix->state = EIGRP_FSM_STATE_PASSIVE;
|
prefix->state = EIGRP_FSM_STATE_PASSIVE;
|
||||||
prefix->distance =
|
prefix->distance =
|
||||||
prefix->rdistance =
|
prefix->rdistance =
|
||||||
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance;
|
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance;
|
||||||
prefix->reported_metric =
|
prefix->reported_metric =
|
||||||
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric;
|
((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric;
|
||||||
prefix->fdistance =
|
prefix->fdistance =
|
||||||
prefix->fdistance > prefix->distance ?
|
prefix->fdistance > prefix->distance ?
|
||||||
prefix->distance : prefix->fdistance;
|
prefix->distance : prefix->fdistance;
|
||||||
if (prefix->state == EIGRP_FSM_STATE_ACTIVE_2)
|
if (prefix->state == EIGRP_FSM_STATE_ACTIVE_2) {
|
||||||
eigrp_send_reply(
|
struct list *successors = eigrp_topology_get_successor(prefix);
|
||||||
((struct eigrp_neighbor_entry *) (eigrp_topology_get_successor(
|
|
||||||
prefix)->head->data))->adv_router, prefix);
|
assert(successors); // Having a spoon and all you need is a knife
|
||||||
|
|
||||||
|
eigrp_send_reply(((struct eigrp_neighbor_entry *)successors->head->data)->adv_router, prefix);
|
||||||
|
|
||||||
|
list_delete(successors);
|
||||||
|
}
|
||||||
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
||||||
listnode_add(eigrp->topology_changes_internalIPV4,prefix);
|
listnode_add(eigrp->topology_changes_internalIPV4,prefix);
|
||||||
eigrp_topology_update_node_flags(prefix);
|
eigrp_topology_update_node_flags(prefix);
|
||||||
@ -475,12 +498,15 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) {
|
|||||||
int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) {
|
int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) {
|
||||||
struct eigrp *eigrp = msg->eigrp;
|
struct eigrp *eigrp = msg->eigrp;
|
||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
|
struct list *successors = eigrp_topology_get_successor(prefix);
|
||||||
|
|
||||||
|
assert(successors); // Routing without a stack
|
||||||
|
|
||||||
prefix->state =
|
prefix->state =
|
||||||
prefix->state == EIGRP_FSM_STATE_ACTIVE_0 ?
|
prefix->state == EIGRP_FSM_STATE_ACTIVE_0 ?
|
||||||
EIGRP_FSM_STATE_ACTIVE_1 : EIGRP_FSM_STATE_ACTIVE_3;
|
EIGRP_FSM_STATE_ACTIVE_1 : EIGRP_FSM_STATE_ACTIVE_3;
|
||||||
struct eigrp_neighbor_entry *best_successor =
|
struct eigrp_neighbor_entry *best_successor =
|
||||||
((struct eigrp_neighbor_entry *) (eigrp_topology_get_successor(
|
((struct eigrp_neighbor_entry *) (successors->head->data));
|
||||||
prefix)->head->data));
|
|
||||||
prefix->rdistance = prefix->distance = best_successor->distance;
|
prefix->rdistance = prefix->distance = best_successor->distance;
|
||||||
prefix->reported_metric = best_successor->total_metric;
|
prefix->reported_metric = best_successor->total_metric;
|
||||||
if (eigrp_nbr_count_get()) {
|
if (eigrp_nbr_count_get()) {
|
||||||
@ -490,13 +516,20 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) {
|
|||||||
eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
|
eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_delete(successors);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) {
|
int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) {
|
||||||
|
struct list *successors = eigrp_topology_get_successor(msg->prefix);
|
||||||
|
|
||||||
|
assert(successors); // Cats and no Dogs
|
||||||
|
|
||||||
msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2;
|
msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2;
|
||||||
msg->prefix->distance =
|
msg->prefix->distance =
|
||||||
((struct eigrp_neighbor_entry *) (eigrp_topology_get_successor(
|
((struct eigrp_neighbor_entry *) (successors->head->data))->distance;
|
||||||
msg->prefix)->head->data))->distance;
|
|
||||||
|
list_delete(successors);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -316,23 +316,7 @@ eigrp_topology_table_lookup_ipv4(struct list *topology_table,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* TODO
|
|
||||||
struct eigrp_prefix_entry *
|
|
||||||
eigrp_topology_table_lookup_ipv6 (struct list *topology_table,
|
|
||||||
struct prefix_ipv6 * address)
|
|
||||||
{
|
|
||||||
struct eigrp_prefix_entry *data;
|
|
||||||
struct listnode *node, *nnode;
|
|
||||||
for (ALL_LIST_ELEMENTS (topology_table, node, nnode, data))
|
|
||||||
{
|
|
||||||
|
|
||||||
if (comparison)
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
struct list *
|
struct list *
|
||||||
eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
|
eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
|
||||||
{
|
{
|
||||||
@ -348,6 +332,15 @@ eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have no successors return NULL
|
||||||
|
*/
|
||||||
|
if (!successors->count)
|
||||||
|
{
|
||||||
|
list_delete(successors);
|
||||||
|
successors = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return successors;
|
return successors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,18 +58,5 @@ extern int eigrp_topology_update_distance ( struct eigrp_fsm_action_message *);
|
|||||||
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
|
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
|
||||||
extern void eigrp_topology_neighbor_down(struct eigrp *, struct eigrp_neighbor *);
|
extern void eigrp_topology_neighbor_down(struct eigrp *, struct eigrp_neighbor *);
|
||||||
extern void eigrp_update_topology_table_prefix(struct list *, struct eigrp_prefix_entry * );
|
extern void eigrp_update_topology_table_prefix(struct list *, struct eigrp_prefix_entry * );
|
||||||
//extern int eigrp_topology_get_successor_count (struct eigrp_prefix_entry *);
|
|
||||||
/* Set all stats to -1 (LSA_SPF_NOT_EXPLORED). */
|
|
||||||
/*extern void eigrp_lsdb_clean_stat (struct eigrp_lsdb *lsdb);
|
|
||||||
extern struct eigrp_lsa *eigrp_lsdb_lookup_by_id (struct eigrp_lsdb *, u_char,
|
|
||||||
struct in_addr, struct in_addr);
|
|
||||||
extern struct eigrp_lsa *eigrp_lsdb_lookup_by_id_next (struct eigrp_lsdb *, u_char,
|
|
||||||
struct in_addr, struct in_addr,
|
|
||||||
int);
|
|
||||||
extern unsigned long eigrp_lsdb_count_all (struct eigrp_lsdb *);
|
|
||||||
extern unsigned long eigrp_lsdb_count (struct eigrp_lsdb *, int);
|
|
||||||
extern unsigned long eigrp_lsdb_count_self (struct eigrp_lsdb *, int);
|
|
||||||
extern unsigned int eigrp_lsdb_checksum (struct eigrp_lsdb *, int);
|
|
||||||
extern unsigned long eigrp_lsdb_isempty (struct eigrp_lsdb *);
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user