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
|
#define EIGRP_FSM_NEED_QUERY 2
|
||||||
|
|
||||||
/*EIGRP FSM events*/
|
/*EIGRP FSM events*/
|
||||||
#define EIGRP_FSM_EVENT_NQ_FCN 0 /*input event other than query from succ, FC not satisfied*/
|
enum eigrp_fsm_events {
|
||||||
#define EIGRP_FSM_EVENT_LR 1 /*last reply, FD is reset*/
|
/*
|
||||||
#define EIGRP_FSM_EVENT_Q_FCN 2 /*query from succ, FC not satisfied*/
|
* Input event other than query from succ,
|
||||||
#define EIGRP_FSM_EVENT_LR_FCS 3 /*last reply, FC satisfied with current value of FDij*/
|
* FC is not satisified
|
||||||
#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*/
|
EIGRP_FSM_EVENT_NQ_FCN,
|
||||||
#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 */
|
/* 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
|
* 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.
|
* Main function in which are make decisions which event occurred.
|
||||||
* msg - argument of type struct eigrp_fsm_action_message contain
|
* msg - argument of type struct eigrp_fsm_action_message contain
|
||||||
@ -178,7 +257,8 @@ struct {
|
|||||||
* Return number of occurred event (arrow in diagram).
|
* 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
|
// Loading base information from message
|
||||||
// struct eigrp *eigrp = msg->eigrp;
|
// 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);
|
change = eigrp_topology_update_distance(msg);
|
||||||
|
|
||||||
|
/* Store for display later */
|
||||||
|
msg->change = change;
|
||||||
|
|
||||||
switch (actual_state) {
|
switch (actual_state) {
|
||||||
case EIGRP_FSM_STATE_PASSIVE: {
|
case EIGRP_FSM_STATE_PASSIVE: {
|
||||||
struct eigrp_nexthop_entry *head =
|
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");
|
zlog_info("All reply received\n");
|
||||||
return EIGRP_FSM_EVENT_LR;
|
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
|
&& (entry->flags
|
||||||
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
|
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
|
||||||
return EIGRP_FSM_EVENT_DINC;
|
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");
|
zlog_info("All reply received\n");
|
||||||
return EIGRP_FSM_EVENT_LR;
|
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
|
&& (entry->flags
|
||||||
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
|
& EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) {
|
||||||
return EIGRP_FSM_EVENT_DINC;
|
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 eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
|
||||||
{
|
{
|
||||||
int event = eigrp_get_fsm_event(msg);
|
enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
|
||||||
zlog_info("EIGRP AS: %d State: %d Event: %d Network: %s",
|
|
||||||
msg->eigrp->AS, msg->prefix->state, event,
|
zlog_info("EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s",
|
||||||
eigrp_topology_ip_string(msg->prefix));
|
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);
|
(*(NSM[msg->prefix->state][event].func))(msg);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -344,8 +344,18 @@ int eigrp_write(struct thread *thread)
|
|||||||
|
|
||||||
/* Get one packet from queue. */
|
/* Get one packet from queue. */
|
||||||
ep = eigrp_fifo_next(ei->obuf);
|
ep = eigrp_fifo_next(ei->obuf);
|
||||||
assert(ep);
|
if (!ep) {
|
||||||
assert(ep->length >= EIGRP_HEADER_LEN);
|
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))
|
if (ep->dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS))
|
||||||
eigrp_if_ipmulticast(eigrp, ei->address, ei->ifp->ifindex);
|
eigrp_if_ipmulticast(eigrp, ei->address, ei->ifp->ifindex);
|
||||||
@ -442,6 +452,7 @@ int eigrp_write(struct thread *thread)
|
|||||||
/* Now delete packet from queue. */
|
/* Now delete packet from queue. */
|
||||||
eigrp_packet_delete(ei);
|
eigrp_packet_delete(ei);
|
||||||
|
|
||||||
|
out:
|
||||||
if (eigrp_fifo_next(ei->obuf) == NULL) {
|
if (eigrp_fifo_next(ei->obuf) == NULL) {
|
||||||
ei->on_write_q = 0;
|
ei->on_write_q = 0;
|
||||||
list_delete_node(eigrp->oi_write_q, node);
|
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 listnode *node, *nnode, *node2, *nnode2;
|
||||||
struct eigrp_neighbor *nbr;
|
struct eigrp_neighbor *nbr;
|
||||||
struct eigrp_prefix_entry *pe;
|
struct eigrp_prefix_entry *pe;
|
||||||
char has_tlv;
|
bool has_tlv = false;
|
||||||
bool ep_saved = false;
|
bool ep_saved = false;
|
||||||
|
|
||||||
ep = eigrp_packet_new(ei->ifp->mtu, NULL);
|
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);
|
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
|
||||||
}
|
}
|
||||||
|
|
||||||
has_tlv = 0;
|
|
||||||
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
|
for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
|
||||||
nnode, pe)) {
|
nnode, pe)) {
|
||||||
if (pe->req_action & EIGRP_FSM_NEED_QUERY) {
|
if (!(pe->req_action & EIGRP_FSM_NEED_QUERY))
|
||||||
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
|
continue;
|
||||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
|
||||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
|
||||||
listnode_add(pe->rij, nbr);
|
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||||
has_tlv = 1;
|
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
||||||
}
|
listnode_add(pe->rij, nbr);
|
||||||
|
has_tlv = true;;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,6 +212,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
|||||||
|
|
||||||
/*This ack number we await from neighbor*/
|
/*This ack number we await from neighbor*/
|
||||||
ep->sequence_number = ei->eigrp->sequence_number;
|
ep->sequence_number = ei->eigrp->sequence_number;
|
||||||
|
ei->eigrp->sequence_number++;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
||||||
|
@ -149,49 +149,56 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
|
|||||||
|
|
||||||
while (s->endp > s->getp) {
|
while (s->endp > s->getp) {
|
||||||
type = stream_getw(s);
|
type = stream_getw(s);
|
||||||
if (type == EIGRP_TLV_IPv4_INT) {
|
|
||||||
struct prefix dest_addr;
|
|
||||||
|
|
||||||
stream_set_getp(s, s->getp - sizeof(u_int16_t));
|
if (type != EIGRP_TLV_IPv4_INT)
|
||||||
|
continue;
|
||||||
|
|
||||||
tlv = eigrp_read_ipv4_tlv(s);
|
struct prefix dest_addr;
|
||||||
|
|
||||||
dest_addr.family = AF_INET;
|
stream_set_getp(s, s->getp - sizeof(u_int16_t));
|
||||||
dest_addr.u.prefix4 = tlv->destination;
|
|
||||||
dest_addr.prefixlen = tlv->prefix_length;
|
|
||||||
struct eigrp_prefix_entry *dest =
|
|
||||||
eigrp_topology_table_lookup_ipv4(
|
|
||||||
eigrp->topology_table, &dest_addr);
|
|
||||||
/*
|
|
||||||
* Destination must exists
|
|
||||||
*/
|
|
||||||
assert(dest);
|
|
||||||
|
|
||||||
struct eigrp_fsm_action_message msg;
|
tlv = eigrp_read_ipv4_tlv(s);
|
||||||
struct eigrp_nexthop_entry *entry =
|
|
||||||
eigrp_prefix_entry_lookup(dest->entries, nbr);
|
|
||||||
|
|
||||||
if (eigrp_update_prefix_apply(eigrp, ei,
|
dest_addr.family = AF_INET;
|
||||||
EIGRP_FILTER_IN,
|
dest_addr.u.prefix4 = tlv->destination;
|
||||||
&dest_addr)) {
|
dest_addr.prefixlen = tlv->prefix_length;
|
||||||
tlv->metric.delay = EIGRP_MAX_METRIC;
|
struct eigrp_prefix_entry *dest =
|
||||||
}
|
eigrp_topology_table_lookup_ipv4(
|
||||||
/*
|
eigrp->topology_table, &dest_addr);
|
||||||
* End of filtering
|
/*
|
||||||
*/
|
* Destination must exists
|
||||||
|
*/
|
||||||
msg.packet_type = EIGRP_OPC_REPLY;
|
if (!dest) {
|
||||||
msg.eigrp = eigrp;
|
char buf[PREFIX_STRLEN];
|
||||||
msg.data_type = EIGRP_INT;
|
zlog_err("%s: Received prefix %s which we do not know about",
|
||||||
msg.adv_router = nbr;
|
__PRETTY_FUNCTION__,
|
||||||
msg.metrics = tlv->metric;
|
prefix2str(&dest_addr, buf, strlen(buf)));
|
||||||
msg.entry = entry;
|
continue;
|
||||||
msg.prefix = dest;
|
|
||||||
eigrp_fsm_event(&msg);
|
|
||||||
|
|
||||||
|
|
||||||
eigrp_IPv4_InternalTLV_free(tlv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct eigrp_fsm_action_message msg;
|
||||||
|
struct eigrp_nexthop_entry *entry =
|
||||||
|
eigrp_prefix_entry_lookup(dest->entries, nbr);
|
||||||
|
|
||||||
|
if (eigrp_update_prefix_apply(eigrp, ei,
|
||||||
|
EIGRP_FILTER_IN,
|
||||||
|
&dest_addr)) {
|
||||||
|
tlv->metric.delay = EIGRP_MAX_METRIC;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* End of filtering
|
||||||
|
*/
|
||||||
|
|
||||||
|
msg.packet_type = EIGRP_OPC_REPLY;
|
||||||
|
msg.eigrp = eigrp;
|
||||||
|
msg.data_type = EIGRP_INT;
|
||||||
|
msg.adv_router = nbr;
|
||||||
|
msg.metrics = tlv->metric;
|
||||||
|
msg.entry = entry;
|
||||||
|
msg.prefix = dest;
|
||||||
|
eigrp_fsm_event(&msg);
|
||||||
|
|
||||||
|
eigrp_IPv4_InternalTLV_free(tlv);
|
||||||
}
|
}
|
||||||
eigrp_hello_send_ack(nbr);
|
eigrp_hello_send_ack(nbr);
|
||||||
}
|
}
|
||||||
|
@ -499,6 +499,7 @@ struct eigrp_fsm_action_message {
|
|||||||
struct eigrp_prefix_entry *prefix;
|
struct eigrp_prefix_entry *prefix;
|
||||||
msg_data_t data_type; // internal or external tlv type
|
msg_data_t data_type; // internal or external tlv type
|
||||||
struct eigrp_metrics metrics;
|
struct eigrp_metrics metrics;
|
||||||
|
enum metric_change change;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _ZEBRA_EIGRP_STRUCTURES_H_ */
|
#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->eiflist);
|
||||||
list_delete_and_null(&eigrp->oi_write_q);
|
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_cleanup(eigrp->topology_table);
|
||||||
eigrp_topology_free(eigrp->topology_table);
|
eigrp_topology_free(eigrp->topology_table);
|
||||||
|
|
||||||
eigrp_nbr_delete(eigrp->neighbor_self);
|
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);
|
eigrp_delete(eigrp);
|
||||||
|
|
||||||
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
||||||
|
Loading…
Reference in New Issue
Block a user