diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h index a6282665e4..a008891a51 100644 --- a/eigrpd/eigrp_const.h +++ b/eigrpd/eigrp_const.h @@ -94,6 +94,11 @@ #define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/ #define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/ +enum metric_change { + METRIC_DECREASE, + METRIC_SAME, + METRIC_INCREASE +}; #define DEFAULT_ROUTE ZEBRA_ROUTE_MAX #define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE) diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index 852362e192..8e2a26447e 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -185,6 +185,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) struct eigrp_prefix_entry *prefix = msg->prefix; struct eigrp_neighbor_entry *entry = msg->entry; u_char actual_state = prefix->state; + enum metric_change change; if (entry == NULL) { entry = eigrp_neighbor_entry_new(); @@ -194,19 +195,18 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) msg->entry = entry; } - // Dividing by actual state of prefix's FSM + /* + * Calculate resultant metrics and insert to correct position + * in entries list + */ + change = eigrp_topology_update_distance(msg); + switch (actual_state) { case EIGRP_FSM_STATE_PASSIVE: { - // Calculate resultant metrics and insert to correct position in - // entries list - eigrp_topology_update_distance(msg); - struct eigrp_neighbor_entry *head = (struct eigrp_neighbor_entry *) entry->prefix->entries->head->data; - // zlog_info ("flag: %d rdist: %u dist: %u pfdist: %u pdist: - // %u", head->flags, head->reported_distance, head->distance, - // prefix->fdistance, prefix->distance); + if (head->reported_distance < prefix->fdistance) { return EIGRP_FSM_KEEP_STATE; } @@ -215,34 +215,31 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) * move to active state * dependently if it was query from successor */ - else { - if (msg->packet_type == EIGRP_OPC_QUERY) { - return EIGRP_FSM_EVENT_Q_FCN; - } else { - return EIGRP_FSM_EVENT_NQ_FCN; - } + if (msg->packet_type == EIGRP_OPC_QUERY) { + return EIGRP_FSM_EVENT_Q_FCN; + } else { + return EIGRP_FSM_EVENT_NQ_FCN; } break; } case EIGRP_FSM_STATE_ACTIVE_0: { - eigrp_topology_update_distance(msg); - if (msg->packet_type == EIGRP_OPC_REPLY) { - listnode_delete(prefix->rij, entry->adv_router); - if (prefix->rij->count) { - return EIGRP_FSM_KEEP_STATE; - } else { - zlog_info("All reply received\n"); - if (((struct eigrp_neighbor_entry *) - prefix->entries->head->data) - ->reported_distance - < prefix->fdistance) { - return EIGRP_FSM_EVENT_LR_FCS; - } + struct eigrp_neighbor_entry *head = + (struct eigrp_neighbor_entry *) + entry->prefix->entries->head->data; - return EIGRP_FSM_EVENT_LR_FCN; + listnode_delete(prefix->rij, entry->adv_router); + if (prefix->rij->count) + return EIGRP_FSM_KEEP_STATE; + + zlog_info("All reply received\n"); + if (head->reported_distance + < prefix->fdistance) { + return EIGRP_FSM_EVENT_LR_FCS; } + + return EIGRP_FSM_EVENT_LR_FCN; } else if (msg->packet_type == EIGRP_OPC_QUERY && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { @@ -254,15 +251,13 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) break; } case EIGRP_FSM_STATE_ACTIVE_1: { - int change = eigrp_topology_update_distance(msg); - if (msg->packet_type == EIGRP_OPC_QUERY && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_QACT; } else if (msg->packet_type == EIGRP_OPC_REPLY) { listnode_delete(prefix->rij, entry->adv_router); - if (change == 1 + if (change == METRIC_INCREASE && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_DINC; @@ -282,17 +277,17 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) break; } case EIGRP_FSM_STATE_ACTIVE_2: { - eigrp_topology_update_distance(msg); - if (msg->packet_type == EIGRP_OPC_REPLY) { + struct eigrp_neighbor_entry *head = + (struct eigrp_neighbor_entry *) + prefix->entries->head->data; + listnode_delete(prefix->rij, entry->adv_router); if (prefix->rij->count) { return EIGRP_FSM_KEEP_STATE; } else { zlog_info("All reply received\n"); - if (((struct eigrp_neighbor_entry *) - prefix->entries->head->data) - ->reported_distance + if (head->reported_distance < prefix->fdistance) { return EIGRP_FSM_EVENT_LR_FCS; } @@ -305,12 +300,10 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) break; } case EIGRP_FSM_STATE_ACTIVE_3: { - int change = eigrp_topology_update_distance(msg); - if (msg->packet_type == EIGRP_OPC_REPLY) { listnode_delete(prefix->rij, entry->adv_router); - if (change == 1 + if (change == METRIC_INCREASE && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_DINC; diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index ae1396ebaf..50d83430a8 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -374,42 +374,42 @@ struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp, return prefixes; } -int eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg) +enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; struct eigrp_neighbor_entry *entry = msg->entry; - int change = 0; + enum metric_change change = METRIC_SAME; assert(entry); struct TLV_IPv4_External_type *ext_data = NULL; struct TLV_IPv4_Internal_type *int_data = NULL; if (msg->data_type == EIGRP_TLV_IPv4_INT) { + u_int32_t new_reported_distance; + int_data = msg->data.ipv4_int_type; if (eigrp_metrics_is_same(int_data->metric, entry->reported_metric)) { - return 0; // No change + return change; // No change } - change = entry->reported_distance - < eigrp_calculate_metrics( - eigrp, int_data->metric) - ? 1 - : entry->reported_distance - > eigrp_calculate_metrics( - eigrp, - int_data->metric) - ? 2 - : 3; // Increase : Decrease : No - // change + + new_reported_distance = eigrp_calculate_metrics(eigrp, + int_data->metric); + + if (entry->reported_distance < new_reported_distance) + change = METRIC_INCREASE; + else + change = METRIC_DECREASE; + entry->reported_metric = int_data->metric; - entry->reported_distance = + entry->reported_distance = new_reported_distance; eigrp_calculate_metrics(eigrp, int_data->metric); entry->distance = eigrp_calculate_total_metrics(eigrp, entry); } else { ext_data = msg->data.ipv4_ext_data; if (eigrp_metrics_is_same(ext_data->metric, entry->reported_metric)) - return 0; + return change; } /* * Move to correct position in list according to new distance diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h index 1340c82101..0c9b5c60c6 100644 --- a/eigrpd/eigrp_topology.h +++ b/eigrpd/eigrp_topology.h @@ -60,7 +60,7 @@ extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *, struct eigrp_neighbor *); extern void eigrp_topology_update_all_node_flags(struct eigrp *); extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *); -extern int eigrp_topology_update_distance(struct eigrp_fsm_action_message *); +extern enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *); extern void eigrp_update_routing_table(struct eigrp_prefix_entry *); extern void eigrp_topology_neighbor_down(struct eigrp *, struct eigrp_neighbor *);