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:
Renato Westphal 2017-04-27 14:55:23 -03:00 committed by Donald Sharp
parent 7622065349
commit 63863c4797
9 changed files with 117 additions and 95 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);