diff options
author | Renato Westphal <renatowestphal@gmail.com> | 2017-04-27 19:55:23 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-05-13 19:08:00 +0200 |
commit | 63863c4797d0f41f5369b37285de78259b38742f (patch) | |
tree | 818d851f08e56571dc26a938a6c9f76fda46bf97 | |
parent | eigrpd: Some Basic Corrections (diff) | |
download | frr-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.h | 5 | ||||
-rw-r--r-- | eigrpd/eigrp_dump.c | 12 | ||||
-rw-r--r-- | eigrpd/eigrp_dump.h | 2 | ||||
-rw-r--r-- | eigrpd/eigrp_neighbor.c | 3 | ||||
-rw-r--r-- | eigrpd/eigrp_network.c | 4 | ||||
-rw-r--r-- | eigrpd/eigrp_topology.c | 10 | ||||
-rw-r--r-- | eigrpd/eigrp_vty.c | 149 | ||||
-rw-r--r-- | eigrpd/eigrpd.c | 26 | ||||
-rw-r--r-- | eigrpd/eigrpd.h | 1 |
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); |