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_HELLO_INTERVAL_DEFAULT 5
#define EIGRP_HOLD_INTERVAL_DEFAULT 15 #define EIGRP_HOLD_INTERVAL_DEFAULT 15
#define EIGRP_BANDWIDTH_DEFAULT 10000000 #define EIGRP_BANDWIDTH_DEFAULT 100000
#define EIGRP_DELAY_DEFAULT 1000 #define EIGRP_DELAY_DEFAULT 10
#define EIGRP_RELIABILITY_DEFAULT 255 #define EIGRP_RELIABILITY_DEFAULT 255
#define EIGRP_LOAD_DEFAULT 1 #define EIGRP_LOAD_DEFAULT 1
@ -103,6 +103,7 @@
#define INTERFACE_DOWN_BY_ZEBRA 1 #define INTERFACE_DOWN_BY_ZEBRA 1
#define INTERFACE_DOWN_BY_VTY 2 #define INTERFACE_DOWN_BY_VTY 2
#define INTERFACE_DOWN_BY_FINAL 3
#define EIGRP_HELLO_NORMAL 0x00 #define EIGRP_HELLO_NORMAL 0x00
#define EIGRP_HELLO_GRACEFUL_SHUTDOWN 0x01 #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 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) if (te->adv_router == eigrp->neighbor_self)
vty_out (vty, "%-7s%s, %s%s", " ", "via Connected", vty_out (vty, "%-7s%s, %s%s", " ", "via Connected",
eigrp_if_name_string (te->ei), VTY_NEWLINE); 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 *); struct eigrp_interface *);
extern void show_ip_eigrp_neighbor_sub (struct vty *, struct eigrp_neighbor *, int); 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_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); extern void eigrp_debug_init (void);

View File

@ -187,7 +187,8 @@ void
eigrp_nbr_delete (struct eigrp_neighbor *nbr) eigrp_nbr_delete (struct eigrp_neighbor *nbr)
{ {
eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); 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. */ /* Cancel all events. *//* Thread lookup cost would be negligible. */
thread_cancel_event (master, nbr); thread_cancel_event (master, nbr);

View File

@ -425,11 +425,11 @@ eigrp_calculate_total_metrics(struct eigrp *eigrp,
{ {
entry->total_metric = entry->reported_metric; entry->total_metric = entry->reported_metric;
uint64_t temp_delay = (uint64_t) entry->total_metric.delay 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 = entry->total_metric.delay =
temp_delay > EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC : (u_int32_t) temp_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 =
entry->total_metric.bandwith > bw ? bw : 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 (); struct list *l = list_new ();
listnode_add (l, entry);
if (listnode_lookup (node->entries, entry) == NULL) if (listnode_lookup (node->entries, entry) == NULL)
{ {
listnode_add_sort (node->entries, entry); listnode_add_sort (node->entries, entry);
entry->prefix = node; 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); list_delete (l);
} }
@ -250,10 +252,9 @@ eigrp_prefix_entry_delete(struct list *topology,
list_free (node->entries); list_free (node->entries);
list_free (node->rij); list_free (node->rij);
listnode_delete (topology, node); listnode_delete (topology, node);
eigrp_zebra_route_delete (node->destination_ipv4);
XFREE (MTYPE_EIGRP_PREFIX_ENTRY,node); 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) if (listnode_lookup(node->entries, entry) != NULL)
{ {
listnode_delete(node->entries, entry); listnode_delete(node->entries, entry);
eigrp_zebra_route_delete (node->destination_ipv4);
XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY,entry); XFREE(MTYPE_EIGRP_NEIGHBOR_ENTRY,entry);
} }
} }

View File

@ -127,9 +127,33 @@ config_write_interfaces (struct vty *vty, struct eigrp *eigrp)
static int static int
eigrp_write_interface (struct vty *vty) 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; 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; return CMD_SUCCESS;
} }
@ -416,43 +450,7 @@ DEFUN (no_eigrp_neighbor,
DEFUN (show_ip_eigrp_topology, DEFUN (show_ip_eigrp_topology,
show_ip_eigrp_topology_cmd, show_ip_eigrp_topology_cmd,
"show ip eigrp topology", "show ip eigrp topology [all-links]",
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_STR SHOW_STR
IP_STR IP_STR
"IP-EIGRP show commands\n" "IP-EIGRP show commands\n"
@ -460,9 +458,10 @@ DEFUN (show_ip_eigrp_topology_all_links,
"Show all links in topology table\n") "Show all links in topology table\n")
{ {
struct eigrp *eigrp; struct eigrp *eigrp;
struct listnode *node, *nnode, *node2, *nnode2; struct listnode *node, *node2;
struct eigrp_prefix_entry *tn; struct eigrp_prefix_entry *tn;
struct eigrp_neighbor_entry *te; struct eigrp_neighbor_entry *te;
int first;
eigrp = eigrp_lookup (); eigrp = eigrp_lookup ();
if (eigrp == NULL) if (eigrp == NULL)
@ -473,12 +472,18 @@ DEFUN (show_ip_eigrp_topology_all_links,
show_ip_eigrp_topology_header (vty, eigrp); 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); first = 1;
for (ALL_LIST_ELEMENTS (tn->entries, node2, nnode2, te)) 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); delay = atoi (argv[1]->arg);
IF_DEF_PARAMS (ifp)->delay = delay; IF_DEF_PARAMS (ifp)->delay = delay;
eigrp_if_reset (ifp);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -634,6 +640,7 @@ DEFUN (no_eigrp_if_delay,
} }
IF_DEF_PARAMS (ifp)->delay = EIGRP_DELAY_DEFAULT; IF_DEF_PARAMS (ifp)->delay = EIGRP_DELAY_DEFAULT;
eigrp_if_reset (ifp);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -658,23 +665,20 @@ DEFUN (eigrp_if_bandwidth,
bandwidth = atoi (argv[1]->arg); bandwidth = atoi (argv[1]->arg);
IF_DEF_PARAMS (ifp)->bandwidth = bandwidth; IF_DEF_PARAMS (ifp)->bandwidth = bandwidth;
eigrp_if_reset (ifp);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (no_eigrp_if_bandwidth, DEFUN (no_eigrp_if_bandwidth,
no_eigrp_if_bandwidth_cmd, no_eigrp_if_bandwidth_cmd,
"bandwidth (1-10000000)", "no bandwidth [(1-10000000)]",
NO_STR
"Set bandwidth informational parameter\n" "Set bandwidth informational parameter\n"
"Bandwidth in kilobits\n") "Bandwidth in kilobits\n")
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
u_int32_t bandwidth;
struct eigrp *eigrp; 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 (); eigrp = eigrp_lookup ();
if (eigrp == NULL) if (eigrp == NULL)
@ -683,25 +687,8 @@ DEFUN (no_eigrp_if_bandwidth,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
bandwidth = atoi (argv[1]->arg); IF_DEF_PARAMS (ifp)->bandwidth = EIGRP_BANDWIDTH_DEFAULT;
eigrp_if_reset (ifp);
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: */
}
}
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -734,7 +721,7 @@ DEFUN (eigrp_if_ip_hellointerval,
DEFUN (no_eigrp_if_ip_hellointerval, DEFUN (no_eigrp_if_ip_hellointerval,
no_eigrp_if_ip_hellointerval_cmd, no_eigrp_if_ip_hellointerval_cmd,
"no ip hello-interval eigrp (1-65535)", "no ip hello-interval eigrp [(1-65535)]",
NO_STR NO_STR
"Interface Internet Protocol config commands\n" "Interface Internet Protocol config commands\n"
"Configures EIGRP hello interval\n" "Configures EIGRP hello interval\n"
@ -743,6 +730,8 @@ DEFUN (no_eigrp_if_ip_hellointerval,
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
struct eigrp *eigrp; struct eigrp *eigrp;
struct eigrp_interface *ei;
struct listnode *node, *nnode;
eigrp = eigrp_lookup (); eigrp = eigrp_lookup ();
if (eigrp == NULL) if (eigrp == NULL)
@ -753,6 +742,16 @@ DEFUN (no_eigrp_if_ip_hellointerval,
IF_DEF_PARAMS (ifp)->v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; 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; return CMD_SUCCESS;
} }
@ -760,7 +759,7 @@ DEFUN (eigrp_if_ip_holdinterval,
eigrp_if_ip_holdinterval_cmd, eigrp_if_ip_holdinterval_cmd,
"ip hold-time eigrp (1-65535)", "ip hold-time eigrp (1-65535)",
"Interface Internet Protocol config commands\n" "Interface Internet Protocol config commands\n"
"Configures EIGRP hello interval\n" "Configures EIGRP IPv4 hold time\n"
"Enhanced Interior Gateway Routing Protocol (EIGRP)\n" "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
"Seconds before neighbor is considered down\n") "Seconds before neighbor is considered down\n")
{ {
@ -837,8 +836,6 @@ DEFUN (no_eigrp_ip_summary_address,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (no_eigrp_if_ip_holdinterval, DEFUN (no_eigrp_if_ip_holdinterval,
no_eigrp_if_ip_holdinterval_cmd, no_eigrp_if_ip_holdinterval_cmd,
"no ip hold-time eigrp", "no ip hold-time eigrp",
@ -1014,7 +1011,7 @@ DEFUN (no_eigrp_authentication_keychain,
DEFUN (eigrp_redistribute_source_metric, DEFUN (eigrp_redistribute_source_metric,
eigrp_redistribute_source_metric_cmd, eigrp_redistribute_source_metric_cmd,
"redistribute " FRR_REDIST_STR_EIGRPD "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 REDIST_STR
FRR_REDIST_HELP_STR_EIGRPD FRR_REDIST_HELP_STR_EIGRPD
"Metric for redistributed routes\n" "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_cmd);
install_element (VIEW_NODE, &show_ip_eigrp_topology_all_links_cmd);
install_element (VIEW_NODE, &show_ip_eigrp_topology_detail_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; struct eigrp_master *eigrp_om;
static void eigrp_finish_final(struct eigrp *);
static void eigrp_delete(struct eigrp *); static void eigrp_delete(struct eigrp *);
static struct eigrp *eigrp_new(const char *); static struct eigrp *eigrp_new(const char *);
static void eigrp_add(struct eigrp *); static void eigrp_add(struct eigrp *);
@ -262,26 +261,39 @@ eigrp_terminate (void)
void void
eigrp_finish (struct eigrp *eigrp) eigrp_finish (struct eigrp *eigrp)
{ {
eigrp_finish_final(eigrp); eigrp_finish_final(eigrp);
/* eigrp being shut-down? If so, was this the last eigrp instance? */ /* eigrp being shut-down? If so, was this the last eigrp instance? */
if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN) if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN)
&& (listcount(eigrp_om->eigrp) == 0)) && (listcount(eigrp_om->eigrp) == 0))
exit(0); {
if (zclient)
zclient_free (zclient);
exit(0);
}
return; return;
} }
/* Final cleanup of eigrp instance */ /* Final cleanup of eigrp instance */
static void void
eigrp_finish_final (struct eigrp *eigrp) 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) THREAD_OFF (eigrp->t_write);
zclient_free(zclient); THREAD_OFF (eigrp->t_read);
close (eigrp->fd);
list_delete(eigrp->eiflist); list_delete(eigrp->eiflist);
list_delete(eigrp->oi_write_q); list_delete(eigrp->oi_write_q);

View File

@ -46,6 +46,7 @@ extern struct eigrp_master *eigrp_om;
/* Prototypes */ /* Prototypes */
extern void eigrp_master_init (void); extern void eigrp_master_init (void);
extern void eigrp_terminate (void); extern void eigrp_terminate (void);
extern void eigrp_finish_final (struct eigrp *);
extern void eigrp_finish (struct eigrp *); extern void eigrp_finish (struct eigrp *);
extern struct eigrp *eigrp_get (const char *); extern struct eigrp *eigrp_get (const char *);
extern struct eigrp *eigrp_lookup (void); extern struct eigrp *eigrp_lookup (void);