]> git.proxmox.com Git - mirror_frr.git/blobdiff - eigrpd/eigrp_fsm.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / eigrpd / eigrp_fsm.c
index 29357c2b248ee07bb94a8ac6cabf91b62ac0bcaa..374114cf559dd279fa4935c895d8e8dddb756df9 100644 (file)
@@ -67,8 +67,8 @@
  * 7- state not changed, usually by receiving not last reply
  */
 
-#include <thread.h>
 #include <zebra.h>
+#include <thread.h>
 
 #include "prefix.h"
 #include "table.h"
@@ -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 satisfied";
+       case EIGRP_FSM_EVENT_LR_FCS:
+               return "Last Reply Event Feasability satisfied";
+       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,13 +257,14 @@ struct {
  * Return number of occurred event (arrow in diagram).
  *
  */
-static 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_nexthop_entry *entry = msg->entry;
-       u_char actual_state = prefix->state;
+       uint8_t actual_state = prefix->state;
        enum metric_change change;
 
        if (entry == NULL) {
@@ -201,6 +281,9 @@ static 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_nexthop_entry *head =
@@ -232,8 +315,7 @@ static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
                                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;
                        }
 
@@ -265,7 +347,8 @@ static 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_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                        return EIGRP_FSM_EVENT_DINC;
@@ -310,7 +393,8 @@ static 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_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
                        return EIGRP_FSM_EVENT_DINC;
@@ -330,10 +414,14 @@ static int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
  */
 int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
 {
-       int event = eigrp_get_fsm_event(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;
@@ -354,8 +442,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
 
        ne = listnode_head(successors);
        prefix->state = EIGRP_FSM_STATE_ACTIVE_1;
-       prefix->rdistance = prefix->distance = prefix->fdistance =
-               ne->distance;
+       prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
        prefix->reported_metric = ne->total_metric;
 
        if (eigrp_nbr_count_get()) {
@@ -366,7 +453,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
                                         // neighbors left
        }
 
-       list_delete_and_null(&successors);
+       list_delete(&successors);
 
        return 1;
 }
@@ -382,8 +469,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
 
        ne = listnode_head(successors);
        prefix->state = EIGRP_FSM_STATE_ACTIVE_3;
-       prefix->rdistance = prefix->distance = prefix->fdistance =
-               ne->distance;
+       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;
@@ -393,13 +479,14 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
                                         // neighbors left
        }
 
-       list_delete_and_null(&successors);
+       list_delete(&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);
 
@@ -408,14 +495,14 @@ int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
                                           ne->total_metric)) {
                        prefix->rdistance = prefix->fdistance =
                                prefix->distance = ne->distance;
-                       prefix->reported_metric =
-                               ne->total_metric;
+                       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);
@@ -433,8 +520,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
        struct eigrp_prefix_entry *prefix = msg->prefix;
        struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
 
-       prefix->fdistance = prefix->distance = prefix->rdistance =
-               ne->distance;
+       prefix->fdistance = prefix->distance = prefix->rdistance = ne->distance;
        prefix->reported_metric = ne->total_metric;
 
        if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) {
@@ -443,9 +529,8 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
                assert(successors); // It's like Napolean and Waterloo
 
                ne = listnode_head(successors);
-               eigrp_send_reply(ne->adv_router,
-                                prefix);
-               list_delete_and_null(&successors);
+               eigrp_send_reply(ne->adv_router, prefix);
+               list_delete(&successors);
        }
 
        prefix->state = EIGRP_FSM_STATE_PASSIVE;
@@ -475,7 +560,7 @@ int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg)
                        msg);
 
 
-       list_delete_and_null(&successors);
+       list_delete(&successors);
        return 1;
 }
 
@@ -497,10 +582,9 @@ 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(ne->adv_router, prefix);
 
-               list_delete_and_null(&successors);
+               list_delete(&successors);
        }
        prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
        listnode_add(eigrp->topology_changes_internalIPV4, prefix);
@@ -536,7 +620,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
                                         // neighbors left
        }
 
-       list_delete_and_null(&successors);
+       list_delete(&successors);
 
        return 1;
 }
@@ -552,6 +636,6 @@ int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg)
        msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2;
        msg->prefix->distance = ne->distance;
 
-       list_delete_and_null(&successors);
+       list_delete(&successors);
        return 1;
 }