From c63b83fe8d1addecc949258479b8d54180c4da60 Mon Sep 17 00:00:00 2001 From: "Jorge Boncompte [DTI2]" Date: Tue, 10 Apr 2012 16:57:24 +0200 Subject: bgpd: Fix memory leak of some "show ip bgp neighbor" commands sockunion_str2su() use is prone to memory leaks. Remove it's use all over the code. At least these commands leaked a sockunion union: - show ip bgp vpnv4 ... routes - show ip bgp ... received prefix-filter Signed-off-by: Jorge Boncompte [DTI2] Signed-off-by: David Lamparter --- bgpd/bgp_mplsvpn.c | 27 ++++++++++++------------ bgpd/bgp_route.c | 60 ++++++++++++++++++++++++++++++++--------------------- bgpd/bgp_routemap.c | 11 ++++------ bgpd/bgp_vty.c | 12 +++++------ lib/sockunion.c | 33 ----------------------------- lib/sockunion.h | 1 - 6 files changed, 59 insertions(+), 85 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index c1f1fbb3..b0cf2a98 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -581,24 +581,25 @@ DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes, "Neighbor to display information about\n" "Display routes learned from neighbor\n") { - union sockunion *su; + union sockunion su; struct peer *peer; - - su = sockunion_str2su (argv[0]); - if (su == NULL) + int ret; + + ret = str2sockunion (argv[0], &su); + if (ret < 0) { vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; + return CMD_WARNING; } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) { vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, su, 0); + return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0); } DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, @@ -615,7 +616,7 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, "Display routes learned from neighbor\n") { int ret; - union sockunion *su; + union sockunion su; struct peer *peer; struct prefix_rd prd; @@ -626,21 +627,21 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, return CMD_WARNING; } - su = sockunion_str2su (argv[1]); - if (su == NULL) + ret = str2sockunion (argv[1], &su); + if (ret < 0) { vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; + return CMD_WARNING; } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) { vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, su, 0); + return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0); } DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes, diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 9f8d8232..d96224db 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -10202,15 +10202,18 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, "Display the prefixlist filter\n") { char name[BUFSIZ]; - union sockunion *su; + union sockunion su; struct peer *peer; - int count; + int count, ret; - su = sockunion_str2su (argv[0]); - if (su == NULL) - return CMD_WARNING; + ret = str2sockunion (argv[0], &su); + if (ret < 0) + { + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer) return CMD_WARNING; @@ -10241,15 +10244,18 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, "Display the prefixlist filter\n") { char name[BUFSIZ]; - union sockunion *su; + union sockunion su; struct peer *peer; - int count; + int count, ret; - su = sockunion_str2su (argv[1]); - if (su == NULL) - return CMD_WARNING; + ret = str2sockunion (argv[1], &su); + if (ret < 0) + { + vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer) return CMD_WARNING; @@ -10312,15 +10318,18 @@ DEFUN (show_bgp_neighbor_received_prefix_filter, "Display the prefixlist filter\n") { char name[BUFSIZ]; - union sockunion *su; + union sockunion su; struct peer *peer; - int count; + int count, ret; - su = sockunion_str2su (argv[0]); - if (su == NULL) - return CMD_WARNING; + ret = str2sockunion (argv[0], &su); + if (ret < 0) + { + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer) return CMD_WARNING; @@ -10394,10 +10403,10 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, "Display the prefixlist filter\n") { char name[BUFSIZ]; - union sockunion *su; + union sockunion su; struct peer *peer; struct bgp *bgp; - int count; + int count, ret; /* BGP structure lookup. */ bgp = bgp_lookup_by_name (argv[0]); @@ -10407,11 +10416,14 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, return CMD_WARNING; } - su = sockunion_str2su (argv[1]); - if (su == NULL) - return CMD_WARNING; + ret = str2sockunion (argv[1], &su); + if (ret < 0) + { + vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } - peer = peer_lookup (bgp, su); + peer = peer_lookup (bgp, &su); if (! peer) return CMD_WARNING; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index fa645ac4..f2204003 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -111,7 +111,8 @@ route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { union sockunion *su; - union sockunion *su2; + union sockunion su_def = { .sa.sa_family = AF_INET, + .sin.sin_addr.s_addr = INADDR_ANY }; struct peer_group *group; struct peer *peer; struct listnode *node, *nnode; @@ -127,8 +128,7 @@ route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type, /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK, REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */ - su2 = sockunion_str2su ("0.0.0.0"); - if ( sockunion_same (su, su2) ) + if (sockunion_same (su, &su_def)) { int ret; if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) || @@ -137,12 +137,9 @@ route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type, ret = RMAP_MATCH; else ret = RMAP_NOMATCH; - - sockunion_free (su2); return ret; } - sockunion_free (su2); - + if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (sockunion_same (su, &peer->su)) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index bba1c7de..03746bdd 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2943,7 +2943,6 @@ peer_update_source_vty (struct vty *vty, const char *peer_str, const char *source_str) { struct peer *peer; - union sockunion *su; peer = peer_and_group_lookup_vty (vty, peer_str); if (! peer) @@ -2951,12 +2950,11 @@ peer_update_source_vty (struct vty *vty, const char *peer_str, if (source_str) { - su = sockunion_str2su (source_str); - if (su) - { - peer_update_source_addr_set (peer, su); - sockunion_free (su); - } + union sockunion su; + int ret = str2sockunion (source_str, &su); + + if (ret == 0) + peer_update_source_addr_set (peer, &su); else peer_update_source_if_set (peer, source_str); } diff --git a/lib/sockunion.c b/lib/sockunion.c index cfb6f9c5..4c2837b1 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -174,39 +174,6 @@ sockunion2str (union sockunion *su, char *buf, size_t len) return NULL; } -union sockunion * -sockunion_str2su (const char *str) -{ - int ret; - union sockunion *su; - - su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); - - ret = inet_pton (AF_INET, str, &su->sin.sin_addr); - if (ret > 0) /* Valid IPv4 address format. */ - { - su->sin.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - su->sin.sin_len = sizeof(struct sockaddr_in); -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - return su; - } -#ifdef HAVE_IPV6 - ret = inet_pton (AF_INET6, str, &su->sin6.sin6_addr); - if (ret > 0) /* Valid IPv6 address format. */ - { - su->sin6.sin6_family = AF_INET6; -#ifdef SIN6_LEN - su->sin6.sin6_len = sizeof(struct sockaddr_in6); -#endif /* SIN6_LEN */ - return su; - } -#endif /* HAVE_IPV6 */ - - XFREE (MTYPE_SOCKUNION, su); - return NULL; -} - /* Convert IPv4 compatible IPv6 address to IPv4 address. */ static void sockunion_normalise_mapped (union sockunion *su) diff --git a/lib/sockunion.h b/lib/sockunion.h index 8b060586..180b2b4d 100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h @@ -94,7 +94,6 @@ extern const char *sockunion2str (union sockunion *, char *, size_t); extern int sockunion_cmp (union sockunion *, union sockunion *); extern int sockunion_same (union sockunion *, union sockunion *); -extern union sockunion *sockunion_str2su (const char *str); extern struct in_addr sockunion_get_in_addr (union sockunion *su); extern int sockunion_accept (int sock, union sockunion *); extern int sockunion_stream_socket (union sockunion *); -- cgit v1.2.1