]> git.proxmox.com Git - mirror_frr.git/blobdiff - eigrpd/eigrp_fsm.c
babeld: Add BABEL_ERR_XXX error messages.
[mirror_frr.git] / eigrpd / eigrp_fsm.c
index ba2d1f7e8d05eedd53b246bbfc4376b48b6189d5..eeefc519688ccce2c37f7298254b46bfa46b91be 100644 (file)
@@ -170,6 +170,85 @@ struct {
        },
 };
 
+static const char *packet_type2str(uint8_t packet_type)
+{
+       if (packet_type == EIGRP_OPC_UPDATE)
+               return "Update";
+       if (packet_type == EIGRP_OPC_REQUEST)
+               return "Request";
+       if (packet_type == EIGRP_OPC_QUERY)
+               return "Query";
+       if (packet_type == EIGRP_OPC_REPLY)
+               return "Reply";
+       if (packet_type == EIGRP_OPC_HELLO)
+               return "Hello";
+       if (packet_type == EIGRP_OPC_IPXSAP)
+               return "IPXSAP";
+       if (packet_type == EIGRP_OPC_ACK)
+               return "Ack";
+       if (packet_type == EIGRP_OPC_SIAQUERY)
+               return "SIA Query";
+       if (packet_type == EIGRP_OPC_SIAREPLY)
+               return "SIA Reply";
+
+       return "Unknown";
+}
+
+static const char *prefix_state2str(enum eigrp_fsm_states state)
+{
+       switch (state) {
+       case EIGRP_FSM_STATE_PASSIVE:
+               return "Passive";
+       case EIGRP_FSM_STATE_ACTIVE_0:
+               return "Active oij0";
+       case EIGRP_FSM_STATE_ACTIVE_1:
+               return "Active oij1";
+       case EIGRP_FSM_STATE_ACTIVE_2:
+               return "Active oij2";
+       case EIGRP_FSM_STATE_ACTIVE_3:
+               return "Active oij3";
+       }
+
+       return "Unknown";
+}
+
+static const char *fsm_state2str(enum eigrp_fsm_events event)
+{
+       switch (event) {
+       case EIGRP_FSM_KEEP_STATE:
+               return "Keep State Event";
+       case EIGRP_FSM_EVENT_NQ_FCN:
+               return "Non Query Event Feasability not satisfied";
+       case EIGRP_FSM_EVENT_LR:
+               return "Last Reply Event";
+       case EIGRP_FSM_EVENT_Q_FCN:
+               return "Query Event Feasability not satisified";
+       case EIGRP_FSM_EVENT_LR_FCS:
+               return "Last Reply Event Feasability satisified";
+       case EIGRP_FSM_EVENT_DINC:
+               return "Distance Increase Event";
+       case EIGRP_FSM_EVENT_QACT:
+               return "Query from Successor while in active state";
+       case EIGRP_FSM_EVENT_LR_FCN:
+               return "Last Reply Event, Feasibility not satisfied";
+       };
+
+       return "Unknown";
+}
+
+static const char *change2str(enum metric_change change)
+{
+       switch (change) {
+       case METRIC_DECREASE:
+               return "Decrease";
+       case METRIC_SAME:
+               return "Same";
+       case METRIC_INCREASE:
+               return "Increase";
+       }
+
+       return "Unknown";
+}
 /*
  * Main function in which are make decisions which event occurred.
  * msg - argument of type struct eigrp_fsm_action_message contain
@@ -178,17 +257,18 @@ struct {
  * Return number of occurred event (arrow in diagram).
  *
  */
-int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
+static enum eigrp_fsm_events
+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;
+       struct eigrp_nexthop_entry *entry = msg->entry;
+       uint8_t actual_state = prefix->state;
        enum metric_change change;
 
        if (entry == NULL) {
-               entry = eigrp_neighbor_entry_new();
+               entry = eigrp_nexthop_entry_new();
                entry->adv_router = msg->adv_router;
                entry->ei = msg->adv_router->ei;
                entry->prefix = prefix;
@@ -201,11 +281,13 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
         */
        change = eigrp_topology_update_distance(msg);
 
+       /* Store for display later */
+       msg->change = change;
+
        switch (actual_state) {
        case EIGRP_FSM_STATE_PASSIVE: {
-               struct eigrp_neighbor_entry *head =
-                       (struct eigrp_neighbor_entry *)
-                               entry->prefix->entries->head->data;
+               struct eigrp_nexthop_entry *head =
+                       listnode_head(prefix->entries);
 
                if (head->reported_distance < prefix->fdistance) {
                        return EIGRP_FSM_KEEP_STATE;
@@ -225,24 +307,22 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
        }
        case EIGRP_FSM_STATE_ACTIVE_0: {
                if (msg->packet_type == EIGRP_OPC_REPLY) {
-                       struct eigrp_neighbor_entry *head =
-                               (struct eigrp_neighbor_entry *)
-                               entry->prefix->entries->head->data;
+                       struct eigrp_nexthop_entry *head =
+                               listnode_head(prefix->entries);
 
                        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) {
+                       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)) {
+                              & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                        return EIGRP_FSM_EVENT_QACT;
                }
 
@@ -252,14 +332,14 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
        }
        case EIGRP_FSM_STATE_ACTIVE_1: {
                if (msg->packet_type == EIGRP_OPC_QUERY
-                   && (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
+                   && (entry->flags & EIGRP_NEXTHOP_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 == METRIC_INCREASE
                            && (entry->flags
-                               & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
+                               & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                                return EIGRP_FSM_EVENT_DINC;
                        } else if (prefix->rij->count) {
                                return EIGRP_FSM_KEEP_STATE;
@@ -267,9 +347,10 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
                                zlog_info("All reply received\n");
                                return EIGRP_FSM_EVENT_LR;
                        }
-               } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1
+               } else if (msg->packet_type == EIGRP_OPC_UPDATE
+                          && change == METRIC_INCREASE
                           && (entry->flags
-                              & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
+                              & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                        return EIGRP_FSM_EVENT_DINC;
                }
                return EIGRP_FSM_KEEP_STATE;
@@ -278,9 +359,8 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
        }
        case EIGRP_FSM_STATE_ACTIVE_2: {
                if (msg->packet_type == EIGRP_OPC_REPLY) {
-                       struct eigrp_neighbor_entry *head =
-                               (struct eigrp_neighbor_entry *)
-                               prefix->entries->head->data;
+                       struct eigrp_nexthop_entry *head =
+                               listnode_head(prefix->entries);
 
                        listnode_delete(prefix->rij, entry->adv_router);
                        if (prefix->rij->count) {
@@ -305,7 +385,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
 
                        if (change == METRIC_INCREASE
                            && (entry->flags
-                               & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
+                               & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                                return EIGRP_FSM_EVENT_DINC;
                        } else if (prefix->rij->count) {
                                return EIGRP_FSM_KEEP_STATE;
@@ -313,9 +393,10 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
                                zlog_info("All reply received\n");
                                return EIGRP_FSM_EVENT_LR;
                        }
-               } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == 1
+               } else if (msg->packet_type == EIGRP_OPC_UPDATE
+                          && change == METRIC_INCREASE
                           && (entry->flags
-                              & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
+                              & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                        return EIGRP_FSM_EVENT_DINC;
                }
                return EIGRP_FSM_KEEP_STATE;
@@ -331,11 +412,16 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
  * Function made to execute in separate thread.
  * Load argument from thread and execute proper NSM function
  */
-int eigrp_fsm_event(struct eigrp_fsm_action_message *msg, int event)
+int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
 {
-       zlog_info("EIGRP AS: %d State: %d  Event: %d Network: %s",
-                 msg->eigrp->AS, msg->prefix->state, event,
-                 eigrp_topology_ip_string(msg->prefix));
+       enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
+
+       zlog_info(
+               "EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s",
+               msg->eigrp->AS, prefix_state2str(msg->prefix->state),
+               fsm_state2str(event), eigrp_topology_ip_string(msg->prefix),
+               packet_type2str(msg->packet_type), msg->prefix->rij->count,
+               change2str(msg->change));
        (*(NSM[msg->prefix->state][event].func))(msg);
 
        return 1;
@@ -350,16 +436,14 @@ 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);
+       struct eigrp_nexthop_entry *ne;
 
        assert(successors); // If this is NULL we have shit the bed, fun huh?
 
+       ne = listnode_head(successors);
        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;
+       prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
+       prefix->reported_metric = ne->total_metric;
 
        if (eigrp_nbr_count_get()) {
                prefix->req_action |= EIGRP_FSM_NEED_QUERY;
@@ -369,7 +453,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
                                         // neighbors left
        }
 
-       list_delete(successors);
+       list_delete_and_null(&successors);
 
        return 1;
 }
@@ -379,16 +463,14 @@ 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);
+       struct eigrp_nexthop_entry *ne;
 
        assert(successors); // If this is NULL somebody poked us in the eye.
 
+       ne = listnode_head(successors);
        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;
+       prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
+       prefix->reported_metric = ne->total_metric;
        if (eigrp_nbr_count_get()) {
                prefix->req_action |= EIGRP_FSM_NEED_QUERY;
                listnode_add(eigrp->topology_changes_internalIPV4, prefix);
@@ -397,35 +479,30 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
                                         // neighbors left
        }
 
-       list_delete(successors);
+       list_delete_and_null(&successors);
 
        return 1;
 }
 
 int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
 {
+       struct eigrp *eigrp;
        struct eigrp_prefix_entry *prefix = msg->prefix;
+       struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
 
        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)) {
+                                          ne->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;
+                               prefix->distance = ne->distance;
+                       prefix->reported_metric = ne->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 = eigrp_lookup();
+                       assert(eigrp);
+                       listnode_add(eigrp->topology_changes_internalIPV4,
+                                    prefix);
                }
                eigrp_topology_update_node_flags(prefix);
                eigrp_update_routing_table(prefix);
@@ -441,23 +518,19 @@ 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;
+       struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
+
+       prefix->fdistance = prefix->distance = prefix->rdistance = ne->distance;
+       prefix->reported_metric = ne->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);
+               ne = listnode_head(successors);
+               eigrp_send_reply(ne->adv_router, prefix);
+               list_delete_and_null(&successors);
        }
 
        prefix->state = EIGRP_FSM_STATE_PASSIVE;
@@ -473,21 +546,21 @@ int eigrp_fsm_event_lr(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);
+       struct eigrp_nexthop_entry *ne;
 
        assert(successors); // Trump and his big hands
 
+       ne = listnode_head(successors);
        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;
+       msg->prefix->distance = ne->distance;
        if (!msg->prefix->rij->count)
                (*(NSM[msg->prefix->state][eigrp_get_fsm_event(msg)].func))(
                        msg);
 
 
-       list_delete(successors);
+       list_delete_and_null(&successors);
        return 1;
 }
 
@@ -495,13 +568,11 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
 {
        struct eigrp *eigrp = msg->eigrp;
        struct eigrp_prefix_entry *prefix = msg->prefix;
+       struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
+
        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->distance = prefix->rdistance = ne->distance;
+       prefix->reported_metric = ne->total_metric;
        prefix->fdistance = prefix->fdistance > prefix->distance
                                    ? prefix->distance
                                    : prefix->fdistance;
@@ -510,13 +581,10 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
 
                assert(successors); // Having a spoon and all you need is a
                                    // knife
+               ne = listnode_head(successors);
+               eigrp_send_reply(ne->adv_router, prefix);
 
-               eigrp_send_reply(
-                       ((struct eigrp_neighbor_entry *)successors->head->data)
-                               ->adv_router,
-                       prefix);
-
-               list_delete(successors);
+               list_delete_and_null(&successors);
        }
        prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
        listnode_add(eigrp->topology_changes_internalIPV4, prefix);
@@ -531,6 +599,7 @@ 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 eigrp_nexthop_entry *best_successor;
        struct list *successors = eigrp_topology_get_successor(prefix);
 
        assert(successors); // Routing without a stack
@@ -538,8 +607,8 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
        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));
+
+       best_successor = listnode_head(successors);
        prefix->rdistance = prefix->distance = best_successor->distance;
        prefix->reported_metric = best_successor->total_metric;
 
@@ -551,7 +620,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
                                         // neighbors left
        }
 
-       list_delete(successors);
+       list_delete_and_null(&successors);
 
        return 1;
 }
@@ -559,14 +628,14 @@ int eigrp_fsm_event_lr_fcn(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);
+       struct eigrp_nexthop_entry *ne;
 
        assert(successors); // Cats and no Dogs
 
+       ne = listnode_head(successors);
        msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2;
-       msg->prefix->distance =
-               ((struct eigrp_neighbor_entry *)(successors->head->data))
-                       ->distance;
+       msg->prefix->distance = ne->distance;
 
-       list_delete(successors);
+       list_delete_and_null(&successors);
        return 1;
 }