From f81e127ed15b7500249be9b4294ce795ec2b08d6 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Fri, 9 Sep 2016 06:35:47 -0700 Subject: [PATCH 1/6] bgpd: Display interface next-hop for "show ip bgp" with unnumbered Found that the logic had been changed to determine whether the next-hop is a v4 or v6 address. This caused an unnumbered interface to be seen as ipv4 instead of ipv6 so the swp port was not correctly displayed. Changed it back. Manual testing attaced to the ticket and bgp-min will be run before committing. Ticket: CM-12759 Signed-off-by: Don Slice Reviewed-by: CCR-5166 --- bgpd/bgp_route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f767fae1a9..af0159855d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5922,7 +5922,7 @@ route_vty_out (struct vty *vty, struct prefix *p, vty_out(vty, "?"); } /* IPv4 Next Hop */ - else if (p->family == AF_INET || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { if (json_paths) { From e544fa850992c19ec35a6cf7d49530a822b492e2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 9 Sep 2016 14:42:22 -0400 Subject: [PATCH 2/6] debian: Update release information Signed-off-by: Donald Sharp --- configure.ac | 2 +- debian/changelog | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8fcafbb0f0..3fc22e9505 100755 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ(2.60) -AC_INIT(Quagga, 0.99.24+cl3u3, [https://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.24+cl3u4, [https://bugzilla.quagga.net]) CONFIG_ARGS="$*" AC_SUBST(CONFIG_ARGS) AC_CONFIG_SRCDIR(lib/zebra.h) diff --git a/debian/changelog b/debian/changelog index 3114db3fd1..44974cecd4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +quagga (0.99.24+cl3u4) RELEASED; urgency=medium + + * Closes: CM-12687 - Buffer overflow in zebra RA code + + -- dev-support Wed, 31 Aug 2016 12:36:10 -0400 + quagga (0.99.24+cl3u3) RELEASED; urgency=medium * New Enabled: Merge up-to 0.99.24 code from upstream From ddb13fd374ee736c20198c1075c855efa7af74e9 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Mon, 12 Sep 2016 06:32:11 -0700 Subject: [PATCH 3/6] lib: apply mask to prefix in prefix-list A crash occurred if a prefix was defined in a prefix-list that contained bits in the prefix but a /0 mask. Resolving that crash and improving usability by applying the mask to the supplied prefix and notifying the user if the prefix was modified. Ticket: CM-12744 Signed-off-by: Don Slice Reviewed_By: Testing Done: Manual testing attached to the ticket, bgp-min, bgp-smoke ospf-min, and ospf-smoke all completed before commit --- lib/plist.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/plist.c b/lib/plist.c index a1289801c4..87d46a1054 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -894,7 +894,7 @@ vty_prefix_list_install (struct vty *vty, afi_t afi, const char *name, struct prefix_list *plist; struct prefix_list_entry *pentry; struct prefix_list_entry *dup; - struct prefix p; + struct prefix p, p_tmp; int any = 0; int seqnum = -1; int lenum = 0; @@ -940,6 +940,11 @@ vty_prefix_list_install (struct vty *vty, afi_t afi, const char *name, vty_out (vty, "%% Malformed IPv4 prefix%s", VTY_NEWLINE); return CMD_WARNING; } + + /* make a copy to verify prefix matches mask length */ + prefix_copy (&p_tmp, &p); + apply_mask_ipv4 ((struct prefix_ipv4 *) &p_tmp); + break; case AFI_IP6: if (strncmp ("any", prefix, strlen (prefix)) == 0) @@ -957,9 +962,26 @@ vty_prefix_list_install (struct vty *vty, afi_t afi, const char *name, vty_out (vty, "%% Malformed IPv6 prefix%s", VTY_NEWLINE); return CMD_WARNING; } + + /* make a copy to verify prefix matches mask length */ + prefix_copy (&p_tmp, &p); + apply_mask_ipv6 ((struct prefix_ipv6 *) &p_tmp); + break; } + /* If prefix has bits not under the mask, adjust it to fit */ + if (!prefix_same (&p_tmp, &p)) + { + char buf[PREFIX2STR_BUFFER]; + char buf_tmp[PREFIX2STR_BUFFER]; + prefix2str(&p, buf, sizeof(buf)); + prefix2str(&p_tmp, buf_tmp, sizeof(buf_tmp)); + zlog_warn ("Prefix-list %s prefix changed from %s to %s to match length", + name, buf, buf_tmp); + p = p_tmp; + } + /* ge and le check. */ if (genum && (genum <= p.prefixlen)) return vty_invalid_prefix_range (vty, prefix); @@ -985,14 +1007,6 @@ vty_prefix_list_install (struct vty *vty, afi_t afi, const char *name, if (dup) { prefix_list_entry_free (pentry); - vty_out (vty, "%% Insertion failed - prefix-list entry exists:%s", - VTY_NEWLINE); - vty_out (vty, " seq %u %s %s", dup->seq, typestr, prefix); - if (! any && genum) - vty_out (vty, " ge %d", genum); - if (! any && lenum) - vty_out (vty, " le %d", lenum); - vty_out (vty, "%s", VTY_NEWLINE); return CMD_SUCCESS; } From 87aea55d3436b8cfaf80334c4a498baaef1f0284 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 9 Sep 2016 12:41:35 -0400 Subject: [PATCH 4/6] ospfd: Fix crash with usage of incorrect command Entering 'show ip ospf interface json' causes ospf to crash. Entering 'show ip ospf interface json' causes ospf to crash if intf has no neighbors on the otherside Modify the code to not crash in these cases. Ticket: CM-12776 Signed-off-by: Donald Sharp Reviewed-by: Daniel Walton --- ospfd/ospf_vty.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 16fab68c99..980d59d341 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3877,7 +3877,13 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface { struct timeval result; unsigned long time_store = 0; - result = tv_sub (oi->t_hello->u.sands, recent_relative_time()); + if (oi->t_hello) + result = tv_sub (oi->t_hello->u.sands, recent_relative_time()); + else + { + result.tv_sec = 0; + result.tv_usec = 0; + } time_store = (1000 * result.tv_sec) + (result.tv_usec / 1000); json_object_int_add(json_interface_sub, "timerHelloInMsecs", time_store); } @@ -3939,20 +3945,29 @@ show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc, if (ospf_oi_count(ifp)) { show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); + if (use_json) + json_object_object_add (json, ifp->name, json_interface_sub); } } } else if (argv[iface_argv] && strcmp(argv[iface_argv], "json") == 0) { + if (!use_json) + { + json = json_object_new_object(); + json_interface_sub = json_object_new_object (); + use_json = 1; + } /* Show All Interfaces. */ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) { if (ospf_oi_count(ifp)) { show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); - json_object_object_add(json, ifp->name, json_interface_sub); - } - } + if (use_json) + json_object_object_add(json, ifp->name, json_interface_sub); + } + } } else { From b6df4090322446a2ee32fc5e2d43d074d34a8f1f Mon Sep 17 00:00:00 2001 From: Don Slice Date: Fri, 16 Sep 2016 09:20:03 -0700 Subject: [PATCH 5/6] bgpd: resolve memory leaks in "show ip bgp neighbor json" Found several leaks in bgp_show_peer and bgp_show_peer_afi where json objects are created and then not attached to the parent, causing them to be leaked. If not attaching them, freeing the created objects. Manual testing performed successfully. Fix tested succesfully by the submitter and bgp-smoke completed with same failures as base. Ticket: CM-12846 Signed-off-by: Don Slice Reviewed-by: CCR-5181 --- bgpd/bgp_vty.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f16cf53cbe..04bb81548a 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10971,8 +10971,6 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi, { json_addr = json_object_new_object(); json_af = json_object_new_object(); - json_prefA = json_object_new_object(); - json_prefB = json_object_new_object(); filter = &p->filter[afi][safi]; if (peer_group_active(p)) @@ -10992,6 +10990,7 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi, || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) { json_object_int_add(json_af, "orfType", ORF_TYPE_PREFIX); + json_prefA = json_object_new_object(); bgp_show_peer_afi_orf_cap (vty, p, afi, safi, PEER_CAP_ORF_PREFIX_SM_ADV, PEER_CAP_ORF_PREFIX_RM_ADV, @@ -11006,6 +11005,7 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi, || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) { json_object_int_add(json_af, "orfOldType", ORF_TYPE_PREFIX_OLD); + json_prefB = json_object_new_object(); bgp_show_peer_afi_orf_cap (vty, p, afi, safi, PEER_CAP_ORF_PREFIX_SM_ADV, PEER_CAP_ORF_PREFIX_RM_ADV, @@ -11021,6 +11021,8 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi, || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV) || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) json_object_object_add(json_addr, "afDependentCap", json_af); + else + json_object_free(json_af); sprintf (orf_pfx_name, "%s.%d.%d", p->host, afi, safi); orf_pfx_count = prefix_bgp_show_prefix_list (NULL, afi, orf_pfx_name, use_json); @@ -11743,6 +11745,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) json_object_object_add(json_add, print_store, json_sub); + else + json_object_free(json_sub); } json_object_object_add(json_cap, "addPath", json_add); @@ -11767,7 +11771,6 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js json_object *json_nxt = NULL; const char *print_store; - json_nxt = json_object_new_object(); if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV) && CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) json_object_string_add(json_cap, "extendedNexthop", "advertisedAndReceived"); @@ -11778,6 +11781,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) { + json_nxt = json_object_new_object(); + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) { if (CHECK_FLAG (p->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_RCV)) @@ -11875,7 +11880,10 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js } } if (! restart_af_count) - json_object_string_add(json_cap, "addressFamiliesByPeer", "none"); + { + json_object_string_add(json_cap, "addressFamiliesByPeer", "none"); + json_object_free(json_restart); + } else json_object_object_add(json_cap, "addressFamiliesByPeer", json_restart); } From 8d62b1417ee85862a85454f635168e5e3fcf682d Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 27 Sep 2016 15:56:36 +0000 Subject: [PATCH 6/6] tools: quagga-reload should raise Exception instead of exiting Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp NCLU imports quagga-reload.py and uses its Config class to parse Quagga.conf. The Config class will call 'vtysh -m -f Quagga.conf" and if that exited with an error Config would call sys.exit(1) which in my cases causes the NCLU daemon to exit which is bad. The fix is to have the Config class raise an exception instead of exiting, then NCLU can catch the exception, log it and move on. (cherry picked from commit 276887bb1c2961fa37b42ce7160346f1417577a8) --- tools/quagga-reload.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/quagga-reload.py b/tools/quagga-reload.py index 900ed55c43..ed36b940a9 100755 --- a/tools/quagga-reload.py +++ b/tools/quagga-reload.py @@ -26,6 +26,10 @@ from pprint import pformat log = logging.getLogger(__name__) +class VtyshMarkException(Exception): + pass + + class Context(object): """ @@ -88,9 +92,7 @@ class Config(object): try: file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename]) except subprocess.CalledProcessError as e: - log.error('vtysh marking of config file %s failed with error %s:', filename, str(e)) - print "vtysh marking of file %s failed with error: %s" % (filename, str(e)) - sys.exit(1) + raise VtyshMarkException(str(e)) for line in file_output.split('\n'): line = line.strip() @@ -115,9 +117,7 @@ class Config(object): "/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -", shell=True) except subprocess.CalledProcessError as e: - log.error('vtysh marking of running config failed with error %s:', str(e)) - print "vtysh marking of running config failed with error %s:" % (str(e)) - sys.exit(1) + raise VtyshMarkException(str(e)) for line in config_text.split('\n'): line = line.strip()