[packages] quagga: Fix various sockunion_{str2su,su2str} memleaks
[packages.git] / net / quagga / patches / 004-fix-sockunion-memleaks.patch
1 --- a/bgpd/bgp_routemap.c
2 +++ b/bgpd/bgp_routemap.c
3 @@ -111,7 +111,8 @@ route_match_peer (void *rule, struct pre
4        void *object)
5  {
6    union sockunion *su;
7 -  union sockunion *su2;
8 +  union sockunion su_def = { .sa.sa_family = AF_INET,
9 +                            .sin.sin_addr.s_addr = INADDR_ANY };
10    struct peer_group *group;
11    struct peer *peer;
12    struct listnode *node, *nnode;
13 @@ -127,8 +128,7 @@ route_match_peer (void *rule, struct pre
14  
15        /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
16            REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
17 -      su2 = sockunion_str2su ("0.0.0.0");
18 -      if ( sockunion_same (su, su2) )
19 +      if (sockunion_same (su, &su_def))
20          {
21            int ret;
22            if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
23 @@ -137,12 +137,9 @@ route_match_peer (void *rule, struct pre
24              ret = RMAP_MATCH;
25            else
26              ret = RMAP_NOMATCH;
27 -          
28 -          sockunion_free (su2);
29            return ret;
30          }
31 -      sockunion_free (su2);
32 -      
33 +
34        if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
35          {
36            if (sockunion_same (su, &peer->su))
37 @@ -878,7 +875,6 @@ route_set_ip_nexthop (void *rule, struct
38                       route_map_object_t type, void *object)
39  {
40    struct rmap_ip_nexthop_set *rins = rule;
41 -  struct in_addr peer_address;
42    struct bgp_info *bgp_info;
43    struct peer *peer;
44  
45 @@ -894,16 +890,14 @@ route_set_ip_nexthop (void *rule, struct
46               && peer->su_remote 
47               && sockunion_family (peer->su_remote) == AF_INET)
48             {
49 -              inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
50 -              bgp_info->attr->nexthop = peer_address;
51 +             bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
52               bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
53             }
54           else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
55                    && peer->su_local
56                    && sockunion_family (peer->su_local) == AF_INET)
57             {
58 -              inet_aton (sockunion_su2str (peer->su_local), &peer_address);
59 -              bgp_info->attr->nexthop = peer_address;
60 +             bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
61               bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
62             }
63         }
64 --- a/lib/sockunion.h
65 +++ b/lib/sockunion.h
66 @@ -78,23 +78,17 @@ enum connect_result
67  #define SET_IN6_LINKLOCAL_IFINDEX(a, i)
68  #endif /* KAME */
69  
70 -/* shortcut macro to specify address field of struct sockaddr */
71 -#define sock2ip(X)   (((struct sockaddr_in *)(X))->sin_addr.s_addr)
72 -#ifdef HAVE_IPV6
73 -#define sock2ip6(X)  (((struct sockaddr_in6 *)(X))->sin6_addr.s6_addr)
74 -#endif /* HAVE_IPV6 */
75 -
76  #define sockunion_family(X)  (X)->sa.sa_family
77  
78 +#define sockunion2ip(X)      (X)->sin.sin_addr.s_addr
79 +
80  /* Prototypes. */
81  extern int str2sockunion (const char *, union sockunion *);
82  extern const char *sockunion2str (union sockunion *, char *, size_t);
83  extern int sockunion_cmp (union sockunion *, union sockunion *);
84  extern int sockunion_same (union sockunion *, union sockunion *);
85  
86 -extern char *sockunion_su2str (union sockunion *su);
87  extern union sockunion *sockunion_str2su (const char *str);
88 -extern struct in_addr sockunion_get_in_addr (union sockunion *su);
89  extern int sockunion_accept (int sock, union sockunion *);
90  extern int sockunion_stream_socket (union sockunion *);
91  extern int sockopt_reuseaddr (int);
92 --- a/bgpd/bgp_fsm.c
93 +++ b/bgpd/bgp_fsm.c
94 @@ -597,8 +597,6 @@ bgp_stop_with_error (struct peer *peer)
95  static int
96  bgp_connect_success (struct peer *peer)
97  {
98 -  char buf1[BUFSIZ];
99 -
100    if (peer->fd < 0)
101      {
102        zlog_err ("bgp_connect_success peer's fd is negative value %d",
103 @@ -612,6 +610,8 @@ bgp_connect_success (struct peer *peer)
104  
105    if (BGP_DEBUG (normal, NORMAL))
106      {
107 +      char buf1[SU_ADDRSTRLEN];
108 +
109        if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
110         zlog_debug ("%s open active, local address %s", peer->host,
111                     sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
112 --- a/bgpd/bgp_mplsvpn.c
113 +++ b/bgpd/bgp_mplsvpn.c
114 @@ -581,24 +581,25 @@ DEFUN (show_ip_bgp_vpnv4_all_neighbor_ro
115         "Neighbor to display information about\n"
116         "Display routes learned from neighbor\n")
117  {
118 -  union sockunion *su;
119 +  union sockunion su;
120    struct peer *peer;
121 -  
122 -  su = sockunion_str2su (argv[0]);
123 -  if (su == NULL)
124 +  int ret;
125 +
126 +  ret = str2sockunion (argv[0], &su);
127 +  if (ret < 0)
128      {
129        vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
130 -               return CMD_WARNING;
131 +      return CMD_WARNING;
132      }
133  
134 -  peer = peer_lookup (NULL, su);
135 +  peer = peer_lookup (NULL, &su);
136    if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
137      {
138        vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
139        return CMD_WARNING;
140      }
141  
142 -  return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, su, 0);
143 +  return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
144  }
145  
146  DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
147 @@ -615,7 +616,7 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_rou
148         "Display routes learned from neighbor\n")
149  {
150    int ret;
151 -  union sockunion *su;
152 +  union sockunion su;
153    struct peer *peer;
154    struct prefix_rd prd;
155  
156 @@ -626,21 +627,21 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_rou
157        return CMD_WARNING;
158      }
159  
160 -  su = sockunion_str2su (argv[1]);
161 -  if (su == NULL)
162 +  ret = str2sockunion (argv[1], &su);
163 +  if (ret < 0)
164      {
165        vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
166 -               return CMD_WARNING;
167 +      return CMD_WARNING;
168      }
169  
170 -  peer = peer_lookup (NULL, su);
171 +  peer = peer_lookup (NULL, &su);
172    if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
173      {
174        vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
175        return CMD_WARNING;
176      }
177  
178 -  return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, su, 0);
179 +  return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
180  }
181  
182  DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
183 --- a/bgpd/bgp_network.c
184 +++ b/bgpd/bgp_network.c
185 @@ -185,7 +185,7 @@ bgp_accept (struct thread *thread)
186      zlog_debug ("[Event] Make dummy peer structure until read Open packet");
187  
188    {
189 -    char buf[SU_ADDRSTRLEN + 1];
190 +    char buf[SU_ADDRSTRLEN];
191  
192      peer = peer_create_accept (peer1->bgp);
193      SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
194 --- a/bgpd/bgp_route.c
195 +++ b/bgpd/bgp_route.c
196 @@ -10202,15 +10202,18 @@ DEFUN (show_ip_bgp_neighbor_received_pre
197         "Display the prefixlist filter\n")
198  {
199    char name[BUFSIZ];
200 -  union sockunion *su;
201 +  union sockunion su;
202    struct peer *peer;
203 -  int count;
204 +  int count, ret;
205  
206 -  su = sockunion_str2su (argv[0]);
207 -  if (su == NULL)
208 -    return CMD_WARNING;
209 +  ret = str2sockunion (argv[0], &su);
210 +  if (ret < 0)
211 +    {
212 +      vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
213 +      return CMD_WARNING;
214 +    }
215  
216 -  peer = peer_lookup (NULL, su);
217 +  peer = peer_lookup (NULL, &su);
218    if (! peer)
219      return CMD_WARNING;
220  
221 @@ -10241,15 +10244,18 @@ DEFUN (show_ip_bgp_ipv4_neighbor_receive
222         "Display the prefixlist filter\n")
223  {
224    char name[BUFSIZ];
225 -  union sockunion *su;
226 +  union sockunion su;
227    struct peer *peer;
228 -  int count;
229 +  int count, ret;
230  
231 -  su = sockunion_str2su (argv[1]);
232 -  if (su == NULL)
233 -    return CMD_WARNING;
234 +  ret = str2sockunion (argv[1], &su);
235 +  if (ret < 0)
236 +    {
237 +      vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
238 +      return CMD_WARNING;
239 +    }
240  
241 -  peer = peer_lookup (NULL, su);
242 +  peer = peer_lookup (NULL, &su);
243    if (! peer)
244      return CMD_WARNING;
245  
246 @@ -10312,15 +10318,18 @@ DEFUN (show_bgp_neighbor_received_prefix
247         "Display the prefixlist filter\n")
248  {
249    char name[BUFSIZ];
250 -  union sockunion *su;
251 +  union sockunion su;
252    struct peer *peer;
253 -  int count;
254 +  int count, ret;
255  
256 -  su = sockunion_str2su (argv[0]);
257 -  if (su == NULL)
258 -    return CMD_WARNING;
259 +  ret = str2sockunion (argv[0], &su);
260 +  if (ret < 0)
261 +    {
262 +      vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
263 +      return CMD_WARNING;
264 +    }
265  
266 -  peer = peer_lookup (NULL, su);
267 +  peer = peer_lookup (NULL, &su);
268    if (! peer)
269      return CMD_WARNING;
270  
271 @@ -10394,10 +10403,10 @@ DEFUN (show_bgp_view_neighbor_received_p
272         "Display the prefixlist filter\n")
273  {
274    char name[BUFSIZ];
275 -  union sockunion *su;
276 +  union sockunion su;
277    struct peer *peer;
278    struct bgp *bgp;
279 -  int count;
280 +  int count, ret;
281  
282    /* BGP structure lookup. */
283    bgp = bgp_lookup_by_name (argv[0]);
284 @@ -10407,11 +10416,14 @@ DEFUN (show_bgp_view_neighbor_received_p
285           return CMD_WARNING;
286         }
287    
288 -  su = sockunion_str2su (argv[1]);
289 -  if (su == NULL)
290 -    return CMD_WARNING;
291 +  ret = str2sockunion (argv[1], &su);
292 +  if (ret < 0)
293 +    {
294 +      vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
295 +      return CMD_WARNING;
296 +    }
297  
298 -  peer = peer_lookup (bgp, su);
299 +  peer = peer_lookup (bgp, &su);
300    if (! peer)
301      return CMD_WARNING;
302  
303 --- a/bgpd/bgp_vty.c
304 +++ b/bgpd/bgp_vty.c
305 @@ -2943,7 +2943,6 @@ peer_update_source_vty (struct vty *vty,
306                          const char *source_str)
307  {
308    struct peer *peer;
309 -  union sockunion *su;
310  
311    peer = peer_and_group_lookup_vty (vty, peer_str);
312    if (! peer)
313 @@ -2951,12 +2950,11 @@ peer_update_source_vty (struct vty *vty,
314  
315    if (source_str)
316      {
317 -      su = sockunion_str2su (source_str);
318 -      if (su)
319 -       {
320 -         peer_update_source_addr_set (peer, su);
321 -         sockunion_free (su);
322 -       }
323 +      union sockunion su;
324 +      int ret = str2sockunion (source_str, &su);
325 +
326 +      if (ret == 0)
327 +       peer_update_source_addr_set (peer, &su);
328        else
329         peer_update_source_if_set (peer, source_str);
330      }
331 --- a/lib/sockunion.c
332 +++ b/lib/sockunion.c
333 @@ -177,55 +177,15 @@ sockunion2str (union sockunion *su, char
334  union sockunion *
335  sockunion_str2su (const char *str)
336  {
337 -  int ret;
338 -  union sockunion *su;
339 -
340 -  su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));
341 -
342 -  ret = inet_pton (AF_INET, str, &su->sin.sin_addr);
343 -  if (ret > 0)                 /* Valid IPv4 address format. */
344 -    {
345 -      su->sin.sin_family = AF_INET;
346 -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
347 -      su->sin.sin_len = sizeof(struct sockaddr_in);
348 -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
349 -      return su;
350 -    }
351 -#ifdef HAVE_IPV6
352 -  ret = inet_pton (AF_INET6, str, &su->sin6.sin6_addr);
353 -  if (ret > 0)                 /* Valid IPv6 address format. */
354 -    {
355 -      su->sin6.sin6_family = AF_INET6;
356 -#ifdef SIN6_LEN
357 -      su->sin6.sin6_len = sizeof(struct sockaddr_in6);
358 -#endif /* SIN6_LEN */
359 -      return su;
360 -    }
361 -#endif /* HAVE_IPV6 */
362 -
363 +  union sockunion *su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));
364 +  
365 +  if (!str2sockunion (str, su))
366 +    return su;
367 +  
368    XFREE (MTYPE_SOCKUNION, su);
369    return NULL;
370  }
371  
372 -char *
373 -sockunion_su2str (union sockunion *su)
374 -{
375 -  char str[SU_ADDRSTRLEN];
376 -
377 -  switch (su->sa.sa_family)
378 -    {
379 -    case AF_INET:
380 -      inet_ntop (AF_INET, &su->sin.sin_addr, str, sizeof (str));
381 -      break;
382 -#ifdef HAVE_IPV6
383 -    case AF_INET6:
384 -      inet_ntop (AF_INET6, &su->sin6.sin6_addr, str, sizeof (str));
385 -      break;
386 -#endif /* HAVE_IPV6 */
387 -    }
388 -  return XSTRDUP (MTYPE_TMP, str);
389 -}
390 -
391  /* Convert IPv4 compatible IPv6 address to IPv4 address. */
392  static void
393  sockunion_normalise_mapped (union sockunion *su)
394 @@ -422,7 +382,7 @@ sockunion_bind (int sock, union sockunio
395        su->sin.sin_len = size;
396  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
397        if (su_addr == NULL)
398 -       su->sin.sin_addr.s_addr = htonl (INADDR_ANY);
399 +       sockunion2ip (su) = htonl (INADDR_ANY);
400      }
401  #ifdef HAVE_IPV6
402    else if (su->sa.sa_family == AF_INET6)
403 @@ -779,9 +739,9 @@ sockunion_cmp (union sockunion *su1, uni
404  
405    if (su1->sa.sa_family == AF_INET)
406      {
407 -      if (ntohl (su1->sin.sin_addr.s_addr) == ntohl (su2->sin.sin_addr.s_addr))
408 +      if (ntohl (sockunion2ip (su1)) == ntohl (sockunion2ip (su2)))
409         return 0;
410 -      if (ntohl (su1->sin.sin_addr.s_addr) > ntohl (su2->sin.sin_addr.s_addr))
411 +      if (ntohl (sockunion2ip (su1)) > ntohl (sockunion2ip (su2)))
412         return 1;
413        else
414         return -1;
415 --- a/lib/vty.c
416 +++ b/lib/vty.c
417 @@ -1612,13 +1612,16 @@ vty_flush (struct thread *thread)
418  static struct vty *
419  vty_create (int vty_sock, union sockunion *su)
420  {
421 +  char buf[SU_ADDRSTRLEN];
422    struct vty *vty;
423  
424 +  sockunion2str(su, buf, SU_ADDRSTRLEN);
425 +
426    /* Allocate new vty structure and set up default values. */
427    vty = vty_new ();
428    vty->fd = vty_sock;
429    vty->type = VTY_TERM;
430 -  vty->address = sockunion_su2str (su);
431 +  strcpy (vty->address, buf);
432    if (no_password_check)
433      {
434        if (restricted_mode)
435 @@ -1693,7 +1696,7 @@ vty_accept (struct thread *thread)
436    int accept_sock;
437    struct prefix *p = NULL;
438    struct access_list *acl = NULL;
439 -  char *bufp;
440 +  char buf[SU_ADDRSTRLEN];
441  
442    accept_sock = THREAD_FD (thread);
443  
444 @@ -1719,10 +1722,8 @@ vty_accept (struct thread *thread)
445        if ((acl = access_list_lookup (AFI_IP, vty_accesslist_name)) &&
446           (access_list_apply (acl, p) == FILTER_DENY))
447         {
448 -         char *buf;
449           zlog (NULL, LOG_INFO, "Vty connection refused from %s",
450 -               (buf = sockunion_su2str (&su)));
451 -         free (buf);
452 +               sockunion2str (&su, buf, SU_ADDRSTRLEN));
453           close (vty_sock);
454           
455           /* continue accepting connections */
456 @@ -1741,10 +1742,8 @@ vty_accept (struct thread *thread)
457        if ((acl = access_list_lookup (AFI_IP6, vty_ipv6_accesslist_name)) &&
458           (access_list_apply (acl, p) == FILTER_DENY))
459         {
460 -         char *buf;
461           zlog (NULL, LOG_INFO, "Vty connection refused from %s",
462 -               (buf = sockunion_su2str (&su)));
463 -         free (buf);
464 +               sockunion2str (&su, buf, SU_ADDRSTRLEN));
465           close (vty_sock);
466           
467           /* continue accepting connections */
468 @@ -1767,9 +1766,7 @@ vty_accept (struct thread *thread)
469           safe_strerror (errno));
470  
471    zlog (NULL, LOG_INFO, "Vty connection from %s",
472 -    (bufp = sockunion_su2str (&su)));
473 -  if (bufp)
474 -    XFREE (MTYPE_TMP, bufp);
475 +       sockunion2str (&su, buf, SU_ADDRSTRLEN));
476  
477    vty_create (vty_sock, &su);
478  
479 @@ -2193,8 +2190,6 @@ vty_close (struct vty *vty)
480    if (vty->fd > 0)
481      close (vty->fd);
482  
483 -  if (vty->address)
484 -    XFREE (MTYPE_TMP, vty->address);
485    if (vty->buf)
486      XFREE (MTYPE_VTY, vty->buf);
487  
488 --- a/lib/vty.h
489 +++ b/lib/vty.h
490 @@ -23,6 +23,7 @@ Software Foundation, Inc., 59 Temple Pla
491  
492  #include "thread.h"
493  #include "log.h"
494 +#include "sockunion.h"
495  
496  #define VTY_BUFSIZ 512
497  #define VTY_MAXHIST 20
498 @@ -39,9 +40,6 @@ struct vty
499    /* Node status of this vty */
500    int node;
501  
502 -  /* What address is this vty comming from. */
503 -  char *address;
504 -
505    /* Failure count */
506    int fail;
507  
508 @@ -118,6 +116,9 @@ struct vty
509    /* Timeout seconds and thread. */
510    unsigned long v_timeout;
511    struct thread *t_timeout;
512 +
513 +  /* What address is this vty comming from. */
514 +  char address[SU_ADDRSTRLEN];
515  };
516  
517  /* Integrated configuration file. */
518 --- a/zebra/zebra_rib.c
519 +++ b/zebra/zebra_rib.c
520 @@ -678,8 +678,8 @@ rib_lookup_ipv4_route (struct prefix_ipv
521      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
522      {
523        /* We are happy with either direct or recursive hexthop */
524 -      if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
525 -          nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
526 +      if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate) ||
527 +          nexthop->rgate.ipv4.s_addr == sockunion2ip (qgate))
528          return ZEBRA_RIB_FOUND_EXACT;
529        else
530        {
531 @@ -688,7 +688,7 @@ rib_lookup_ipv4_route (struct prefix_ipv
532            char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
533            inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
534            inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
535 -          inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
536 +          inet_ntop (AF_INET, &sockunion2ip (qgate), qgate_buf, INET_ADDRSTRLEN);
537            zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
538          }
539          return ZEBRA_RIB_FOUND_NOGATE;