mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 13:51:53 +00:00
commit
58239911bf
@ -153,14 +153,37 @@ enum eigrp_fsm_states {
|
||||
#define EIGRP_FSM_NEED_QUERY 2
|
||||
|
||||
/*EIGRP FSM events*/
|
||||
#define EIGRP_FSM_EVENT_NQ_FCN 0 /*input event other than query from succ, FC not satisfied*/
|
||||
#define EIGRP_FSM_EVENT_LR 1 /*last reply, FD is reset*/
|
||||
#define EIGRP_FSM_EVENT_Q_FCN 2 /*query from succ, FC not satisfied*/
|
||||
#define EIGRP_FSM_EVENT_LR_FCS 3 /*last reply, FC satisfied with current value of FDij*/
|
||||
#define EIGRP_FSM_EVENT_DINC 4 /*distance increase while in active state*/
|
||||
#define EIGRP_FSM_EVENT_QACT 5 /*query from succ while in active state*/
|
||||
#define EIGRP_FSM_EVENT_LR_FCN 6 /*last reply, FC not satisfied with current value of FDij*/
|
||||
#define EIGRP_FSM_KEEP_STATE 7 /*state not changed, usually by receiving not last reply */
|
||||
enum eigrp_fsm_events {
|
||||
/*
|
||||
* Input event other than query from succ,
|
||||
* FC is not satisified
|
||||
*/
|
||||
EIGRP_FSM_EVENT_NQ_FCN,
|
||||
|
||||
/* last reply, FD is reset */
|
||||
EIGRP_FSM_EVENT_LR,
|
||||
|
||||
/* Query from succ, FC not satisfied */
|
||||
EIGRP_FSM_EVENT_Q_FCN,
|
||||
|
||||
/* last reply, FC satisifed with current value of FDij */
|
||||
EIGRP_FSM_EVENT_LR_FCS,
|
||||
|
||||
/* distance increase while in a active state */
|
||||
EIGRP_FSM_EVENT_DINC,
|
||||
|
||||
/* Query from succ while in active state */
|
||||
EIGRP_FSM_EVENT_QACT,
|
||||
|
||||
/* last reply, FC not satisified */
|
||||
EIGRP_FSM_EVENT_LR_FCN,
|
||||
|
||||
/*
|
||||
* state not changed
|
||||
* usually by receiving not last reply
|
||||
*/
|
||||
EIGRP_FSM_KEEP_STATE,
|
||||
};
|
||||
|
||||
/**
|
||||
* External routes originate from some other protocol - these are them
|
||||
|
@ -170,6 +170,85 @@ struct {
|
||||
},
|
||||
};
|
||||
|
||||
static const char *packet_type2str(u_char 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,7 +257,8 @@ 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;
|
||||
@ -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 =
|
||||
@ -265,7 +348,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 +394,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 +415,15 @@ 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;
|
||||
|
@ -344,8 +344,18 @@ int eigrp_write(struct thread *thread)
|
||||
|
||||
/* Get one packet from queue. */
|
||||
ep = eigrp_fifo_next(ei->obuf);
|
||||
assert(ep);
|
||||
assert(ep->length >= EIGRP_HEADER_LEN);
|
||||
if (!ep) {
|
||||
zlog_err("%s: Interface %s no packet on queue?",
|
||||
__PRETTY_FUNCTION__, ei->ifp->name);
|
||||
goto out;
|
||||
}
|
||||
if (ep->length < EIGRP_HEADER_LEN) {
|
||||
zlog_err("%s: Packet just has a header?",
|
||||
__PRETTY_FUNCTION__);
|
||||
eigrp_header_dump((struct eigrp_header *)ep->s->data);
|
||||
eigrp_packet_delete(ei);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ep->dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS))
|
||||
eigrp_if_ipmulticast(eigrp, ei->address, ei->ifp->ifindex);
|
||||
@ -442,6 +452,7 @@ int eigrp_write(struct thread *thread)
|
||||
/* Now delete packet from queue. */
|
||||
eigrp_packet_delete(ei);
|
||||
|
||||
out:
|
||||
if (eigrp_fifo_next(ei->obuf) == NULL) {
|
||||
ei->on_write_q = 0;
|
||||
list_delete_node(eigrp->oi_write_q, node);
|
||||
|
@ -165,7 +165,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct eigrp_prefix_entry *pe;
|
||||
char has_tlv;
|
||||
bool has_tlv = false;
|
||||
bool ep_saved = false;
|
||||
|
||||
ep = eigrp_packet_new(ei->ifp->mtu, NULL);
|
||||
@ -180,16 +180,16 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
||||
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
|
||||
}
|
||||
|
||||
has_tlv = 0;
|
||||
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
|
||||
nnode, pe)) {
|
||||
if (pe->req_action & EIGRP_FSM_NEED_QUERY) {
|
||||
if (!(pe->req_action & EIGRP_FSM_NEED_QUERY))
|
||||
continue;
|
||||
|
||||
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
||||
listnode_add(pe->rij, nbr);
|
||||
has_tlv = 1;
|
||||
}
|
||||
has_tlv = true;;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,6 +212,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
||||
|
||||
/*This ack number we await from neighbor*/
|
||||
ep->sequence_number = ei->eigrp->sequence_number;
|
||||
ei->eigrp->sequence_number++;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
||||
|
@ -149,7 +149,10 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
|
||||
while (s->endp > s->getp) {
|
||||
type = stream_getw(s);
|
||||
if (type == EIGRP_TLV_IPv4_INT) {
|
||||
|
||||
if (type != EIGRP_TLV_IPv4_INT)
|
||||
continue;
|
||||
|
||||
struct prefix dest_addr;
|
||||
|
||||
stream_set_getp(s, s->getp - sizeof(u_int16_t));
|
||||
@ -165,7 +168,13 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
/*
|
||||
* Destination must exists
|
||||
*/
|
||||
assert(dest);
|
||||
if (!dest) {
|
||||
char buf[PREFIX_STRLEN];
|
||||
zlog_err("%s: Received prefix %s which we do not know about",
|
||||
__PRETTY_FUNCTION__,
|
||||
prefix2str(&dest_addr, buf, strlen(buf)));
|
||||
continue;
|
||||
}
|
||||
|
||||
struct eigrp_fsm_action_message msg;
|
||||
struct eigrp_nexthop_entry *entry =
|
||||
@ -189,9 +198,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
msg.prefix = dest;
|
||||
eigrp_fsm_event(&msg);
|
||||
|
||||
|
||||
eigrp_IPv4_InternalTLV_free(tlv);
|
||||
}
|
||||
}
|
||||
eigrp_hello_send_ack(nbr);
|
||||
}
|
||||
|
@ -499,6 +499,7 @@ struct eigrp_fsm_action_message {
|
||||
struct eigrp_prefix_entry *prefix;
|
||||
msg_data_t data_type; // internal or external tlv type
|
||||
struct eigrp_metrics metrics;
|
||||
enum metric_change change;
|
||||
};
|
||||
|
||||
#endif /* _ZEBRA_EIGRP_STRUCTURES_H_ */
|
||||
|
@ -284,14 +284,15 @@ void eigrp_finish_final(struct eigrp *eigrp)
|
||||
|
||||
list_delete_and_null(&eigrp->eiflist);
|
||||
list_delete_and_null(&eigrp->oi_write_q);
|
||||
list_delete_and_null(&eigrp->topology_changes_externalIPV4);
|
||||
list_delete_and_null(&eigrp->topology_changes_internalIPV4);
|
||||
|
||||
eigrp_topology_cleanup(eigrp->topology_table);
|
||||
eigrp_topology_free(eigrp->topology_table);
|
||||
|
||||
eigrp_nbr_delete(eigrp->neighbor_self);
|
||||
|
||||
list_delete_and_null(&eigrp->topology_changes_externalIPV4);
|
||||
list_delete_and_null(&eigrp->topology_changes_internalIPV4);
|
||||
|
||||
eigrp_delete(eigrp);
|
||||
|
||||
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
||||
|
Loading…
Reference in New Issue
Block a user