summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renatowestphal@gmail.com>2017-04-27 19:55:23 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-05-13 19:08:00 +0200
commit63863c4797d0f41f5369b37285de78259b38742f (patch)
tree818d851f08e56571dc26a938a6c9f76fda46bf97
parenteigrpd: Some Basic Corrections (diff)
downloadfrr-63863c4797d0f41f5369b37285de78259b38742f.tar.xz
frr-63863c4797d0f41f5369b37285de78259b38742f.zip
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>
-rw-r--r--eigrpd/eigrp_const.h5
-rw-r--r--eigrpd/eigrp_dump.c12
-rw-r--r--eigrpd/eigrp_dump.h2
-rw-r--r--eigrpd/eigrp_neighbor.c3
-rw-r--r--eigrpd/eigrp_network.c4
-rw-r--r--eigrpd/eigrp_topology.c10
-rw-r--r--eigrpd/eigrp_vty.c149
-rw-r--r--eigrpd/eigrpd.c26
-rw-r--r--eigrpd/eigrpd.h1
9 files changed, 117 insertions, 95 deletions
diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h
index 9397717be..13eba207e 100644
--- a/eigrpd/eigrp_const.h
+++ b/eigrpd/eigrp_const.h
@@ -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
diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c
index 21bef48ec..97ef37d8a 100644
--- a/eigrpd/eigrp_dump.c
+++ b/eigrpd/eigrp_dump.c
@@ -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);
diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h
index 54e6338a3..bbc0d306d 100644
--- a/eigrpd/eigrp_dump.h
+++ b/eigrpd/eigrp_dump.h
@@ -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);
diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c
index 003d3a7a7..dfea5258f 100644
--- a/eigrpd/eigrp_neighbor.c
+++ b/eigrpd/eigrp_neighbor.c
@@ -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);
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
index dff7f2727..b8f21f1e8 100644
--- a/eigrpd/eigrp_network.c
+++ b/eigrpd/eigrp_network.c
@@ -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;
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index 4fcbef7f1..cab56c19d 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -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);
}
}
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
index cc346405a..c3413992c 100644
--- a/eigrpd/eigrp_vty.c
+++ b/eigrpd/eigrp_vty.c
@@ -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;
+
+ 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 write;
+ 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);
}
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
index c6af8986b..6c0033481 100644
--- a/eigrpd/eigrpd.c
+++ b/eigrpd/eigrpd.c
@@ -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);
diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h
index 61d4ba752..901d413c0 100644
--- a/eigrpd/eigrpd.h
+++ b/eigrpd/eigrpd.h
@@ -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);