]> 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 84f21013e4079b959f7b4d3c871b13fc3cc543f2..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,30 @@ 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) {
@@ -198,9 +222,9 @@ static const char *fsm_state2str(enum eigrp_fsm_events event)
        case EIGRP_FSM_EVENT_LR:
                return "Last Reply Event";
        case EIGRP_FSM_EVENT_Q_FCN:
-               return "Query Event Feasability not satisified";
+               return "Query Event Feasability not satisfied";
        case EIGRP_FSM_EVENT_LR_FCS:
-               return "Last Reply Event Feasability satisified";
+               return "Last Reply Event Feasability satisfied";
        case EIGRP_FSM_EVENT_DINC:
                return "Distance Increase Event";
        case EIGRP_FSM_EVENT_QACT:
@@ -211,6 +235,20 @@ static const char *fsm_state2str(enum eigrp_fsm_events event)
 
        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
@@ -219,14 +257,14 @@ static const char *fsm_state2str(enum eigrp_fsm_events event)
  * Return number of occurred event (arrow in diagram).
  *
  */
-static enum eigrp_fsm_events 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) {
@@ -243,6 +281,9 @@ static enum eigrp_fsm_events eigrp_get_fsm_event(
         */
        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 =
@@ -274,8 +315,7 @@ static enum eigrp_fsm_events eigrp_get_fsm_event(
                                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;
                        }
 
@@ -307,7 +347,8 @@ static enum eigrp_fsm_events eigrp_get_fsm_event(
                                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;
@@ -352,7 +393,8 @@ static enum eigrp_fsm_events eigrp_get_fsm_event(
                                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;
@@ -374,10 +416,12 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
 {
        enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
 
-       zlog_info("EIGRP AS: %d State: %s Event: %s Network: %s",
-                 msg->eigrp->AS, prefix_state2str(msg->prefix->state),
-                 fsm_state2str(event),
-                 eigrp_topology_ip_string(msg->prefix));
+       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;
@@ -398,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()) {
@@ -410,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;
 }
@@ -426,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;
@@ -437,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);
 
@@ -452,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);
@@ -477,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) {
@@ -487,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;
@@ -519,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;
 }
 
@@ -541,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);
@@ -580,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;
 }
@@ -596,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;
 }