From 0f9bc496479098d88750823e054ad6c372e7aa9f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 3 Feb 2019 09:56:20 -0500 Subject: [PATCH 1/5] eigrpd: Modify code to pass down metric to zebra Modify EIGRP code to pass its used metric down to zebra. Additionally update topotests to pass with these changes. Fixes: #3703 Signed-off-by: Donald Sharp --- eigrpd/eigrp_topology.c | 5 +++-- eigrpd/eigrp_zebra.c | 5 ++++- eigrpd/eigrp_zebra.h | 3 ++- tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref | 8 ++++---- tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref | 8 ++++---- tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref | 8 ++++---- tests/topotests/eigrp-topo1/test_eigrp_topo1.py | 1 - 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 2d0ebf1bc5..23f5a705eb 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -161,7 +161,7 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node, listnode_add_sort(node->entries, entry); entry->prefix = node; - eigrp_zebra_route_add(node->destination, l); + eigrp_zebra_route_add(node->destination, l, node->fdistance); } list_delete(&l); @@ -477,7 +477,8 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths); if (successors) { - eigrp_zebra_route_add(prefix->destination, successors); + eigrp_zebra_route_add(prefix->destination, successors, + prefix->fdistance); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index a810e01468..09d876afaa 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -353,7 +353,8 @@ static struct interface *zebra_interface_if_lookup(struct stream *s) return if_lookup_by_name(ifname_tmp, VRF_DEFAULT); } -void eigrp_zebra_route_add(struct prefix *p, struct list *successors) +void eigrp_zebra_route_add(struct prefix *p, struct list *successors, + uint32_t distance) { struct zapi_route api; struct zapi_nexthop *api_nh; @@ -368,9 +369,11 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors) api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; + api.metric = distance; memcpy(&api.prefix, p, sizeof(*p)); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO(successors, node, te)) { diff --git a/eigrpd/eigrp_zebra.h b/eigrpd/eigrp_zebra.h index 1c418dddef..86b337cfe6 100644 --- a/eigrpd/eigrp_zebra.h +++ b/eigrpd/eigrp_zebra.h @@ -33,7 +33,8 @@ extern void eigrp_zebra_init(void); -extern void eigrp_zebra_route_add(struct prefix *, struct list *); +extern void eigrp_zebra_route_add(struct prefix *, struct list *, + uint32_t distance); extern void eigrp_zebra_route_delete(struct prefix *); extern int eigrp_redistribute_set(struct eigrp *, int, struct eigrp_metrics); extern int eigrp_redistribute_unset(struct eigrp *, int); diff --git a/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref b/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref index 36dd5da597..26fa7ca415 100644 --- a/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref +++ b/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref @@ -3,7 +3,7 @@ { "prefix":"192.168.1.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -31,7 +31,7 @@ "prefix":"192.168.3.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":33280, "nexthops":[ { "fib":true, @@ -47,7 +47,7 @@ { "prefix":"193.1.1.0/26", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -75,7 +75,7 @@ "prefix":"193.1.2.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, diff --git a/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref b/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref index 44903ce3ff..71c931b17a 100644 --- a/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref +++ b/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref @@ -4,7 +4,7 @@ "prefix":"192.168.1.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, @@ -21,7 +21,7 @@ "prefix":"192.168.3.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, @@ -37,7 +37,7 @@ { "prefix":"193.1.1.0/26", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -64,7 +64,7 @@ { "prefix":"193.1.2.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, diff --git a/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref b/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref index d80e1d97e6..5e0b79d811 100644 --- a/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref +++ b/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref @@ -4,7 +4,7 @@ "prefix":"192.168.1.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":33280, "nexthops":[ { "fib":true, @@ -38,7 +38,7 @@ { "prefix":"192.168.3.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -66,7 +66,7 @@ "prefix":"193.1.1.0/26", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, @@ -82,7 +82,7 @@ { "prefix":"193.1.2.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, diff --git a/tests/topotests/eigrp-topo1/test_eigrp_topo1.py b/tests/topotests/eigrp-topo1/test_eigrp_topo1.py index de8cb81f8f..8ea2f0b506 100755 --- a/tests/topotests/eigrp-topo1/test_eigrp_topo1.py +++ b/tests/topotests/eigrp-topo1/test_eigrp_topo1.py @@ -153,7 +153,6 @@ def test_eigrp_routes(): assertmsg = '"show ip eigrp topo" mismatches on {}'.format(router.name) assert topotest.json_cmp(actual, expected) is None, assertmsg - def test_zebra_ipv4_routingTable(): "Test 'show ip route'" From 95fc2ae7911d32056a411c3d0caac5f8b9a628b2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 3 Feb 2019 15:46:31 -0500 Subject: [PATCH 2/5] eigrpd: Modify from int to boolean for display Track based upon boolean instead of an int Signed-off-by: Donald Sharp --- eigrpd/eigrp_dump.c | 4 ++-- eigrpd/eigrp_dump.h | 5 +++-- eigrpd/eigrp_vty.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 876e1cac07..6033290914 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -301,14 +301,14 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) } void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, - struct eigrp_nexthop_entry *te, int *first) + struct eigrp_nexthop_entry *te, bool *first) { if (te->reported_distance == EIGRP_MAX_METRIC) return; if (*first) { show_ip_eigrp_prefix_entry(vty, te->prefix); - *first = 0; + *first = false; } if (te->adv_router == eigrp->neighbor_self) diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h index 389ac1b5fd..34b55ab419 100644 --- a/eigrpd/eigrp_dump.h +++ b/eigrpd/eigrp_dump.h @@ -156,8 +156,9 @@ 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_nexthop_entry(struct vty *, struct eigrp *, - struct eigrp_nexthop_entry *, int *); +extern void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, + struct eigrp_nexthop_entry *ne, + bool *first); extern void eigrp_debug_init(void); diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 474f683989..f1de59e0aa 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -469,7 +469,7 @@ DEFUN (show_ip_eigrp_topology, struct eigrp_prefix_entry *tn; struct eigrp_nexthop_entry *te; struct route_node *rn; - int first; + bool first; eigrp = eigrp_lookup(); if (eigrp == NULL) { @@ -484,7 +484,7 @@ DEFUN (show_ip_eigrp_topology, continue; tn = rn->info; - first = 1; + first = true; for (ALL_LIST_ELEMENTS_RO(tn->entries, node, te)) { if (argc == 5 || (((te->flags From b0534a89201fd8cc6216f7bbffb37a931b21079f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 3 Feb 2019 15:47:53 -0500 Subject: [PATCH 3/5] eigrpd: Abstract display of an individual entry Abstract the individual display of a entry in the eigrp topology table. Signed-off-by: Donald Sharp --- eigrpd/eigrp_vty.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index f1de59e0aa..a6e03b22b2 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -455,6 +455,30 @@ DEFUN (no_eigrp_neighbor, return CMD_SUCCESS; } +static void eigrp_vty_display_prefix_entry(struct vty *vty, + struct eigrp *eigrp, + struct eigrp_prefix_entry *pe, + bool all) +{ + bool first = true; + struct eigrp_nexthop_entry *te; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(pe->entries, node, te)) { + if (all + || (((te->flags + & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) + == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) + || ((te->flags + & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) + == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { + show_ip_eigrp_nexthop_entry(vty, eigrp, te, + &first); + first = false; + } + } +} + DEFUN (show_ip_eigrp_topology, show_ip_eigrp_topology_cmd, "show ip eigrp topology [all-links]", @@ -465,11 +489,8 @@ DEFUN (show_ip_eigrp_topology, "Show all links in topology table\n") { struct eigrp *eigrp; - struct listnode *node; struct eigrp_prefix_entry *tn; - struct eigrp_nexthop_entry *te; struct route_node *rn; - bool first; eigrp = eigrp_lookup(); if (eigrp == NULL) { @@ -484,20 +505,7 @@ DEFUN (show_ip_eigrp_topology, continue; tn = rn->info; - first = true; - for (ALL_LIST_ELEMENTS_RO(tn->entries, node, te)) { - if (argc == 5 - || (((te->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) - == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) - || ((te->flags - & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) - == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { - show_ip_eigrp_nexthop_entry(vty, eigrp, te, - &first); - first = 0; - } - } + eigrp_vty_display_prefix_entry(vty, eigrp, tn, argc == 5); } return CMD_SUCCESS; From 1313365236085bae90a700c23ab1e7a9fb12489a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 3 Feb 2019 16:25:47 -0500 Subject: [PATCH 4/5] eigrpd: Allow A.B.C.D and A.B.C.D/M for topology specification Allow eigrp to display interesting topo information to the end user. Fixes: #3705 Signed-off-by: Donald Sharp --- eigrpd/eigrp_vty.c | 70 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index a6e03b22b2..104f35244e 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -479,9 +479,9 @@ static void eigrp_vty_display_prefix_entry(struct vty *vty, } } -DEFUN (show_ip_eigrp_topology, - show_ip_eigrp_topology_cmd, - "show ip eigrp topology [all-links]", +DEFPY (show_ip_eigrp_topology_all, + show_ip_eigrp_topology_all_cmd, + "show ip eigrp topology [all-links$all]", SHOW_STR IP_STR "IP-EIGRP show commands\n" @@ -505,21 +505,62 @@ DEFUN (show_ip_eigrp_topology, continue; tn = rn->info; - eigrp_vty_display_prefix_entry(vty, eigrp, tn, argc == 5); + eigrp_vty_display_prefix_entry(vty, eigrp, tn, + all ? true : false); } return CMD_SUCCESS; + } -ALIAS(show_ip_eigrp_topology, show_ip_eigrp_topology_detail_cmd, - "show ip eigrp topology ", - SHOW_STR IP_STR - "IP-EIGRP show commands\n" - "IP-EIGRP topology\n" - "Netwok to display information about\n" - "IP prefix /, e.g., 192.168.0.0/16\n" - "Show all links in topology table\n" - "Show a summary of the topology table\n") +DEFPY (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" + "For a specific address\n" + "For a specific prefix\n") +{ + struct eigrp *eigrp; + struct eigrp_prefix_entry *tn; + struct route_node *rn; + struct prefix cmp; + + eigrp = eigrp_lookup(); + if (eigrp == NULL) { + vty_out(vty, " EIGRP Routing Process not enabled\n"); + return CMD_SUCCESS; + } + + show_ip_eigrp_topology_header(vty, eigrp); + + if (address_str) + prefix_str = address_str; + + if (str2prefix(prefix_str, &cmp) < 0) { + vty_out(vty, "%% Malformed address\n"); + return CMD_WARNING; + } + + rn = route_node_match(eigrp->topology_table, &cmp); + if (!rn) { + vty_out(vty, "%% Network not in table\n"); + return CMD_WARNING; + } + + if (!rn->info) { + vty_out(vty, "%% Network not in table\n"); + route_unlock_node(rn); + return CMD_WARNING; + } + + tn = rn->info; + eigrp_vty_display_prefix_entry(vty, eigrp, tn, argc == 5); + + return CMD_SUCCESS; +} DEFUN (show_ip_eigrp_interfaces, show_ip_eigrp_interfaces_cmd, @@ -1493,8 +1534,7 @@ void eigrp_vty_show_init(void) install_element(VIEW_NODE, &show_ip_eigrp_neighbors_cmd); install_element(VIEW_NODE, &show_ip_eigrp_topology_cmd); - - install_element(VIEW_NODE, &show_ip_eigrp_topology_detail_cmd); + install_element(VIEW_NODE, &show_ip_eigrp_topology_all_cmd); } /* eigrpd's interface node. */ From c45db77d6f55f9abc06ea334e3278b650664e22b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 3 Feb 2019 19:24:28 -0500 Subject: [PATCH 5/5] eigrpd: Don't crash on a `no network A.B.C.D/M` This command was crashing. This fixes the crash we are still not behaving quite correctly on handling routes we have learned from those peers covered by the network statement. Signed-off-by: Donald Sharp --- eigrpd/eigrp_interface.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index e6cfe1deea..4ad1005f2f 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -114,6 +114,8 @@ int eigrp_if_delete_hook(struct interface *ifp) eigrp = ei->eigrp; listnode_delete(eigrp->eiflist, ei); + eigrp_fifo_free(ei->obuf); + XFREE(MTYPE_EIGRP_IF_INFO, ifp->info); ifp->info = NULL; @@ -265,16 +267,11 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei) { struct eigrp *eigrp = ei->eigrp; - if (ei->obuf) { - eigrp_fifo_free(ei->obuf); - ei->obuf = NULL; - - if (ei->on_write_q) { - listnode_delete(eigrp->oi_write_q, ei); - if (list_isempty(eigrp->oi_write_q)) - thread_cancel(eigrp->t_write); - ei->on_write_q = 0; - } + if (ei->on_write_q) { + listnode_delete(eigrp->oi_write_q, ei); + if (list_isempty(eigrp->oi_write_q)) + thread_cancel(eigrp->t_write); + ei->on_write_q = 0; } } @@ -351,7 +348,6 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_if_down(ei); - list_delete(&ei->nbrs); listnode_delete(ei->eigrp->eiflist, ei); }