diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ChangeLog | 36 | ||||
| -rw-r--r-- | tests/Makefile.am | 4 | ||||
| -rw-r--r-- | tests/aspath_test.c | 245 | ||||
| -rw-r--r-- | tests/bgp_capability_test.c | 157 | 
4 files changed, 379 insertions, 63 deletions
| diff --git a/tests/ChangeLog b/tests/ChangeLog index 46ab9766..94f58749 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,28 @@ +2007-09-27 Paul Jakma <paul.jakma@sun.com> + +	* aspath_test.c: Test dupe-weeding from sets. +	  Test that reconciliation merges AS_PATH and AS4_PATH where +	  former is shorter than latter. + +2007-09-26 Paul Jakma <paul.jakma@sun.com> + +	* aspath_test.c: Test AS4_PATH reconcilation where length +	  of AS_PATH and AS4_PATH is same. + +2007-09-25 Paul Jakma <paul.jakma@sun.com> + +	* bgp_capability_test.c: (general) Extend tests to validate +	  peek_for_as4_capability. +	  Add test of full OPEN Option block, with multiple capabilities, +	  both as a series of Option, and a single option. +	  Add some crap to beginning of stream, to prevent code depending +	  on getp == 0. + +2007-09-18 Paul Jakma <paul.jakma@sun.com> + +	* bgp_capability_test.c: (parse_test) update for changes to +	  peek_for_as4_capability +  2007-09-17 Paul Jakma <paul.jakma@sun.com>  	* bgp_capability_test.c: Test that peer's adv_recv and adv_nego get @@ -9,6 +34,17 @@  	* bgp_capability_test.c: new, capability parser unit tests.  	* Makefile.am: add previous. +2007-07-25 Paul Jakma <paul.jakma@sun.com> + +	* aspath_test.c: Exercise 32bit parsing. Test reconcile +	  function. +	* ecommunity_test.c: New, test AS4 ecommunity changes, positive +	  test only at this time, error cases not tested yet. +	 +2006-12-01 Juergen Kammer <j.kammer@eurodata.de> + +	* aspath_test.c: Support asn32 changes, call aspath_parse with 16 bit. +  2006-08-26 Paul Jakma <paul.jakma@sun.com>  	* heavy-wq.c: (slow_func_del,slow_func) update to match workqueue diff --git a/tests/Makefile.am b/tests/Makefile.am index a63416ff..2045496e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,7 +2,7 @@ INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib  DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"  noinst_PROGRAMS = testsig testbuffer testmemory heavy heavywq heavythread \ -		aspathtest testprivs teststream testbgpcap +		aspathtest testprivs teststream testbgpcap ecommtest  testsig_SOURCES = test-sig.c  testbuffer_SOURCES = test-buffer.c  testmemory_SOURCES = test-memory.c @@ -13,6 +13,7 @@ heavywq_SOURCES = heavy-wq.c main.c  heavythread_SOURCES = heavy-thread.c main.c  aspathtest_SOURCES = aspath_test.c  testbgpcap_SOURCES = bgp_capability_test.c +ecommtest_SOURCES = ecommunity_test.c  testsig_LDADD = ../lib/libzebra.la @LIBCAP@  testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@ @@ -24,3 +25,4 @@ heavywq_LDADD = ../lib/libzebra.la @LIBCAP@ -lm  heavythread_LDADD = ../lib/libzebra.la @LIBCAP@ -lm  aspathtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a  testbgpcap_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a +ecommtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a diff --git a/tests/aspath_test.c b/tests/aspath_test.c index 1d28dbed..c12d07a5 100644 --- a/tests/aspath_test.c +++ b/tests/aspath_test.c @@ -7,6 +7,13 @@  #include "bgpd/bgpd.h"  #include "bgpd/bgp_aspath.h" +#define VT100_RESET "\x1b[0m" +#define VT100_RED "\x1b[31m" +#define VT100_GREEN "\x1b[32m" +#define VT100_YELLOW "\x1b[33m" +#define OK VT100_GREEN "OK" VT100_RESET +#define FAILED VT100_RED "failed" VT100_RESET +  /* need these to link in libbgp */  struct zebra_privs_t *bgpd_privs = NULL;  struct thread_master *master = NULL; @@ -312,8 +319,87 @@ static struct test_segment {       /* We shouldn't ever /generate/ such paths. However, we should        * cope with them fine.        */ -     "8466 3 52737 4096 3456 {7099,8153,8153,8153}", -      "8466 3 52737 4096 3456 {7099,8153,8153,8153}", +     "8466 3 52737 4096 3456 {7099,8153}", +      "8466 3 52737 4096 3456 {7099,8153}", +      6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 }, +  }, +  { /* 18 */ +    "reconcile_lead_asp", +    "seq(6435,59408,21665) set(23456,23456,23456), seq(23456,23456,23456)", +    { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, +      0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0, +      0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 }, +    24, +    { "6435 59408 21665 {23456} 23456 23456 23456", +      "6435 59408 21665 {23456} 23456 23456 23456", +      7, 0, NOT_ALL_PRIVATE, 23456, 1, 6435 }, +  }, +  { /* 19 */ +    "reconcile_new_asp", +    "set(2457,61697,4369), seq(1842,41591,51793)", +    {  +      0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11, +      0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51 }, +    16, +    { "{2457,4369,61697} 1842 41591 51793", +      "{2457,4369,61697} 1842 41591 51793", +      4, 0, NOT_ALL_PRIVATE, 51793, 1, 2457 }, +  }, +  { /* 20 */ +    "reconcile_confed", +    "confseq(123,456,789) confset(456,124,788) seq(6435,59408,21665)" +    " set(23456,23456,23456), seq(23456,23456,23456)", +    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15, +      0x4,0x3, 0x01,0xc8, 0x00,0x7c, 0x03,0x14, +      0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, +      0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0, +      0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 }, +    40, +    { "(123 456 789) [124,456,788] 6435 59408 21665" +      " {23456} 23456 23456 23456", +      "6435 59408 21665 {23456} 23456 23456 23456", +      7, 4, NOT_ALL_PRIVATE, 23456, 1, 6435 }, +  }, +  { /* 21 */ +    "reconcile_start_trans", +    "seq(23456,23456,23456) seq(6435,59408,21665)", +    { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0, +      0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, }, +    16, +    { "23456 23456 23456 6435 59408 21665", +      "23456 23456 23456 6435 59408 21665", +      6, 0, NOT_ALL_PRIVATE, 21665, 1, 23456 }, +  }, +  { /* 22 */ +    "reconcile_start_trans4", +    "seq(1842,41591,51793) seq(6435,59408,21665)", +    { 0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51, +      0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, }, +    16, +    { "1842 41591 51793 6435 59408 21665", +      "1842 41591 51793 6435 59408 21665", +      6, 0, NOT_ALL_PRIVATE, 41591, 1, 1842 }, +  }, +  { /* 23 */ +    "reconcile_start_trans_error", +    "seq(23456,23456,23456) seq(6435,59408)", +    { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0, +      0x2,0x2, 0x19,0x23, 0xe8,0x10, }, +    14, +    { "23456 23456 23456 6435 59408", +      "23456 23456 23456 6435 59408", +      5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456 }, +  }, +  { /* 24 */  +    "redundantset2", +    "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)", +    { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80, +      0x1,0x5, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9, 0x1b,0xbb,}, +    24, +    { +     /* We should weed out duplicate set members. */ +     "8466 3 52737 4096 3456 {7099,8153}", +      "8466 3 52737 4096 3456 {7099,8153}",        6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },    },    { NULL, NULL, {0}, 0, { NULL, 0, 0 } } @@ -432,13 +518,43 @@ static struct tests {    { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },  }; -struct tests aggregate_tests[] = +struct tests reconcile_tests[] =  { -  { &test_segments[0], &test_segments[1], -    { "{3,4,4096,8466,8722,52737}", -      "{3,4,4096,8466,8722,52737}", -      1, 0, NOT_ALL_PRIVATE, 52737, 1, NULL_ASN }, +  { &test_segments[18], &test_segments[19], +    { "6435 59408 21665 {2457,4369,61697} 1842 41591 51793", +      "6435 59408 21665 {2457,4369,61697} 1842 41591 51793", +      7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 }, +  }, +  { &test_segments[19], &test_segments[18], +    /* AS_PATH (19) has more hops than NEW_AS_PATH, +     * so just AS_PATH should be used (though, this practice +     * is bad imho). +     */ +    { "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456", +      "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456", +      11, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 }, +  }, +  { &test_segments[20], &test_segments[19], +    { "(123 456 789) [124,456,788] 6435 59408 21665" +      " {2457,4369,61697} 1842 41591 51793", +      "6435 59408 21665 {2457,4369,61697} 1842 41591 51793", +      7, 4, NOT_ALL_PRIVATE, 51793, 1, 6435 }, +  }, +  { &test_segments[21], &test_segments[22], +    { "1842 41591 51793 6435 59408 21665", +      "1842 41591 51793 6435 59408 21665", +      6, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 }, +  }, +  { &test_segments[23], &test_segments[22], +    { "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665", +      "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665", +      11, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },    }, +  { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } }, +}; +   +struct tests aggregate_tests[] = +{    { &test_segments[0], &test_segments[2],      { "8466 3 52737 4096 {4,8722}",        "8466 3 52737 4096 {4,8722}", @@ -459,6 +575,13 @@ struct tests aggregate_tests[] =        "8466 {2,3,4,4096,8722,52737}",        2, 0, NOT_ALL_PRIVATE, 2, 20000, 8466 },    }, + +  { &test_segments[5], &test_segments[18], +    { "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}", +      "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}", +      4, 0, NOT_ALL_PRIVATE, 41590, 1, 6435 }, +  }, +    { NULL, NULL, { NULL, 0, 0}  },  }; @@ -498,7 +621,7 @@ struct compare_tests  /* make an aspath from a data stream */  static struct aspath * -make_aspath (const u_char *data, size_t len) +make_aspath (const u_char *data, size_t len, int use32bit)  {    struct stream *s = NULL;    struct aspath *as; @@ -508,7 +631,7 @@ make_aspath (const u_char *data, size_t len)        s = stream_new (len);        stream_put (s, data, len);      } -  as = aspath_parse (s, len); +  as = aspath_parse (s, len, use32bit);    if (s)      stream_free (s); @@ -535,18 +658,27 @@ printbytes (const u_char *bytes, int len)  static int  validate (struct aspath *as, const struct test_spec *sp)  { -  size_t bytes; +  size_t bytes, bytes4;    int fails = 0;    const u_char *out; -  struct aspath *asinout, *asconfeddel, *asstr; +  static struct stream *s; +  struct aspath *asinout, *asconfeddel, *asstr, *as4;    out = aspath_snmp_pathseg (as, &bytes); -  asinout = make_aspath (out, bytes); +  asinout = make_aspath (out, bytes, 0); +   +  /* Excercise AS4 parsing a bit, with a dogfood test */ +  if (!s) +    s = stream_new (4096); +  bytes4 = aspath_put (s, as, 1); +  as4 = make_aspath (STREAM_DATA(s), bytes4, 1);    asstr = aspath_str2aspath (sp->shouldbe);    asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout)); +  printf ("got: %s\n", aspath_print(as)); +      /* the parsed path should match the specified 'shouldbe' string.     * We should pass the "eat our own dog food" test, be able to output     * this path and then input it again. Ie the path resulting from: @@ -562,6 +694,10 @@ validate (struct aspath *as, const struct test_spec *sp)     *     * aspath_str2aspath() and shouldbe should match     * +   * We do the same for: +   * +   *   aspath_parse(aspath_put(as,USE32BIT)) +   *     * Confederation related tests:      * - aspath_delete_confed_seq(aspath) should match shouldbe_confed     * - aspath_delete_confed_seq should be idempotent. @@ -571,6 +707,8 @@ validate (struct aspath *as, const struct test_spec *sp)        || (aspath_key_make (as) != aspath_key_make (asinout))           /* by string */        || strcmp(aspath_print (asinout), sp->shouldbe) +         /* By 4-byte parsing */ +      || strcmp(aspath_print (as4), sp->shouldbe)           /* by various path counts */        || (aspath_count_hops (as) != sp->hops)        || (aspath_count_confeds (as) != sp->confeds) @@ -580,7 +718,7 @@ validate (struct aspath *as, const struct test_spec *sp)        failed++;        fails++;        printf ("shouldbe:\n%s\n", sp->shouldbe); -      printf ("got:\n%s\n", aspath_print(as)); +      printf ("as4:\n%s\n", aspath_print (as4));        printf ("hash keys: in: %d out->in: %d\n",                 aspath_key_make (as), aspath_key_make (asinout));        printf ("hops: %d, counted %d %d\n", sp->hops,  @@ -635,11 +773,13 @@ validate (struct aspath *as, const struct test_spec *sp)                aspath_private_as_check (as));      }    aspath_unintern (asinout); +  aspath_unintern (as4); +      aspath_free (asconfeddel);    aspath_free (asstr); +  stream_reset (s);    return fails; -    }  static void @@ -650,9 +790,9 @@ empty_get_test ()    printf ("empty_get_test, as: %s\n",aspath_print (as));    if (!validate (as, &sp)) -    printf ("OK\n"); +    printf ("%s\n", OK);    else -    printf ("failed!\n"); +    printf ("%s!\n", FAILED);    printf ("\n"); @@ -667,14 +807,14 @@ parse_test (struct test_segment *t)    printf ("%s: %s\n", t->name, t->desc); -  asp = make_aspath (t->asdata, t->len); +  asp = make_aspath (t->asdata, t->len, 0);    printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));    if (!validate (asp, &t->sp)) -    printf ("OK\n"); +    printf (OK "\n");    else -    printf ("failed\n"); +    printf (FAILED "\n");    printf ("\n");    aspath_unintern (asp); @@ -689,8 +829,8 @@ prepend_test (struct tests *t)    printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);    printf ("to %s: %s\n", t->test2->name, t->test2->desc); -  asp1 = make_aspath (t->test1->asdata, t->test1->len); -  asp2 = make_aspath (t->test2->asdata, t->test2->len); +  asp1 = make_aspath (t->test1->asdata, t->test1->len, 0); +  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);    ascratch = aspath_dup (asp2);    aspath_unintern (asp2); @@ -700,9 +840,9 @@ prepend_test (struct tests *t)    printf ("aspath: %s\n", aspath_print (asp2));    if (!validate (asp2, &t->sp)) -    printf ("OK\n"); +    printf ("%s\n", OK);    else -    printf ("failed!\n"); +    printf ("%s!\n", FAILED);    printf ("\n");    aspath_unintern (asp1); @@ -717,7 +857,7 @@ empty_prepend_test (struct test_segment *t)    printf ("empty prepend %s: %s\n", t->name, t->desc); -  asp1 = make_aspath (t->asdata, t->len); +  asp1 = make_aspath (t->asdata, t->len, 0);    asp2 = aspath_empty ();    ascratch = aspath_dup (asp2); @@ -728,15 +868,41 @@ empty_prepend_test (struct test_segment *t)    printf ("aspath: %s\n", aspath_print (asp2));    if (!validate (asp2, &t->sp)) -    printf ("OK\n"); +    printf (OK "\n");    else -    printf ("failed!\n"); +    printf (FAILED "!\n");    printf ("\n");    aspath_unintern (asp1);    aspath_free (asp2);  } +/* as2+as4 reconciliation testing */ +static void +as4_reconcile_test (struct tests *t) +{ +  struct aspath *asp1, *asp2, *ascratch; +   +  printf ("reconciling %s:\n  %s\n", t->test1->name, t->test1->desc); +  printf ("with %s:\n  %s\n", t->test2->name, t->test2->desc); +   +  asp1 = make_aspath (t->test1->asdata, t->test1->len, 0); +  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0); +   +  ascratch = aspath_reconcile_as4 (asp1, asp2); +   +  if (!validate (ascratch, &t->sp)) +    printf (OK "\n"); +  else +    printf (FAILED "!\n"); +   +  printf ("\n"); +  aspath_unintern (asp1); +  aspath_unintern (asp2); +  aspath_free (ascratch); +} + +  /* aggregation testing */  static void  aggregate_test (struct tests *t) @@ -746,17 +912,15 @@ aggregate_test (struct tests *t)    printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);    printf ("with %s: %s\n", t->test2->name, t->test2->desc); -  asp1 = make_aspath (t->test1->asdata, t->test1->len); -  asp2 = make_aspath (t->test2->asdata, t->test2->len); +  asp1 = make_aspath (t->test1->asdata, t->test1->len, 0); +  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);    ascratch = aspath_aggregate (asp1, asp2); -  printf ("aspath: %s\n", aspath_print (ascratch)); -      if (!validate (ascratch, &t->sp)) -    printf ("OK\n"); +    printf (OK "\n");    else -    printf ("failed!\n"); +    printf (FAILED "!\n");    printf ("\n");    aspath_unintern (asp1); @@ -782,8 +946,8 @@ cmp_test ()        printf ("left cmp %s: %s\n", t1->name, t1->desc);        printf ("and %s: %s\n", t2->name, t2->desc); -      asp1 = make_aspath (t1->asdata, t1->len); -      asp2 = make_aspath (t2->asdata, t2->len); +      asp1 = make_aspath (t1->asdata, t1->len, 0); +      asp2 = make_aspath (t2->asdata, t2->len, 0);        if (aspath_cmp_left (asp1, asp2) != left_compare[i].shouldbe_cmp            || aspath_cmp_left (asp2, asp1) != left_compare[i].shouldbe_cmp @@ -792,7 +956,8 @@ cmp_test ()            || aspath_cmp_left_confed (asp2, asp1)                  != left_compare[i].shouldbe_confed)          { -          printf ("failed\n"); +          failed++; +          printf (FAILED "\n");            printf ("result should be: cmp: %d, confed: %d\n",                     left_compare[i].shouldbe_cmp,                    left_compare[i].shouldbe_confed); @@ -801,10 +966,9 @@ cmp_test ()                    aspath_cmp_left_confed (asp1, asp2));            printf("path1: %s\npath2: %s\n", aspath_print (asp1),                   aspath_print (asp2)); -          failed++;          }        else -        printf ("OK\n"); +        printf (OK "\n");        printf ("\n");        aspath_unintern (asp1); @@ -831,6 +995,13 @@ main (void)    while (aggregate_tests[i].test1)      aggregate_test (&aggregate_tests[i++]); +  i = 0; +   +  while (reconcile_tests[i].test1) +    as4_reconcile_test (&reconcile_tests[i++]); +   +  i = 0; +      cmp_test();    i = 0; diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c index 020dfb0f..6771b579 100644 --- a/tests/bgp_capability_test.c +++ b/tests/bgp_capability_test.c @@ -15,8 +15,9 @@  #define VT100_YELLOW "\x1b[33m" -#define OPEN	0 -#define DYNCAP	1 +#define CAPABILITY 0 +#define DYNCAP     1 +#define OPT_PARAM  2  /* need these to link in libbgp */  struct zebra_privs_t *bgpd_privs = NULL; @@ -34,7 +35,8 @@ static struct test_segment {  #define SHOULD_PARSE	0  #define SHOULD_ERR	-1    int parses; /* whether it should parse or not */ - +  int peek_for; /* what peek_for_as4_capability should say */ +      /* AFI/SAFI validation */    int validate_afi;    afi_t afi; @@ -76,54 +78,55 @@ static struct test_segment mp_segments[] =    { "MP4",      "MP IP/Uni",      { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 }, -    6, SHOULD_PARSE, AFI_IP, SAFI_UNICAST, +    6, SHOULD_PARSE, 0, +    1, AFI_IP, SAFI_UNICAST, VALID_AFI,    },    { "MPv6",      "MP IPv6/Uni",      { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 }, -    6, SHOULD_PARSE,  +    6, SHOULD_PARSE, 0,      1, AFI_IP6, SAFI_UNICAST, VALID_AFI,    },    /* 5 */    { "MP2",      "MP IP/Multicast",      { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 }, -    6, SHOULD_PARSE,  +    6, SHOULD_PARSE, 0,      1, AFI_IP, SAFI_MULTICAST, VALID_AFI,    },    /* 6 */    { "MP3",      "MP IP6/VPNv4",      { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 }, -    6, SHOULD_PARSE, /* parses, but invalid afi,safi */ +    6, SHOULD_PARSE, 0, /* parses, but invalid afi,safi */      1, AFI_IP6, BGP_SAFI_VPNV4, INVALID_AFI,    },    /* 7 */    { "MP5",      "MP IP6/MPLS-VPN",      { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 }, -    6, SHOULD_PARSE,  +    6, SHOULD_PARSE, 0,      1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,    },    /* 8 */    { "MP6",      "MP IP4/VPNv4",      { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 }, -    6, SHOULD_PARSE,  +    6, SHOULD_PARSE, 0,      1, AFI_IP, BGP_SAFI_VPNV4, VALID_AFI,    },      /* 9 */    { "MP7",      "MP IP4/VPNv6",      { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x81 }, -    6, SHOULD_PARSE, /* parses, but invalid afi,safi tuple */ +    6, SHOULD_PARSE, 0, /* parses, but invalid afi,safi tuple */      1, AFI_IP, BGP_SAFI_VPNV6, INVALID_AFI,    },    /* 10 */    { "MP8",      "MP unknown AFI",      { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 }, -    6, SHOULD_PARSE,  +    6, SHOULD_PARSE, 0,      1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */    },    /* 11 */ @@ -136,7 +139,7 @@ static struct test_segment mp_segments[] =    { "MP-overflow",      "MP IP4/Unicast, length too long",      { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 }, -    6, SHOULD_ERR, +    6, SHOULD_ERR, 0,      1, AFI_IP, SAFI_UNICAST, VALID_AFI,    },    { NULL, NULL, {0}, 0, 0} @@ -290,8 +293,8 @@ static struct test_segment misc_segments[] =    /* 19 */    { "AS4",      "AS4 capability", -    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, -    6, SHOULD_PARSE, +    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */ +    6, SHOULD_PARSE, 2882400018,    },    /* 20 */    { "GR", @@ -367,7 +370,7 @@ static struct test_segment misc_segments[] =    { NULL, NULL, {0}, 0, 0}  }; - +/* DYNAMIC message */  struct test_segment dynamic_cap_msgs[] =   {    { "DynCap", @@ -397,18 +400,97 @@ struct test_segment dynamic_cap_msgs[] =    },    { NULL, NULL, {0}, 0, 0}  }; + +/* Entire Optional-Parameters block */ +struct test_segment opt_params[] = +{ +  { "Cap-singlets", +    "One capability per Optional-Param", +    { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */ +      0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */ +      0x02, 0x02, 0x80, 0x00, /* RR (old) */ +      0x02, 0x02, 0x02, 0x00, /* RR */   +    }, +    24, SHOULD_PARSE, +  }, +  { "Cap-series", +    "Series of capability, one Optional-Param", +    { 0x02, 0x10, +      0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */ +      0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */ +      0x80, 0x00, /* RR (old) */ +      0x02, 0x00, /* RR */   +    }, +    18, SHOULD_PARSE, +  }, +  { "AS4more", +    "AS4 capability after other caps (singlets)", +    { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */ +      0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */ +      0x02, 0x02, 0x80, 0x00, /* RR (old) */ +      0x02, 0x02, 0x02, 0x00, /* RR */ +      0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06  /* AS4: 1996614 */ +    }, +    32, SHOULD_PARSE, 196614, +  }, +  { "AS4series", +    "AS4 capability, in series of capabilities", +    { 0x02, 0x16, +      0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */ +      0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */ +      0x80, 0x00, /* RR (old) */ +      0x02, 0x00, /* RR */   +      0x41, 0x04, 0x00, 0x03, 0x00, 0x06  /* AS4: 1996614 */ +    }, +    24, SHOULD_PARSE, 196614, +  }, +  { "AS4real", +    "AS4 capability, in series of capabilities", +    { +      0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */ +      0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */ +      0x02, 0x02, 0x80, 0x00, /* RR old */ +      0x02, 0x02, 0x02, 0x00, /* RR */ +      0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */ +    }, +    32, SHOULD_PARSE, 196614, +  }, +  { "AS4real2", +    "AS4 capability, in series of capabilities", +    { +      0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, +      0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, +      0x02, 0x02, 0x80, 0x00, +      0x02, 0x02, 0x02, 0x00, +      0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03, +      0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03, +      0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03, +      0x02, 0x02, 0x42, 0x00, +    }, +    58, SHOULD_PARSE, 64515, +  }, + +  { NULL, NULL, {0}, 0, 0} +}; +  /* basic parsing test */  static void  parse_test (struct peer *peer, struct test_segment *t, int type)  {    int ret;    int capability = 0; +  as_t as4 = 0;    int oldfailed = failed; +  int len = t->len; +#define RANDOM_FUZZ 35    stream_reset (peer->ibuf); +  stream_put (peer->ibuf, NULL, RANDOM_FUZZ); +  stream_set_getp (peer->ibuf, RANDOM_FUZZ); +      switch (type)      { -      case OPEN: +      case CAPABILITY:          stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);          stream_putc (peer->ibuf, t->len);          break; @@ -422,11 +504,20 @@ parse_test (struct peer *peer, struct test_segment *t, int type)    stream_write (peer->ibuf, t->data, t->len);    printf ("%s: %s\n", t->name, t->desc); -   +    switch (type)      { -      case OPEN: -        ret = bgp_open_option_parse (peer, t->len + 2, &capability); +      case CAPABILITY: +        len += 2; /* to cover the OPT-Param header */ +      case OPT_PARAM: +        printf ("len: %u\n", len); +        /* peek_for_as4 wants getp at capibility*/ +        as4 = peek_for_as4_capability (peer, len); +        printf ("peek_for_as4: as4 is %u\n", as4); +        /* and it should leave getp as it found it */ +        assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ); +         +        ret = bgp_open_option_parse (peer, len, &capability);          break;        case DYNCAP:          ret = bgp_capability_receive (peer, t->len); @@ -458,18 +549,27 @@ parse_test (struct peer *peer, struct test_segment *t, int type)          }      } +  if (as4 != t->peek_for) +    { +      printf ("as4 %u != %u\n", as4, t->peek_for); +      failed++; +    } +      printf ("parsed?: %s\n", ret ? "no" : "yes");    if (ret != t->parses)      failed++;    if (tty) -    printf ("%s\n", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET  +    printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET                                            : VT100_GREEN "OK" VT100_RESET);    else -    printf ("%s\n", (failed > oldfailed) ? "failed!" : "OK" ); +    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" ); +   +  if (failed) +    printf (" (%u)", failed); -  printf ("\n"); +  printf ("\n\n");  }  static struct bgp *bgp; @@ -485,10 +585,12 @@ main (void)    conf_bgp_debug_events = -1UL;    conf_bgp_debug_packet = -1UL;    conf_bgp_debug_normal = -1UL; +  conf_bgp_debug_as4 = -1UL;    term_bgp_debug_fsm = -1UL;    term_bgp_debug_events = -1UL;    term_bgp_debug_packet = -1UL;    term_bgp_debug_normal = -1UL; +  term_bgp_debug_as4 = -1UL;    master = thread_master_create ();    bgp_master_init (); @@ -500,6 +602,7 @@ main (void)      return -1;    peer = peer_create_accept (bgp); +  peer->host = "foo";    for (i = AFI_IP; i < AFI_MAX; i++)      for (j = SAFI_UNICAST; j < SAFI_MAX; j++) @@ -510,18 +613,22 @@ main (void)    i = 0;    while (mp_segments[i].name) -    parse_test (peer, &mp_segments[i++], OPEN); +    parse_test (peer, &mp_segments[i++], CAPABILITY);    /* These tests assume mp_segments tests set at least     * one of the afc_nego's     */    i = 0;    while (test_segments[i].name)    -    parse_test (peer, &test_segments[i++], OPEN); +    parse_test (peer, &test_segments[i++], CAPABILITY);    i = 0;    while (misc_segments[i].name) -    parse_test (peer, &misc_segments[i++], OPEN); +    parse_test (peer, &misc_segments[i++], CAPABILITY); + +  i = 0; +  while (opt_params[i].name) +    parse_test (peer, &opt_params[i++], OPT_PARAM);    SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);    peer->status = Established; | 
