From 9b86009a38e127c4797aa7818537d4577ed9bf6a Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Tue, 25 Jul 2017 13:55:48 -0300 Subject: [PATCH 1/5] bgpd/eigrpd: fix crashes found by the CLI fuzzer Fixes the following crashes: * bgpd aborted: vtysh -c "show ip bgp l2vpn evpn all 1.1.1.1 json" * bgpd aborted: vtysh -c "show ip bgp l2vpn evpn all 1.1.1.1" * bgpd aborted: vtysh -c "show ip bgp l2vpn evpn all 1.1.1.1/32 json" * bgpd aborted: vtysh -c "show ip bgp l2vpn evpn all 1.1.1.1/32" * bgpd aborted: vtysh -c "show bgp l2vpn evpn all 1.1.1.1 json" * bgpd aborted: vtysh -c "show bgp l2vpn evpn all 1.1.1.1" * bgpd aborted: vtysh -c "show bgp l2vpn evpn all 1.1.1.1/32 json" * bgpd aborted: vtysh -c "show bgp l2vpn evpn all 1.1.1.1/32" * bgpd aborted: vtysh -c "show bgp ipv4 vpn rd 1:1 1.1.1.1/32 json" * bgpd aborted: vtysh -c "show bgp ipv4 vpn rd 1:1 1.1.1.1/32" * bgpd aborted: vtysh -c "show bgp ipv4 vpn rd 1:1 2001:db8::1/128 json" * bgpd aborted: vtysh -c "show bgp ipv4 vpn rd 1:1 2001:db8::1/128" * bgpd aborted: vtysh -c "show bgp ipv6 vpn rd 1:1 1.1.1.1/32 json" * bgpd aborted: vtysh -c "show bgp ipv6 vpn rd 1:1 1.1.1.1/32" * bgpd aborted: vtysh -c "show bgp ipv6 vpn rd 1:1 2001:db8::1/128 json" * bgpd aborted: vtysh -c "show bgp ipv6 vpn rd 1:1 2001:db8::1/128" * bgpd aborted: vtysh -c "show vnc responses 1.1.1.1/32" * bgpd aborted: vtysh -c "show vnc responses 2001:db8::1/128" * bgpd aborted: vtysh -c "show vnc responses 11:11:11:11:11:11" * bgpd aborted: vtysh -c "show vnc responses" * eigrpd aborted: vtysh -c "configure terminal" -c "no router eigrp 65535" Signed-off-by: Renato Westphal --- bgpd/bgp_route.c | 8 +++++++- bgpd/rfapi/rfapi_rib.c | 10 +++++++++- eigrpd/eigrp_vty.c | 5 +++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 38ad7a6e0a..7cdc839618 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8617,8 +8617,14 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, int prefix_check, enum bgp_path_type pathtype, u_char use_json) { - if (!bgp) + if (!bgp) { bgp = bgp_get_default(); + if (!bgp) { + if (!use_json) + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING; + } + } /* labeled-unicast routes live in the unicast table */ if (safi == SAFI_LABELED_UNICAST) diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index a414df1ab4..791eb4c916 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -2236,9 +2236,12 @@ void rfapiRibShowResponsesSummary(void *stream) struct rfapi_descriptor *rfd; struct listnode *node; - if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) return; + if (!bgp) { + fp(out, "Unable to find default BGP instance\n"); + return; + } fp(out, "%-24s ", "Responses: (Prefixes)"); fp(out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); @@ -2388,6 +2391,11 @@ void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) return; + if (!bgp) { + fp(out, "Unable to find default BGP instance\n"); + return; + } + /* * loop over NVEs */ diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index d416183f52..746db2abe9 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -237,6 +237,11 @@ DEFUN (no_router_eigrp, struct eigrp *eigrp; eigrp = eigrp_lookup(); + if (eigrp == NULL) { + vty_out(vty, " EIGRP Routing Process not enabled\n"); + return CMD_SUCCESS; + } + if (eigrp->AS != atoi(argv[3]->arg)) { vty_out(vty, "%% Attempting to deconfigure non-existent AS\n"); return CMD_WARNING_CONFIG_FAILED; From 493c8ac787162d0a5a3ead3dbfa20b003aeb5823 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 26 Jul 2017 11:30:56 -0300 Subject: [PATCH 2/5] eigrpd: minor fix in the redistribute command Commands like "redistribute stati" and "redistribute osp" were being silently ignored. Signed-off-by: Renato Westphal --- eigrpd/eigrp_vty.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 746db2abe9..465007478d 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -1005,9 +1005,11 @@ DEFUN (eigrp_redistribute_source_metric, /* Get distribute source. */ argv_find(argv, argc, "redistribute", &idx); - source = proto_redistnum(AFI_IP, argv[idx + 1]->arg); - if (source < 0) + source = proto_redistnum(AFI_IP, argv[idx + 1]->text); + if (source < 0) { + vty_out(vty, "%% Invalid route type\n"); return CMD_WARNING_CONFIG_FAILED; + } /* Get metrics values */ @@ -1034,9 +1036,11 @@ DEFUN (no_eigrp_redistribute_source_metric, /* Get distribute source. */ argv_find(argv, argc, "redistribute", &idx); - source = proto_redistnum(AFI_IP, argv[idx + 1]->arg); - if (source < 0) + source = proto_redistnum(AFI_IP, argv[idx + 1]->text); + if (source < 0) { + vty_out(vty, "%% Invalid route type\n"); return CMD_WARNING_CONFIG_FAILED; + } /* Get metrics values */ From dd8765cad5ff747be42e2a70e1aadd56ef8f4021 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 26 Jul 2017 11:31:54 -0300 Subject: [PATCH 3/5] babel: fix crashes and improve the redistribute command Fixes the following crashes: babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "no redistribute pim" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "no redistribute eigrp" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "no redistribute nhrp" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "no redistribute table" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "no redistribute vnc" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "redistribute pim" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "redistribute eigrp" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "redistribute nhrp" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "redistribute table" babeld aborted: vtysh -c "configure terminal" -c "router babel" -c "redistribute vnc" While here, add an option to chose if we want to redistribute IPv4 or IPv6 routes (e.g. we might want static IPv4 routes only). Also, join the "no" version of the command in the same DEFUN (Yes We Can). Signed-off-by: Renato Westphal --- babeld/babel_zebra.c | 94 +++++++++++++------------------------------- babeld/babeld.c | 17 +++++--- 2 files changed, 38 insertions(+), 73 deletions(-) diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index 52d7eaee83..11b9c5956c 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -55,25 +55,6 @@ static struct { {0, 0, NULL} }; -static struct { - int str_min_len; - const char *str; -} proto_redistnum_type[ZEBRA_ROUTE_MAX] = { - [ZEBRA_ROUTE_BABEL] = {2, "babel"}, - [ZEBRA_ROUTE_BGP] = {2, "bgp"}, - [ZEBRA_ROUTE_CONNECT] = {1, "connected"}, - [ZEBRA_ROUTE_HSLS] = {1, "hsls"}, - [ZEBRA_ROUTE_ISIS] = {1, "isis"}, - [ZEBRA_ROUTE_KERNEL] = {1, "kernel"}, - [ZEBRA_ROUTE_OLSR] = {2, "olsr"}, - [ZEBRA_ROUTE_OSPF] = {2, "ospf"}, - [ZEBRA_ROUTE_OSPF6] = {5, "ospf6"}, - [ZEBRA_ROUTE_RIP] = {1, "rip"}, - [ZEBRA_ROUTE_RIPNG] = {4, "ripng"}, - [ZEBRA_ROUTE_STATIC] = {2, "static"}, - [ZEBRA_ROUTE_SYSTEM] = {2, "system"}, -}; - /* Zebra node structure. */ struct cmd_node zebra_node = { @@ -191,66 +172,46 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient, return 0; } -static int -babel_proto_redistnum(const char *s) -{ - int i; - if (! s) - return -1; - int len = strlen(s); - - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (len <= (int)strlen(proto_redistnum_type[i].str) && - strncmp(proto_redistnum_type[i].str, s, - proto_redistnum_type[i].str_min_len) == 0) { - return i; - } - } - - return -1; -} - /* [Babel Command] */ DEFUN (babel_redistribute_type, babel_redistribute_type_cmd, - "redistribute " FRR_REDIST_STR_BABELD, - "Redistribute\n" - FRR_REDIST_HELP_STR_BABELD) -{ - int type; - - type = babel_proto_redistnum(argv[1]->arg); - - if (type < 0) { - vty_out (vty, "Invalid type %s\n", argv[1]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, VRF_DEFAULT); - zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, VRF_DEFAULT); - return CMD_SUCCESS; -} - -/* [Babel Command] */ -DEFUN (no_babel_redistribute_type, - no_babel_redistribute_type_cmd, - "no redistribute " FRR_REDIST_STR_BABELD, + "[no] redistribute ", NO_STR "Redistribute\n" - FRR_REDIST_HELP_STR_BABELD) + "Redistribute IPv4 routes\n" + FRR_IP_REDIST_HELP_STR_BABELD + "Redistribute IPv6 routes\n" + FRR_IP6_REDIST_HELP_STR_BABELD) { + int negate = 0; + int family; + int afi; int type; + int idx = 0; - type = babel_proto_redistnum(argv[2]->arg); + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "redistribute", &idx); + family = str2family(argv[idx + 1]->text); + if (family < 0) + return CMD_WARNING_CONFIG_FAILED; + afi = family2afi(family); + if (!afi) + return CMD_WARNING_CONFIG_FAILED; + + type = proto_redistnum(afi, argv[idx + 2]->text); if (type < 0) { - vty_out (vty, "Invalid type %s\n", argv[2]->arg); + vty_out (vty, "Invalid type %s\n", argv[idx + 2]->arg); return CMD_WARNING_CONFIG_FAILED; } - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT); - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT); - /* perhaps should we remove xroutes having the same type... */ + if (!negate) + zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT); + else { + zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT); + /* perhaps should we remove xroutes having the same type... */ + } return CMD_SUCCESS; } @@ -374,7 +335,6 @@ void babelz_zebra_init(void) install_node (&zebra_node, zebra_config_write); install_element(BABEL_NODE, &babel_redistribute_type_cmd); - install_element(BABEL_NODE, &no_babel_redistribute_type_cmd); install_element(ENABLE_NODE, &debug_babel_cmd); install_element(ENABLE_NODE, &no_debug_babel_cmd); install_element(CONFIG_NODE, &debug_babel_cmd); diff --git a/babeld/babeld.c b/babeld/babeld.c index b2f8176aab..f995745e41 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -76,6 +76,7 @@ static int babel_config_write (struct vty *vty) { int lines = 0; + int afi; int i; /* list enabled debug modes */ @@ -108,13 +109,17 @@ babel_config_write (struct vty *vty) /* list enabled interfaces */ lines = 1 + babel_enable_if_config_write (vty); /* list redistributed protocols */ - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (i != zclient->redist_default && - vrf_bitmap_check (zclient->redist[AFI_IP][i], VRF_DEFAULT)) - { - vty_out (vty, " redistribute %s\n", zebra_route_string(i)); - lines++; + for (afi = AFI_IP; afi <= AFI_IP6; afi++) { + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (i != zclient->redist_default && + vrf_bitmap_check (zclient->redist[afi][i], VRF_DEFAULT)) { + vty_out (vty, " redistribute %s %s\n", + (afi == AFI_IP) ? "ipv4" : "ipv6", + zebra_route_string(i)); + lines++; + } } + } lines += config_write_distribute (vty); From 66a43eb221d8aed1194269f25157741a09083e10 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 26 Jul 2017 11:32:23 -0300 Subject: [PATCH 4/5] babeld: remove redundant startup message The frr_run() function already logs a startup message (and after reading the config so the "log" commands are honored). Signed-off-by: Renato Westphal --- babeld/babel_main.c | 2 -- babeld/babeld.h | 1 - 2 files changed, 3 deletions(-) diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 517489f15f..54626a4aeb 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -207,8 +207,6 @@ main(int argc, char **argv) schedule_neighbours_check(5000, 1); - zlog_notice ("BABELd %s starting: vty@%d", BABEL_VERSION, babel_vty_port); - frr_config_fork(); frr_run(master); diff --git a/babeld/babeld.h b/babeld/babeld.h index d933f18805..899b4f175c 100644 --- a/babeld/babeld.h +++ b/babeld/babeld.h @@ -90,7 +90,6 @@ THE SOFTWARE. #define BABEL_VTY_PORT 2609 #define BABEL_DEFAULT_CONFIG "babeld.conf" -#define BABEL_VERSION "0.1 for quagga" /* Values in milliseconds */ #define BABEL_DEFAULT_HELLO_INTERVAL 4000 From 163076686edf41dfd77b889de1227334977ba070 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 26 Jul 2017 12:27:37 -0300 Subject: [PATCH 5/5] bgpd/ospfd: fix json leaks and blank output Signed-off-by: Renato Westphal --- bgpd/bgp_evpn_vty.c | 2 ++ bgpd/bgp_mplsvpn.c | 2 ++ bgpd/bgp_route.c | 4 ++++ bgpd/bgp_vpn.c | 2 ++ ospfd/ospf_vty.c | 8 ++++++++ 5 files changed, 18 insertions(+) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 4b39ee8627..1225354c0a 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -347,6 +347,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, if (bgp == NULL) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); + else + vty_out(vty, "{}\n"); return CMD_WARNING; } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 5d2966d1ad..baf081c815 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -374,6 +374,8 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, if (bgp == NULL) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); + else + vty_out(vty, "{}\n"); return CMD_WARNING; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7cdc839618..b554aeb32b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8257,6 +8257,8 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, if (bgp == NULL) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); + else + vty_out(vty, "{}\n"); return CMD_WARNING; } @@ -8622,6 +8624,8 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, if (!bgp) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); + else + vty_out(vty, "{}\n"); return CMD_WARNING; } } diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index ca98ff0668..4661e195a2 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -51,6 +51,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, if (bgp == NULL) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); + else + vty_out(vty, "{}\n"); return CMD_WARNING; } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 55d6c27e8c..a8bfb669af 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4402,6 +4402,10 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, if (!ret) { if (!use_json) vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); + else { + vty_out(vty, "{}\n"); + json_object_free(json); + } return CMD_WARNING; } @@ -4682,6 +4686,10 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty, if (!ifp) { if (!use_json) vty_out(vty, "No such interface.\n"); + else { + vty_out(vty, "{}\n"); + json_object_free(json); + } return CMD_WARNING; }