[quagga-dev 6535] Re: update on bgpd AS4 crashes
Chris Caputo
ccaputo at alt.net
Thu Apr 30 20:53:41 IST 2009
On Thu, 30 Apr 2009, Stephen Hemminger wrote:
> On Thu, 30 Apr 2009 17:44:54 +0400 Denis Ovsienko <pilot at etcnet.org> wrote:
> > Hello, all.
> >
> > There is an issue with Quagga 0.99.11 bgpd crashing on today's version
> > of Internet, and I confirm, that the cause of the problem is in Quagga
> > code. A patch by Chris Caputo, which addresses this specific
> > issue, has been available since February, and today I have committed it
> > into the main development repository. This patch can be applied to the
> > source tree of 0.99.11 release, and it seems to be the best hotfix we
> > have today. Try it and let me know, if it helped or not. Below is an
> > URL for your convenience:
> >
> > http://code.quagga.net/cgi-bin/gitweb.cgi?p=quagga.git;a=commitdiff_plain;h=aea339f72807c34a7916d8614e030069815e144c
> >
> > This issue will get further treatment after necessary research.
> > Thank you.
> > _______________________________________________
> > Quagga-dev mailing list
> > Quagga-dev at lists.quagga.net
> > http://lists.quagga.net/mailman/listinfo/quagga-dev
>
> Thank you for fixing the bug but this looks like one of those ugly
> maintenance patches, not like the original code.
>
> 1. Multiple fixes should not have been rolled into one patch. The unsigned
> print arguments should be separate
> 2. #define TERMINATOR 1 is unhelpful ugliness
> 3. it is cleaner to pass value than to use pass by reference
> 4. better naming
> 5. don't loop reallocing, just get size right first
> 6. don't use int when should be using size_t or int
> 7. put size math in caller not the growth function.
>
> i.e
> static char *aspath_expand(char *path, size_t *space, size_t needed)
> {
> while (*space < needed)
> *space *= 2;
> return XREALLOC(path, *space);
> }
Hey Stephen,
I appreciate the feedback.
Please consider the following patch against git-current based on your
suggestions. (the realloc in the while loop was really silly on my part -
thanks especially for catching that)
Chris
---
Subject: [PATCH] Cleanup previous 'BGP 4-byte ASN bug fixes' patch
* bgpd/bgp_aspath.c: (aspath_make_str_count) Incorporate suggestions
from code review. Fix egregious realloc() while in while loop
inefficiency.
Signed-off-by: Chris Caputo <ccaputo at alt.net>
---
bgpd/bgp_aspath.c | 40 ++++++++++++++++++----------------------
1 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index a1e4608..9f55305 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -502,19 +502,14 @@ aspath_count_numas (struct aspath *aspath)
return num;
}
-static void
-aspath_make_str_big_enough (int len,
- char **str_buf,
- int *str_size,
- int count_to_be_added)
+static char *
+aspath_expand (char *path,
+ size_t *space,
+ size_t needed)
{
-#define TERMINATOR 1
- while (len + count_to_be_added + TERMINATOR > *str_size)
- {
- *str_size *= 2;
- *str_buf = XREALLOC (MTYPE_AS_STR, *str_buf, *str_size);
- }
-#undef TERMINATOR
+ while (*space < needed)
+ *space *= 2;
+ return XREALLOC (MTYPE_AS_STR, path, *space);
}
/* Convert aspath structure to string expression. */
@@ -522,8 +517,8 @@ static char *
aspath_make_str_count (struct aspath *as)
{
struct assegment *seg;
- int str_size;
- int len = 0;
+ size_t str_size;
+ size_t len = 0;
char *str_buf;
/* Empty aspath. */
@@ -562,7 +557,9 @@ aspath_make_str_count (struct aspath *as)
if (seg->type != AS_SEQUENCE)
{
- aspath_make_str_big_enough (len, &str_buf, &str_size, 1); /* %c */
+ str_buf = aspath_expand (str_buf,
+ &str_size,
+ len + 2); /* %c + '\0' */
len += snprintf (str_buf + len, str_size - len,
"%c",
aspath_delimiter_char (seg->type, AS_SEG_START));
@@ -571,13 +568,12 @@ aspath_make_str_count (struct aspath *as)
/* write out the ASNs, with their seperators, bar the last one*/
for (i = 0; i < seg->length; i++)
{
-#define APPROX_DIG_CNT(x) (x < 100000U ? 5 : 10)
- /* %u + %c + %c + " " (last two are below loop) */
- aspath_make_str_big_enough (len,
- &str_buf,
- &str_size,
- APPROX_DIG_CNT(seg->as[i]) + 1 + 1 + 1);
-
+#define APPROX_DIGIT_COUNT(x) (x < 100000U ? 5 : 10)
+ /* %u + %c + %c + " " + '\0' (last two are below loop) */
+ str_buf = aspath_expand (str_buf,
+ &str_size,
+ len + APPROX_DIGIT_COUNT(seg->as[i]) + 4);
+
len += snprintf (str_buf + len, str_size - len, "%u", seg->as[i]);
if (i < (seg->length - 1))
--
1.6.0.6
More information about the Quagga-dev
mailing list