mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-14 17:24:25 +00:00
commit
863f4bf143
@ -94,6 +94,11 @@
|
|||||||
#define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/
|
#define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/
|
||||||
|
|
||||||
#define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/
|
#define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/
|
||||||
|
enum metric_change {
|
||||||
|
METRIC_DECREASE,
|
||||||
|
METRIC_SAME,
|
||||||
|
METRIC_INCREASE
|
||||||
|
};
|
||||||
|
|
||||||
#define DEFAULT_ROUTE ZEBRA_ROUTE_MAX
|
#define DEFAULT_ROUTE ZEBRA_ROUTE_MAX
|
||||||
#define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE)
|
#define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE)
|
||||||
|
@ -185,6 +185,7 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
struct eigrp_neighbor_entry *entry = msg->entry;
|
struct eigrp_neighbor_entry *entry = msg->entry;
|
||||||
u_char actual_state = prefix->state;
|
u_char actual_state = prefix->state;
|
||||||
|
enum metric_change change;
|
||||||
|
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
entry = eigrp_neighbor_entry_new();
|
entry = eigrp_neighbor_entry_new();
|
||||||
@ -194,19 +195,18 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||||||
msg->entry = entry;
|
msg->entry = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dividing by actual state of prefix's FSM
|
/*
|
||||||
|
* Calculate resultant metrics and insert to correct position
|
||||||
|
* in entries list
|
||||||
|
*/
|
||||||
|
change = eigrp_topology_update_distance(msg);
|
||||||
|
|
||||||
switch (actual_state) {
|
switch (actual_state) {
|
||||||
case EIGRP_FSM_STATE_PASSIVE: {
|
case EIGRP_FSM_STATE_PASSIVE: {
|
||||||
// Calculate resultant metrics and insert to correct position in
|
|
||||||
// entries list
|
|
||||||
eigrp_topology_update_distance(msg);
|
|
||||||
|
|
||||||
struct eigrp_neighbor_entry *head =
|
struct eigrp_neighbor_entry *head =
|
||||||
(struct eigrp_neighbor_entry *)
|
(struct eigrp_neighbor_entry *)
|
||||||
entry->prefix->entries->head->data;
|
entry->prefix->entries->head->data;
|
||||||
// zlog_info ("flag: %d rdist: %u dist: %u pfdist: %u pdist:
|
|
||||||
// %u", head->flags, head->reported_distance, head->distance,
|
|
||||||
// prefix->fdistance, prefix->distance);
|
|
||||||
if (head->reported_distance < prefix->fdistance) {
|
if (head->reported_distance < prefix->fdistance) {
|
||||||
return EIGRP_FSM_KEEP_STATE;
|
return EIGRP_FSM_KEEP_STATE;
|
||||||
}
|
}
|
||||||
@ -215,34 +215,31 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||||||
* move to active state
|
* move to active state
|
||||||
* dependently if it was query from successor
|
* dependently if it was query from successor
|
||||||
*/
|
*/
|
||||||
else {
|
|
||||||
if (msg->packet_type == EIGRP_OPC_QUERY) {
|
if (msg->packet_type == EIGRP_OPC_QUERY) {
|
||||||
return EIGRP_FSM_EVENT_Q_FCN;
|
return EIGRP_FSM_EVENT_Q_FCN;
|
||||||
} else {
|
} else {
|
||||||
return EIGRP_FSM_EVENT_NQ_FCN;
|
return EIGRP_FSM_EVENT_NQ_FCN;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EIGRP_FSM_STATE_ACTIVE_0: {
|
case EIGRP_FSM_STATE_ACTIVE_0: {
|
||||||
eigrp_topology_update_distance(msg);
|
|
||||||
|
|
||||||
if (msg->packet_type == EIGRP_OPC_REPLY) {
|
if (msg->packet_type == EIGRP_OPC_REPLY) {
|
||||||
|
struct eigrp_neighbor_entry *head =
|
||||||
|
(struct eigrp_neighbor_entry *)
|
||||||
|
entry->prefix->entries->head->data;
|
||||||
|
|
||||||
listnode_delete(prefix->rij, entry->adv_router);
|
listnode_delete(prefix->rij, entry->adv_router);
|
||||||
if (prefix->rij->count) {
|
if (prefix->rij->count)
|
||||||
return EIGRP_FSM_KEEP_STATE;
|
return EIGRP_FSM_KEEP_STATE;
|
||||||
} else {
|
|
||||||
zlog_info("All reply received\n");
|
zlog_info("All reply received\n");
|
||||||
if (((struct eigrp_neighbor_entry *)
|
if (head->reported_distance
|
||||||
prefix->entries->head->data)
|
|
||||||
->reported_distance
|
|
||||||
< prefix->fdistance) {
|
< prefix->fdistance) {
|
||||||
return EIGRP_FSM_EVENT_LR_FCS;
|
return EIGRP_FSM_EVENT_LR_FCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EIGRP_FSM_EVENT_LR_FCN;
|
return EIGRP_FSM_EVENT_LR_FCN;
|
||||||
}
|
|
||||||
} else if (msg->packet_type == EIGRP_OPC_QUERY
|
} else if (msg->packet_type == EIGRP_OPC_QUERY
|
||||||
&& (entry->flags
|
&& (entry->flags
|
||||||
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
||||||
@ -254,15 +251,13 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EIGRP_FSM_STATE_ACTIVE_1: {
|
case EIGRP_FSM_STATE_ACTIVE_1: {
|
||||||
int change = eigrp_topology_update_distance(msg);
|
|
||||||
|
|
||||||
if (msg->packet_type == EIGRP_OPC_QUERY
|
if (msg->packet_type == EIGRP_OPC_QUERY
|
||||||
&& (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
&& (entry->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
||||||
return EIGRP_FSM_EVENT_QACT;
|
return EIGRP_FSM_EVENT_QACT;
|
||||||
} else if (msg->packet_type == EIGRP_OPC_REPLY) {
|
} else if (msg->packet_type == EIGRP_OPC_REPLY) {
|
||||||
listnode_delete(prefix->rij, entry->adv_router);
|
listnode_delete(prefix->rij, entry->adv_router);
|
||||||
|
|
||||||
if (change == 1
|
if (change == METRIC_INCREASE
|
||||||
&& (entry->flags
|
&& (entry->flags
|
||||||
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
||||||
return EIGRP_FSM_EVENT_DINC;
|
return EIGRP_FSM_EVENT_DINC;
|
||||||
@ -282,17 +277,17 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EIGRP_FSM_STATE_ACTIVE_2: {
|
case EIGRP_FSM_STATE_ACTIVE_2: {
|
||||||
eigrp_topology_update_distance(msg);
|
|
||||||
|
|
||||||
if (msg->packet_type == EIGRP_OPC_REPLY) {
|
if (msg->packet_type == EIGRP_OPC_REPLY) {
|
||||||
|
struct eigrp_neighbor_entry *head =
|
||||||
|
(struct eigrp_neighbor_entry *)
|
||||||
|
prefix->entries->head->data;
|
||||||
|
|
||||||
listnode_delete(prefix->rij, entry->adv_router);
|
listnode_delete(prefix->rij, entry->adv_router);
|
||||||
if (prefix->rij->count) {
|
if (prefix->rij->count) {
|
||||||
return EIGRP_FSM_KEEP_STATE;
|
return EIGRP_FSM_KEEP_STATE;
|
||||||
} else {
|
} else {
|
||||||
zlog_info("All reply received\n");
|
zlog_info("All reply received\n");
|
||||||
if (((struct eigrp_neighbor_entry *)
|
if (head->reported_distance
|
||||||
prefix->entries->head->data)
|
|
||||||
->reported_distance
|
|
||||||
< prefix->fdistance) {
|
< prefix->fdistance) {
|
||||||
return EIGRP_FSM_EVENT_LR_FCS;
|
return EIGRP_FSM_EVENT_LR_FCS;
|
||||||
}
|
}
|
||||||
@ -305,12 +300,10 @@ int eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EIGRP_FSM_STATE_ACTIVE_3: {
|
case EIGRP_FSM_STATE_ACTIVE_3: {
|
||||||
int change = eigrp_topology_update_distance(msg);
|
|
||||||
|
|
||||||
if (msg->packet_type == EIGRP_OPC_REPLY) {
|
if (msg->packet_type == EIGRP_OPC_REPLY) {
|
||||||
listnode_delete(prefix->rij, entry->adv_router);
|
listnode_delete(prefix->rij, entry->adv_router);
|
||||||
|
|
||||||
if (change == 1
|
if (change == METRIC_INCREASE
|
||||||
&& (entry->flags
|
&& (entry->flags
|
||||||
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
& EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)) {
|
||||||
return EIGRP_FSM_EVENT_DINC;
|
return EIGRP_FSM_EVENT_DINC;
|
||||||
|
@ -374,42 +374,42 @@ struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
|
|||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg)
|
enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg)
|
||||||
{
|
{
|
||||||
struct eigrp *eigrp = msg->eigrp;
|
struct eigrp *eigrp = msg->eigrp;
|
||||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||||
struct eigrp_neighbor_entry *entry = msg->entry;
|
struct eigrp_neighbor_entry *entry = msg->entry;
|
||||||
int change = 0;
|
enum metric_change change = METRIC_SAME;
|
||||||
assert(entry);
|
assert(entry);
|
||||||
|
|
||||||
struct TLV_IPv4_External_type *ext_data = NULL;
|
struct TLV_IPv4_External_type *ext_data = NULL;
|
||||||
struct TLV_IPv4_Internal_type *int_data = NULL;
|
struct TLV_IPv4_Internal_type *int_data = NULL;
|
||||||
if (msg->data_type == EIGRP_TLV_IPv4_INT) {
|
if (msg->data_type == EIGRP_TLV_IPv4_INT) {
|
||||||
|
u_int32_t new_reported_distance;
|
||||||
|
|
||||||
int_data = msg->data.ipv4_int_type;
|
int_data = msg->data.ipv4_int_type;
|
||||||
if (eigrp_metrics_is_same(int_data->metric,
|
if (eigrp_metrics_is_same(int_data->metric,
|
||||||
entry->reported_metric)) {
|
entry->reported_metric)) {
|
||||||
return 0; // No change
|
return change; // No change
|
||||||
}
|
}
|
||||||
change = entry->reported_distance
|
|
||||||
< eigrp_calculate_metrics(
|
new_reported_distance = eigrp_calculate_metrics(eigrp,
|
||||||
eigrp, int_data->metric)
|
int_data->metric);
|
||||||
? 1
|
|
||||||
: entry->reported_distance
|
if (entry->reported_distance < new_reported_distance)
|
||||||
> eigrp_calculate_metrics(
|
change = METRIC_INCREASE;
|
||||||
eigrp,
|
else
|
||||||
int_data->metric)
|
change = METRIC_DECREASE;
|
||||||
? 2
|
|
||||||
: 3; // Increase : Decrease : No
|
|
||||||
// change
|
|
||||||
entry->reported_metric = int_data->metric;
|
entry->reported_metric = int_data->metric;
|
||||||
entry->reported_distance =
|
entry->reported_distance = new_reported_distance;
|
||||||
eigrp_calculate_metrics(eigrp, int_data->metric);
|
eigrp_calculate_metrics(eigrp, int_data->metric);
|
||||||
entry->distance = eigrp_calculate_total_metrics(eigrp, entry);
|
entry->distance = eigrp_calculate_total_metrics(eigrp, entry);
|
||||||
} else {
|
} else {
|
||||||
ext_data = msg->data.ipv4_ext_data;
|
ext_data = msg->data.ipv4_ext_data;
|
||||||
if (eigrp_metrics_is_same(ext_data->metric,
|
if (eigrp_metrics_is_same(ext_data->metric,
|
||||||
entry->reported_metric))
|
entry->reported_metric))
|
||||||
return 0;
|
return change;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Move to correct position in list according to new distance
|
* Move to correct position in list according to new distance
|
||||||
|
@ -60,7 +60,7 @@ extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *,
|
|||||||
struct eigrp_neighbor *);
|
struct eigrp_neighbor *);
|
||||||
extern void eigrp_topology_update_all_node_flags(struct eigrp *);
|
extern void eigrp_topology_update_all_node_flags(struct eigrp *);
|
||||||
extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *);
|
extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *);
|
||||||
extern int eigrp_topology_update_distance(struct eigrp_fsm_action_message *);
|
extern enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *);
|
||||||
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
|
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
|
||||||
extern void eigrp_topology_neighbor_down(struct eigrp *,
|
extern void eigrp_topology_neighbor_down(struct eigrp *,
|
||||||
struct eigrp_neighbor *);
|
struct eigrp_neighbor *);
|
||||||
|
Loading…
Reference in New Issue
Block a user