diff options
Diffstat (limited to 'eigrpd/eigrp_fsm.c')
-rw-r--r-- | eigrpd/eigrp_fsm.c | 827 |
1 files changed, 410 insertions, 417 deletions
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index 44a474758..852362e19 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -44,12 +44,14 @@ * / / / +----+ \ \ * | | | | | | * | v | | | v - * +===========+ (6) +===========+ +===========+ (6) +===========+ - * | |------->| | (5) | |-------->| | - * | | (4) | |------>| | (4) | | - * | ACTIVE 0 |<-------| ACTIVE 1 | | ACTIVE 2 |<--------| ACTIVE 3 | - * +--| | +--| | +--| | +--| | - * | +===========+ | +===========+ | +===========+ | +===========+ + * +===========+ (6) +===========+ +===========+ (6) +===========+ + * | |------->| | (5) | |-------->| | + * | | (4) | |------>| | (4) | | + * | ACTIVE 0 |<-------| ACTIVE 1 | | ACTIVE 2 |<--------| ACTIVE 3 + * | + * +--| | +--| | +--| | +--| | + * | +===========+ | +===========+ | +===========+ | + * +===========+ * | ^ |(5) | ^ | ^ ^ | ^ * | | +---------|------|------------|----+ | | | * +-------+ +------+ +---------+ +---------+ @@ -109,59 +111,64 @@ int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *); * Functions are should be executed within separate thread. */ struct { - int - (*func)(struct eigrp_fsm_action_message *); -} NSM[EIGRP_FSM_STATE_MAX][EIGRP_FSM_EVENT_MAX] = { { - //PASSIVE STATE - { eigrp_fsm_event_nq_fcn }, /* Event 0 */ - { eigrp_fsm_event_keep_state }, /* Event 1 */ - { eigrp_fsm_event_q_fcn }, /* Event 2 */ - { eigrp_fsm_event_keep_state }, /* Event 3 */ - { eigrp_fsm_event_keep_state }, /* Event 4 */ - { eigrp_fsm_event_keep_state }, /* Event 5 */ - { eigrp_fsm_event_keep_state }, /* Event 6 */ - { eigrp_fsm_event_keep_state }, /* Event 7 */ - }, { - //Active 0 state - { eigrp_fsm_event_keep_state }, /* Event 0 */ - { eigrp_fsm_event_keep_state }, /* Event 1 */ - { eigrp_fsm_event_keep_state }, /* Event 2 */ - { eigrp_fsm_event_lr_fcs }, /* Event 3 */ - { eigrp_fsm_event_keep_state }, /* Event 4 */ - { eigrp_fsm_event_qact }, /* Event 5 */ - { eigrp_fsm_event_lr_fcn }, /* Event 6 */ - { eigrp_fsm_event_keep_state }, /* Event 7 */ - }, { - //Active 1 state - { eigrp_fsm_event_keep_state }, /* Event 0 */ - { eigrp_fsm_event_lr }, /* Event 1 */ - { eigrp_fsm_event_keep_state }, /* Event 2 */ - { eigrp_fsm_event_keep_state }, /* Event 3 */ - { eigrp_fsm_event_dinc }, /* Event 4 */ - { eigrp_fsm_event_qact }, /* Event 5 */ - { eigrp_fsm_event_keep_state }, /* Event 6 */ - { eigrp_fsm_event_keep_state }, /* Event 7 */ - }, { - //Active 2 state - { eigrp_fsm_event_keep_state }, /* Event 0 */ - { eigrp_fsm_event_keep_state }, /* Event 1 */ - { eigrp_fsm_event_keep_state }, /* Event 2 */ - { eigrp_fsm_event_lr_fcs }, /* Event 3 */ - { eigrp_fsm_event_keep_state }, /* Event 4 */ - { eigrp_fsm_event_keep_state }, /* Event 5 */ - { eigrp_fsm_event_lr_fcn }, /* Event 6 */ - { eigrp_fsm_event_keep_state }, /* Event 7 */ - }, { - //Active 3 state - { eigrp_fsm_event_keep_state }, /* Event 0 */ - { eigrp_fsm_event_lr }, /* Event 1 */ - { eigrp_fsm_event_keep_state }, /* Event 2 */ - { eigrp_fsm_event_keep_state }, /* Event 3 */ - { eigrp_fsm_event_dinc }, /* Event 4 */ - { eigrp_fsm_event_keep_state }, /* Event 5 */ - { eigrp_fsm_event_keep_state }, /* Event 6 */ - { eigrp_fsm_event_keep_state }, /* Event 7 */ -}, }; + int (*func)(struct eigrp_fsm_action_message *); +} NSM[EIGRP_FSM_STATE_MAX][EIGRP_FSM_EVENT_MAX] = { + { + // PASSIVE STATE + {eigrp_fsm_event_nq_fcn}, /* Event 0 */ + {eigrp_fsm_event_keep_state}, /* Event 1 */ + {eigrp_fsm_event_q_fcn}, /* Event 2 */ + {eigrp_fsm_event_keep_state}, /* Event 3 */ + {eigrp_fsm_event_keep_state}, /* Event 4 */ + {eigrp_fsm_event_keep_state}, /* Event 5 */ + {eigrp_fsm_event_keep_state}, /* Event 6 */ + {eigrp_fsm_event_keep_state}, /* Event 7 */ + }, + { + // Active 0 state + {eigrp_fsm_event_keep_state}, /* Event 0 */ + {eigrp_fsm_event_keep_state}, /* Event 1 */ + {eigrp_fsm_event_keep_state}, /* Event 2 */ + {eigrp_fsm_event_lr_fcs}, /* Event 3 */ + {eigrp_fsm_event_keep_state}, /* Event 4 */ + {eigrp_fsm_event_qact}, /* Event 5 */ + {eigrp_fsm_event_lr_fcn}, /* Event 6 */ + {eigrp_fsm_event_keep_state}, /* Event 7 */ + }, + { + // Active 1 state + {eigrp_fsm_event_keep_state}, /* Event 0 */ + {eigrp_fsm_event_lr}, /* Event 1 */ + {eigrp_fsm_event_keep_state}, /* Event 2 */ + {eigrp_fsm_event_keep_state}, /* Event 3 */ + {eigrp_fsm_event_dinc}, /* Event 4 */ + {eigrp_fsm_event_qact}, /* Event 5 */ + {eigrp_fsm_event_keep_state}, /* Event 6 */ + {eigrp_fsm_event_keep_state}, /* Event 7 */ + }, + { + // Active 2 state + {eigrp_fsm_event_keep_state}, /* Event 0 */ + {eigrp_fsm_event_keep_state}, /* Event 1 */ + {eigrp_fsm_event_keep_state}, /* Event 2 */ + {eigrp_fsm_event_lr_fcs}, /* Event 3 */ + {eigrp_fsm_event_keep_state}, /* Event 4 */ + {eigrp_fsm_event_keep_state}, /* Event 5 */ + {eigrp_fsm_event_lr_fcn}, /* Event 6 */ + {eigrp_fsm_event_keep_state}, /* Event 7 */ + }, + { + // Active 3 state + {eigrp_fsm_event_keep_state}, /* Event 0 */ + {eigrp_fsm_event_lr}, /* Event 1 */ + {eigrp_fsm_event_keep_state}, /* Event 2 */ + {eigrp_fsm_event_keep_state}, /* Event 3 */ + {eigrp_fsm_event_dinc}, /* Event 4 */ + {eigrp_fsm_event_keep_state}, /* Event 5 */ + {eigrp_fsm_event_keep_state}, /* Event 6 */ + {eigrp_fsm_event_keep_state}, /* Event 7 */ + }, +}; /* * Main function in which are make decisions which event occurred. @@ -173,185 +180,158 @@ struct { */ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) { - // Loading base information from message - //struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_neighbor_entry *entry = msg->entry; - u_char actual_state = prefix->state; - - if (entry == NULL) - { - entry = eigrp_neighbor_entry_new(); - entry->adv_router = msg->adv_router; - entry->ei = msg->adv_router->ei; - entry->prefix = prefix; - msg->entry = entry; - } - - // Dividing by actual state of prefix's FSM - 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; - } - /* - * if best entry doesn't satisfy feasibility condition it means 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; - } - } - - 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; - } - - return EIGRP_FSM_EVENT_LR_FCN; - } - } - else if (msg->packet_type == EIGRP_OPC_QUERY - && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) - { - return EIGRP_FSM_EVENT_QACT; - } - - return EIGRP_FSM_KEEP_STATE; - - 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 - && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) - { - return EIGRP_FSM_EVENT_DINC; - } - else if (prefix->rij->count) - { - return EIGRP_FSM_KEEP_STATE; - } - else - { - zlog_info("All reply received\n"); - return EIGRP_FSM_EVENT_LR; - } - } - else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1 - && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) - { - return EIGRP_FSM_EVENT_DINC; - } - return EIGRP_FSM_KEEP_STATE; - - break; - } - case EIGRP_FSM_STATE_ACTIVE_2: - { - 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; - } - - return EIGRP_FSM_EVENT_LR_FCN; - } - } - return EIGRP_FSM_KEEP_STATE; - - 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 - && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) - { - return EIGRP_FSM_EVENT_DINC; - } - else if (prefix->rij->count) - { - return EIGRP_FSM_KEEP_STATE; - } - else - { - zlog_info("All reply received\n"); - return EIGRP_FSM_EVENT_LR; - } - } - else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1 - && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) - { - return EIGRP_FSM_EVENT_DINC; - } - return EIGRP_FSM_KEEP_STATE; - - break; - } - } - - return EIGRP_FSM_KEEP_STATE; + // Loading base information from message + // struct eigrp *eigrp = msg->eigrp; + struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_neighbor_entry *entry = msg->entry; + u_char actual_state = prefix->state; + + if (entry == NULL) { + entry = eigrp_neighbor_entry_new(); + entry->adv_router = msg->adv_router; + entry->ei = msg->adv_router->ei; + entry->prefix = prefix; + msg->entry = entry; + } + + // Dividing by actual state of prefix's FSM + 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; + } + /* + * if best entry doesn't satisfy feasibility condition it means + * 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; + } + } + + 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; + } + + return EIGRP_FSM_EVENT_LR_FCN; + } + } else if (msg->packet_type == EIGRP_OPC_QUERY + && (entry->flags + & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { + return EIGRP_FSM_EVENT_QACT; + } + + return EIGRP_FSM_KEEP_STATE; + + 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 + && (entry->flags + & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { + return EIGRP_FSM_EVENT_DINC; + } else if (prefix->rij->count) { + return EIGRP_FSM_KEEP_STATE; + } else { + zlog_info("All reply received\n"); + return EIGRP_FSM_EVENT_LR; + } + } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1 + && (entry->flags + & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { + return EIGRP_FSM_EVENT_DINC; + } + return EIGRP_FSM_KEEP_STATE; + + break; + } + case EIGRP_FSM_STATE_ACTIVE_2: { + 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; + } + + return EIGRP_FSM_EVENT_LR_FCN; + } + } + return EIGRP_FSM_KEEP_STATE; + + 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 + && (entry->flags + & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { + return EIGRP_FSM_EVENT_DINC; + } else if (prefix->rij->count) { + return EIGRP_FSM_KEEP_STATE; + } else { + zlog_info("All reply received\n"); + return EIGRP_FSM_EVENT_LR; + } + } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1 + && (entry->flags + & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) { + return EIGRP_FSM_EVENT_DINC; + } + return EIGRP_FSM_KEEP_STATE; + + break; + } + } + + return EIGRP_FSM_KEEP_STATE; } /* @@ -360,11 +340,12 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) */ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg, int event) { - zlog_info("EIGRP AS: %d State: %d Event: %d Network: %s\n", msg->eigrp->AS, - msg->prefix->state, event, eigrp_topology_ip_string(msg->prefix)); - (*(NSM[msg->prefix->state][event].func))(msg); + zlog_info("EIGRP AS: %d State: %d Event: %d Network: %s\n", + msg->eigrp->AS, msg->prefix->state, event, + eigrp_topology_ip_string(msg->prefix)); + (*(NSM[msg->prefix->state][event].func))(msg); - return 1; + return 1; } /* @@ -373,214 +354,226 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg, int event) */ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) { - struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->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->rdistance = prefix->distance = prefix->fdistance = - ((struct eigrp_neighbor_entry *) successors->head->data)->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *) successors->head->data)->total_metric; - - if (eigrp_nbr_count_get()) - { - prefix->req_action |= EIGRP_FSM_NEED_QUERY; - listnode_add(eigrp->topology_changes_internalIPV4,prefix); - } - else - { - eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left - } - - list_delete(successors); - - return 1; + struct eigrp *eigrp = msg->eigrp; + struct eigrp_prefix_entry *prefix = msg->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->rdistance = prefix->distance = prefix->fdistance = + ((struct eigrp_neighbor_entry *)successors->head->data) + ->distance; + prefix->reported_metric = + ((struct eigrp_neighbor_entry *)successors->head->data) + ->total_metric; + + if (eigrp_nbr_count_get()) { + prefix->req_action |= EIGRP_FSM_NEED_QUERY; + listnode_add(eigrp->topology_changes_internalIPV4, prefix); + } else { + eigrp_fsm_event_lr(msg); // in the case that there are no more + // neighbors left + } + + list_delete(successors); + + return 1; } int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) { - struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->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->rdistance = prefix->distance = prefix->fdistance = - ((struct eigrp_neighbor_entry *) successors->head->data)->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *) successors->head->data)->total_metric; - if (eigrp_nbr_count_get()) - { - prefix->req_action |= EIGRP_FSM_NEED_QUERY; - listnode_add(eigrp->topology_changes_internalIPV4,prefix); - } - else - { - eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left - } - - list_delete(successors); - - return 1; + struct eigrp *eigrp = msg->eigrp; + struct eigrp_prefix_entry *prefix = msg->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->rdistance = prefix->distance = prefix->fdistance = + ((struct eigrp_neighbor_entry *)successors->head->data) + ->distance; + prefix->reported_metric = + ((struct eigrp_neighbor_entry *)successors->head->data) + ->total_metric; + if (eigrp_nbr_count_get()) { + prefix->req_action |= EIGRP_FSM_NEED_QUERY; + listnode_add(eigrp->topology_changes_internalIPV4, prefix); + } else { + eigrp_fsm_event_lr(msg); // in the case that there are no more + // neighbors left + } + + list_delete(successors); + + return 1; } int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg) { - struct eigrp_prefix_entry *prefix = msg->prefix; - - if (prefix->state == EIGRP_FSM_STATE_PASSIVE) - { - if (!eigrp_metrics_is_same(prefix->reported_metric, - ((struct eigrp_neighbor_entry *) prefix->entries->head->data)->total_metric)) - { - prefix->rdistance = - prefix->fdistance = - prefix->distance = - ((struct eigrp_neighbor_entry *) prefix->entries->head->data)->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *) prefix->entries->head->data)->total_metric; - if (msg->packet_type == EIGRP_OPC_QUERY) - eigrp_send_reply(msg->adv_router, prefix); - prefix->req_action |= EIGRP_FSM_NEED_UPDATE; - listnode_add((eigrp_lookup())->topology_changes_internalIPV4,prefix); - } - eigrp_topology_update_node_flags(prefix); - eigrp_update_routing_table(prefix); - } - - if (msg->packet_type == EIGRP_OPC_QUERY) - eigrp_send_reply(msg->adv_router, prefix); - - return 1; + struct eigrp_prefix_entry *prefix = msg->prefix; + + if (prefix->state == EIGRP_FSM_STATE_PASSIVE) { + if (!eigrp_metrics_is_same(prefix->reported_metric, + ((struct eigrp_neighbor_entry *) + prefix->entries->head->data) + ->total_metric)) { + prefix->rdistance = prefix->fdistance = + prefix->distance = + ((struct eigrp_neighbor_entry *) + prefix->entries->head->data) + ->distance; + prefix->reported_metric = + ((struct eigrp_neighbor_entry *) + prefix->entries->head->data) + ->total_metric; + if (msg->packet_type == EIGRP_OPC_QUERY) + eigrp_send_reply(msg->adv_router, prefix); + prefix->req_action |= EIGRP_FSM_NEED_UPDATE; + listnode_add( + (eigrp_lookup())->topology_changes_internalIPV4, + prefix); + } + eigrp_topology_update_node_flags(prefix); + eigrp_update_routing_table(prefix); + } + + if (msg->packet_type == EIGRP_OPC_QUERY) + eigrp_send_reply(msg->adv_router, prefix); + + return 1; } int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) { - struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - prefix->fdistance = - prefix->distance = - prefix->rdistance = - ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric; - - if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) - { - struct list *successors = eigrp_topology_get_successor(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->req_action |= EIGRP_FSM_NEED_UPDATE; - listnode_add(eigrp->topology_changes_internalIPV4,prefix); - eigrp_topology_update_node_flags(prefix); - eigrp_update_routing_table(prefix); - eigrp_update_topology_table_prefix(eigrp->topology_table, prefix); - - return 1; + struct eigrp *eigrp = msg->eigrp; + struct eigrp_prefix_entry *prefix = msg->prefix; + prefix->fdistance = prefix->distance = prefix->rdistance = + ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) + ->distance; + prefix->reported_metric = + ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) + ->total_metric; + + if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) { + struct list *successors = eigrp_topology_get_successor(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->req_action |= EIGRP_FSM_NEED_UPDATE; + listnode_add(eigrp->topology_changes_internalIPV4, prefix); + eigrp_topology_update_node_flags(prefix); + eigrp_update_routing_table(prefix); + eigrp_update_topology_table_prefix(eigrp->topology_table, prefix); + + return 1; } int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) { - struct list *successors = eigrp_topology_get_successor(msg->prefix); + struct list *successors = eigrp_topology_get_successor(msg->prefix); - assert(successors); // Trump and his big hands + assert(successors); // Trump and his big hands - msg->prefix->state = - msg->prefix->state == EIGRP_FSM_STATE_ACTIVE_1 ? - EIGRP_FSM_STATE_ACTIVE_0 : EIGRP_FSM_STATE_ACTIVE_2; - msg->prefix->distance = - ((struct eigrp_neighbor_entry *)successors->head->data)->distance; - if (!msg->prefix->rij->count) - (*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))(msg); + msg->prefix->state = msg->prefix->state == EIGRP_FSM_STATE_ACTIVE_1 + ? EIGRP_FSM_STATE_ACTIVE_0 + : EIGRP_FSM_STATE_ACTIVE_2; + msg->prefix->distance = + ((struct eigrp_neighbor_entry *)successors->head->data) + ->distance; + if (!msg->prefix->rij->count) + (*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))( + msg); - list_delete(successors); - return 1; + list_delete(successors); + return 1; } int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) { - struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - prefix->state = EIGRP_FSM_STATE_PASSIVE; - prefix->distance = - prefix->rdistance = - ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->distance; - prefix->reported_metric = - ((struct eigrp_neighbor_entry *) (prefix->entries->head->data))->total_metric; - prefix->fdistance = - prefix->fdistance > prefix->distance ? - prefix->distance : prefix->fdistance; - if (prefix->state == EIGRP_FSM_STATE_ACTIVE_2) - { - struct list *successors = eigrp_topology_get_successor(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; - listnode_add(eigrp->topology_changes_internalIPV4,prefix); - eigrp_topology_update_node_flags(prefix); - eigrp_update_routing_table(prefix); - eigrp_update_topology_table_prefix(eigrp->topology_table, prefix); - - return 1; + struct eigrp *eigrp = msg->eigrp; + struct eigrp_prefix_entry *prefix = msg->prefix; + prefix->state = EIGRP_FSM_STATE_PASSIVE; + prefix->distance = prefix->rdistance = + ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) + ->distance; + prefix->reported_metric = + ((struct eigrp_neighbor_entry *)(prefix->entries->head->data)) + ->total_metric; + prefix->fdistance = prefix->fdistance > prefix->distance + ? prefix->distance + : prefix->fdistance; + if (prefix->state == EIGRP_FSM_STATE_ACTIVE_2) { + struct list *successors = eigrp_topology_get_successor(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; + listnode_add(eigrp->topology_changes_internalIPV4, prefix); + eigrp_topology_update_node_flags(prefix); + eigrp_update_routing_table(prefix); + eigrp_update_topology_table_prefix(eigrp->topology_table, prefix); + + return 1; } int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) { - struct eigrp *eigrp = msg->eigrp; - 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 == EIGRP_FSM_STATE_ACTIVE_0 ? - EIGRP_FSM_STATE_ACTIVE_1 : EIGRP_FSM_STATE_ACTIVE_3; - struct eigrp_neighbor_entry *best_successor = - ((struct eigrp_neighbor_entry *) (successors->head->data)); - prefix->rdistance = prefix->distance = best_successor->distance; - prefix->reported_metric = best_successor->total_metric; - - if (eigrp_nbr_count_get()) - { - prefix->req_action |= EIGRP_FSM_NEED_QUERY; - listnode_add(eigrp->topology_changes_internalIPV4,prefix); - } - else - { - eigrp_fsm_event_lr(msg); //in the case that there are no more neighbors left - } - - list_delete(successors); - - return 1; + struct eigrp *eigrp = msg->eigrp; + 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 == EIGRP_FSM_STATE_ACTIVE_0 + ? EIGRP_FSM_STATE_ACTIVE_1 + : EIGRP_FSM_STATE_ACTIVE_3; + struct eigrp_neighbor_entry *best_successor = + ((struct eigrp_neighbor_entry *)(successors->head->data)); + prefix->rdistance = prefix->distance = best_successor->distance; + prefix->reported_metric = best_successor->total_metric; + + if (eigrp_nbr_count_get()) { + prefix->req_action |= EIGRP_FSM_NEED_QUERY; + listnode_add(eigrp->topology_changes_internalIPV4, prefix); + } else { + eigrp_fsm_event_lr(msg); // in the case that there are no more + // neighbors left + } + + list_delete(successors); + + return 1; } int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) { - struct list *successors = eigrp_topology_get_successor(msg->prefix); + struct list *successors = eigrp_topology_get_successor(msg->prefix); - assert(successors); // Cats and no Dogs + assert(successors); // Cats and no Dogs - msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2; - msg->prefix->distance = - ((struct eigrp_neighbor_entry *) (successors->head->data))->distance; + msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2; + msg->prefix->distance = + ((struct eigrp_neighbor_entry *)(successors->head->data)) + ->distance; - list_delete(successors); - return 1; + list_delete(successors); + return 1; } |