mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 20:55:25 +00:00
eigrpd: Diverse Fixes
* Correct the metric calculation as well as the default metrics; * Do not show invalid routes in the "show ip eigrp topology". * Add support to VRFs; * When downloading a neighbor remove the related routes; * Fix bugs in the parser of packages they were creating Invalid default routes; * Add and remove routes in the zebra; * Add command "on router eigrp AS"; * Make "delay" and "bandwitch" commands work as well as Display them in running config; * Add "no" version of several commands; * Fix a serious momory leaks; * Fix segfault when there is no 'successor' route to a Given prefix; * Other minor corrections; Signed-off-by: Renato Westphal <renatowestphal@gmail.com> Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
7622065349
commit
63863c4797
@ -89,8 +89,8 @@
|
||||
|
||||
#define EIGRP_HELLO_INTERVAL_DEFAULT 5
|
||||
#define EIGRP_HOLD_INTERVAL_DEFAULT 15
|
||||
#define EIGRP_BANDWIDTH_DEFAULT 10000000
|
||||
#define EIGRP_DELAY_DEFAULT 1000
|
||||
#define EIGRP_BANDWIDTH_DEFAULT 100000
|
||||
#define EIGRP_DELAY_DEFAULT 10
|
||||
#define EIGRP_RELIABILITY_DEFAULT 255
|
||||
#define EIGRP_LOAD_DEFAULT 1
|
||||
|
||||
@ -103,6 +103,7 @@
|
||||
|
||||
#define INTERFACE_DOWN_BY_ZEBRA 1
|
||||
#define INTERFACE_DOWN_BY_VTY 2
|
||||
#define INTERFACE_DOWN_BY_FINAL 3
|
||||
|
||||
#define EIGRP_HELLO_NORMAL 0x00
|
||||
#define EIGRP_HELLO_GRACEFUL_SHUTDOWN 0x01
|
||||
|
@ -317,8 +317,18 @@ show_ip_eigrp_prefix_entry (struct vty *vty, struct eigrp_prefix_entry *tn)
|
||||
}
|
||||
|
||||
void
|
||||
show_ip_eigrp_neighbor_entry (struct vty *vty, struct eigrp *eigrp, struct eigrp_neighbor_entry *te)
|
||||
show_ip_eigrp_neighbor_entry (struct vty *vty, struct eigrp *eigrp,
|
||||
struct eigrp_neighbor_entry *te, int *first)
|
||||
{
|
||||
if (te->reported_distance == EIGRP_MAX_METRIC)
|
||||
return;
|
||||
|
||||
if (*first)
|
||||
{
|
||||
show_ip_eigrp_prefix_entry (vty, te->prefix);
|
||||
*first = 0;
|
||||
}
|
||||
|
||||
if (te->adv_router == eigrp->neighbor_self)
|
||||
vty_out (vty, "%-7s%s, %s%s", " ", "via Connected",
|
||||
eigrp_if_name_string (te->ei), VTY_NEWLINE);
|
||||
|
@ -158,7 +158,7 @@ extern void show_ip_eigrp_interface_sub (struct vty *, struct eigrp *,
|
||||
struct eigrp_interface *);
|
||||
extern void show_ip_eigrp_neighbor_sub (struct vty *, struct eigrp_neighbor *, int);
|
||||
extern void show_ip_eigrp_prefix_entry (struct vty *, struct eigrp_prefix_entry *);
|
||||
extern void show_ip_eigrp_neighbor_entry (struct vty *, struct eigrp *, struct eigrp_neighbor_entry *);
|
||||
extern void show_ip_eigrp_neighbor_entry (struct vty *, struct eigrp *, struct eigrp_neighbor_entry *, int *);
|
||||
|
||||
extern void eigrp_debug_init (void);
|
||||
|
||||
|
@ -187,7 +187,8 @@ void
|
||||
eigrp_nbr_delete (struct eigrp_neighbor *nbr)
|
||||
{
|
||||
eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
|
||||
eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr);
|
||||
if (nbr->ei)
|
||||
eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr);
|
||||
|
||||
/* Cancel all events. *//* Thread lookup cost would be negligible. */
|
||||
thread_cancel_event (master, nbr);
|
||||
|
@ -425,11 +425,11 @@ eigrp_calculate_total_metrics(struct eigrp *eigrp,
|
||||
{
|
||||
entry->total_metric = entry->reported_metric;
|
||||
uint64_t temp_delay = (uint64_t) entry->total_metric.delay
|
||||
+ (uint64_t) EIGRP_IF_PARAM (entry->ei, delay);
|
||||
+ (uint64_t) eigrp_delay_to_scaled (EIGRP_IF_PARAM (entry->ei, delay));
|
||||
entry->total_metric.delay =
|
||||
temp_delay > EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC : (u_int32_t) temp_delay;
|
||||
|
||||
u_int32_t bw = EIGRP_IF_PARAM (entry->ei,bandwidth);
|
||||
u_int32_t bw = eigrp_bandwidth_to_scaled (EIGRP_IF_PARAM (entry->ei,bandwidth));
|
||||
entry->total_metric.bandwith =
|
||||
entry->total_metric.bandwith > bw ? bw : entry->total_metric.bandwith;
|
||||
|
||||
|
@ -218,14 +218,16 @@ eigrp_neighbor_entry_add(struct eigrp_prefix_entry *node,
|
||||
{
|
||||
struct list *l = list_new ();
|
||||
|
||||
listnode_add (l, entry);
|
||||
|
||||
if (listnode_lookup (node->entries, entry) == NULL)
|
||||
{
|
||||
listnode_add_sort (node->entries, entry);
|
||||
entry->prefix = node;
|
||||
|
||||
eigrp_zebra_route_add (node->destination_ipv4, l);
|
||||
}
|
||||
|
||||
listnode_add (l, entry);
|
||||
eigrp_zebra_route_add (node->destination_ipv4, l);
|
||||
list_delete (l);
|
||||
}
|
||||
|
||||
@ -250,10 +252,9 @@ eigrp_prefix_entry_delete(struct list *topology,
|
||||
list_free (node->entries);
|
||||
list_free (node->rij);
|
||||
listnode_delete (topology, node);
|
||||
eigrp_zebra_route_delete (node->destination_ipv4);
|
||||
XFREE (MTYPE_EIGRP_PREFIX_ENTRY,node);
|
||||
}
|
||||
|
||||
eigrp_zebra_route_delete (node->destination_ipv4);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -266,6 +267,7 @@ eigrp_neighbor_entry_delete(struct eigrp_prefix_entry *node,
|
||||
if (listnode_lookup(node->entries, entry) != NULL)
|
||||
{
|
||||
listnode_delete(node->entries, entry);
|
||||
eigrp_zebra_route_delete (node->destination_ipv4);
|
||||
XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY,entry);
|
||||
}
|
||||
}
|
||||
|
@ -127,9 +127,33 @@ config_write_interfaces (struct vty *vty, struct eigrp *eigrp)
|
||||
static int
|
||||
eigrp_write_interface (struct vty *vty)
|
||||
{
|
||||
int write=0;
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
|
||||
return write;
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT), node, ifp)) {
|
||||
vty_out (vty, "interface %s%s", ifp->name,
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (ifp->desc)
|
||||
vty_out (vty, " description %s%s", ifp->desc,
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (IF_DEF_PARAMS (ifp)->bandwidth != EIGRP_BANDWIDTH_DEFAULT)
|
||||
vty_out (vty, " bandwidth %u%s", IF_DEF_PARAMS (ifp)->bandwidth,
|
||||
VTY_NEWLINE);
|
||||
if (IF_DEF_PARAMS (ifp)->delay != EIGRP_DELAY_DEFAULT)
|
||||
vty_out (vty, " delay %u%s", IF_DEF_PARAMS (ifp)->delay, VTY_NEWLINE);
|
||||
if (IF_DEF_PARAMS (ifp)->v_hello != EIGRP_HELLO_INTERVAL_DEFAULT)
|
||||
vty_out (vty, " ip hello-interval eigrp %u%s",
|
||||
IF_DEF_PARAMS (ifp)->v_hello, VTY_NEWLINE);
|
||||
if (IF_DEF_PARAMS (ifp)->v_wait != EIGRP_HOLD_INTERVAL_DEFAULT)
|
||||
vty_out (vty, " ip hold-time eigrp %u%s",
|
||||
IF_DEF_PARAMS (ifp)->v_wait, VTY_NEWLINE);
|
||||
|
||||
vty_out (vty, "!%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,7 +230,17 @@ DEFUN (no_router_eigrp,
|
||||
{
|
||||
vty->node = CONFIG_NODE;
|
||||
|
||||
/*TODO: */
|
||||
struct eigrp *eigrp;
|
||||
|
||||
eigrp = eigrp_lookup ();
|
||||
if (eigrp->AS != atoi (argv[3]->arg))
|
||||
{
|
||||
vty_out (vty, "%% Attempting to deconfigure non-existent AS%s",
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
eigrp_finish_final (eigrp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -416,43 +450,7 @@ DEFUN (no_eigrp_neighbor,
|
||||
|
||||
DEFUN (show_ip_eigrp_topology,
|
||||
show_ip_eigrp_topology_cmd,
|
||||
"show ip eigrp topology",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP-EIGRP show commands\n"
|
||||
"IP-EIGRP topology\n")
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
struct eigrp_prefix_entry *tn;
|
||||
struct eigrp_neighbor_entry *te;
|
||||
|
||||
eigrp = eigrp_lookup ();
|
||||
if (eigrp == NULL)
|
||||
{
|
||||
vty_out (vty, " EIGRP Routing Process not enabled%s", VTY_NEWLINE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
show_ip_eigrp_topology_header (vty, eigrp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (eigrp->topology_table, node, nnode, tn))
|
||||
{
|
||||
show_ip_eigrp_prefix_entry (vty,tn);
|
||||
for (ALL_LIST_ELEMENTS (tn->entries, node2, nnode2, te))
|
||||
{
|
||||
if (((te->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)||
|
||||
((te->flags & EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG))
|
||||
show_ip_eigrp_neighbor_entry (vty, eigrp, te);
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ip_eigrp_topology_all_links,
|
||||
show_ip_eigrp_topology_all_links_cmd,
|
||||
"show ip eigrp topology all-links",
|
||||
"show ip eigrp topology [all-links]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP-EIGRP show commands\n"
|
||||
@ -460,9 +458,10 @@ DEFUN (show_ip_eigrp_topology_all_links,
|
||||
"Show all links in topology table\n")
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
struct listnode *node, *node2;
|
||||
struct eigrp_prefix_entry *tn;
|
||||
struct eigrp_neighbor_entry *te;
|
||||
int first;
|
||||
|
||||
eigrp = eigrp_lookup ();
|
||||
if (eigrp == NULL)
|
||||
@ -473,12 +472,18 @@ DEFUN (show_ip_eigrp_topology_all_links,
|
||||
|
||||
show_ip_eigrp_topology_header (vty, eigrp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (eigrp->topology_table, node, nnode, tn))
|
||||
for (ALL_LIST_ELEMENTS_RO (eigrp->topology_table, node, tn))
|
||||
{
|
||||
show_ip_eigrp_prefix_entry (vty,tn);
|
||||
for (ALL_LIST_ELEMENTS (tn->entries, node2, nnode2, te))
|
||||
first = 1;
|
||||
for (ALL_LIST_ELEMENTS_RO (tn->entries, node2, te))
|
||||
{
|
||||
show_ip_eigrp_neighbor_entry (vty, eigrp, te);
|
||||
if (argc == 5 ||
|
||||
(((te->flags & EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG)||
|
||||
((te->flags & EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG) == EIGRP_NEIGHBOR_ENTRY_FSUCCESSOR_FLAG)))
|
||||
{
|
||||
show_ip_eigrp_neighbor_entry (vty, eigrp, te, &first);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,6 +616,7 @@ DEFUN (eigrp_if_delay,
|
||||
delay = atoi (argv[1]->arg);
|
||||
|
||||
IF_DEF_PARAMS (ifp)->delay = delay;
|
||||
eigrp_if_reset (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -634,6 +640,7 @@ DEFUN (no_eigrp_if_delay,
|
||||
}
|
||||
|
||||
IF_DEF_PARAMS (ifp)->delay = EIGRP_DELAY_DEFAULT;
|
||||
eigrp_if_reset (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -658,23 +665,20 @@ DEFUN (eigrp_if_bandwidth,
|
||||
bandwidth = atoi (argv[1]->arg);
|
||||
|
||||
IF_DEF_PARAMS (ifp)->bandwidth = bandwidth;
|
||||
eigrp_if_reset (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_eigrp_if_bandwidth,
|
||||
no_eigrp_if_bandwidth_cmd,
|
||||
"bandwidth (1-10000000)",
|
||||
"no bandwidth [(1-10000000)]",
|
||||
NO_STR
|
||||
"Set bandwidth informational parameter\n"
|
||||
"Bandwidth in kilobits\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||
u_int32_t bandwidth;
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
struct eigrp_prefix_entry *pe;
|
||||
struct eigrp_neighbor_entry *ne;
|
||||
|
||||
eigrp = eigrp_lookup ();
|
||||
if (eigrp == NULL)
|
||||
@ -683,25 +687,8 @@ DEFUN (no_eigrp_if_bandwidth,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
bandwidth = atoi (argv[1]->arg);
|
||||
|
||||
IF_DEF_PARAMS (ifp)->bandwidth = bandwidth;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
|
||||
{
|
||||
if (ei->ifp == ifp)
|
||||
break;
|
||||
}
|
||||
|
||||
for (ALL_LIST_ELEMENTS (eigrp->topology_table, node, nnode, pe))
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (pe->entries, node2, nnode2, ne))
|
||||
{
|
||||
if (ne->ei == ei)
|
||||
break;
|
||||
/*TODO: */
|
||||
}
|
||||
}
|
||||
IF_DEF_PARAMS (ifp)->bandwidth = EIGRP_BANDWIDTH_DEFAULT;
|
||||
eigrp_if_reset (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -734,7 +721,7 @@ DEFUN (eigrp_if_ip_hellointerval,
|
||||
|
||||
DEFUN (no_eigrp_if_ip_hellointerval,
|
||||
no_eigrp_if_ip_hellointerval_cmd,
|
||||
"no ip hello-interval eigrp (1-65535)",
|
||||
"no ip hello-interval eigrp [(1-65535)]",
|
||||
NO_STR
|
||||
"Interface Internet Protocol config commands\n"
|
||||
"Configures EIGRP hello interval\n"
|
||||
@ -743,6 +730,8 @@ DEFUN (no_eigrp_if_ip_hellointerval,
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
eigrp = eigrp_lookup ();
|
||||
if (eigrp == NULL)
|
||||
@ -753,6 +742,16 @@ DEFUN (no_eigrp_if_ip_hellointerval,
|
||||
|
||||
IF_DEF_PARAMS (ifp)->v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
|
||||
{
|
||||
if (ei->ifp == ifp)
|
||||
{
|
||||
THREAD_TIMER_OFF (ei->t_hello);
|
||||
thread_add_timer (master, eigrp_hello_timer, ei, 1, &ei->t_hello);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -760,7 +759,7 @@ DEFUN (eigrp_if_ip_holdinterval,
|
||||
eigrp_if_ip_holdinterval_cmd,
|
||||
"ip hold-time eigrp (1-65535)",
|
||||
"Interface Internet Protocol config commands\n"
|
||||
"Configures EIGRP hello interval\n"
|
||||
"Configures EIGRP IPv4 hold time\n"
|
||||
"Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
|
||||
"Seconds before neighbor is considered down\n")
|
||||
{
|
||||
@ -837,8 +836,6 @@ DEFUN (no_eigrp_ip_summary_address,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFUN (no_eigrp_if_ip_holdinterval,
|
||||
no_eigrp_if_ip_holdinterval_cmd,
|
||||
"no ip hold-time eigrp",
|
||||
@ -1014,7 +1011,7 @@ DEFUN (no_eigrp_authentication_keychain,
|
||||
DEFUN (eigrp_redistribute_source_metric,
|
||||
eigrp_redistribute_source_metric_cmd,
|
||||
"redistribute " FRR_REDIST_STR_EIGRPD
|
||||
" metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)",
|
||||
" [metric (1-4294967295) (0-4294967295) (0-255) (1-255) (1-65535)]",
|
||||
REDIST_STR
|
||||
FRR_REDIST_HELP_STR_EIGRPD
|
||||
"Metric for redistributed routes\n"
|
||||
@ -1482,8 +1479,6 @@ eigrp_vty_show_init (void)
|
||||
|
||||
install_element (VIEW_NODE, &show_ip_eigrp_topology_cmd);
|
||||
|
||||
install_element (VIEW_NODE, &show_ip_eigrp_topology_all_links_cmd);
|
||||
|
||||
install_element (VIEW_NODE, &show_ip_eigrp_topology_detail_cmd);
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ static struct eigrp_master eigrp_master;
|
||||
|
||||
struct eigrp_master *eigrp_om;
|
||||
|
||||
static void eigrp_finish_final(struct eigrp *);
|
||||
static void eigrp_delete(struct eigrp *);
|
||||
static struct eigrp *eigrp_new(const char *);
|
||||
static void eigrp_add(struct eigrp *);
|
||||
@ -262,26 +261,39 @@ eigrp_terminate (void)
|
||||
void
|
||||
eigrp_finish (struct eigrp *eigrp)
|
||||
{
|
||||
|
||||
eigrp_finish_final(eigrp);
|
||||
|
||||
/* eigrp being shut-down? If so, was this the last eigrp instance? */
|
||||
if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN)
|
||||
&& (listcount(eigrp_om->eigrp) == 0))
|
||||
exit(0);
|
||||
{
|
||||
if (zclient)
|
||||
zclient_free (zclient);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Final cleanup of eigrp instance */
|
||||
static void
|
||||
void
|
||||
eigrp_finish_final (struct eigrp *eigrp)
|
||||
{
|
||||
struct eigrp_interface *ei;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
|
||||
close(eigrp->fd);
|
||||
for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei))
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (ei->nbrs, node2, nnode2, nbr))
|
||||
eigrp_nbr_delete (nbr);
|
||||
eigrp_if_free (ei, INTERFACE_DOWN_BY_FINAL);
|
||||
}
|
||||
|
||||
if (zclient)
|
||||
zclient_free(zclient);
|
||||
THREAD_OFF (eigrp->t_write);
|
||||
THREAD_OFF (eigrp->t_read);
|
||||
close (eigrp->fd);
|
||||
|
||||
list_delete(eigrp->eiflist);
|
||||
list_delete(eigrp->oi_write_q);
|
||||
|
@ -46,6 +46,7 @@ extern struct eigrp_master *eigrp_om;
|
||||
/* Prototypes */
|
||||
extern void eigrp_master_init (void);
|
||||
extern void eigrp_terminate (void);
|
||||
extern void eigrp_finish_final (struct eigrp *);
|
||||
extern void eigrp_finish (struct eigrp *);
|
||||
extern struct eigrp *eigrp_get (const char *);
|
||||
extern struct eigrp *eigrp_lookup (void);
|
||||
|
Loading…
Reference in New Issue
Block a user