]> git.proxmox.com Git - mirror_frr.git/commitdiff
tests: reorganize tests hierarchically
authorChristian Franke <chris@opensourcerouting.org>
Fri, 3 Feb 2017 15:58:11 +0000 (16:58 +0100)
committerChristian Franke <chris@opensourcerouting.org>
Wed, 8 Feb 2017 18:09:35 +0000 (19:09 +0100)
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
67 files changed:
tests/.gitignore
tests/Makefile.am
tests/aspath_test.c [deleted file]
tests/bgp_capability_test.c [deleted file]
tests/bgp_mp_attr_test.c [deleted file]
tests/bgp_mpath_test.c [deleted file]
tests/bgpd/test_aspath.c [new file with mode: 0644]
tests/bgpd/test_capability.c [new file with mode: 0644]
tests/bgpd/test_ecommunity.c [new file with mode: 0644]
tests/bgpd/test_mp_attr.c [new file with mode: 0644]
tests/bgpd/test_mpath.c [new file with mode: 0644]
tests/common-cli.c [deleted file]
tests/common-cli.h [deleted file]
tests/ecommunity_test.c [deleted file]
tests/heavy-thread.c [deleted file]
tests/heavy-wq.c [deleted file]
tests/heavy.c [deleted file]
tests/helpers/c/main.c [new file with mode: 0644]
tests/helpers/c/prng.c [new file with mode: 0644]
tests/helpers/c/prng.h [new file with mode: 0644]
tests/helpers/c/tests.h [new file with mode: 0644]
tests/lib/cli/common_cli.c [new file with mode: 0644]
tests/lib/cli/common_cli.h [new file with mode: 0644]
tests/lib/cli/test_cli.c [new file with mode: 0644]
tests/lib/cli/test_cli.in [new file with mode: 0644]
tests/lib/cli/test_cli.refout [new file with mode: 0644]
tests/lib/cli/test_commands.c [new file with mode: 0644]
tests/lib/cli/test_commands.in [new file with mode: 0644]
tests/lib/cli/test_commands.refout [new file with mode: 0644]
tests/lib/test_buffer.c [new file with mode: 0644]
tests/lib/test_checksum.c [new file with mode: 0644]
tests/lib/test_heavy.c [new file with mode: 0644]
tests/lib/test_heavy_thread.c [new file with mode: 0644]
tests/lib/test_heavy_wq.c [new file with mode: 0644]
tests/lib/test_memory.c [new file with mode: 0644]
tests/lib/test_nexthop_iter.c [new file with mode: 0644]
tests/lib/test_privs.c [new file with mode: 0644]
tests/lib/test_segv.c [new file with mode: 0644]
tests/lib/test_sig.c [new file with mode: 0644]
tests/lib/test_srcdest_table.c [new file with mode: 0644]
tests/lib/test_stream.c [new file with mode: 0644]
tests/lib/test_stream.refout [new file with mode: 0644]
tests/lib/test_table.c [new file with mode: 0644]
tests/lib/test_timer_correctness.c [new file with mode: 0644]
tests/lib/test_timer_performance.c [new file with mode: 0644]
tests/main.c [deleted file]
tests/prng.c [deleted file]
tests/prng.h [deleted file]
tests/table_test.c [deleted file]
tests/test-buffer.c [deleted file]
tests/test-checksum.c [deleted file]
tests/test-cli.c [deleted file]
tests/test-commands.c [deleted file]
tests/test-memory.c [deleted file]
tests/test-nexthop-iter.c [deleted file]
tests/test-privs.c [deleted file]
tests/test-segv.c [deleted file]
tests/test-sig.c [deleted file]
tests/test-srcdest-table.c [deleted file]
tests/test-stream.c [deleted file]
tests/test-timer-correctness.c [deleted file]
tests/test-timer-performance.c [deleted file]
tests/testcli.in [deleted file]
tests/testcli.refout [deleted file]
tests/testcommands.in [deleted file]
tests/testcommands.refout [deleted file]
tests/tests.h [deleted file]

index 3002b27149e1172e22cb26506d3289e0216fe636..1642fa9493d57314ff941a33731009b3e8132157 100644 (file)
@@ -16,26 +16,26 @@ TAGS
 *.xml
 .arch-inventory
 .arch-ids
-aspathtest
-ecommtest
-heavy
-heavythread
-heavywq
-tabletest
-test-timer-correctness
-test-timer-performance
-testbgpcap
-testbgpmpath
-testbgpmpattr
-testbuffer
-testchecksum
-testcli
-testmemory
-testprivs
-testsegv
-testsig
-teststream
-testnexthopiter
-testcommands
-test-commands-defun.c
-site.exp
+/bgpd/test_aspath
+/bgpd/test_capability
+/bgpd/test_ecommunity
+/bgpd/test_mp_attr
+/bgpd/test_mpath
+/lib/cli/test_cli
+/lib/cli/test_commands
+/lib/cli/test_commands_defun.c
+/lib/test_buffer
+/lib/test_checksum
+/lib/test_heavy
+/lib/test_heavy_thread
+/lib/test_heavy_wq
+/lib/test_memory
+/lib/test_nexthop_iter
+/lib/test_privs
+/lib/test_srcdest_table
+/lib/test_segv
+/lib/test_sig
+/lib/test_stream
+/lib/test_table
+/lib/test_timer_correctness
+/lib/test_timer_performance
index bee9feaf1ec19901a53850d6f09e72b75d512308..86e432648c3803be2f8927c4175e47fd1c688460 100644 (file)
-AUTOMAKE_OPTIONS    = dejagnu
-DEJATOOL = libfrr
-
-SUBDIRS = \
-       bgpd.tests \
-       libfrr.tests
-
-EXTRA_DIST = \
-       config/unix.exp \
-       lib/bgpd.exp \
-       lib/libfrr.exp \
-       global-conf.exp \
-       testcommands.in \
-       testcommands.refout \
-       testcli.in \
-       testcli.refout
-
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+AUTOMAKE_OPTIONS = subdir-objects
+AM_CPPFLAGS = \
+       -I.. \
+       -I$(top_srcdir) \
+       -I$(top_srcdir)/lib \
+       -I$(top_builddir)/lib \
+       -I$(top_srcdir)/tests/helpers/c \
+       -I$(top_builddir)/tests/helpers/c \
+       -O
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 
 if BGPD
-TESTS_BGPD = aspathtest testbgpcap ecommtest testbgpmpattr testbgpmpath
-DEJATOOL += bgpd
+TESTS_BGPD = \
+       bgpd/test_aspath \
+       bgpd/test_capability \
+       bgpd/test_ecommunity \
+       bgpd/test_mp_attr \
+       bgpd/test_mpath
 else
 TESTS_BGPD =
 endif
 
 if ENABLE_BGP_VNC
-BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a 
+BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a
 else
 BGP_VNC_RFP_LIB =
 endif
 
-check_PROGRAMS = testsig testsegv testbuffer testmemory heavy heavywq heavythread \
-               testprivs teststream testchecksum tabletest testnexthopiter \
-               testcommands test-timer-correctness test-timer-performance \
-               testcli \
-               test-srcdest-table \
-               $(TESTS_BGPD)
+check_PROGRAMS = \
+       lib/test_buffer \
+       lib/test_checksum \
+       lib/test_heavy_thread \
+       lib/test_heavy_wq \
+       lib/test_heavy \
+       lib/test_memory \
+       lib/test_nexthop_iter \
+       lib/test_privs \
+       lib/test_srcdest_table \
+       lib/test_segv \
+       lib/test_sig \
+       lib/test_stream \
+       lib/test_table \
+       lib/test_timer_correctness \
+       lib/test_timer_performance \
+       lib/cli/test_cli \
+       lib/cli/test_commands \
+       $(TESTS_BGPD)
 
 ../vtysh/vtysh_cmd.c:
        $(MAKE) -C ../vtysh vtysh_cmd.c
 
-test-commands-defun.c: ../vtysh/vtysh_cmd.c
+lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c
        sed \
                -e 's/"vtysh\.h"/"tests.h"/' \
                -e 's/vtysh_init_cmd/test_init_cmd/' \
                -e 's/VTYSH_[A-Z][A-Z_0-9]*/0/g' \
                < ../vtysh/vtysh_cmd.c \
-               > test-commands-defun.c
+               > "$@"
+
+BUILT_SOURCES = lib/cli/test_commands_defun.c
+
+noinst_HEADERS = \
+       ./helpers/c/prng.h \
+       ./helpers/c/tests.h \
+       ./lib/cli/common_cli.h
 
-BUILT_SOURCES = test-commands-defun.c
-noinst_HEADERS = prng.h tests.h common-cli.h
+lib_test_buffer_SOURCES = lib/test_buffer.c
+lib_test_checksum_SOURCES = lib/test_checksum.c
+lib_test_heavy_thread_SOURCES = lib/test_heavy_thread.c helpers/c/main.c
+lib_test_heavy_wq_SOURCES = lib/test_heavy_wq.c helpers/c/main.c
+lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c
+lib_test_memory_SOURCES = lib/test_memory.c
+lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c
+lib_test_privs_SOURCES = lib/test_privs.c
+lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \
+                                 helpers/c/prng.c
+lib_test_segv_SOURCES = lib/test_segv.c
+lib_test_sig_SOURCES = lib/test_sig.c
+lib_test_stream_SOURCES = lib/test_stream.c
+lib_test_table_SOURCES = lib/test_table.c
+lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \
+                                     helpers/c/prng.c
+lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \
+                                     helpers/c/prng.c
+lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c
+lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \
+                                lib/cli/test_commands.c \
+                                helpers/c/prng.c
+bgpd_test_aspath_SOURCES = bgpd/test_aspath.c
+bgpd_test_capability_SOURCES = bgpd/test_capability.c
+bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
+bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
+bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
 
-testcli_SOURCES = test-cli.c common-cli.c
-testsig_SOURCES = test-sig.c
-testsegv_SOURCES = test-segv.c
-testbuffer_SOURCES = test-buffer.c
-testmemory_SOURCES = test-memory.c
-testprivs_SOURCES = test-privs.c
-teststream_SOURCES = test-stream.c
-heavy_SOURCES = heavy.c main.c
-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
-testbgpmpattr_SOURCES =  bgp_mp_attr_test.c
-testchecksum_SOURCES = test-checksum.c
-testbgpmpath_SOURCES = bgp_mpath_test.c
-tabletest_SOURCES = table_test.c
-testnexthopiter_SOURCES = test-nexthop-iter.c prng.c
-testcommands_SOURCES = test-commands-defun.c test-commands.c prng.c
-test_timer_correctness_SOURCES = test-timer-correctness.c prng.c
-test_timer_performance_SOURCES = test-timer-performance.c prng.c
-test_srcdest_table_SOURCES = test-srcdest-table.c prng.c
+ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@
+BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm
 
-testcli_LDADD = ../lib/libfrr.la @LIBCAP@
-testsig_LDADD = ../lib/libfrr.la @LIBCAP@
-testsegv_LDADD = ../lib/libfrr.la @LIBCAP@
-testbuffer_LDADD = ../lib/libfrr.la @LIBCAP@
-testmemory_LDADD = ../lib/libfrr.la @LIBCAP@
-testprivs_LDADD = ../lib/libfrr.la @LIBCAP@
-teststream_LDADD = ../lib/libfrr.la @LIBCAP@
-heavy_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-heavywq_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-heavythread_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-aspathtest_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-testbgpcap_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-ecommtest_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-testbgpmpattr_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-testchecksum_LDADD = ../lib/libfrr.la @LIBCAP@ 
-testbgpmpath_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ -lm
-tabletest_LDADD = ../lib/libfrr.la @LIBCAP@ -lm
-testnexthopiter_LDADD = ../lib/libfrr.la @LIBCAP@
-testcommands_LDADD = ../lib/libfrr.la @LIBCAP@
-test_timer_correctness_LDADD = ../lib/libfrr.la @LIBCAP@
-test_timer_performance_LDADD = ../lib/libfrr.la @LIBCAP@
-test_srcdest_table_LDADD = ../lib/libfrr.la @LIBCAP@
+lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
+lib_test_checksum_LDADD = $(ALL_TESTS_LDADD)
+lib_test_heavy_thread_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_heavy_wq_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_heavy_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_memory_LDADD = $(ALL_TESTS_LDADD)
+lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD)
+lib_test_privs_LDADD = $(ALL_TESTS_LDADD)
+lib_test_srcdest_table_LDADD = $(ALL_TESTS_LDADD)
+lib_test_segv_LDADD = $(ALL_TESTS_LDADD)
+lib_test_sig_LDADD = $(ALL_TESTS_LDADD)
+lib_test_stream_LDADD = $(ALL_TESTS_LDADD)
+lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm
+lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD)
+lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD)
+lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
+lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
+bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
diff --git a/tests/aspath_test.c b/tests/aspath_test.c
deleted file mode 100644 (file)
index f3999cb..0000000
+++ /dev/null
@@ -1,1389 +0,0 @@
-/* 
- * Copyright (C) 2005 Sun Microsystems, Inc.
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-
-#include "vty.h"
-#include "stream.h"
-#include "privs.h"
-#include "queue.h"
-#include "filter.h"
-
-#include "bgpd/bgpd.h"
-#include "bgpd/bgp_aspath.h"
-#include "bgpd/bgp_attr.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;
-
-static int failed = 0;
-
-/* specification for a test - what the results should be */
-struct test_spec 
-{
-  const char *shouldbe; /* the string the path should parse to */
-  const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
-  const unsigned int hops; /* aspath_count_hops result */
-  const unsigned int confeds; /* aspath_count_confeds */
-  const int private_as; /* whether the private_as check should pass or fail */
-#define NOT_ALL_PRIVATE 0
-#define ALL_PRIVATE 1
-  const as_t does_loop; /* an ASN which should trigger loop-check */
-  const as_t doesnt_loop; /* one which should not */
-  const as_t first; /* the first ASN, if there is one */
-#define NULL_ASN 0
-};
-
-
-/* test segments to parse and validate, and use for other tests */
-static struct test_segment {
-  const char *name;
-  const char *desc;
-  const u_char asdata[1024];
-  int len;
-  struct test_spec sp;
-} test_segments [] = 
-{
-  { /* 0 */ 
-    "seq1",
-    "seq(8466,3,52737,4096)",
-    { 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
-    10,
-    { "8466 3 52737 4096",
-      "8466 3 52737 4096",
-      4, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
-  },
-  { /* 1 */
-    "seq2",
-    "seq(8722) seq(4)",
-    { 0x2,0x1, 0x22,0x12,
-      0x2,0x1, 0x00,0x04 },
-    8,
-    { "8722 4",
-      "8722 4",
-      2, 0, NOT_ALL_PRIVATE, 4, 5, 8722, },
-  },
-  { /* 2 */
-    "seq3",
-    "seq(8466,3,52737,4096,8722,4)",
-    { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 
-               0x22,0x12, 0x00,0x04},
-    14,
-    { "8466 3 52737 4096 8722 4",
-      "8466 3 52737 4096 8722 4",
-       6, 0, NOT_ALL_PRIVATE, 3, 5, 8466 },
-  },
-  { /* 3 */
-    "seqset",
-    "seq(8482,51457) set(5204)",
-    { 0x2,0x2, 0x21,0x22, 0xc9,0x01,
-      0x1,0x1, 0x14,0x54 },
-    10,
-    { "8482 51457 {5204}",
-      "8482 51457 {5204}",
-      3, 0, NOT_ALL_PRIVATE, 5204, 51456, 8482},
-  },
-  { /* 4 */
-    "seqset2",
-    "seq(8467, 59649) set(4196,48658) set(17322,30745)",
-    { 0x2,0x2, 0x21,0x13, 0xe9,0x01,
-      0x1,0x2, 0x10,0x64, 0xbe,0x12,
-      0x1,0x2, 0x43,0xaa, 0x78,0x19 },    
-    18,
-    { "8467 59649 {4196,48658} {17322,30745}",
-      "8467 59649 {4196,48658} {17322,30745}",
-      4, 0, NOT_ALL_PRIVATE, 48658, 1, 8467},
-  },
-  { /* 5 */
-    "multi",
-    "seq(6435,59408,21665) set(2457,61697,4369), seq(1842,41590,51793)",
-    { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
-      0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
-      0x2,0x3, 0x07,0x32, 0xa2,0x76, 0xca,0x51 },
-    24,
-    { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
-      "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
-      7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
-  },
-  { /* 6 */
-    "confed",
-    "confseq(123,456,789)",
-    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15 },
-    8,
-    { "(123 456 789)",
-      "",
-      0, 3, NOT_ALL_PRIVATE, 789, 1, NULL_ASN },
-  },
-  { /* 7 */
-    "confed2",
-    "confseq(123,456,789) confseq(111,222)",
-    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
-      0x3,0x2, 0x00,0x6f, 0x00,0xde },
-    14,
-    { "(123 456 789) (111 222)",
-      "",
-      0, 5, NOT_ALL_PRIVATE, 111, 1, NULL_ASN },
-  },
-  { /* 8 */
-    "confset",
-    "confset(456,123,789)",
-    { 0x4,0x3, 0x01,0xc8, 0x00,0x7b, 0x03,0x15 },
-    8,
-    { "[123,456,789]",
-      "",
-      0, 1, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
-  },
-  { /* 9 */
-    "confmulti",
-    "confseq(123,456,789) confset(222,111) seq(8722) set(4196,48658)",
-    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
-      0x4,0x2, 0x00,0xde, 0x00,0x6f,
-      0x2,0x1, 0x22,0x12,
-      0x1,0x2, 0x10,0x64, 0xbe,0x12 },
-    24,
-    { "(123 456 789) [111,222] 8722 {4196,48658}",
-      "8722 {4196,48658}",
-      2, 4, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
-  },
-  { /* 10 */
-    "seq4",
-    "seq(8466,2,52737,4096,8722,4)",
-    { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00, 
-               0x22,0x12, 0x00,0x04},
-    14,
-    { "8466 2 52737 4096 8722 4",
-      "8466 2 52737 4096 8722 4",
-      6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
-  },
-  { /* 11 */
-    "tripleseq1",
-    "seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
-    { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01, 
-      0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
-      0x2,0x1, 0x22,0x12},
-    20,
-    { "8466 2 52737 4096 8722 4 8722",
-      "8466 2 52737 4096 8722 4 8722",
-      7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
-  },
-  { /* 12 */ 
-    "someprivate",
-    "seq(8466,64512,52737,65535)",
-    { 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
-    10,
-    { "8466 64512 52737 65535",
-      "8466 64512 52737 65535",
-      4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
-  },
-  { /* 13 */ 
-    "allprivate",
-    "seq(65534,64512,64513,65535)",
-    { 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
-    10,
-    { "65534 64512 64513 65535",
-      "65534 64512 64513 65535",
-      4, 0, ALL_PRIVATE, 65534, 4, 65534 },
-  },
-  { /* 14 */ 
-    "long",
-    "seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
-    { 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
-                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed, },
-    502,
-    { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
-      
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
-      250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
-  },
-  { /* 15 */ 
-    "seq1extra",
-    "seq(8466,3,52737,4096,3456)",
-    { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
-    12,
-    { "8466 3 52737 4096 3456",
-      "8466 3 52737 4096 3456",
-      5, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
-  },
-  { /* 16 */
-    "empty",
-    "<empty>",
-    {},
-    0,
-    { "", "", 0, 0, 0, 0, 0, 0 },
-  },
-  { /* 17 */ 
-    "redundantset",
-    "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
-    { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
-      0x1,0x4, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9 },
-    22,
-    {
-     /* We shouldn't ever /generate/ such paths. However, we should
-      * cope with them fine.
-      */
-     "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 },
-  },
-  { /* 25 */ 
-    "zero-size overflow",
-    "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
-    { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
-    12,
-    { NULL, NULL,
-      0, 0, 0, 0, 0, 0 },
-  },
-  { /* 26  */ 
-    "zero-size overflow + valid segment",
-    "seq(#AS=0:8466 3 52737),seq(4096 3456)",
-    { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 
-      0x2,0x2, 0x10,0x00, 0x0d,0x80 },
-    14
-    ,
-    { NULL, NULL,
-      0, 0, 0, 0, 0, 0 },
-  },
-  { /* 27  */ 
-    "invalid segment type",
-    "type=8(4096 3456)",
-    { 0x8,0x2, 0x10,0x00, 0x0d,0x80 },
-    14
-    ,
-    { NULL, NULL,
-      0, 0, 0, 0, 0, 0 },
-  },  { NULL, NULL, {0}, 0, { NULL, 0, 0 } }
-};
-
-#define COMMON_ATTRS \
-      BGP_ATTR_FLAG_TRANS, \
-      BGP_ATTR_ORIGIN, \
-      1, \
-      BGP_ORIGIN_EGP, \
-      BGP_ATTR_FLAG_TRANS, \
-      BGP_ATTR_NEXT_HOP, \
-      4, 192, 0, 2, 0
-#define COMMON_ATTR_SIZE 11
-
-/* */
-static struct aspath_tests {
-  const char *desc;
-  const struct test_segment *segment;
-  const char *shouldbe;  /* String it should evaluate to */
-  const enum as4 { AS4_DATA, AS2_DATA }
-          as4;         /* whether data should be as4 or not (ie as2) */
-  const int result;    /* expected result for bgp_attr_parse */
-  const int cap;       /* capabilities to set for peer */
-  const char attrheader [1024];
-  size_t len;
-  const struct test_segment *old_segment;
-} aspath_tests [] =
-{
-  /* 0 */
-  {
-    "basic test",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS2_DATA, 0,
-    0,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH,
-      10,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 1 */
-  {
-    "length too short",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS2_DATA, -1,
-    0,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH, 
-      8,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 2 */
-  {
-    "length too long",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS2_DATA, -1,
-    0,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH, 
-      12,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 3 */
-  {
-    "incorrect flag",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS2_DATA, -1,
-    0,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
-      BGP_ATTR_AS_PATH, 
-      10,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 4 */
-  {
-    "as4_path, with as2 format data",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS2_DATA, -1,
-    0,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
-      BGP_ATTR_AS4_PATH, 
-      10,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 5 */
-  {
-    "as4, with incorrect attr length",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS4_DATA, -1,
-    PEER_CAP_AS4_RCV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
-      BGP_ATTR_AS4_PATH, 
-      10,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 6 */
-  {
-    "basic 4-byte as-path",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS4_DATA, 0,
-    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH, 
-      18,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 7 */
-  {
-    "4b AS_PATH: too short",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS4_DATA, -1,
-    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH, 
-      16,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 8 */
-  {
-    "4b AS_PATH: too long",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS4_DATA, -1,
-    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH, 
-      20,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 9 */
-  {
-    "4b AS_PATH: too long2",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS4_DATA, -1,
-    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS,
-      BGP_ATTR_AS_PATH, 
-      22,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 10 */
-  {
-    "4b AS_PATH: bad flags",
-    &test_segments[0],
-    "8466 3 52737 4096",
-    AS4_DATA, -1,
-    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
-      BGP_ATTR_AS_PATH, 
-      18,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 11 */
-  {
-    "4b AS4_PATH w/o AS_PATH",
-    &test_segments[6],
-    NULL,
-    AS4_DATA, -1,
-    PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
-      BGP_ATTR_AS4_PATH, 
-      14,
-    },
-    COMMON_ATTR_SIZE + 3,
-  },
-  /* 12 */
-  {
-    "4b AS4_PATH: confed",
-    &test_segments[6],
-    "8466 3 52737 4096 (123 456 789)",
-    AS4_DATA, 0,
-    PEER_CAP_AS4_ADV,
-    { COMMON_ATTRS,
-      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
-      BGP_ATTR_AS4_PATH, 
-      14,
-    },
-    COMMON_ATTR_SIZE + 3,
-    &test_segments[0],
-  },
-  { NULL, NULL, NULL, 0, 0, 0, { 0 }, 0 },
-};
-
-/* prepending tests */
-static struct tests {
-  const struct test_segment *test1;
-  const struct test_segment *test2;
-  struct test_spec sp;
-} prepend_tests[] = 
-{
-  /* 0 */
-  { &test_segments[0], &test_segments[1],
-    { "8466 3 52737 4096 8722 4",
-      "8466 3 52737 4096 8722 4",
-      6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
-  },
-  /* 1 */
-  { &test_segments[1], &test_segments[3],
-    { "8722 4 8482 51457 {5204}",
-      "8722 4 8482 51457 {5204}",
-      5, 0, NOT_ALL_PRIVATE, 5204, 1, 8722 }
-  },
-  /* 2 */
-  { &test_segments[3], &test_segments[4],
-    { "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
-      "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
-      7, 0, NOT_ALL_PRIVATE, 5204, 1, 8482 },
-  },
-  /* 3 */
-  { &test_segments[4], &test_segments[5],
-    { "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
-      " {2457,4369,61697} 1842 41590 51793",
-      "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
-      " {2457,4369,61697} 1842 41590 51793",
-      11, 0, NOT_ALL_PRIVATE, 61697, 1, 8467 }
-  },
-  /* 4 */
-  { &test_segments[5], &test_segments[6],
-    { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
-      "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
-      7, 0, NOT_ALL_PRIVATE, 1842, 1, 6435 },
-  },
-  /* 5 */
-  { &test_segments[6], &test_segments[7],
-    { "(123 456 789) (123 456 789) (111 222)",
-      "",
-      0, 8, NOT_ALL_PRIVATE, 111, 1, 0 }
-  },
-  { &test_segments[7], &test_segments[8],
-    { "(123 456 789) (111 222) [123,456,789]",
-      "",
-      0, 6, NOT_ALL_PRIVATE, 111, 1, 0 }
-  },
-  { &test_segments[8], &test_segments[9],
-    { "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
-      "8722 {4196,48658}",
-      2, 5, NOT_ALL_PRIVATE, 456, 1, NULL_ASN },
-  },
-  { &test_segments[9], &test_segments[8],
-    { "(123 456 789) [111,222] 8722 {4196,48658} [123,456,789]",
-      "8722 {4196,48658}",
-      2, 5, NOT_ALL_PRIVATE, 48658, 1, NULL_ASN },
-  },
-  { &test_segments[14], &test_segments[11],
-    { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 2 52737 4096 8722 4 8722",
-      
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
-      "8466 2 52737 4096 8722 4 8722",
-      257, 0, NOT_ALL_PRIVATE, 4096, 1000, 8466 },
-  },
-  { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
-};
-
-struct tests reconcile_tests[] =
-{
-  { &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}",
-      5, 0, NOT_ALL_PRIVATE, 4, 1, 8466 },
-  },
-  { &test_segments[2], &test_segments[0],
-    { "8466 3 52737 4096 {4,8722}",
-      "8466 3 52737 4096 {4,8722}",
-      5, 0, NOT_ALL_PRIVATE, 8722, 1, 8466 },
-  },
-  { &test_segments[2], &test_segments[10],
-    { "8466 {2,3,4,4096,8722,52737}",
-      "8466 {2,3,4,4096,8722,52737}",
-      2, 0, NOT_ALL_PRIVATE, 8722, 5, 8466 },
-  },
-  { &test_segments[10], &test_segments[2],
-    { "8466 {2,3,4,4096,8722,52737}",
-      "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}  },
-};
-
-struct compare_tests 
-{
-  int test_index1;
-  int test_index2;
-#define CMP_RES_YES 1
-#define CMP_RES_NO 0
-  char shouldbe_cmp;
-  char shouldbe_confed;
-} left_compare [] =
-{
-  { 0, 1, CMP_RES_NO, CMP_RES_NO },
-  { 0, 2, CMP_RES_YES, CMP_RES_NO },
-  { 0, 11, CMP_RES_YES, CMP_RES_NO },
-  { 0, 15, CMP_RES_YES, CMP_RES_NO },
-  { 0, 16, CMP_RES_NO, CMP_RES_NO },
-  { 1, 11, CMP_RES_NO, CMP_RES_NO },
-  { 6, 7, CMP_RES_NO, CMP_RES_YES },
-  { 6, 8, CMP_RES_NO, CMP_RES_NO },
-  { 7, 8, CMP_RES_NO, CMP_RES_NO },
-  { 1, 9, CMP_RES_YES, CMP_RES_NO },
-  { 0, 9, CMP_RES_NO, CMP_RES_NO },
-  { 3, 9, CMP_RES_NO, CMP_RES_NO },
-  { 0, 6, CMP_RES_NO, CMP_RES_NO },
-  { 1, 6, CMP_RES_NO, CMP_RES_NO },
-  { 0, 8, CMP_RES_NO, CMP_RES_NO },
-  { 1, 8, CMP_RES_NO, CMP_RES_NO },
-  { 11, 6, CMP_RES_NO, CMP_RES_NO },
-  { 11, 7, CMP_RES_NO, CMP_RES_NO },
-  { 11, 8, CMP_RES_NO, CMP_RES_NO },
-  { 9, 6, CMP_RES_NO, CMP_RES_YES },
-  { 9, 7, CMP_RES_NO, CMP_RES_YES },
-  { 9, 8, CMP_RES_NO, CMP_RES_NO },
-};
-
-/* make an aspath from a data stream */
-static struct aspath *
-make_aspath (const u_char *data, size_t len, int use32bit)
-{
-  struct stream *s = NULL;
-  struct aspath *as;
-  
-  if (len)
-    {
-      s = stream_new (len);
-      stream_put (s, data, len);
-    }
-  as = aspath_parse (s, len, use32bit);
-  
-  if (s)
-    stream_free (s);
-  
-  return as;
-}
-
-static void
-printbytes (const u_char *bytes, int len)
-{
-  int i = 0;
-  while (i < len)
-    {
-      if (i % 2)
-        printf ("%02hhx%s", bytes[i], " ");
-      else
-        printf ("0x%02hhx", bytes[i]);
-      i++;
-    }
-  printf ("\n");
-}  
-
-/* validate the given aspath */
-static int
-validate (struct aspath *as, const struct test_spec *sp)
-{
-  size_t bytes, bytes4;
-  int fails = 0;
-  const u_char *out;
-  static struct stream *s;
-  struct aspath *asinout, *asconfeddel, *asstr, *as4;
-  
-  if (as == NULL && sp->shouldbe == NULL)
-    {
-      printf ("Correctly failed to parse\n");
-      return fails;
-    }
-  
-  out = aspath_snmp_pathseg (as, &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:
-   *
-   *   aspath_parse(aspath_put(as)) 
-   *
-   * should:
-   *
-   * - also match the specified 'shouldbe' value
-   * - hash to same value as original path
-   * - have same hops and confed counts as original, and as the
-   *   the specified counts
-   *
-   * 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.
-   */
-  if (strcmp(aspath_print (as), sp->shouldbe)
-         /* hash validation */
-      || (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)
-      || (aspath_count_hops (asinout) != sp->hops)
-      || (aspath_count_confeds (asinout) != sp->confeds))
-    {
-      failed++;
-      fails++;
-      printf ("shouldbe:\n%s\n", sp->shouldbe);
-      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, 
-              aspath_count_hops (as),
-              aspath_count_hops (asinout) );
-      printf ("confeds: %d, counted %d %d\n", sp->confeds,
-              aspath_count_confeds (as),
-              aspath_count_confeds (asinout));
-      printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
-      printbytes (out, bytes);
-    }
-         /* basic confed related tests */
-  if ((aspath_print (asconfeddel) == NULL 
-          && sp->shouldbe_delete_confed != NULL)
-      || (aspath_print (asconfeddel) != NULL 
-          && sp->shouldbe_delete_confed == NULL)
-      || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
-         /* delete_confed_seq should be idempotent */
-      || (aspath_key_make (asconfeddel) 
-          != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
-    {
-      failed++;
-      fails++;
-      printf ("as-path minus confeds is: %s\n", aspath_print (asconfeddel));
-      printf ("as-path minus confeds should be: %s\n", sp->shouldbe_delete_confed);
-    }
-      /* aspath_str2aspath test */
-  if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
-      || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
-      || strcmp(aspath_print (asstr), sp->shouldbe))
-    {
-      failed++;
-      fails++;
-      printf ("asstr: %s\n", aspath_print (asstr));
-    }
-  
-    /* loop, private and first as checks */
-  if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
-      || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
-      || (aspath_private_as_check (as) != sp->private_as)
-      || (aspath_firstas_check (as,sp->first)
-          && sp->first == 0))
-    {
-      failed++;
-      fails++;
-      printf ("firstas: %d,  got %d\n", sp->first,
-              aspath_firstas_check (as,sp->first));
-      printf ("loop does: %d %d, doesnt: %d %d\n",
-              sp->does_loop, aspath_loop_check (as, sp->does_loop),
-              sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
-      printf ("private check: %d %d\n", sp->private_as,
-              aspath_private_as_check (as));
-    }
-  aspath_unintern (&asinout);
-  aspath_unintern (&as4);
-  
-  aspath_free (asconfeddel);
-  aspath_free (asstr);
-  stream_reset (s);
-  
-  return fails;
-}
-
-static void
-empty_get_test ()
-{
-  struct aspath *as = aspath_empty_get ();
-  struct test_spec sp = { "", "", 0, 0, 0, 0, 0, 0 };
-
-  printf ("empty_get_test, as: %s\n",aspath_print (as));
-  if (!validate (as, &sp))
-    printf ("%s\n", OK);
-  else
-    printf ("%s!\n", FAILED);
-  
-  printf ("\n");
-  
-  aspath_free (as);
-}
-
-/* basic parsing test */
-static void
-parse_test (struct test_segment *t)
-{
-  struct aspath *asp;
-  
-  printf ("%s: %s\n", t->name, t->desc);
-
-  asp = make_aspath (t->asdata, t->len, 0);
-  
-  printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));
-
-  if (!validate (asp, &t->sp))
-    printf (OK "\n");
-  else
-    printf (FAILED "\n");
-  
-  printf ("\n");
-  
-  if (asp)
-    aspath_unintern (&asp);
-}
-
-/* prepend testing */
-static void
-prepend_test (struct tests *t)
-{
-  struct aspath *asp1, *asp2, *ascratch;
-  
-  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, 0);
-  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-  
-  ascratch = aspath_dup (asp2);
-  aspath_unintern (&asp2);
-  
-  asp2 = aspath_prepend (asp1, ascratch);
-  
-  printf ("aspath: %s\n", aspath_print (asp2));
-  
-  if (!validate (asp2, &t->sp))
-    printf ("%s\n", OK);
-  else
-    printf ("%s!\n", FAILED);
-  
-  printf ("\n");
-  aspath_unintern (&asp1);
-  aspath_free (asp2);
-}
-
-/* empty-prepend testing */
-static void
-empty_prepend_test (struct test_segment *t)
-{
-  struct aspath *asp1, *asp2, *ascratch;
-  
-  printf ("empty prepend %s: %s\n", t->name, t->desc);
-  
-  asp1 = make_aspath (t->asdata, t->len, 0);
-  asp2 = aspath_empty ();
-  
-  ascratch = aspath_dup (asp2);
-  aspath_unintern (&asp2);
-  
-  asp2 = aspath_prepend (asp1, ascratch);
-  
-  printf ("aspath: %s\n", aspath_print (asp2));
-  
-  if (!validate (asp2, &t->sp))
-    printf (OK "\n");
-  else
-    printf (FAILED "!\n");
-  
-  printf ("\n");
-  if (asp1)
-    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)
-{
-  struct aspath *asp1, *asp2, *ascratch;
-  
-  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, 0);
-  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-  
-  ascratch = aspath_aggregate (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);
-/*  aspath_unintern (ascratch);*/
-}
-
-/* cmp_left tests  */
-static void
-cmp_test ()
-{
-  unsigned int i;
-#define CMP_TESTS_MAX \
-  (sizeof(left_compare) / sizeof (struct compare_tests))
-
-  for (i = 0; i < CMP_TESTS_MAX; i++)
-    {
-      struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
-      struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
-      struct aspath *asp1, *asp2;
-      
-      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, 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
-          || aspath_cmp_left_confed (asp1, asp2) 
-               != left_compare[i].shouldbe_confed
-          || aspath_cmp_left_confed (asp2, asp1) 
-               != left_compare[i].shouldbe_confed)
-        {
-          failed++;
-          printf (FAILED "\n");
-          printf ("result should be: cmp: %d, confed: %d\n", 
-                  left_compare[i].shouldbe_cmp,
-                  left_compare[i].shouldbe_confed);
-          printf ("got: cmp %d, cmp_confed: %d\n",
-                  aspath_cmp_left (asp1, asp2),
-                  aspath_cmp_left_confed (asp1, asp2));
-          printf("path1: %s\npath2: %s\n", aspath_print (asp1),
-                 aspath_print (asp2));
-        }
-      else
-        printf (OK "\n");
-      
-      printf ("\n");
-      aspath_unintern (&asp1);
-      aspath_unintern (&asp2);
-    }
-}
-
-static int
-handle_attr_test (struct aspath_tests *t)
-{
-  struct bgp bgp = { 0 }; 
-  struct peer peer = { 0 };
-  struct attr attr = { 0 };  
-  int ret;
-  int initfail = failed;
-  struct aspath *asp;
-  size_t datalen;
-  
-  asp = make_aspath (t->segment->asdata, t->segment->len, 0);
-    
-  peer.ibuf = stream_new (BGP_MAX_PACKET_SIZE);
-  peer.obuf = stream_fifo_new ();
-  peer.bgp = &bgp;
-  peer.host = (char *)"none";
-  peer.fd = -1;
-  peer.cap = t->cap;
-  
-  stream_write (peer.ibuf, t->attrheader, t->len);
-  datalen = aspath_put (peer.ibuf, asp, t->as4 == AS4_DATA);
-  if (t->old_segment)
-    {
-      char dummyaspath[] = { BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH,
-                             t->old_segment->len };
-      stream_write (peer.ibuf, dummyaspath, sizeof (dummyaspath));
-      stream_write (peer.ibuf, t->old_segment->asdata, t->old_segment->len);
-      datalen += sizeof (dummyaspath) + t->old_segment->len;
-    }
-  
-  ret = bgp_attr_parse (&peer, &attr, t->len + datalen, NULL, NULL);
-  
-  if (ret != t->result)
-    {
-      printf ("bgp_attr_parse returned %d, expected %d\n", ret, t->result);
-      printf ("datalen %zd\n", datalen);
-      failed++;
-    }
-  if (ret != 0)
-    goto out;
-  
-  if (t->shouldbe && attr.aspath == NULL)
-    {
-      printf ("aspath is NULL, but should be: %s\n", t->shouldbe);
-      failed++;
-    }
-  if (t->shouldbe && attr.aspath && strcmp (attr.aspath->str, t->shouldbe))
-    {
-      printf ("attr str and 'shouldbe' mismatched!\n"
-              "attr str:  %s\n"
-              "shouldbe:  %s\n",
-              attr.aspath->str, t->shouldbe);
-      failed++;
-    }
-  if (!t->shouldbe && attr.aspath)
-    {
-      printf ("aspath should be NULL, but is: %s\n", attr.aspath->str);
-      failed++;
-    }
-
-out:
-  if (attr.aspath)
-    aspath_unintern (&attr.aspath);
-  if (asp)
-    aspath_unintern (&asp);
-  return failed - initfail;
-}
-
-static void
-attr_test (struct aspath_tests *t)
-{
-    printf ("%s\n", t->desc);
-    printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);  
-}
-
-int
-main (void)
-{
-  int i = 0;
-  qobj_init ();
-  bgp_master_init ();
-  master = bm->master;
-  bgp_option_set (BGP_OPT_NO_LISTEN);
-  bgp_attr_init ();
-  
-  while (test_segments[i].name)
-    {
-      printf ("test %u\n", i);
-      parse_test (&test_segments[i]);
-      empty_prepend_test (&test_segments[i++]);
-    }
-  
-  i = 0;
-  while (prepend_tests[i].test1)
-    {
-      printf ("prepend test %u\n", i);
-      prepend_test (&prepend_tests[i++]);
-    }
-  
-  i = 0;
-  while (aggregate_tests[i].test1)
-    {
-      printf ("aggregate test %u\n", i);
-      aggregate_test (&aggregate_tests[i++]);
-    }
-  
-  i = 0;
-  
-  while (reconcile_tests[i].test1)
-    {
-      printf ("reconcile test %u\n", i);
-      as4_reconcile_test (&reconcile_tests[i++]);
-    }
-  
-  i = 0;
-  
-  cmp_test();
-  
-  i = 0;
-  
-  empty_get_test();
-  
-  i = 0;
-  
-  while (aspath_tests[i].desc)
-    {
-      printf ("aspath_attr test %d\n", i);
-      attr_test (&aspath_tests[i++]);
-    }
-  
-  printf ("failures: %d\n", failed);
-  printf ("aspath count: %ld\n", aspath_count());
-  
-  return (failed + aspath_count());
-}
diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c
deleted file mode 100644 (file)
index f83dee5..0000000
+++ /dev/null
@@ -1,701 +0,0 @@
-/* 
- * Copyright (C) 2007 Sun Microsystems, Inc.
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-
-#include "qobj.h"
-#include "vty.h"
-#include "stream.h"
-#include "privs.h"
-#include "memory.h"
-#include "queue.h"
-#include "filter.h"
-
-#include "bgpd/bgpd.h"
-#include "bgpd/bgp_open.h"
-#include "bgpd/bgp_debug.h"
-#include "bgpd/bgp_packet.h"
-
-#define VT100_RESET "\x1b[0m"
-#define VT100_RED "\x1b[31m"
-#define VT100_GREEN "\x1b[32m"
-#define VT100_YELLOW "\x1b[33m"
-
-
-#define CAPABILITY 0
-#define DYNCAP     1
-#define OPT_PARAM  2
-
-/* need these to link in libbgp */
-struct zebra_privs_t *bgpd_privs = NULL;
-struct thread_master *master = NULL;
-
-static int failed = 0;
-static int tty = 0;
-
-/* test segments to parse and validate, and use for other tests */
-static struct test_segment {
-  const char *name;
-  const char *desc;
-  const u_char data[1024];
-  int len;
-#define SHOULD_PARSE   0
-#define SHOULD_ERR     -1
-  int parses; /* whether it should parse or not */
-  as_t peek_for; /* what peek_for_as4_capability should say */
-  
-  /* AFI/SAFI validation */
-  int validate_afi;
-  afi_t afi;
-  safi_t safi;
-#define VALID_AFI 1
-#define INVALID_AFI 0
-  int afi_valid;
-} test_segments [] = 
-{
-  /* 0 */
-  { "caphdr", 
-    "capability header, and no more",
-    { CAPABILITY_CODE_REFRESH, 0x0 },
-    2, SHOULD_PARSE,
-  },
-  /* 1 */
-  { "nodata",
-    "header, no data but length says there is",
-    { 0x1, 0xa },
-    2, SHOULD_ERR,
-  },
-  /* 2 */
-  { "padded",
-    "valid, with padding",
-    { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
-    4, SHOULD_PARSE,
-  },
-  /* 3 */
-  { "minsize",
-    "violates minsize requirement",
-    { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
-    4, SHOULD_ERR,
-  },
-  { NULL, NULL, {0}, 0, 0},
-};
-
-static struct test_segment mp_segments[] =
-{
-  { "MP4",
-    "MP IP/Uni",
-    { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
-    6, SHOULD_PARSE, 0,
-    1, AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { "MPv6",
-    "MP IPv6/Uni",
-    { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
-    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, 0,
-    1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
-  },
-  /* 6 */
-  { "MP3",
-    "MP IP6/MPLS-labeled VPN",
-    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
-    6, SHOULD_PARSE, 0,
-    1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  /* 7 */
-  { "MP5",
-    "MP IP6/MPLS-VPN",
-    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
-    6, SHOULD_PARSE, 0,
-    1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  /* 8 */
-  { "MP6",
-    "MP IP4/MPLS-laveled VPN",
-    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
-    6, SHOULD_PARSE, 0,
-    1, AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },  
-  /* 10 */
-  { "MP8",
-    "MP unknown AFI/SAFI",
-    { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
-    6, SHOULD_PARSE, 0,
-    1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
-  },
-  /* 11 */
-  { "MP-short",
-    "MP IP4/Unicast, length too short (< minimum)",
-    { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
-    6, SHOULD_ERR,
-  },
-  /* 12 */
-  { "MP-overflow",
-    "MP IP4/Unicast, length too long",
-    { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
-    6, SHOULD_ERR, 0,
-    1, AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { NULL, NULL, {0}, 0, 0}
-};
-
-static struct test_segment misc_segments[] =
-{
-  /* 13 */
-  { "ORF",
-    "ORF, simple, single entry, single tuple",
-    { /* hdr */                CAPABILITY_CODE_ORF, 0x7, 
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x1, 
-      /* tuples */     0x40, 0x3
-    },
-    9, SHOULD_PARSE,
-  },
-  /* 14 */
-  { "ORF-many",
-    "ORF, multi entry/tuple",
-    { /* hdr */                CAPABILITY_CODE_ORF, 0x21,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, ORF_MODE_BOTH,
-                        0x80, ORF_MODE_RECEIVE,
-                        0x80, ORF_MODE_SEND,
-      /* mpc */                0x0, 0x2, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, ORF_MODE_BOTH,
-                        0x80, ORF_MODE_RECEIVE,
-                        0x80, ORF_MODE_SEND,
-      /* mpc */                0x0, 0x2, 0x0, 0x2,
-      /* num */                0x3, 
-      /* tuples */     0x40, ORF_MODE_RECEIVE,
-                        0x80, ORF_MODE_SEND,
-                        0x80, ORF_MODE_BOTH,
-    },
-    35, SHOULD_PARSE,
-  },
-  /* 15 */
-  { "ORFlo",
-    "ORF, multi entry/tuple, hdr length too short",
-    { /* hdr */                CAPABILITY_CODE_ORF, 0x15,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x2,
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-    },
-    35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
-  },
-  /* 16 */
-  { "ORFlu",
-    "ORF, multi entry/tuple, length too long",
-    { /* hdr */                0x3, 0x22,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x2,
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-    },
-    35, SHOULD_ERR
-  },
-  /* 17 */
-  { "ORFnu",
-    "ORF, multi entry/tuple, entry number too long",
-    { /* hdr */                0x3, 0x21,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x1, 
-      /* num */                0x4, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x2,
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-    },
-    35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
-  },
-  /* 18 */
-  { "ORFno",
-    "ORF, multi entry/tuple, entry number too short",
-    { /* hdr */                0x3, 0x21,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x1, 
-      /* num */                0x1, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x2,
-      /* num */                0x3,
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-    },
-    35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
-  },
-  /* 17 */
-  { "ORFpad",
-    "ORF, multi entry/tuple, padded to align",
-    { /* hdr */                0x3, 0x22,
-      /* mpc */                0x0, 0x1, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x1, 
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-      /* mpc */                0x0, 0x2, 0x0, 0x2,
-      /* num */                0x3, 
-      /* tuples */     0x40, 0x3,
-                        0x80, 0x1,
-                        0x80, 0x2,
-                        0x00,
-    },
-    36, SHOULD_PARSE,
-  },
-  /* 19 */
-  { "AS4",
-    "AS4 capability",
-    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
-    6, SHOULD_PARSE, 2882400018,
-  },
-  { "AS4",
-    "AS4 capability: short",
-    { 0x41, 0x4, 0xab, 0xcd, 0xef }, /* AS: 2882400018 */
-    5, SHOULD_ERR,
-  },
-  { "AS4",
-    "AS4 capability: long",
-    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12 },
-    7, SHOULD_ERR, 2882400018,
-  },
-  { "GR",
-    "GR capability",
-    { /* hdr */                CAPABILITY_CODE_RESTART, 0xe,
-      /* R-bit, time */        0xf1, 0x12,
-      /* afi */                0x0, 0x1,
-      /* safi */       0x1,
-      /* flags */      0xf,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x1,
-      /* flags */      0x0,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x2,
-      /* flags */      0x1,
-    },
-    16, SHOULD_PARSE,
-  },
-  { "GR-short",
-    "GR capability, but header length too short",
-    { /* hdr */                0x40, 0xa,
-      /* R-bit, time */        0xf1, 0x12,
-      /* afi */                0x0, 0x1,
-      /* safi */       0x1,
-      /* flags */      0xf,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x1,
-      /* flags */      0x0,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x2,
-      /* flags */      0x1,
-    },
-    15 /* array is 16 though */, SHOULD_ERR,
-  },
-  { "GR-long",
-    "GR capability, but header length too long",
-    { /* hdr */                0x40, 0xf,
-      /* R-bit, time */        0xf1, 0x12,
-      /* afi */                0x0, 0x1,
-      /* safi */       0x1,
-      /* flags */      0xf,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x1,
-      /* flags */      0x0,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x2,
-      /* flags */      0x01,
-    },
-    16, SHOULD_ERR,
-  },
-  { "GR-trunc",
-    "GR capability, but truncated",
-    { /* hdr */                0x40, 0xf,
-      /* R-bit, time */        0xf1, 0x12,
-      /* afi */                0x0, 0x1,
-      /* safi */       0x1,
-      /* flags */      0xf,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x1,
-      /* flags */      0x0,
-      /* afi */                0x0, 0x2,
-      /* safi */       0x2,
-      /* flags */      0x1,
-    },
-    15, SHOULD_ERR,
-  },
-  { "GR-empty",
-    "GR capability, but empty.",
-    { /* hdr */                0x40, 0x0,
-    },
-    2, SHOULD_ERR,
-  },
-  { "MP-empty",
-    "MP capability, but empty.",
-    { /* hdr */                0x1, 0x0,
-    },
-    2, SHOULD_ERR,
-  },
-  { "ORF-empty",
-    "ORF capability, but empty.",
-    { /* hdr */                0x3, 0x0,
-    },
-    2, SHOULD_ERR,
-  },
-  { "AS4-empty",
-    "AS4 capability, but empty.",
-    { /* hdr */                0x41, 0x0,
-    },
-    2, SHOULD_ERR,
-  },
-  { "dyn-empty",
-    "Dynamic capability, but empty.",
-    { /* hdr */                0x42, 0x0,
-    },
-    2, SHOULD_PARSE,
-  },
-  { "dyn-old",
-    "Dynamic capability (deprecated version)",
-    { CAPABILITY_CODE_DYNAMIC, 0x0 },
-    2, SHOULD_PARSE,
-  },
-  { NULL, NULL, {0}, 0, 0}
-};
-
-/* DYNAMIC message */
-struct test_segment dynamic_cap_msgs[] = 
-{
-  { "DynCap",
-    "Dynamic Capability Message, IP/Multicast",
-    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
-      7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
-  },
-  { "DynCapLong",
-    "Dynamic Capability Message, IP/Multicast, truncated",
-    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
-      5, SHOULD_ERR,
-  },
-  { "DynCapPadded",
-    "Dynamic Capability Message, IP/Multicast, padded",
-    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
-      8, SHOULD_ERR, /* No way to tell padding from data.. */
-  },
-  { "DynCapMPCpadded",
-    "Dynamic Capability Message, IP/Multicast, cap data padded",
-    { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
-      8, SHOULD_PARSE, /* You can though add padding to the capability data */
-  },
-  { "DynCapMPCoverflow",
-    "Dynamic Capability Message, IP/Multicast, cap data != length",
-    { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
-      8, SHOULD_ERR,
-  },
-  { 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 CAPABILITY:
-        stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
-        stream_putc (peer->ibuf, t->len);
-        break;
-      case DYNCAP:
-/*        for (i = 0; i < BGP_MARKER_SIZE; i++)
-          stream_putc (peer->, 0xff);
-        stream_putw (s, 0);
-        stream_putc (s, BGP_MSG_CAPABILITY);*/
-        break;
-    }
-  stream_write (peer->ibuf, t->data, t->len);
-  
-  printf ("%s: %s\n", t->name, t->desc);
-
-  switch (type)
-    {
-      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);
-        break;
-      default:
-        printf ("unknown type %u\n", type);
-        exit(1);
-    }
-  
-  if (!ret && t->validate_afi)
-    {
-      afi_t afi;
-      safi_t safi;
-      
-      /* Convert AFI, SAFI to internal values, check. */
-      if (bgp_map_afi_safi_iana2int (afi_int2iana(t->afi), t->safi, &afi, &safi))
-        {
-          if (t->afi_valid == VALID_AFI)
-            failed++;
-        }
-      printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
-              t->afi, afi, t->safi, safi,
-              peer->afc_recv[afi][safi],
-              peer->afc_nego[afi][safi]);
-        
-      if (t->afi_valid == VALID_AFI)
-        {
-        
-          if (!peer->afc_recv[afi][safi])
-            failed++;
-          if (!peer->afc_nego[afi][safi])
-            failed++;
-        }
-    }
-  
-  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", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
-                                         : VT100_GREEN "OK" VT100_RESET);
-  else
-    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
-  
-  if (failed)
-    printf (" (%u)", failed);
-  
-  printf ("\n\n");
-}
-
-static struct bgp *bgp;
-static as_t asn = 100;
-
-int
-main (void)
-{
-  struct peer *peer;
-  int i, j;
-  
-  conf_bgp_debug_neighbor_events = -1UL;
-  conf_bgp_debug_packet = -1UL;
-  conf_bgp_debug_as4 = -1UL;
-  term_bgp_debug_neighbor_events = -1UL;
-  term_bgp_debug_packet = -1UL;
-  term_bgp_debug_as4 = -1UL;
-  
-  qobj_init ();
-  master = thread_master_create ();
-  bgp_master_init ();
-  vrf_init ();
-  bgp_option_set (BGP_OPT_NO_LISTEN);
-  
-  if (fileno (stdout) >= 0) 
-    tty = isatty (fileno (stdout));
-  
-  if (bgp_get (&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
-    return -1;
-  
-  peer = peer_create_accept (bgp);
-  peer->host = (char *) "foo";
-  
-  for (i = AFI_IP; i < AFI_MAX; i++)
-    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
-      {
-        peer->afc[i][j] = 1;
-        peer->afc_adv[i][j] = 1;
-      }
-  
-  i = 0;
-  while (mp_segments[i].name)
-    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++], CAPABILITY);
-  
-  i = 0;
-  while (misc_segments[i].name)
-    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;
-  
-  i = 0;
-  while (dynamic_cap_msgs[i].name)
-    parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
-  
-  printf ("failures: %d\n", failed);
-  return failed;
-}
diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c
deleted file mode 100644 (file)
index 397612c..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-/* 
- * Copyright (C) 2008 Sun Microsystems, Inc.
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-
-#include "qobj.h"
-#include "vty.h"
-#include "stream.h"
-#include "privs.h"
-#include "memory.h"
-#include "queue.h"
-#include "filter.h"
-
-#include "bgpd/bgpd.h"
-#include "bgpd/bgp_attr.h"
-#include "bgpd/bgp_open.h"
-#include "bgpd/bgp_debug.h"
-#include "bgpd/bgp_route.h"
-#include "bgpd/bgp_packet.h"
-#include "bgpd/bgp_mplsvpn.h"
-#include "bgpd/bgp_nexthop.h"
-
-#define VT100_RESET "\x1b[0m"
-#define VT100_RED "\x1b[31m"
-#define VT100_GREEN "\x1b[32m"
-#define VT100_YELLOW "\x1b[33m"
-
-
-#define CAPABILITY 0
-#define DYNCAP     1
-#define OPT_PARAM  2
-
-/* need these to link in libbgp */
-struct zebra_privs_t *bgpd_privs = NULL;
-struct thread_master *master = NULL;
-
-static int failed = 0;
-static int tty = 0;
-
-/* test segments to parse and validate, and use for other tests */
-static struct test_segment {
-  const char *name;
-  const char *desc;
-  const u_char data[1024];
-  int len;
-#define SHOULD_PARSE   0
-#define SHOULD_ERR     -1
-  int parses; /* whether it should parse or not */
-  
-  /* AFI/SAFI validation */
-  afi_t afi;
-  safi_t safi;
-#define VALID_AFI 1
-#define INVALID_AFI 0
-  int afi_valid;
-} mp_reach_segments [] = 
-{
-  { "IPv6",
-    "IPV6 MP Reach, global nexthop, 1 NLRI", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      16,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-    },
-    (4 + 16 + 1 + 5), 
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-2",
-    "IPV6 MP Reach, global nexthop, 2 NLRIs", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      16,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,   /* ffee:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-    },
-    (4 + 16 + 1 + 5 + 9), 
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-default",
-    "IPV6 MP Reach, global nexthop, 2 NLRIs + default", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      16,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0x0, /* ::/0 */
-    },
-    (4 + 16 + 1 + 5 + 9 + 1),
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-lnh",
-    "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      32,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
-                                0x0,  0x0,  0x0,  0x0,
-                                0x2,  0x10, 0x2,  0xff,
-                                0x1,  0x2,  0x3,  0x4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0x0, /* ::/0 */
-    },
-    (4 + 32 + 1 + 5 + 9 + 1),
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-nhlen",
-    "IPV6 MP Reach, inappropriate nexthop length", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      4,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
-                                0x0,  0x0,  0x0,  0x0,
-                                0x2,  0x10, 0x2,  0xff,
-                                0x1,  0x2,  0x3,  0x4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0x0, /* ::/0 */
-    },
-    (4 + 32 + 1 + 5 + 9 + 1),
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-nhlen2",
-    "IPV6 MP Reach, invalid nexthop length", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      5,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
-                                0x0,  0x0,  0x0,  0x0,
-                                0x2,  0x10, 0x2,  0xff,
-                                0x1,  0x2,  0x3,  0x4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0x0, /* ::/0 */
-    },
-    (4 + 32 + 1 + 5 + 9 + 1),
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-nhlen3",
-    "IPV6 MP Reach, nexthop length overflow", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      32,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-    },
-    (4 + 16),
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-nhlen4",
-    "IPV6 MP Reach, nexthop length short", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      16,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
-                                0x0,  0x0,  0x0,  0x0,
-                                0x2,  0x10, 0x2,  0xff,
-                                0x1,  0x2,  0x3,  0x4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0x0, /* ::/0 */
-    },
-    (4 + 32 + 1 + 5 + 9 + 1),
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-nlri",
-    "IPV6 MP Reach, NLRI bitlen overflow", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* nexthop bytes */      32,
-      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
-                                0xaa, 0xbb, 0xcc, 0xdd,
-                                0x3,  0x4,  0x5,  0x6,
-                                0xa1, 0xa2, 0xa3, 0xa4,
-      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
-                                0x0,  0x0,  0x0,  0x0,
-                                0x2,  0x10, 0x2,  0xff,
-                                0x1,  0x2,  0x3,  0x4,
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                120, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0, /* ::/0 */
-    },
-    (4 + 32 + 1 + 5 + 9 + 1),
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4",
-    "IPv4 MP Reach, 2 NLRIs + default", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
-      /* nexthop bytes */      4,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
-                                17, 10, 2, 3, /* 10.2.3/17 */
-                                0, /* 0/0 */
-    },
-    (4 + 4 + 1 + 3 + 4 + 1),
-    SHOULD_PARSE,
-    AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4-nhlen",
-    "IPv4 MP Reach, nexthop lenth overflow", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
-      /* nexthop bytes */      32,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
-                                17, 10, 2, 3, /* 10.2.3/17 */
-                                0, /* 0/0 */
-    },
-    (4 + 4 + 1 + 3 + 4 + 1),
-    SHOULD_ERR,
-    AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4-nlrilen",
-    "IPv4 MP Reach, nlri lenth overflow", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
-      /* nexthop bytes */      4,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
-                                30, 10, 
-                                0, /* 0/0 */
-    },
-    (4 + 4 + 1 + 3 + 2 + 1),
-    SHOULD_ERR,
-    AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4-VPNv4",
-    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 16,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
-    SHOULD_PARSE,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-bogus-plen",
-    "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 1, 2,
-                                0, 0xff, 3, 4,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
-                                17, 10, 2, 3,  /* 10.2.3/17 */
-                                0, /* 0/0 */
-    },
-    (3 + 1 + 3*4 + 1 + 3 + 4 + 1),
-    SHOULD_ERR,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-plen1-short",
-    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 1,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
-    SHOULD_ERR,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-plen1-long",
-    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 32,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
-    SHOULD_ERR,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-plenn-long",
-    "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 16,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-                                88 + 1, /* bogus */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
-    SHOULD_ERR,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-plenn-short",
-    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 16,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 2,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
-    SHOULD_ERR,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-bogus-rd-type",
-    "IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 16,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0xff, 0, /* Bogus RD */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
-    SHOULD_PARSE,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { "IPv4-VPNv4-0-nlri",
-    "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* nexthop bytes */      12,
-      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
-                                0, 0, 0, 0,
-      /* Nexthop */            192, 168,   0,  1, 
-      /* SNPA (defunct, MBZ) */        0x0,
-      /* NLRI tuples */                88 + 16,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-                                0 /* 0/0, bogus for vpnv4 ?? */
-    },
-    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
-    SHOULD_ERR,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-
-  /* From bug #385 */
-  { "IPv6-bug",
-    "IPv6, global nexthop, 1 default NLRI", 
-    {
-      /* AFI / SAFI */         0x0, 0x2, 0x1,
-      /* nexthop bytes */      0x20,
-      /* Nexthop (global) */   0x20, 0x01, 0x04, 0x70, 
-                                0x00, 0x01, 0x00, 0x06,
-                                0x00, 0x00, 0x00, 0x00,
-                                0x00, 0x00, 0x00, 0x01, 
-      /* Nexthop (local) */     0xfe, 0x80, 0x00, 0x00, 
-                                0x00, 0x00, 0x00, 0x00,
-                                0x02, 0x0c, 0xdb, 0xff, 
-                                0xfe, 0xfe, 0xeb, 0x00,
-      /* SNPA (defunct, MBZ) */        0,
-      /* NLRI tuples */                /* Should have 0 here for ::/0, but dont */
-    },
-    37,
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  
-  { NULL, NULL, {0}, 0, 0}
-};
-
-/* MP_UNREACH_NLRI tests */
-static struct test_segment mp_unreach_segments [] =
-{
-  { "IPv6-unreach",
-    "IPV6 MP Unreach, 1 NLRI", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* NLRI tuples */                32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-    },
-    (3 + 5), 
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-unreach2",
-    "IPV6 MP Unreach, 2 NLRIs", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-    },
-    (3 + 5 + 9), 
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-unreach-default",
-    "IPV6 MP Unreach, 2 NLRIs + default", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* NLRI tuples */                32, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0x0, /* ::/0 */
-    },
-    (3 + 5 + 9 + 1),
-    SHOULD_PARSE,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv6-unreach-nlri",
-    "IPV6 MP Unreach, NLRI bitlen overflow", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
-      /* NLRI tuples */                120, 
-                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
-                                64,
-                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
-                                0x0,  0x2,  0x0, 0x3,
-                                0, /* ::/0 */
-    },
-    (3 + 5 + 9 + 1),
-    SHOULD_ERR,
-    AFI_IP6, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4-unreach",
-    "IPv4 MP Unreach, 2 NLRIs + default", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
-      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
-                                17, 10, 2, 3, /* 10.2.3/17 */
-                                0, /* 0/0 */
-    },
-    (3 + 3 + 4 + 1),
-    SHOULD_PARSE,
-    AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4-unreach-nlrilen",
-    "IPv4 MP Unreach, nlri length overflow", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
-      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
-                                30, 10, 
-                                0, /* 0/0 */
-    },
-    (3 + 3 + 2 + 1),
-    SHOULD_ERR,
-    AFI_IP, SAFI_UNICAST, VALID_AFI,
-  },
-  { "IPv4-unreach-VPNv4",
-    "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", 
-    {
-      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
-      /* NLRI tuples */                88 + 16,
-                                  0, 1, 2,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_AS */
-                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
-                                  10, 1,    /* 10.1/16 */
-                                88 + 17,
-                                  0xff, 0, 0,   /* tag */
-                                  /* rd, 8 octets */
-                                    0, 0, /* RD_TYPE_IP */
-                                    192, 168, 0, 1, /* IPv4 */
-                                  10, 2, 3,  /* 10.2.3/17 */
-    },
-    (3 + (1+3+8+2) + (1+3+8+3)),
-    SHOULD_PARSE,
-    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
-  },
-  { NULL, NULL, {0}, 0, 0}
-};
-
-/* nlri_parse indicates 0 on successful parse, and -1 otherwise.
- * attr_parse indicates BGP_ATTR_PARSE_PROCEED/0 on success,
- * and BGP_ATTR_PARSE_ERROR/-1 or lower negative ret on err.
- */
-static void
-handle_result (struct peer *peer, struct test_segment *t,
-               int parse_ret, int nlri_ret)
-{
-  int oldfailed = failed;
-  
-  printf ("mp attr parsed?: %s\n", parse_ret ? "no" : "yes");
-  if (!parse_ret)
-    printf ("nrli parsed?:  %s\n", nlri_ret ? "no" : "yes");
-  printf ("should parse?:  %s\n", t->parses ? "no" : "yes");
-  
-  if ((parse_ret != 0 || nlri_ret != 0) != (t->parses != 0))
-    failed++;
-  
-    
-  if (tty)
-    printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
-                                         : VT100_GREEN "OK" VT100_RESET);
-  else
-    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
-  
-  if (failed)
-    printf (" (%u)", failed);
-  
-  printf ("\n\n");
-}
-
-/* basic parsing test */
-static void
-parse_test (struct peer *peer, struct test_segment *t, int type)
-{
-  int parse_ret = 0, nlri_ret = 0;
-  struct attr attr = { };
-  struct bgp_nlri nlri = { };
-  struct bgp_attr_parser_args attr_args = {
-    .peer = peer,
-    .length = t->len,
-    .total = 1,
-    .attr = &attr,
-    .type = type,
-    .flags = BGP_ATTR_FLAG_OPTIONAL, 
-    .startp = BGP_INPUT_PNT (peer),
-  };
-#define RANDOM_FUZZ 35
-  
-  stream_reset (peer->ibuf);
-  stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
-  stream_set_getp (peer->ibuf, RANDOM_FUZZ);
-  
-  stream_write (peer->ibuf, t->data, t->len);
-  
-  printf ("%s: %s\n", t->name, t->desc);
-  
-  if (type == BGP_ATTR_MP_REACH_NLRI)
-    parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
-  else
-    parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri);
-  if (!parse_ret)
-    {
-      iana_afi_t pkt_afi;
-      safi_t pkt_safi;
-      
-      /* Convert AFI, SAFI to internal values, check. */
-      if (bgp_map_afi_safi_int2iana (nlri.afi, nlri.safi, &pkt_afi, &pkt_safi))
-        assert (0);
-
-      printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
-              nlri.afi , pkt_afi, nlri.safi, pkt_safi,
-              peer->afc_recv[nlri.afi][nlri.safi],
-              peer->afc_nego[nlri.afi][nlri.safi]);
-    }
-  
-  if (!parse_ret)
-    {
-      if (type == BGP_ATTR_MP_REACH_NLRI)
-        nlri_ret = bgp_nlri_parse (peer, &attr, &nlri);
-      else
-        nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
-    }
-  zlog_err("xxxxxxxxxxxxxxxx nlri ret %u", nlri_ret);
-  handle_result (peer, t, parse_ret, nlri_ret);
-}
-
-static struct bgp *bgp;
-static as_t asn = 100;
-
-int
-main (void)
-{
-  struct peer *peer;
-  int i, j;
-  
-  conf_bgp_debug_neighbor_events = -1UL;
-  conf_bgp_debug_packet = -1UL;
-  conf_bgp_debug_as4 = -1UL;
-  term_bgp_debug_neighbor_events = -1UL;
-  term_bgp_debug_packet = -1UL;
-  term_bgp_debug_as4 = -1UL;
-  
-  qobj_init ();
-  master = thread_master_create ();
-  bgp_master_init ();
-  vrf_init ();
-  bgp_option_set (BGP_OPT_NO_LISTEN);
-  bgp_attr_init ();
-  
-  if (fileno (stdout) >= 0) 
-    tty = isatty (fileno (stdout));
-  
-  if (bgp_get (&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
-    return -1;
-  
-  peer = peer_create_accept (bgp);
-  peer->host = (char *)"foo";
-  peer->status = Established;
-  
-  for (i = AFI_IP; i < AFI_MAX; i++)
-    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
-      {
-        peer->afc[i][j] = 1;
-        peer->afc_adv[i][j] = 1;
-      }
-  
-  i = 0;
-  while (mp_reach_segments[i].name)
-    parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);
-
-  i = 0;
-  while (mp_unreach_segments[i].name)
-    parse_test (peer, &mp_unreach_segments[i++], BGP_ATTR_MP_UNREACH_NLRI);
-
-  printf ("failures: %d\n", failed);
-  return failed;
-}
diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c
deleted file mode 100644 (file)
index f9eb153..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * BGP Multipath Unit Test
- * Copyright (C) 2010 Google Inc.
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include "qobj.h"
-#include "vty.h"
-#include "stream.h"
-#include "privs.h"
-#include "linklist.h"
-#include "memory.h"
-#include "zclient.h"
-#include "queue.h"
-#include "filter.h"
-
-#include "bgpd/bgpd.h"
-#include "bgpd/bgp_table.h"
-#include "bgpd/bgp_route.h"
-#include "bgpd/bgp_attr.h"
-#include "bgpd/bgp_nexthop.h"
-#include "bgpd/bgp_mpath.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
-
-#define TEST_PASSED 0
-#define TEST_FAILED -1
-
-#define EXPECT_TRUE(expr, res)                                          \
-  if (!(expr))                                                          \
-    {                                                                   \
-      printf ("Test failure in %s line %u: %s\n",                       \
-              __FUNCTION__, __LINE__, #expr);                           \
-      (res) = TEST_FAILED;                                              \
-    }
-
-typedef struct testcase_t__ testcase_t;
-
-typedef int (*test_setup_func)(testcase_t *);
-typedef int (*test_run_func)(testcase_t *);
-typedef int (*test_cleanup_func)(testcase_t *);
-
-struct testcase_t__ {
-  const char *desc;
-  void *test_data;
-  void *verify_data;
-  void *tmp_data;
-  test_setup_func setup;
-  test_run_func run;
-  test_cleanup_func cleanup;
-};
-
-/* need these to link in libbgp */
-struct thread_master *master = NULL;
-struct zclient *zclient;
-struct zebra_privs_t bgpd_privs =
-{
-  .user = NULL,
-  .group = NULL,
-  .vty_group = NULL,
-};
-
-static int tty = 0;
-
-/* Create fake bgp instance */
-static struct bgp *
-bgp_create_fake (as_t *as, const char *name)
-{
-  struct bgp *bgp;
-  afi_t afi;
-  safi_t safi;
-
-  if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
-    return NULL;
-
-  bgp_lock (bgp);
-  //bgp->peer_self = peer_new (bgp);
-  //bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement");
-
-  bgp->peer = list_new ();
-  //bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
-
-  bgp->group = list_new ();
-  //bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
-
-  for (afi = AFI_IP; afi < AFI_MAX; afi++)
-    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
-      {
-        bgp->route[afi][safi] = bgp_table_init (afi, safi);
-        bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
-        bgp->rib[afi][safi] = bgp_table_init (afi, safi);
-        bgp->maxpaths[afi][safi].maxpaths_ebgp = MULTIPATH_NUM;
-        bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM;
-      }
-
-  bgp_scan_init (bgp);
-  bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
-  bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
-  bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
-  bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
-  bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
-
-  bgp->as = *as;
-
-  if (name)
-    bgp->name = strdup (name);
-
-  return bgp;
-}
-
-/*=========================================================
- * Testcase for maximum-paths configuration
- */
-static int
-setup_bgp_cfg_maximum_paths (testcase_t *t)
-{
-  as_t asn = 1;
-  t->tmp_data = bgp_create_fake (&asn, NULL);
-  if (!t->tmp_data)
-    return -1;
-  return 0;
-}
-
-static int
-run_bgp_cfg_maximum_paths (testcase_t *t)
-{
-  afi_t afi;
-  safi_t safi;
-  struct bgp *bgp;
-  int api_result;
-  int test_result = TEST_PASSED;
-
-  bgp = t->tmp_data;
-  for (afi = AFI_IP; afi < AFI_MAX; afi++)
-    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
-      {
-        /* test bgp_maximum_paths_set */
-        api_result = bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_EBGP, 10, 0);
-        EXPECT_TRUE (api_result == 0, test_result);
-        api_result = bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_IBGP, 10, 0);
-        EXPECT_TRUE (api_result == 0, test_result);
-        EXPECT_TRUE (bgp->maxpaths[afi][safi].maxpaths_ebgp == 10, test_result);
-        EXPECT_TRUE (bgp->maxpaths[afi][safi].maxpaths_ibgp == 10, test_result);
-
-        /* test bgp_maximum_paths_unset */
-        api_result = bgp_maximum_paths_unset (bgp, afi, safi, BGP_PEER_EBGP);
-        EXPECT_TRUE (api_result == 0, test_result);
-        api_result = bgp_maximum_paths_unset (bgp, afi, safi, BGP_PEER_IBGP);
-        EXPECT_TRUE (api_result == 0, test_result);
-        EXPECT_TRUE ((bgp->maxpaths[afi][safi].maxpaths_ebgp ==
-                      MULTIPATH_NUM), test_result);
-        EXPECT_TRUE ((bgp->maxpaths[afi][safi].maxpaths_ibgp ==
-                      MULTIPATH_NUM), test_result);
-      }
-
-  return test_result;
-}
-
-static int
-cleanup_bgp_cfg_maximum_paths (testcase_t *t)
-{
-  return bgp_delete ((struct bgp *)t->tmp_data);
-}
-
-testcase_t test_bgp_cfg_maximum_paths = {
-  .desc = "Test bgp maximum-paths config",
-  .setup = setup_bgp_cfg_maximum_paths,
-  .run = run_bgp_cfg_maximum_paths,
-  .cleanup = cleanup_bgp_cfg_maximum_paths,
-};
-
-/*=========================================================
- * Testcase for bgp_mp_list
- */
-struct peer test_mp_list_peer[] = {
-  { .local_as = 1, .as = 2 },
-  { .local_as = 1, .as = 2 },
-  { .local_as = 1, .as = 2 },
-  { .local_as = 1, .as = 2 },
-  { .local_as = 1, .as = 2 },
-};
-int test_mp_list_peer_count = sizeof (test_mp_list_peer)/ sizeof (struct peer);
-struct attr test_mp_list_attr[4];
-struct bgp_info test_mp_list_info[] = {
-  { .peer = &test_mp_list_peer[0], .attr = &test_mp_list_attr[0] },
-  { .peer = &test_mp_list_peer[1], .attr = &test_mp_list_attr[1] },
-  { .peer = &test_mp_list_peer[2], .attr = &test_mp_list_attr[1] },
-  { .peer = &test_mp_list_peer[3], .attr = &test_mp_list_attr[2] },
-  { .peer = &test_mp_list_peer[4], .attr = &test_mp_list_attr[3] },
-};
-int test_mp_list_info_count =
-  sizeof (test_mp_list_info)/sizeof (struct bgp_info);
-
-static int
-setup_bgp_mp_list (testcase_t *t)
-{
-  test_mp_list_attr[0].nexthop.s_addr = 0x01010101;
-  test_mp_list_attr[1].nexthop.s_addr = 0x02020202;
-  test_mp_list_attr[2].nexthop.s_addr = 0x03030303;
-  test_mp_list_attr[3].nexthop.s_addr = 0x04040404;
-
-  if ((test_mp_list_peer[0].su_remote = sockunion_str2su ("1.1.1.1")) == NULL)
-    return -1;
-  if ((test_mp_list_peer[1].su_remote = sockunion_str2su ("2.2.2.2")) == NULL)
-    return -1;
-  if ((test_mp_list_peer[2].su_remote = sockunion_str2su ("3.3.3.3")) == NULL)
-    return -1;
-  if ((test_mp_list_peer[3].su_remote = sockunion_str2su ("4.4.4.4")) == NULL)
-    return -1;
-  if ((test_mp_list_peer[4].su_remote = sockunion_str2su ("5.5.5.5")) == NULL)
-    return -1;
-
-  return 0;
-}
-
-static int
-run_bgp_mp_list (testcase_t *t)
-{
-  struct list mp_list;
-  struct listnode *mp_node;
-  struct bgp_info *info;
-  int i;
-  int test_result = TEST_PASSED;
-  bgp_mp_list_init (&mp_list);
-  EXPECT_TRUE (listcount(&mp_list) == 0, test_result);
-
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[4]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[2]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[3]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
-
-  for (i = 0, mp_node = mp_list.head; i < test_mp_list_info_count;
-       i++, mp_node = listnextnode(mp_node))
-    {
-      info = listgetdata(mp_node);
-      EXPECT_TRUE (info == &test_mp_list_info[i], test_result);
-    }
-
-  bgp_mp_list_clear (&mp_list);
-  EXPECT_TRUE (listcount(&mp_list) == 0, test_result);
-
-  return test_result;
-}
-
-static int
-cleanup_bgp_mp_list (testcase_t *t)
-{
-  int i;
-
-  for (i = 0; i < test_mp_list_peer_count; i++)
-    sockunion_free (test_mp_list_peer[i].su_remote);
-
-  return 0;
-}
-
-testcase_t test_bgp_mp_list = {
-  .desc = "Test bgp_mp_list",
-  .setup = setup_bgp_mp_list,
-  .run = run_bgp_mp_list,
-  .cleanup = cleanup_bgp_mp_list,
-};
-
-/*=========================================================
- * Testcase for bgp_info_mpath_update
- */
-
-struct bgp_node test_rn;
-
-static int
-setup_bgp_info_mpath_update (testcase_t *t)
-{
-  int i;
-  str2prefix ("42.1.1.0/24", &test_rn.p);
-  setup_bgp_mp_list (t);
-  for (i = 0; i < test_mp_list_info_count; i++)
-    bgp_info_add (&test_rn, &test_mp_list_info[i]);
-  return 0;
-}
-
-static int
-run_bgp_info_mpath_update (testcase_t *t)
-{
-  struct bgp_info *new_best, *old_best, *mpath;
-  struct list mp_list;
-  struct bgp_maxpaths_cfg mp_cfg = { 3, 3 };
-  int test_result = TEST_PASSED;
-  bgp_mp_list_init (&mp_list);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[4]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[3]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
-  new_best = &test_mp_list_info[3];
-  old_best = NULL;
-  bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg);
-  bgp_mp_list_clear (&mp_list);
-  EXPECT_TRUE (bgp_info_mpath_count (new_best) == 2, test_result);
-  mpath = bgp_info_mpath_first (new_best);
-  EXPECT_TRUE (mpath == &test_mp_list_info[0], test_result);
-  EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
-  mpath = bgp_info_mpath_next (mpath);
-  EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result);
-  EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
-
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
-  bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
-  new_best = &test_mp_list_info[0];
-  old_best = &test_mp_list_info[3];
-  bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg);
-  bgp_mp_list_clear (&mp_list);
-  EXPECT_TRUE (bgp_info_mpath_count (new_best) == 1, test_result);
-  mpath = bgp_info_mpath_first (new_best);
-  EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result);
-  EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
-  EXPECT_TRUE (!CHECK_FLAG (test_mp_list_info[0].flags, BGP_INFO_MULTIPATH),
-               test_result);
-
-  return test_result;
-}
-
-static int
-cleanup_bgp_info_mpath_update (testcase_t *t)
-{
-  int i;
-
-  for (i = 0; i < test_mp_list_peer_count; i++)
-    sockunion_free (test_mp_list_peer[i].su_remote);
-
-  return 0;
-}
-
-testcase_t test_bgp_info_mpath_update = {
-  .desc = "Test bgp_info_mpath_update",
-  .setup = setup_bgp_info_mpath_update,
-  .run = run_bgp_info_mpath_update,
-  .cleanup = cleanup_bgp_info_mpath_update,
-};
-
-/*=========================================================
- * Set up testcase vector
- */
-testcase_t *all_tests[] = {
-  &test_bgp_cfg_maximum_paths,
-  &test_bgp_mp_list,
-  &test_bgp_info_mpath_update,
-};
-
-int all_tests_count = (sizeof(all_tests)/sizeof(testcase_t *));
-
-/*=========================================================
- * Test Driver Functions
- */
-static int
-global_test_init (void)
-{
-  qobj_init ();
-  master = thread_master_create ();
-  zclient = zclient_new(master);
-  bgp_master_init ();
-  vrf_init ();
-  bgp_option_set (BGP_OPT_NO_LISTEN);
-  
-  if (fileno (stdout) >= 0)
-    tty = isatty (fileno (stdout));
-  return 0;
-}
-
-static int
-global_test_cleanup (void)
-{
-  if (zclient != NULL)
-    zclient_free (zclient);
-  thread_master_free (master);
-  return 0;
-}
-
-static void
-display_result (testcase_t *test, int result)
-{
-  if (tty)
-    printf ("%s: %s\n", test->desc, result == TEST_PASSED ? OK : FAILED);
-  else
-    printf ("%s: %s\n", test->desc, result == TEST_PASSED ? "OK" : "FAILED");
-}
-
-static int
-setup_test (testcase_t *t)
-{
-  int res = 0;
-  if (t->setup)
-    res = t->setup (t);
-  return res;
-}
-
-static int
-cleanup_test (testcase_t *t)
-{
-  int res = 0;
-  if (t->cleanup)
-    res = t->cleanup (t);
-  return res;
-}
-
-static void
-run_tests (testcase_t *tests[], int num_tests, int *pass_count, int *fail_count)
-{
-  int test_index, result;
-  testcase_t *cur_test;
-
-  *pass_count = *fail_count = 0;
-
-  for (test_index = 0; test_index < num_tests; test_index++)
-    {
-      cur_test = tests[test_index];
-      if (!cur_test->desc)
-        {
-          printf ("error: test %d has no description!\n", test_index);
-          continue;
-        }
-      if (!cur_test->run)
-        {
-          printf ("error: test %s has no run function!\n", cur_test->desc);
-          continue;
-        }
-      if (setup_test (cur_test) != 0)
-        {
-          printf ("error: setup failed for test %s\n", cur_test->desc);
-          continue;
-        }
-      result = cur_test->run (cur_test);
-      if (result == TEST_PASSED)
-        *pass_count += 1;
-      else
-        *fail_count += 1;
-      display_result (cur_test, result);
-      if (cleanup_test (cur_test) != 0)
-        {
-          printf ("error: cleanup failed for test %s\n", cur_test->desc);
-          continue;
-        }
-    }
-}
-
-int
-main (void)
-{
-  int pass_count, fail_count;
-  time_t cur_time;
-
-  time (&cur_time);
-  printf("BGP Multipath Tests Run at %s", ctime(&cur_time));
-  if (global_test_init () != 0)
-    {
-      printf("Global init failed. Terminating.\n");
-      exit(1);
-    }
-  run_tests (all_tests, all_tests_count, &pass_count, &fail_count);
-  global_test_cleanup ();
-  printf("Total pass/fail: %d/%d\n", pass_count, fail_count);
-  return fail_count;
-}
diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c
new file mode 100644 (file)
index 0000000..f3999cb
--- /dev/null
@@ -0,0 +1,1389 @@
+/* 
+ * Copyright (C) 2005 Sun Microsystems, Inc.
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+
+#include "vty.h"
+#include "stream.h"
+#include "privs.h"
+#include "queue.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_aspath.h"
+#include "bgpd/bgp_attr.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;
+
+static int failed = 0;
+
+/* specification for a test - what the results should be */
+struct test_spec 
+{
+  const char *shouldbe; /* the string the path should parse to */
+  const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
+  const unsigned int hops; /* aspath_count_hops result */
+  const unsigned int confeds; /* aspath_count_confeds */
+  const int private_as; /* whether the private_as check should pass or fail */
+#define NOT_ALL_PRIVATE 0
+#define ALL_PRIVATE 1
+  const as_t does_loop; /* an ASN which should trigger loop-check */
+  const as_t doesnt_loop; /* one which should not */
+  const as_t first; /* the first ASN, if there is one */
+#define NULL_ASN 0
+};
+
+
+/* test segments to parse and validate, and use for other tests */
+static struct test_segment {
+  const char *name;
+  const char *desc;
+  const u_char asdata[1024];
+  int len;
+  struct test_spec sp;
+} test_segments [] = 
+{
+  { /* 0 */ 
+    "seq1",
+    "seq(8466,3,52737,4096)",
+    { 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
+    10,
+    { "8466 3 52737 4096",
+      "8466 3 52737 4096",
+      4, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
+  },
+  { /* 1 */
+    "seq2",
+    "seq(8722) seq(4)",
+    { 0x2,0x1, 0x22,0x12,
+      0x2,0x1, 0x00,0x04 },
+    8,
+    { "8722 4",
+      "8722 4",
+      2, 0, NOT_ALL_PRIVATE, 4, 5, 8722, },
+  },
+  { /* 2 */
+    "seq3",
+    "seq(8466,3,52737,4096,8722,4)",
+    { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 
+               0x22,0x12, 0x00,0x04},
+    14,
+    { "8466 3 52737 4096 8722 4",
+      "8466 3 52737 4096 8722 4",
+       6, 0, NOT_ALL_PRIVATE, 3, 5, 8466 },
+  },
+  { /* 3 */
+    "seqset",
+    "seq(8482,51457) set(5204)",
+    { 0x2,0x2, 0x21,0x22, 0xc9,0x01,
+      0x1,0x1, 0x14,0x54 },
+    10,
+    { "8482 51457 {5204}",
+      "8482 51457 {5204}",
+      3, 0, NOT_ALL_PRIVATE, 5204, 51456, 8482},
+  },
+  { /* 4 */
+    "seqset2",
+    "seq(8467, 59649) set(4196,48658) set(17322,30745)",
+    { 0x2,0x2, 0x21,0x13, 0xe9,0x01,
+      0x1,0x2, 0x10,0x64, 0xbe,0x12,
+      0x1,0x2, 0x43,0xaa, 0x78,0x19 },    
+    18,
+    { "8467 59649 {4196,48658} {17322,30745}",
+      "8467 59649 {4196,48658} {17322,30745}",
+      4, 0, NOT_ALL_PRIVATE, 48658, 1, 8467},
+  },
+  { /* 5 */
+    "multi",
+    "seq(6435,59408,21665) set(2457,61697,4369), seq(1842,41590,51793)",
+    { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
+      0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
+      0x2,0x3, 0x07,0x32, 0xa2,0x76, 0xca,0x51 },
+    24,
+    { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
+      "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
+      7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
+  },
+  { /* 6 */
+    "confed",
+    "confseq(123,456,789)",
+    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15 },
+    8,
+    { "(123 456 789)",
+      "",
+      0, 3, NOT_ALL_PRIVATE, 789, 1, NULL_ASN },
+  },
+  { /* 7 */
+    "confed2",
+    "confseq(123,456,789) confseq(111,222)",
+    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
+      0x3,0x2, 0x00,0x6f, 0x00,0xde },
+    14,
+    { "(123 456 789) (111 222)",
+      "",
+      0, 5, NOT_ALL_PRIVATE, 111, 1, NULL_ASN },
+  },
+  { /* 8 */
+    "confset",
+    "confset(456,123,789)",
+    { 0x4,0x3, 0x01,0xc8, 0x00,0x7b, 0x03,0x15 },
+    8,
+    { "[123,456,789]",
+      "",
+      0, 1, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
+  },
+  { /* 9 */
+    "confmulti",
+    "confseq(123,456,789) confset(222,111) seq(8722) set(4196,48658)",
+    { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
+      0x4,0x2, 0x00,0xde, 0x00,0x6f,
+      0x2,0x1, 0x22,0x12,
+      0x1,0x2, 0x10,0x64, 0xbe,0x12 },
+    24,
+    { "(123 456 789) [111,222] 8722 {4196,48658}",
+      "8722 {4196,48658}",
+      2, 4, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
+  },
+  { /* 10 */
+    "seq4",
+    "seq(8466,2,52737,4096,8722,4)",
+    { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00, 
+               0x22,0x12, 0x00,0x04},
+    14,
+    { "8466 2 52737 4096 8722 4",
+      "8466 2 52737 4096 8722 4",
+      6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
+  },
+  { /* 11 */
+    "tripleseq1",
+    "seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
+    { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01, 
+      0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
+      0x2,0x1, 0x22,0x12},
+    20,
+    { "8466 2 52737 4096 8722 4 8722",
+      "8466 2 52737 4096 8722 4 8722",
+      7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
+  },
+  { /* 12 */ 
+    "someprivate",
+    "seq(8466,64512,52737,65535)",
+    { 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
+    10,
+    { "8466 64512 52737 65535",
+      "8466 64512 52737 65535",
+      4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
+  },
+  { /* 13 */ 
+    "allprivate",
+    "seq(65534,64512,64513,65535)",
+    { 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
+    10,
+    { "65534 64512 64513 65535",
+      "65534 64512 64513 65535",
+      4, 0, ALL_PRIVATE, 65534, 4, 65534 },
+  },
+  { /* 14 */ 
+    "long",
+    "seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
+    { 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
+                0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed, },
+    502,
+    { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
+      
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
+      250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
+  },
+  { /* 15 */ 
+    "seq1extra",
+    "seq(8466,3,52737,4096,3456)",
+    { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
+    12,
+    { "8466 3 52737 4096 3456",
+      "8466 3 52737 4096 3456",
+      5, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
+  },
+  { /* 16 */
+    "empty",
+    "<empty>",
+    {},
+    0,
+    { "", "", 0, 0, 0, 0, 0, 0 },
+  },
+  { /* 17 */ 
+    "redundantset",
+    "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
+    { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
+      0x1,0x4, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9 },
+    22,
+    {
+     /* We shouldn't ever /generate/ such paths. However, we should
+      * cope with them fine.
+      */
+     "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 },
+  },
+  { /* 25 */ 
+    "zero-size overflow",
+    "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
+    { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
+    12,
+    { NULL, NULL,
+      0, 0, 0, 0, 0, 0 },
+  },
+  { /* 26  */ 
+    "zero-size overflow + valid segment",
+    "seq(#AS=0:8466 3 52737),seq(4096 3456)",
+    { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 
+      0x2,0x2, 0x10,0x00, 0x0d,0x80 },
+    14
+    ,
+    { NULL, NULL,
+      0, 0, 0, 0, 0, 0 },
+  },
+  { /* 27  */ 
+    "invalid segment type",
+    "type=8(4096 3456)",
+    { 0x8,0x2, 0x10,0x00, 0x0d,0x80 },
+    14
+    ,
+    { NULL, NULL,
+      0, 0, 0, 0, 0, 0 },
+  },  { NULL, NULL, {0}, 0, { NULL, 0, 0 } }
+};
+
+#define COMMON_ATTRS \
+      BGP_ATTR_FLAG_TRANS, \
+      BGP_ATTR_ORIGIN, \
+      1, \
+      BGP_ORIGIN_EGP, \
+      BGP_ATTR_FLAG_TRANS, \
+      BGP_ATTR_NEXT_HOP, \
+      4, 192, 0, 2, 0
+#define COMMON_ATTR_SIZE 11
+
+/* */
+static struct aspath_tests {
+  const char *desc;
+  const struct test_segment *segment;
+  const char *shouldbe;  /* String it should evaluate to */
+  const enum as4 { AS4_DATA, AS2_DATA }
+          as4;         /* whether data should be as4 or not (ie as2) */
+  const int result;    /* expected result for bgp_attr_parse */
+  const int cap;       /* capabilities to set for peer */
+  const char attrheader [1024];
+  size_t len;
+  const struct test_segment *old_segment;
+} aspath_tests [] =
+{
+  /* 0 */
+  {
+    "basic test",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS2_DATA, 0,
+    0,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH,
+      10,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 1 */
+  {
+    "length too short",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS2_DATA, -1,
+    0,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH, 
+      8,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 2 */
+  {
+    "length too long",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS2_DATA, -1,
+    0,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH, 
+      12,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 3 */
+  {
+    "incorrect flag",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS2_DATA, -1,
+    0,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
+      BGP_ATTR_AS_PATH, 
+      10,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 4 */
+  {
+    "as4_path, with as2 format data",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS2_DATA, -1,
+    0,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
+      BGP_ATTR_AS4_PATH, 
+      10,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 5 */
+  {
+    "as4, with incorrect attr length",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS4_DATA, -1,
+    PEER_CAP_AS4_RCV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
+      BGP_ATTR_AS4_PATH, 
+      10,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 6 */
+  {
+    "basic 4-byte as-path",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS4_DATA, 0,
+    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH, 
+      18,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 7 */
+  {
+    "4b AS_PATH: too short",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS4_DATA, -1,
+    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH, 
+      16,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 8 */
+  {
+    "4b AS_PATH: too long",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS4_DATA, -1,
+    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH, 
+      20,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 9 */
+  {
+    "4b AS_PATH: too long2",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS4_DATA, -1,
+    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS,
+      BGP_ATTR_AS_PATH, 
+      22,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 10 */
+  {
+    "4b AS_PATH: bad flags",
+    &test_segments[0],
+    "8466 3 52737 4096",
+    AS4_DATA, -1,
+    PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
+      BGP_ATTR_AS_PATH, 
+      18,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 11 */
+  {
+    "4b AS4_PATH w/o AS_PATH",
+    &test_segments[6],
+    NULL,
+    AS4_DATA, -1,
+    PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
+      BGP_ATTR_AS4_PATH, 
+      14,
+    },
+    COMMON_ATTR_SIZE + 3,
+  },
+  /* 12 */
+  {
+    "4b AS4_PATH: confed",
+    &test_segments[6],
+    "8466 3 52737 4096 (123 456 789)",
+    AS4_DATA, 0,
+    PEER_CAP_AS4_ADV,
+    { COMMON_ATTRS,
+      BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
+      BGP_ATTR_AS4_PATH, 
+      14,
+    },
+    COMMON_ATTR_SIZE + 3,
+    &test_segments[0],
+  },
+  { NULL, NULL, NULL, 0, 0, 0, { 0 }, 0 },
+};
+
+/* prepending tests */
+static struct tests {
+  const struct test_segment *test1;
+  const struct test_segment *test2;
+  struct test_spec sp;
+} prepend_tests[] = 
+{
+  /* 0 */
+  { &test_segments[0], &test_segments[1],
+    { "8466 3 52737 4096 8722 4",
+      "8466 3 52737 4096 8722 4",
+      6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
+  },
+  /* 1 */
+  { &test_segments[1], &test_segments[3],
+    { "8722 4 8482 51457 {5204}",
+      "8722 4 8482 51457 {5204}",
+      5, 0, NOT_ALL_PRIVATE, 5204, 1, 8722 }
+  },
+  /* 2 */
+  { &test_segments[3], &test_segments[4],
+    { "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
+      "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
+      7, 0, NOT_ALL_PRIVATE, 5204, 1, 8482 },
+  },
+  /* 3 */
+  { &test_segments[4], &test_segments[5],
+    { "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
+      " {2457,4369,61697} 1842 41590 51793",
+      "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
+      " {2457,4369,61697} 1842 41590 51793",
+      11, 0, NOT_ALL_PRIVATE, 61697, 1, 8467 }
+  },
+  /* 4 */
+  { &test_segments[5], &test_segments[6],
+    { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
+      "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
+      7, 0, NOT_ALL_PRIVATE, 1842, 1, 6435 },
+  },
+  /* 5 */
+  { &test_segments[6], &test_segments[7],
+    { "(123 456 789) (123 456 789) (111 222)",
+      "",
+      0, 8, NOT_ALL_PRIVATE, 111, 1, 0 }
+  },
+  { &test_segments[7], &test_segments[8],
+    { "(123 456 789) (111 222) [123,456,789]",
+      "",
+      0, 6, NOT_ALL_PRIVATE, 111, 1, 0 }
+  },
+  { &test_segments[8], &test_segments[9],
+    { "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
+      "8722 {4196,48658}",
+      2, 5, NOT_ALL_PRIVATE, 456, 1, NULL_ASN },
+  },
+  { &test_segments[9], &test_segments[8],
+    { "(123 456 789) [111,222] 8722 {4196,48658} [123,456,789]",
+      "8722 {4196,48658}",
+      2, 5, NOT_ALL_PRIVATE, 48658, 1, NULL_ASN },
+  },
+  { &test_segments[14], &test_segments[11],
+    { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 2 52737 4096 8722 4 8722",
+      
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
+      "8466 2 52737 4096 8722 4 8722",
+      257, 0, NOT_ALL_PRIVATE, 4096, 1000, 8466 },
+  },
+  { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
+};
+
+struct tests reconcile_tests[] =
+{
+  { &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}",
+      5, 0, NOT_ALL_PRIVATE, 4, 1, 8466 },
+  },
+  { &test_segments[2], &test_segments[0],
+    { "8466 3 52737 4096 {4,8722}",
+      "8466 3 52737 4096 {4,8722}",
+      5, 0, NOT_ALL_PRIVATE, 8722, 1, 8466 },
+  },
+  { &test_segments[2], &test_segments[10],
+    { "8466 {2,3,4,4096,8722,52737}",
+      "8466 {2,3,4,4096,8722,52737}",
+      2, 0, NOT_ALL_PRIVATE, 8722, 5, 8466 },
+  },
+  { &test_segments[10], &test_segments[2],
+    { "8466 {2,3,4,4096,8722,52737}",
+      "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}  },
+};
+
+struct compare_tests 
+{
+  int test_index1;
+  int test_index2;
+#define CMP_RES_YES 1
+#define CMP_RES_NO 0
+  char shouldbe_cmp;
+  char shouldbe_confed;
+} left_compare [] =
+{
+  { 0, 1, CMP_RES_NO, CMP_RES_NO },
+  { 0, 2, CMP_RES_YES, CMP_RES_NO },
+  { 0, 11, CMP_RES_YES, CMP_RES_NO },
+  { 0, 15, CMP_RES_YES, CMP_RES_NO },
+  { 0, 16, CMP_RES_NO, CMP_RES_NO },
+  { 1, 11, CMP_RES_NO, CMP_RES_NO },
+  { 6, 7, CMP_RES_NO, CMP_RES_YES },
+  { 6, 8, CMP_RES_NO, CMP_RES_NO },
+  { 7, 8, CMP_RES_NO, CMP_RES_NO },
+  { 1, 9, CMP_RES_YES, CMP_RES_NO },
+  { 0, 9, CMP_RES_NO, CMP_RES_NO },
+  { 3, 9, CMP_RES_NO, CMP_RES_NO },
+  { 0, 6, CMP_RES_NO, CMP_RES_NO },
+  { 1, 6, CMP_RES_NO, CMP_RES_NO },
+  { 0, 8, CMP_RES_NO, CMP_RES_NO },
+  { 1, 8, CMP_RES_NO, CMP_RES_NO },
+  { 11, 6, CMP_RES_NO, CMP_RES_NO },
+  { 11, 7, CMP_RES_NO, CMP_RES_NO },
+  { 11, 8, CMP_RES_NO, CMP_RES_NO },
+  { 9, 6, CMP_RES_NO, CMP_RES_YES },
+  { 9, 7, CMP_RES_NO, CMP_RES_YES },
+  { 9, 8, CMP_RES_NO, CMP_RES_NO },
+};
+
+/* make an aspath from a data stream */
+static struct aspath *
+make_aspath (const u_char *data, size_t len, int use32bit)
+{
+  struct stream *s = NULL;
+  struct aspath *as;
+  
+  if (len)
+    {
+      s = stream_new (len);
+      stream_put (s, data, len);
+    }
+  as = aspath_parse (s, len, use32bit);
+  
+  if (s)
+    stream_free (s);
+  
+  return as;
+}
+
+static void
+printbytes (const u_char *bytes, int len)
+{
+  int i = 0;
+  while (i < len)
+    {
+      if (i % 2)
+        printf ("%02hhx%s", bytes[i], " ");
+      else
+        printf ("0x%02hhx", bytes[i]);
+      i++;
+    }
+  printf ("\n");
+}  
+
+/* validate the given aspath */
+static int
+validate (struct aspath *as, const struct test_spec *sp)
+{
+  size_t bytes, bytes4;
+  int fails = 0;
+  const u_char *out;
+  static struct stream *s;
+  struct aspath *asinout, *asconfeddel, *asstr, *as4;
+  
+  if (as == NULL && sp->shouldbe == NULL)
+    {
+      printf ("Correctly failed to parse\n");
+      return fails;
+    }
+  
+  out = aspath_snmp_pathseg (as, &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:
+   *
+   *   aspath_parse(aspath_put(as)) 
+   *
+   * should:
+   *
+   * - also match the specified 'shouldbe' value
+   * - hash to same value as original path
+   * - have same hops and confed counts as original, and as the
+   *   the specified counts
+   *
+   * 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.
+   */
+  if (strcmp(aspath_print (as), sp->shouldbe)
+         /* hash validation */
+      || (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)
+      || (aspath_count_hops (asinout) != sp->hops)
+      || (aspath_count_confeds (asinout) != sp->confeds))
+    {
+      failed++;
+      fails++;
+      printf ("shouldbe:\n%s\n", sp->shouldbe);
+      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, 
+              aspath_count_hops (as),
+              aspath_count_hops (asinout) );
+      printf ("confeds: %d, counted %d %d\n", sp->confeds,
+              aspath_count_confeds (as),
+              aspath_count_confeds (asinout));
+      printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
+      printbytes (out, bytes);
+    }
+         /* basic confed related tests */
+  if ((aspath_print (asconfeddel) == NULL 
+          && sp->shouldbe_delete_confed != NULL)
+      || (aspath_print (asconfeddel) != NULL 
+          && sp->shouldbe_delete_confed == NULL)
+      || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
+         /* delete_confed_seq should be idempotent */
+      || (aspath_key_make (asconfeddel) 
+          != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
+    {
+      failed++;
+      fails++;
+      printf ("as-path minus confeds is: %s\n", aspath_print (asconfeddel));
+      printf ("as-path minus confeds should be: %s\n", sp->shouldbe_delete_confed);
+    }
+      /* aspath_str2aspath test */
+  if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
+      || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
+      || strcmp(aspath_print (asstr), sp->shouldbe))
+    {
+      failed++;
+      fails++;
+      printf ("asstr: %s\n", aspath_print (asstr));
+    }
+  
+    /* loop, private and first as checks */
+  if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
+      || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
+      || (aspath_private_as_check (as) != sp->private_as)
+      || (aspath_firstas_check (as,sp->first)
+          && sp->first == 0))
+    {
+      failed++;
+      fails++;
+      printf ("firstas: %d,  got %d\n", sp->first,
+              aspath_firstas_check (as,sp->first));
+      printf ("loop does: %d %d, doesnt: %d %d\n",
+              sp->does_loop, aspath_loop_check (as, sp->does_loop),
+              sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
+      printf ("private check: %d %d\n", sp->private_as,
+              aspath_private_as_check (as));
+    }
+  aspath_unintern (&asinout);
+  aspath_unintern (&as4);
+  
+  aspath_free (asconfeddel);
+  aspath_free (asstr);
+  stream_reset (s);
+  
+  return fails;
+}
+
+static void
+empty_get_test ()
+{
+  struct aspath *as = aspath_empty_get ();
+  struct test_spec sp = { "", "", 0, 0, 0, 0, 0, 0 };
+
+  printf ("empty_get_test, as: %s\n",aspath_print (as));
+  if (!validate (as, &sp))
+    printf ("%s\n", OK);
+  else
+    printf ("%s!\n", FAILED);
+  
+  printf ("\n");
+  
+  aspath_free (as);
+}
+
+/* basic parsing test */
+static void
+parse_test (struct test_segment *t)
+{
+  struct aspath *asp;
+  
+  printf ("%s: %s\n", t->name, t->desc);
+
+  asp = make_aspath (t->asdata, t->len, 0);
+  
+  printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));
+
+  if (!validate (asp, &t->sp))
+    printf (OK "\n");
+  else
+    printf (FAILED "\n");
+  
+  printf ("\n");
+  
+  if (asp)
+    aspath_unintern (&asp);
+}
+
+/* prepend testing */
+static void
+prepend_test (struct tests *t)
+{
+  struct aspath *asp1, *asp2, *ascratch;
+  
+  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, 0);
+  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
+  
+  ascratch = aspath_dup (asp2);
+  aspath_unintern (&asp2);
+  
+  asp2 = aspath_prepend (asp1, ascratch);
+  
+  printf ("aspath: %s\n", aspath_print (asp2));
+  
+  if (!validate (asp2, &t->sp))
+    printf ("%s\n", OK);
+  else
+    printf ("%s!\n", FAILED);
+  
+  printf ("\n");
+  aspath_unintern (&asp1);
+  aspath_free (asp2);
+}
+
+/* empty-prepend testing */
+static void
+empty_prepend_test (struct test_segment *t)
+{
+  struct aspath *asp1, *asp2, *ascratch;
+  
+  printf ("empty prepend %s: %s\n", t->name, t->desc);
+  
+  asp1 = make_aspath (t->asdata, t->len, 0);
+  asp2 = aspath_empty ();
+  
+  ascratch = aspath_dup (asp2);
+  aspath_unintern (&asp2);
+  
+  asp2 = aspath_prepend (asp1, ascratch);
+  
+  printf ("aspath: %s\n", aspath_print (asp2));
+  
+  if (!validate (asp2, &t->sp))
+    printf (OK "\n");
+  else
+    printf (FAILED "!\n");
+  
+  printf ("\n");
+  if (asp1)
+    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)
+{
+  struct aspath *asp1, *asp2, *ascratch;
+  
+  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, 0);
+  asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
+  
+  ascratch = aspath_aggregate (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);
+/*  aspath_unintern (ascratch);*/
+}
+
+/* cmp_left tests  */
+static void
+cmp_test ()
+{
+  unsigned int i;
+#define CMP_TESTS_MAX \
+  (sizeof(left_compare) / sizeof (struct compare_tests))
+
+  for (i = 0; i < CMP_TESTS_MAX; i++)
+    {
+      struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
+      struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
+      struct aspath *asp1, *asp2;
+      
+      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, 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
+          || aspath_cmp_left_confed (asp1, asp2) 
+               != left_compare[i].shouldbe_confed
+          || aspath_cmp_left_confed (asp2, asp1) 
+               != left_compare[i].shouldbe_confed)
+        {
+          failed++;
+          printf (FAILED "\n");
+          printf ("result should be: cmp: %d, confed: %d\n", 
+                  left_compare[i].shouldbe_cmp,
+                  left_compare[i].shouldbe_confed);
+          printf ("got: cmp %d, cmp_confed: %d\n",
+                  aspath_cmp_left (asp1, asp2),
+                  aspath_cmp_left_confed (asp1, asp2));
+          printf("path1: %s\npath2: %s\n", aspath_print (asp1),
+                 aspath_print (asp2));
+        }
+      else
+        printf (OK "\n");
+      
+      printf ("\n");
+      aspath_unintern (&asp1);
+      aspath_unintern (&asp2);
+    }
+}
+
+static int
+handle_attr_test (struct aspath_tests *t)
+{
+  struct bgp bgp = { 0 }; 
+  struct peer peer = { 0 };
+  struct attr attr = { 0 };  
+  int ret;
+  int initfail = failed;
+  struct aspath *asp;
+  size_t datalen;
+  
+  asp = make_aspath (t->segment->asdata, t->segment->len, 0);
+    
+  peer.ibuf = stream_new (BGP_MAX_PACKET_SIZE);
+  peer.obuf = stream_fifo_new ();
+  peer.bgp = &bgp;
+  peer.host = (char *)"none";
+  peer.fd = -1;
+  peer.cap = t->cap;
+  
+  stream_write (peer.ibuf, t->attrheader, t->len);
+  datalen = aspath_put (peer.ibuf, asp, t->as4 == AS4_DATA);
+  if (t->old_segment)
+    {
+      char dummyaspath[] = { BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH,
+                             t->old_segment->len };
+      stream_write (peer.ibuf, dummyaspath, sizeof (dummyaspath));
+      stream_write (peer.ibuf, t->old_segment->asdata, t->old_segment->len);
+      datalen += sizeof (dummyaspath) + t->old_segment->len;
+    }
+  
+  ret = bgp_attr_parse (&peer, &attr, t->len + datalen, NULL, NULL);
+  
+  if (ret != t->result)
+    {
+      printf ("bgp_attr_parse returned %d, expected %d\n", ret, t->result);
+      printf ("datalen %zd\n", datalen);
+      failed++;
+    }
+  if (ret != 0)
+    goto out;
+  
+  if (t->shouldbe && attr.aspath == NULL)
+    {
+      printf ("aspath is NULL, but should be: %s\n", t->shouldbe);
+      failed++;
+    }
+  if (t->shouldbe && attr.aspath && strcmp (attr.aspath->str, t->shouldbe))
+    {
+      printf ("attr str and 'shouldbe' mismatched!\n"
+              "attr str:  %s\n"
+              "shouldbe:  %s\n",
+              attr.aspath->str, t->shouldbe);
+      failed++;
+    }
+  if (!t->shouldbe && attr.aspath)
+    {
+      printf ("aspath should be NULL, but is: %s\n", attr.aspath->str);
+      failed++;
+    }
+
+out:
+  if (attr.aspath)
+    aspath_unintern (&attr.aspath);
+  if (asp)
+    aspath_unintern (&asp);
+  return failed - initfail;
+}
+
+static void
+attr_test (struct aspath_tests *t)
+{
+    printf ("%s\n", t->desc);
+    printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);  
+}
+
+int
+main (void)
+{
+  int i = 0;
+  qobj_init ();
+  bgp_master_init ();
+  master = bm->master;
+  bgp_option_set (BGP_OPT_NO_LISTEN);
+  bgp_attr_init ();
+  
+  while (test_segments[i].name)
+    {
+      printf ("test %u\n", i);
+      parse_test (&test_segments[i]);
+      empty_prepend_test (&test_segments[i++]);
+    }
+  
+  i = 0;
+  while (prepend_tests[i].test1)
+    {
+      printf ("prepend test %u\n", i);
+      prepend_test (&prepend_tests[i++]);
+    }
+  
+  i = 0;
+  while (aggregate_tests[i].test1)
+    {
+      printf ("aggregate test %u\n", i);
+      aggregate_test (&aggregate_tests[i++]);
+    }
+  
+  i = 0;
+  
+  while (reconcile_tests[i].test1)
+    {
+      printf ("reconcile test %u\n", i);
+      as4_reconcile_test (&reconcile_tests[i++]);
+    }
+  
+  i = 0;
+  
+  cmp_test();
+  
+  i = 0;
+  
+  empty_get_test();
+  
+  i = 0;
+  
+  while (aspath_tests[i].desc)
+    {
+      printf ("aspath_attr test %d\n", i);
+      attr_test (&aspath_tests[i++]);
+    }
+  
+  printf ("failures: %d\n", failed);
+  printf ("aspath count: %ld\n", aspath_count());
+  
+  return (failed + aspath_count());
+}
diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c
new file mode 100644 (file)
index 0000000..f83dee5
--- /dev/null
@@ -0,0 +1,701 @@
+/* 
+ * Copyright (C) 2007 Sun Microsystems, Inc.
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+
+#include "qobj.h"
+#include "vty.h"
+#include "stream.h"
+#include "privs.h"
+#include "memory.h"
+#include "queue.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_open.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_packet.h"
+
+#define VT100_RESET "\x1b[0m"
+#define VT100_RED "\x1b[31m"
+#define VT100_GREEN "\x1b[32m"
+#define VT100_YELLOW "\x1b[33m"
+
+
+#define CAPABILITY 0
+#define DYNCAP     1
+#define OPT_PARAM  2
+
+/* need these to link in libbgp */
+struct zebra_privs_t *bgpd_privs = NULL;
+struct thread_master *master = NULL;
+
+static int failed = 0;
+static int tty = 0;
+
+/* test segments to parse and validate, and use for other tests */
+static struct test_segment {
+  const char *name;
+  const char *desc;
+  const u_char data[1024];
+  int len;
+#define SHOULD_PARSE   0
+#define SHOULD_ERR     -1
+  int parses; /* whether it should parse or not */
+  as_t peek_for; /* what peek_for_as4_capability should say */
+  
+  /* AFI/SAFI validation */
+  int validate_afi;
+  afi_t afi;
+  safi_t safi;
+#define VALID_AFI 1
+#define INVALID_AFI 0
+  int afi_valid;
+} test_segments [] = 
+{
+  /* 0 */
+  { "caphdr", 
+    "capability header, and no more",
+    { CAPABILITY_CODE_REFRESH, 0x0 },
+    2, SHOULD_PARSE,
+  },
+  /* 1 */
+  { "nodata",
+    "header, no data but length says there is",
+    { 0x1, 0xa },
+    2, SHOULD_ERR,
+  },
+  /* 2 */
+  { "padded",
+    "valid, with padding",
+    { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
+    4, SHOULD_PARSE,
+  },
+  /* 3 */
+  { "minsize",
+    "violates minsize requirement",
+    { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
+    4, SHOULD_ERR,
+  },
+  { NULL, NULL, {0}, 0, 0},
+};
+
+static struct test_segment mp_segments[] =
+{
+  { "MP4",
+    "MP IP/Uni",
+    { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
+    6, SHOULD_PARSE, 0,
+    1, AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { "MPv6",
+    "MP IPv6/Uni",
+    { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
+    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, 0,
+    1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
+  },
+  /* 6 */
+  { "MP3",
+    "MP IP6/MPLS-labeled VPN",
+    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
+    6, SHOULD_PARSE, 0,
+    1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  /* 7 */
+  { "MP5",
+    "MP IP6/MPLS-VPN",
+    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
+    6, SHOULD_PARSE, 0,
+    1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  /* 8 */
+  { "MP6",
+    "MP IP4/MPLS-laveled VPN",
+    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
+    6, SHOULD_PARSE, 0,
+    1, AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },  
+  /* 10 */
+  { "MP8",
+    "MP unknown AFI/SAFI",
+    { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
+    6, SHOULD_PARSE, 0,
+    1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
+  },
+  /* 11 */
+  { "MP-short",
+    "MP IP4/Unicast, length too short (< minimum)",
+    { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
+    6, SHOULD_ERR,
+  },
+  /* 12 */
+  { "MP-overflow",
+    "MP IP4/Unicast, length too long",
+    { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
+    6, SHOULD_ERR, 0,
+    1, AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { NULL, NULL, {0}, 0, 0}
+};
+
+static struct test_segment misc_segments[] =
+{
+  /* 13 */
+  { "ORF",
+    "ORF, simple, single entry, single tuple",
+    { /* hdr */                CAPABILITY_CODE_ORF, 0x7, 
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x1, 
+      /* tuples */     0x40, 0x3
+    },
+    9, SHOULD_PARSE,
+  },
+  /* 14 */
+  { "ORF-many",
+    "ORF, multi entry/tuple",
+    { /* hdr */                CAPABILITY_CODE_ORF, 0x21,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, ORF_MODE_BOTH,
+                        0x80, ORF_MODE_RECEIVE,
+                        0x80, ORF_MODE_SEND,
+      /* mpc */                0x0, 0x2, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, ORF_MODE_BOTH,
+                        0x80, ORF_MODE_RECEIVE,
+                        0x80, ORF_MODE_SEND,
+      /* mpc */                0x0, 0x2, 0x0, 0x2,
+      /* num */                0x3, 
+      /* tuples */     0x40, ORF_MODE_RECEIVE,
+                        0x80, ORF_MODE_SEND,
+                        0x80, ORF_MODE_BOTH,
+    },
+    35, SHOULD_PARSE,
+  },
+  /* 15 */
+  { "ORFlo",
+    "ORF, multi entry/tuple, hdr length too short",
+    { /* hdr */                CAPABILITY_CODE_ORF, 0x15,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x2,
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+    },
+    35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
+  },
+  /* 16 */
+  { "ORFlu",
+    "ORF, multi entry/tuple, length too long",
+    { /* hdr */                0x3, 0x22,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x2,
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+    },
+    35, SHOULD_ERR
+  },
+  /* 17 */
+  { "ORFnu",
+    "ORF, multi entry/tuple, entry number too long",
+    { /* hdr */                0x3, 0x21,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x1, 
+      /* num */                0x4, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x2,
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+    },
+    35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
+  },
+  /* 18 */
+  { "ORFno",
+    "ORF, multi entry/tuple, entry number too short",
+    { /* hdr */                0x3, 0x21,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x1, 
+      /* num */                0x1, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x2,
+      /* num */                0x3,
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+    },
+    35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
+  },
+  /* 17 */
+  { "ORFpad",
+    "ORF, multi entry/tuple, padded to align",
+    { /* hdr */                0x3, 0x22,
+      /* mpc */                0x0, 0x1, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x1, 
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+      /* mpc */                0x0, 0x2, 0x0, 0x2,
+      /* num */                0x3, 
+      /* tuples */     0x40, 0x3,
+                        0x80, 0x1,
+                        0x80, 0x2,
+                        0x00,
+    },
+    36, SHOULD_PARSE,
+  },
+  /* 19 */
+  { "AS4",
+    "AS4 capability",
+    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
+    6, SHOULD_PARSE, 2882400018,
+  },
+  { "AS4",
+    "AS4 capability: short",
+    { 0x41, 0x4, 0xab, 0xcd, 0xef }, /* AS: 2882400018 */
+    5, SHOULD_ERR,
+  },
+  { "AS4",
+    "AS4 capability: long",
+    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12 },
+    7, SHOULD_ERR, 2882400018,
+  },
+  { "GR",
+    "GR capability",
+    { /* hdr */                CAPABILITY_CODE_RESTART, 0xe,
+      /* R-bit, time */        0xf1, 0x12,
+      /* afi */                0x0, 0x1,
+      /* safi */       0x1,
+      /* flags */      0xf,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x1,
+      /* flags */      0x0,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x2,
+      /* flags */      0x1,
+    },
+    16, SHOULD_PARSE,
+  },
+  { "GR-short",
+    "GR capability, but header length too short",
+    { /* hdr */                0x40, 0xa,
+      /* R-bit, time */        0xf1, 0x12,
+      /* afi */                0x0, 0x1,
+      /* safi */       0x1,
+      /* flags */      0xf,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x1,
+      /* flags */      0x0,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x2,
+      /* flags */      0x1,
+    },
+    15 /* array is 16 though */, SHOULD_ERR,
+  },
+  { "GR-long",
+    "GR capability, but header length too long",
+    { /* hdr */                0x40, 0xf,
+      /* R-bit, time */        0xf1, 0x12,
+      /* afi */                0x0, 0x1,
+      /* safi */       0x1,
+      /* flags */      0xf,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x1,
+      /* flags */      0x0,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x2,
+      /* flags */      0x01,
+    },
+    16, SHOULD_ERR,
+  },
+  { "GR-trunc",
+    "GR capability, but truncated",
+    { /* hdr */                0x40, 0xf,
+      /* R-bit, time */        0xf1, 0x12,
+      /* afi */                0x0, 0x1,
+      /* safi */       0x1,
+      /* flags */      0xf,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x1,
+      /* flags */      0x0,
+      /* afi */                0x0, 0x2,
+      /* safi */       0x2,
+      /* flags */      0x1,
+    },
+    15, SHOULD_ERR,
+  },
+  { "GR-empty",
+    "GR capability, but empty.",
+    { /* hdr */                0x40, 0x0,
+    },
+    2, SHOULD_ERR,
+  },
+  { "MP-empty",
+    "MP capability, but empty.",
+    { /* hdr */                0x1, 0x0,
+    },
+    2, SHOULD_ERR,
+  },
+  { "ORF-empty",
+    "ORF capability, but empty.",
+    { /* hdr */                0x3, 0x0,
+    },
+    2, SHOULD_ERR,
+  },
+  { "AS4-empty",
+    "AS4 capability, but empty.",
+    { /* hdr */                0x41, 0x0,
+    },
+    2, SHOULD_ERR,
+  },
+  { "dyn-empty",
+    "Dynamic capability, but empty.",
+    { /* hdr */                0x42, 0x0,
+    },
+    2, SHOULD_PARSE,
+  },
+  { "dyn-old",
+    "Dynamic capability (deprecated version)",
+    { CAPABILITY_CODE_DYNAMIC, 0x0 },
+    2, SHOULD_PARSE,
+  },
+  { NULL, NULL, {0}, 0, 0}
+};
+
+/* DYNAMIC message */
+struct test_segment dynamic_cap_msgs[] = 
+{
+  { "DynCap",
+    "Dynamic Capability Message, IP/Multicast",
+    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
+      7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
+  },
+  { "DynCapLong",
+    "Dynamic Capability Message, IP/Multicast, truncated",
+    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
+      5, SHOULD_ERR,
+  },
+  { "DynCapPadded",
+    "Dynamic Capability Message, IP/Multicast, padded",
+    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
+      8, SHOULD_ERR, /* No way to tell padding from data.. */
+  },
+  { "DynCapMPCpadded",
+    "Dynamic Capability Message, IP/Multicast, cap data padded",
+    { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
+      8, SHOULD_PARSE, /* You can though add padding to the capability data */
+  },
+  { "DynCapMPCoverflow",
+    "Dynamic Capability Message, IP/Multicast, cap data != length",
+    { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
+      8, SHOULD_ERR,
+  },
+  { 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 CAPABILITY:
+        stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
+        stream_putc (peer->ibuf, t->len);
+        break;
+      case DYNCAP:
+/*        for (i = 0; i < BGP_MARKER_SIZE; i++)
+          stream_putc (peer->, 0xff);
+        stream_putw (s, 0);
+        stream_putc (s, BGP_MSG_CAPABILITY);*/
+        break;
+    }
+  stream_write (peer->ibuf, t->data, t->len);
+  
+  printf ("%s: %s\n", t->name, t->desc);
+
+  switch (type)
+    {
+      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);
+        break;
+      default:
+        printf ("unknown type %u\n", type);
+        exit(1);
+    }
+  
+  if (!ret && t->validate_afi)
+    {
+      afi_t afi;
+      safi_t safi;
+      
+      /* Convert AFI, SAFI to internal values, check. */
+      if (bgp_map_afi_safi_iana2int (afi_int2iana(t->afi), t->safi, &afi, &safi))
+        {
+          if (t->afi_valid == VALID_AFI)
+            failed++;
+        }
+      printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
+              t->afi, afi, t->safi, safi,
+              peer->afc_recv[afi][safi],
+              peer->afc_nego[afi][safi]);
+        
+      if (t->afi_valid == VALID_AFI)
+        {
+        
+          if (!peer->afc_recv[afi][safi])
+            failed++;
+          if (!peer->afc_nego[afi][safi])
+            failed++;
+        }
+    }
+  
+  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", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
+                                         : VT100_GREEN "OK" VT100_RESET);
+  else
+    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
+  
+  if (failed)
+    printf (" (%u)", failed);
+  
+  printf ("\n\n");
+}
+
+static struct bgp *bgp;
+static as_t asn = 100;
+
+int
+main (void)
+{
+  struct peer *peer;
+  int i, j;
+  
+  conf_bgp_debug_neighbor_events = -1UL;
+  conf_bgp_debug_packet = -1UL;
+  conf_bgp_debug_as4 = -1UL;
+  term_bgp_debug_neighbor_events = -1UL;
+  term_bgp_debug_packet = -1UL;
+  term_bgp_debug_as4 = -1UL;
+  
+  qobj_init ();
+  master = thread_master_create ();
+  bgp_master_init ();
+  vrf_init ();
+  bgp_option_set (BGP_OPT_NO_LISTEN);
+  
+  if (fileno (stdout) >= 0) 
+    tty = isatty (fileno (stdout));
+  
+  if (bgp_get (&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
+    return -1;
+  
+  peer = peer_create_accept (bgp);
+  peer->host = (char *) "foo";
+  
+  for (i = AFI_IP; i < AFI_MAX; i++)
+    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
+      {
+        peer->afc[i][j] = 1;
+        peer->afc_adv[i][j] = 1;
+      }
+  
+  i = 0;
+  while (mp_segments[i].name)
+    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++], CAPABILITY);
+  
+  i = 0;
+  while (misc_segments[i].name)
+    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;
+  
+  i = 0;
+  while (dynamic_cap_msgs[i].name)
+    parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
+  
+  printf ("failures: %d\n", failed);
+  return failed;
+}
diff --git a/tests/bgpd/test_ecommunity.c b/tests/bgpd/test_ecommunity.c
new file mode 100644 (file)
index 0000000..9166af6
--- /dev/null
@@ -0,0 +1,163 @@
+/* 
+ * Copyright (C) 2007 Sun Microsystems, Inc.
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+#include <zebra.h>
+
+#include "vty.h"
+#include "stream.h"
+#include "privs.h"
+#include "memory.h"
+#include "queue.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_ecommunity.h"
+
+/* need these to link in libbgp */
+struct zebra_privs_t *bgpd_privs = NULL;
+struct thread_master *master = NULL;
+
+static int failed = 0;
+
+/* specification for a test - what the results should be */
+struct test_spec 
+{
+  const char *shouldbe; /* the string the path should parse to */
+};
+
+
+/* test segments to parse and validate, and use for other tests */
+static struct test_segment {
+  const char *name;
+  const char *desc;
+  const u_int8_t data[1024];
+  int len;
+  struct test_spec sp;
+} test_segments [] = 
+{
+  { /* 0 */
+    "ipaddr",
+    "rt 1.2.3.4:257",
+    { ECOMMUNITY_ENCODE_IP, ECOMMUNITY_ROUTE_TARGET,
+      0x1,0x2,0x3,0x4, 0x1,0x1 },
+    8,
+    { "rt 1.2.3.4:257" }
+  },
+  { /* 1 */
+    "ipaddr-so",
+    "soo 1.2.3.4:257",
+    { ECOMMUNITY_ENCODE_IP, ECOMMUNITY_SITE_ORIGIN,
+      0x1,0x2,0x3,0x4, 0x1,0x1},
+    8,
+    { "soo 1.2.3.4:257" }
+  },
+  { /* 2 */
+    "asn",
+    "rt 23456:987654321",
+    { ECOMMUNITY_ENCODE_AS, ECOMMUNITY_SITE_ORIGIN,
+      0x5b,0xa0,       0x3a,0xde,0x68,0xb1 },
+    8,
+    { "soo 23456:987654321" }
+  },
+  { /* 3 */
+    "asn4",
+    "rt 168450976:4321",
+    { ECOMMUNITY_ENCODE_AS4, ECOMMUNITY_SITE_ORIGIN,
+      0xa,0xa,0x5b,0xa0,       0x10,0xe1 },
+    8,
+    { "soo 168450976:4321" }
+  },
+  { NULL, NULL, {0}, 0, { NULL } }
+};
+
+
+/* validate the given aspath */
+static int
+validate (struct ecommunity *ecom, const struct test_spec *sp)
+{
+  int fails = 0;
+  struct ecommunity *etmp;
+  char *str1, *str2;
+    
+  printf ("got:\n  %s\n", ecommunity_str (ecom));
+  str1 = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
+  etmp = ecommunity_str2com (str1, 0, 1);
+  if (etmp)
+    str2 = ecommunity_ecom2str (etmp, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
+  else
+    str2 = NULL;
+  
+  if (strcmp (sp->shouldbe, str1))
+    {
+      failed++;
+      fails++;
+      printf ("shouldbe: %s\n%s\n", str1, sp->shouldbe);
+    }
+  if (!etmp || strcmp (str1, str2))
+    {
+      failed++;
+      fails++;
+      printf ("dogfood: in %s\n"
+              "    in->out %s\n",
+              str1, 
+              (etmp && str2) ? str2 : "NULL");
+    }
+  ecommunity_free (&etmp);
+  XFREE (MTYPE_ECOMMUNITY_STR, str1);
+  XFREE (MTYPE_ECOMMUNITY_STR, str2);
+  
+  return fails;
+}
+
+/* basic parsing test */
+static void
+parse_test (struct test_segment *t)
+{
+  struct ecommunity *ecom;
+  
+  printf ("%s: %s\n", t->name, t->desc);
+
+  ecom = ecommunity_parse ((u_int8_t *)t->data, t->len);
+
+  printf ("ecom: %s\nvalidating...:\n", ecommunity_str (ecom));
+
+  if (!validate (ecom, &t->sp))
+    printf ("OK\n");
+  else
+    printf ("failed\n");
+  
+  printf ("\n");
+  ecommunity_unintern (&ecom);
+}
+
+     
+int
+main (void)
+{
+  int i = 0;
+  ecommunity_init();
+  while (test_segments[i].name)
+    parse_test (&test_segments[i++]);
+  
+  printf ("failures: %d\n", failed);
+  //printf ("aspath count: %ld\n", aspath_count());
+  return failed;
+  //return (failed + aspath_count());
+}
diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c
new file mode 100644 (file)
index 0000000..397612c
--- /dev/null
@@ -0,0 +1,786 @@
+/* 
+ * Copyright (C) 2008 Sun Microsystems, Inc.
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+
+#include "qobj.h"
+#include "vty.h"
+#include "stream.h"
+#include "privs.h"
+#include "memory.h"
+#include "queue.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_open.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_packet.h"
+#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_nexthop.h"
+
+#define VT100_RESET "\x1b[0m"
+#define VT100_RED "\x1b[31m"
+#define VT100_GREEN "\x1b[32m"
+#define VT100_YELLOW "\x1b[33m"
+
+
+#define CAPABILITY 0
+#define DYNCAP     1
+#define OPT_PARAM  2
+
+/* need these to link in libbgp */
+struct zebra_privs_t *bgpd_privs = NULL;
+struct thread_master *master = NULL;
+
+static int failed = 0;
+static int tty = 0;
+
+/* test segments to parse and validate, and use for other tests */
+static struct test_segment {
+  const char *name;
+  const char *desc;
+  const u_char data[1024];
+  int len;
+#define SHOULD_PARSE   0
+#define SHOULD_ERR     -1
+  int parses; /* whether it should parse or not */
+  
+  /* AFI/SAFI validation */
+  afi_t afi;
+  safi_t safi;
+#define VALID_AFI 1
+#define INVALID_AFI 0
+  int afi_valid;
+} mp_reach_segments [] = 
+{
+  { "IPv6",
+    "IPV6 MP Reach, global nexthop, 1 NLRI", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      16,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+    },
+    (4 + 16 + 1 + 5), 
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-2",
+    "IPV6 MP Reach, global nexthop, 2 NLRIs", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      16,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,   /* ffee:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+    },
+    (4 + 16 + 1 + 5 + 9), 
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-default",
+    "IPV6 MP Reach, global nexthop, 2 NLRIs + default", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      16,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0x0, /* ::/0 */
+    },
+    (4 + 16 + 1 + 5 + 9 + 1),
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-lnh",
+    "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      32,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
+                                0x0,  0x0,  0x0,  0x0,
+                                0x2,  0x10, 0x2,  0xff,
+                                0x1,  0x2,  0x3,  0x4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0x0, /* ::/0 */
+    },
+    (4 + 32 + 1 + 5 + 9 + 1),
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-nhlen",
+    "IPV6 MP Reach, inappropriate nexthop length", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      4,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
+                                0x0,  0x0,  0x0,  0x0,
+                                0x2,  0x10, 0x2,  0xff,
+                                0x1,  0x2,  0x3,  0x4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0x0, /* ::/0 */
+    },
+    (4 + 32 + 1 + 5 + 9 + 1),
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-nhlen2",
+    "IPV6 MP Reach, invalid nexthop length", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      5,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
+                                0x0,  0x0,  0x0,  0x0,
+                                0x2,  0x10, 0x2,  0xff,
+                                0x1,  0x2,  0x3,  0x4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0x0, /* ::/0 */
+    },
+    (4 + 32 + 1 + 5 + 9 + 1),
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-nhlen3",
+    "IPV6 MP Reach, nexthop length overflow", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      32,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+    },
+    (4 + 16),
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-nhlen4",
+    "IPV6 MP Reach, nexthop length short", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      16,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
+                                0x0,  0x0,  0x0,  0x0,
+                                0x2,  0x10, 0x2,  0xff,
+                                0x1,  0x2,  0x3,  0x4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0x0, /* ::/0 */
+    },
+    (4 + 32 + 1 + 5 + 9 + 1),
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-nlri",
+    "IPV6 MP Reach, NLRI bitlen overflow", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* nexthop bytes */      32,
+      /* Nexthop (global) */   0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
+                                0xaa, 0xbb, 0xcc, 0xdd,
+                                0x3,  0x4,  0x5,  0x6,
+                                0xa1, 0xa2, 0xa3, 0xa4,
+      /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
+                                0x0,  0x0,  0x0,  0x0,
+                                0x2,  0x10, 0x2,  0xff,
+                                0x1,  0x2,  0x3,  0x4,
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                120, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0, /* ::/0 */
+    },
+    (4 + 32 + 1 + 5 + 9 + 1),
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4",
+    "IPv4 MP Reach, 2 NLRIs + default", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
+      /* nexthop bytes */      4,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
+                                17, 10, 2, 3, /* 10.2.3/17 */
+                                0, /* 0/0 */
+    },
+    (4 + 4 + 1 + 3 + 4 + 1),
+    SHOULD_PARSE,
+    AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4-nhlen",
+    "IPv4 MP Reach, nexthop lenth overflow", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
+      /* nexthop bytes */      32,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
+                                17, 10, 2, 3, /* 10.2.3/17 */
+                                0, /* 0/0 */
+    },
+    (4 + 4 + 1 + 3 + 4 + 1),
+    SHOULD_ERR,
+    AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4-nlrilen",
+    "IPv4 MP Reach, nlri lenth overflow", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
+      /* nexthop bytes */      4,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
+                                30, 10, 
+                                0, /* 0/0 */
+    },
+    (4 + 4 + 1 + 3 + 2 + 1),
+    SHOULD_ERR,
+    AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4-VPNv4",
+    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 16,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
+    SHOULD_PARSE,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-bogus-plen",
+    "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 1, 2,
+                                0, 0xff, 3, 4,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
+                                17, 10, 2, 3,  /* 10.2.3/17 */
+                                0, /* 0/0 */
+    },
+    (3 + 1 + 3*4 + 1 + 3 + 4 + 1),
+    SHOULD_ERR,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-plen1-short",
+    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 1,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
+    SHOULD_ERR,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-plen1-long",
+    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 32,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
+    SHOULD_ERR,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-plenn-long",
+    "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 16,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+                                88 + 1, /* bogus */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
+    SHOULD_ERR,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-plenn-short",
+    "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 16,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 2,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
+    SHOULD_ERR,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-bogus-rd-type",
+    "IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 16,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0xff, 0, /* Bogus RD */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
+    SHOULD_PARSE,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { "IPv4-VPNv4-0-nlri",
+    "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* nexthop bytes */      12,
+      /* RD */                 0, 0, 0, 0, /* RD defined to be 0 */
+                                0, 0, 0, 0,
+      /* Nexthop */            192, 168,   0,  1, 
+      /* SNPA (defunct, MBZ) */        0x0,
+      /* NLRI tuples */                88 + 16,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+                                0 /* 0/0, bogus for vpnv4 ?? */
+    },
+    (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
+    SHOULD_ERR,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+
+  /* From bug #385 */
+  { "IPv6-bug",
+    "IPv6, global nexthop, 1 default NLRI", 
+    {
+      /* AFI / SAFI */         0x0, 0x2, 0x1,
+      /* nexthop bytes */      0x20,
+      /* Nexthop (global) */   0x20, 0x01, 0x04, 0x70, 
+                                0x00, 0x01, 0x00, 0x06,
+                                0x00, 0x00, 0x00, 0x00,
+                                0x00, 0x00, 0x00, 0x01, 
+      /* Nexthop (local) */     0xfe, 0x80, 0x00, 0x00, 
+                                0x00, 0x00, 0x00, 0x00,
+                                0x02, 0x0c, 0xdb, 0xff, 
+                                0xfe, 0xfe, 0xeb, 0x00,
+      /* SNPA (defunct, MBZ) */        0,
+      /* NLRI tuples */                /* Should have 0 here for ::/0, but dont */
+    },
+    37,
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  
+  { NULL, NULL, {0}, 0, 0}
+};
+
+/* MP_UNREACH_NLRI tests */
+static struct test_segment mp_unreach_segments [] =
+{
+  { "IPv6-unreach",
+    "IPV6 MP Unreach, 1 NLRI", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* NLRI tuples */                32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+    },
+    (3 + 5), 
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-unreach2",
+    "IPV6 MP Unreach, 2 NLRIs", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+    },
+    (3 + 5 + 9), 
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-unreach-default",
+    "IPV6 MP Unreach, 2 NLRIs + default", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* NLRI tuples */                32, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0x0, /* ::/0 */
+    },
+    (3 + 5 + 9 + 1),
+    SHOULD_PARSE,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv6-unreach-nlri",
+    "IPV6 MP Unreach, NLRI bitlen overflow", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP6, SAFI_UNICAST,
+      /* NLRI tuples */                120, 
+                                0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
+                                64,
+                                0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
+                                0x0,  0x2,  0x0, 0x3,
+                                0, /* ::/0 */
+    },
+    (3 + 5 + 9 + 1),
+    SHOULD_ERR,
+    AFI_IP6, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4-unreach",
+    "IPv4 MP Unreach, 2 NLRIs + default", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
+      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
+                                17, 10, 2, 3, /* 10.2.3/17 */
+                                0, /* 0/0 */
+    },
+    (3 + 3 + 4 + 1),
+    SHOULD_PARSE,
+    AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4-unreach-nlrilen",
+    "IPv4 MP Unreach, nlri length overflow", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, SAFI_UNICAST,
+      /* NLRI tuples */                16, 10, 1,    /* 10.1/16 */
+                                30, 10, 
+                                0, /* 0/0 */
+    },
+    (3 + 3 + 2 + 1),
+    SHOULD_ERR,
+    AFI_IP, SAFI_UNICAST, VALID_AFI,
+  },
+  { "IPv4-unreach-VPNv4",
+    "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", 
+    {
+      /* AFI / SAFI */         0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
+      /* NLRI tuples */                88 + 16,
+                                  0, 1, 2,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_AS */
+                                    0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
+                                  10, 1,    /* 10.1/16 */
+                                88 + 17,
+                                  0xff, 0, 0,   /* tag */
+                                  /* rd, 8 octets */
+                                    0, 0, /* RD_TYPE_IP */
+                                    192, 168, 0, 1, /* IPv4 */
+                                  10, 2, 3,  /* 10.2.3/17 */
+    },
+    (3 + (1+3+8+2) + (1+3+8+3)),
+    SHOULD_PARSE,
+    AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
+  },
+  { NULL, NULL, {0}, 0, 0}
+};
+
+/* nlri_parse indicates 0 on successful parse, and -1 otherwise.
+ * attr_parse indicates BGP_ATTR_PARSE_PROCEED/0 on success,
+ * and BGP_ATTR_PARSE_ERROR/-1 or lower negative ret on err.
+ */
+static void
+handle_result (struct peer *peer, struct test_segment *t,
+               int parse_ret, int nlri_ret)
+{
+  int oldfailed = failed;
+  
+  printf ("mp attr parsed?: %s\n", parse_ret ? "no" : "yes");
+  if (!parse_ret)
+    printf ("nrli parsed?:  %s\n", nlri_ret ? "no" : "yes");
+  printf ("should parse?:  %s\n", t->parses ? "no" : "yes");
+  
+  if ((parse_ret != 0 || nlri_ret != 0) != (t->parses != 0))
+    failed++;
+  
+    
+  if (tty)
+    printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
+                                         : VT100_GREEN "OK" VT100_RESET);
+  else
+    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
+  
+  if (failed)
+    printf (" (%u)", failed);
+  
+  printf ("\n\n");
+}
+
+/* basic parsing test */
+static void
+parse_test (struct peer *peer, struct test_segment *t, int type)
+{
+  int parse_ret = 0, nlri_ret = 0;
+  struct attr attr = { };
+  struct bgp_nlri nlri = { };
+  struct bgp_attr_parser_args attr_args = {
+    .peer = peer,
+    .length = t->len,
+    .total = 1,
+    .attr = &attr,
+    .type = type,
+    .flags = BGP_ATTR_FLAG_OPTIONAL, 
+    .startp = BGP_INPUT_PNT (peer),
+  };
+#define RANDOM_FUZZ 35
+  
+  stream_reset (peer->ibuf);
+  stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
+  stream_set_getp (peer->ibuf, RANDOM_FUZZ);
+  
+  stream_write (peer->ibuf, t->data, t->len);
+  
+  printf ("%s: %s\n", t->name, t->desc);
+  
+  if (type == BGP_ATTR_MP_REACH_NLRI)
+    parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
+  else
+    parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri);
+  if (!parse_ret)
+    {
+      iana_afi_t pkt_afi;
+      safi_t pkt_safi;
+      
+      /* Convert AFI, SAFI to internal values, check. */
+      if (bgp_map_afi_safi_int2iana (nlri.afi, nlri.safi, &pkt_afi, &pkt_safi))
+        assert (0);
+
+      printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
+              nlri.afi , pkt_afi, nlri.safi, pkt_safi,
+              peer->afc_recv[nlri.afi][nlri.safi],
+              peer->afc_nego[nlri.afi][nlri.safi]);
+    }
+  
+  if (!parse_ret)
+    {
+      if (type == BGP_ATTR_MP_REACH_NLRI)
+        nlri_ret = bgp_nlri_parse (peer, &attr, &nlri);
+      else
+        nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
+    }
+  zlog_err("xxxxxxxxxxxxxxxx nlri ret %u", nlri_ret);
+  handle_result (peer, t, parse_ret, nlri_ret);
+}
+
+static struct bgp *bgp;
+static as_t asn = 100;
+
+int
+main (void)
+{
+  struct peer *peer;
+  int i, j;
+  
+  conf_bgp_debug_neighbor_events = -1UL;
+  conf_bgp_debug_packet = -1UL;
+  conf_bgp_debug_as4 = -1UL;
+  term_bgp_debug_neighbor_events = -1UL;
+  term_bgp_debug_packet = -1UL;
+  term_bgp_debug_as4 = -1UL;
+  
+  qobj_init ();
+  master = thread_master_create ();
+  bgp_master_init ();
+  vrf_init ();
+  bgp_option_set (BGP_OPT_NO_LISTEN);
+  bgp_attr_init ();
+  
+  if (fileno (stdout) >= 0) 
+    tty = isatty (fileno (stdout));
+  
+  if (bgp_get (&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
+    return -1;
+  
+  peer = peer_create_accept (bgp);
+  peer->host = (char *)"foo";
+  peer->status = Established;
+  
+  for (i = AFI_IP; i < AFI_MAX; i++)
+    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
+      {
+        peer->afc[i][j] = 1;
+        peer->afc_adv[i][j] = 1;
+      }
+  
+  i = 0;
+  while (mp_reach_segments[i].name)
+    parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);
+
+  i = 0;
+  while (mp_unreach_segments[i].name)
+    parse_test (peer, &mp_unreach_segments[i++], BGP_ATTR_MP_UNREACH_NLRI);
+
+  printf ("failures: %d\n", failed);
+  return failed;
+}
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
new file mode 100644 (file)
index 0000000..f9eb153
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ * BGP Multipath Unit Test
+ * Copyright (C) 2010 Google Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "qobj.h"
+#include "vty.h"
+#include "stream.h"
+#include "privs.h"
+#include "linklist.h"
+#include "memory.h"
+#include "zclient.h"
+#include "queue.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_table.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_nexthop.h"
+#include "bgpd/bgp_mpath.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
+
+#define TEST_PASSED 0
+#define TEST_FAILED -1
+
+#define EXPECT_TRUE(expr, res)                                          \
+  if (!(expr))                                                          \
+    {                                                                   \
+      printf ("Test failure in %s line %u: %s\n",                       \
+              __FUNCTION__, __LINE__, #expr);                           \
+      (res) = TEST_FAILED;                                              \
+    }
+
+typedef struct testcase_t__ testcase_t;
+
+typedef int (*test_setup_func)(testcase_t *);
+typedef int (*test_run_func)(testcase_t *);
+typedef int (*test_cleanup_func)(testcase_t *);
+
+struct testcase_t__ {
+  const char *desc;
+  void *test_data;
+  void *verify_data;
+  void *tmp_data;
+  test_setup_func setup;
+  test_run_func run;
+  test_cleanup_func cleanup;
+};
+
+/* need these to link in libbgp */
+struct thread_master *master = NULL;
+struct zclient *zclient;
+struct zebra_privs_t bgpd_privs =
+{
+  .user = NULL,
+  .group = NULL,
+  .vty_group = NULL,
+};
+
+static int tty = 0;
+
+/* Create fake bgp instance */
+static struct bgp *
+bgp_create_fake (as_t *as, const char *name)
+{
+  struct bgp *bgp;
+  afi_t afi;
+  safi_t safi;
+
+  if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
+    return NULL;
+
+  bgp_lock (bgp);
+  //bgp->peer_self = peer_new (bgp);
+  //bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement");
+
+  bgp->peer = list_new ();
+  //bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
+
+  bgp->group = list_new ();
+  //bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
+
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+      {
+        bgp->route[afi][safi] = bgp_table_init (afi, safi);
+        bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
+        bgp->rib[afi][safi] = bgp_table_init (afi, safi);
+        bgp->maxpaths[afi][safi].maxpaths_ebgp = MULTIPATH_NUM;
+        bgp->maxpaths[afi][safi].maxpaths_ibgp = MULTIPATH_NUM;
+      }
+
+  bgp_scan_init (bgp);
+  bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
+  bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
+  bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
+  bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
+  bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
+
+  bgp->as = *as;
+
+  if (name)
+    bgp->name = strdup (name);
+
+  return bgp;
+}
+
+/*=========================================================
+ * Testcase for maximum-paths configuration
+ */
+static int
+setup_bgp_cfg_maximum_paths (testcase_t *t)
+{
+  as_t asn = 1;
+  t->tmp_data = bgp_create_fake (&asn, NULL);
+  if (!t->tmp_data)
+    return -1;
+  return 0;
+}
+
+static int
+run_bgp_cfg_maximum_paths (testcase_t *t)
+{
+  afi_t afi;
+  safi_t safi;
+  struct bgp *bgp;
+  int api_result;
+  int test_result = TEST_PASSED;
+
+  bgp = t->tmp_data;
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+      {
+        /* test bgp_maximum_paths_set */
+        api_result = bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_EBGP, 10, 0);
+        EXPECT_TRUE (api_result == 0, test_result);
+        api_result = bgp_maximum_paths_set (bgp, afi, safi, BGP_PEER_IBGP, 10, 0);
+        EXPECT_TRUE (api_result == 0, test_result);
+        EXPECT_TRUE (bgp->maxpaths[afi][safi].maxpaths_ebgp == 10, test_result);
+        EXPECT_TRUE (bgp->maxpaths[afi][safi].maxpaths_ibgp == 10, test_result);
+
+        /* test bgp_maximum_paths_unset */
+        api_result = bgp_maximum_paths_unset (bgp, afi, safi, BGP_PEER_EBGP);
+        EXPECT_TRUE (api_result == 0, test_result);
+        api_result = bgp_maximum_paths_unset (bgp, afi, safi, BGP_PEER_IBGP);
+        EXPECT_TRUE (api_result == 0, test_result);
+        EXPECT_TRUE ((bgp->maxpaths[afi][safi].maxpaths_ebgp ==
+                      MULTIPATH_NUM), test_result);
+        EXPECT_TRUE ((bgp->maxpaths[afi][safi].maxpaths_ibgp ==
+                      MULTIPATH_NUM), test_result);
+      }
+
+  return test_result;
+}
+
+static int
+cleanup_bgp_cfg_maximum_paths (testcase_t *t)
+{
+  return bgp_delete ((struct bgp *)t->tmp_data);
+}
+
+testcase_t test_bgp_cfg_maximum_paths = {
+  .desc = "Test bgp maximum-paths config",
+  .setup = setup_bgp_cfg_maximum_paths,
+  .run = run_bgp_cfg_maximum_paths,
+  .cleanup = cleanup_bgp_cfg_maximum_paths,
+};
+
+/*=========================================================
+ * Testcase for bgp_mp_list
+ */
+struct peer test_mp_list_peer[] = {
+  { .local_as = 1, .as = 2 },
+  { .local_as = 1, .as = 2 },
+  { .local_as = 1, .as = 2 },
+  { .local_as = 1, .as = 2 },
+  { .local_as = 1, .as = 2 },
+};
+int test_mp_list_peer_count = sizeof (test_mp_list_peer)/ sizeof (struct peer);
+struct attr test_mp_list_attr[4];
+struct bgp_info test_mp_list_info[] = {
+  { .peer = &test_mp_list_peer[0], .attr = &test_mp_list_attr[0] },
+  { .peer = &test_mp_list_peer[1], .attr = &test_mp_list_attr[1] },
+  { .peer = &test_mp_list_peer[2], .attr = &test_mp_list_attr[1] },
+  { .peer = &test_mp_list_peer[3], .attr = &test_mp_list_attr[2] },
+  { .peer = &test_mp_list_peer[4], .attr = &test_mp_list_attr[3] },
+};
+int test_mp_list_info_count =
+  sizeof (test_mp_list_info)/sizeof (struct bgp_info);
+
+static int
+setup_bgp_mp_list (testcase_t *t)
+{
+  test_mp_list_attr[0].nexthop.s_addr = 0x01010101;
+  test_mp_list_attr[1].nexthop.s_addr = 0x02020202;
+  test_mp_list_attr[2].nexthop.s_addr = 0x03030303;
+  test_mp_list_attr[3].nexthop.s_addr = 0x04040404;
+
+  if ((test_mp_list_peer[0].su_remote = sockunion_str2su ("1.1.1.1")) == NULL)
+    return -1;
+  if ((test_mp_list_peer[1].su_remote = sockunion_str2su ("2.2.2.2")) == NULL)
+    return -1;
+  if ((test_mp_list_peer[2].su_remote = sockunion_str2su ("3.3.3.3")) == NULL)
+    return -1;
+  if ((test_mp_list_peer[3].su_remote = sockunion_str2su ("4.4.4.4")) == NULL)
+    return -1;
+  if ((test_mp_list_peer[4].su_remote = sockunion_str2su ("5.5.5.5")) == NULL)
+    return -1;
+
+  return 0;
+}
+
+static int
+run_bgp_mp_list (testcase_t *t)
+{
+  struct list mp_list;
+  struct listnode *mp_node;
+  struct bgp_info *info;
+  int i;
+  int test_result = TEST_PASSED;
+  bgp_mp_list_init (&mp_list);
+  EXPECT_TRUE (listcount(&mp_list) == 0, test_result);
+
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[4]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[2]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[3]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
+
+  for (i = 0, mp_node = mp_list.head; i < test_mp_list_info_count;
+       i++, mp_node = listnextnode(mp_node))
+    {
+      info = listgetdata(mp_node);
+      EXPECT_TRUE (info == &test_mp_list_info[i], test_result);
+    }
+
+  bgp_mp_list_clear (&mp_list);
+  EXPECT_TRUE (listcount(&mp_list) == 0, test_result);
+
+  return test_result;
+}
+
+static int
+cleanup_bgp_mp_list (testcase_t *t)
+{
+  int i;
+
+  for (i = 0; i < test_mp_list_peer_count; i++)
+    sockunion_free (test_mp_list_peer[i].su_remote);
+
+  return 0;
+}
+
+testcase_t test_bgp_mp_list = {
+  .desc = "Test bgp_mp_list",
+  .setup = setup_bgp_mp_list,
+  .run = run_bgp_mp_list,
+  .cleanup = cleanup_bgp_mp_list,
+};
+
+/*=========================================================
+ * Testcase for bgp_info_mpath_update
+ */
+
+struct bgp_node test_rn;
+
+static int
+setup_bgp_info_mpath_update (testcase_t *t)
+{
+  int i;
+  str2prefix ("42.1.1.0/24", &test_rn.p);
+  setup_bgp_mp_list (t);
+  for (i = 0; i < test_mp_list_info_count; i++)
+    bgp_info_add (&test_rn, &test_mp_list_info[i]);
+  return 0;
+}
+
+static int
+run_bgp_info_mpath_update (testcase_t *t)
+{
+  struct bgp_info *new_best, *old_best, *mpath;
+  struct list mp_list;
+  struct bgp_maxpaths_cfg mp_cfg = { 3, 3 };
+  int test_result = TEST_PASSED;
+  bgp_mp_list_init (&mp_list);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[4]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[3]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
+  new_best = &test_mp_list_info[3];
+  old_best = NULL;
+  bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg);
+  bgp_mp_list_clear (&mp_list);
+  EXPECT_TRUE (bgp_info_mpath_count (new_best) == 2, test_result);
+  mpath = bgp_info_mpath_first (new_best);
+  EXPECT_TRUE (mpath == &test_mp_list_info[0], test_result);
+  EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
+  mpath = bgp_info_mpath_next (mpath);
+  EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result);
+  EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
+
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[0]);
+  bgp_mp_list_add (&mp_list, &test_mp_list_info[1]);
+  new_best = &test_mp_list_info[0];
+  old_best = &test_mp_list_info[3];
+  bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg);
+  bgp_mp_list_clear (&mp_list);
+  EXPECT_TRUE (bgp_info_mpath_count (new_best) == 1, test_result);
+  mpath = bgp_info_mpath_first (new_best);
+  EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result);
+  EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result);
+  EXPECT_TRUE (!CHECK_FLAG (test_mp_list_info[0].flags, BGP_INFO_MULTIPATH),
+               test_result);
+
+  return test_result;
+}
+
+static int
+cleanup_bgp_info_mpath_update (testcase_t *t)
+{
+  int i;
+
+  for (i = 0; i < test_mp_list_peer_count; i++)
+    sockunion_free (test_mp_list_peer[i].su_remote);
+
+  return 0;
+}
+
+testcase_t test_bgp_info_mpath_update = {
+  .desc = "Test bgp_info_mpath_update",
+  .setup = setup_bgp_info_mpath_update,
+  .run = run_bgp_info_mpath_update,
+  .cleanup = cleanup_bgp_info_mpath_update,
+};
+
+/*=========================================================
+ * Set up testcase vector
+ */
+testcase_t *all_tests[] = {
+  &test_bgp_cfg_maximum_paths,
+  &test_bgp_mp_list,
+  &test_bgp_info_mpath_update,
+};
+
+int all_tests_count = (sizeof(all_tests)/sizeof(testcase_t *));
+
+/*=========================================================
+ * Test Driver Functions
+ */
+static int
+global_test_init (void)
+{
+  qobj_init ();
+  master = thread_master_create ();
+  zclient = zclient_new(master);
+  bgp_master_init ();
+  vrf_init ();
+  bgp_option_set (BGP_OPT_NO_LISTEN);
+  
+  if (fileno (stdout) >= 0)
+    tty = isatty (fileno (stdout));
+  return 0;
+}
+
+static int
+global_test_cleanup (void)
+{
+  if (zclient != NULL)
+    zclient_free (zclient);
+  thread_master_free (master);
+  return 0;
+}
+
+static void
+display_result (testcase_t *test, int result)
+{
+  if (tty)
+    printf ("%s: %s\n", test->desc, result == TEST_PASSED ? OK : FAILED);
+  else
+    printf ("%s: %s\n", test->desc, result == TEST_PASSED ? "OK" : "FAILED");
+}
+
+static int
+setup_test (testcase_t *t)
+{
+  int res = 0;
+  if (t->setup)
+    res = t->setup (t);
+  return res;
+}
+
+static int
+cleanup_test (testcase_t *t)
+{
+  int res = 0;
+  if (t->cleanup)
+    res = t->cleanup (t);
+  return res;
+}
+
+static void
+run_tests (testcase_t *tests[], int num_tests, int *pass_count, int *fail_count)
+{
+  int test_index, result;
+  testcase_t *cur_test;
+
+  *pass_count = *fail_count = 0;
+
+  for (test_index = 0; test_index < num_tests; test_index++)
+    {
+      cur_test = tests[test_index];
+      if (!cur_test->desc)
+        {
+          printf ("error: test %d has no description!\n", test_index);
+          continue;
+        }
+      if (!cur_test->run)
+        {
+          printf ("error: test %s has no run function!\n", cur_test->desc);
+          continue;
+        }
+      if (setup_test (cur_test) != 0)
+        {
+          printf ("error: setup failed for test %s\n", cur_test->desc);
+          continue;
+        }
+      result = cur_test->run (cur_test);
+      if (result == TEST_PASSED)
+        *pass_count += 1;
+      else
+        *fail_count += 1;
+      display_result (cur_test, result);
+      if (cleanup_test (cur_test) != 0)
+        {
+          printf ("error: cleanup failed for test %s\n", cur_test->desc);
+          continue;
+        }
+    }
+}
+
+int
+main (void)
+{
+  int pass_count, fail_count;
+  time_t cur_time;
+
+  time (&cur_time);
+  printf("BGP Multipath Tests Run at %s", ctime(&cur_time));
+  if (global_test_init () != 0)
+    {
+      printf("Global init failed. Terminating.\n");
+      exit(1);
+    }
+  run_tests (all_tests, all_tests_count, &pass_count, &fail_count);
+  global_test_cleanup ();
+  printf("Total pass/fail: %d/%d\n", pass_count, fail_count);
+  return fail_count;
+}
diff --git a/tests/common-cli.c b/tests/common-cli.c
deleted file mode 100644 (file)
index 4747671..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * generic CLI test helper functions
- *
- * Copyright (C) 2015 by David Lamparter,
- *                   for Open Source Routing / NetDEF, Inc.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include "thread.h"
-#include "vty.h"
-#include "command.h"
-#include "memory.h"
-#include "memory_vty.h"
-#include "log.h"
-
-#include "common-cli.h"
-
-struct thread_master *master;
-
-int dump_args(struct vty *vty, const char *descr,
-              int argc, struct cmd_token *argv[])
-{
-  int i;
-  vty_out (vty, "%s with %d args.%s", descr, argc, VTY_NEWLINE);
-  for (i = 0; i < argc; i++)
-    {
-      vty_out (vty, "[%02d]: %s%s", i, argv[i]->arg, VTY_NEWLINE);
-    }
-
-  return CMD_SUCCESS;
-}
-
-static void vty_do_exit(void)
-{
-  printf ("\nend.\n");
-  cmd_terminate ();
-  vty_terminate ();
-  thread_master_free (master);
-  closezlog (zlog_default);
-
-  log_memstats_stderr ("testcli");
-  exit (0);
-}
-
-/* main routine. */
-int
-main (int argc, char **argv)
-{
-  struct thread thread;
-
-  /* Set umask before anything for security */
-  umask (0027);
-
-  /* master init. */
-  master = thread_master_create ();
-
-  zlog_default = openzlog ("common-cli", ZLOG_NONE, 0,
-                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
-  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
-  zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
-  zlog_set_level (NULL, ZLOG_DEST_MONITOR, LOG_DEBUG);
-
-  /* Library inits. */
-  cmd_init (1);
-  cmd_hostname_set ("test");
-
-  vty_init (master);
-  memory_init ();
-
-  test_init ();
-
-  vty_stdio (vty_do_exit);
-
-  /* Fetch next active thread. */
-  while (thread_fetch (master, &thread))
-    thread_call (&thread);
-
-  /* Not reached. */
-  exit (0);
-}
-
diff --git a/tests/common-cli.h b/tests/common-cli.h
deleted file mode 100644 (file)
index 9c72b08..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * generic CLI test helper functions
- *
- * Copyright (C) 2015 by David Lamparter,
- *                   for Open Source Routing / NetDEF, Inc.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef _COMMON_CLI_H
-#define _COMMON_CLI_H
-
-#include "zebra.h"
-#include "vty.h"
-#include "command.h"
-
-/* function to be implemented by test */
-extern void test_init (void);
-
-/* functions provided by common cli
- * (includes main())
- */
-extern struct thread_master *master;
-
-extern int dump_args(struct vty *vty, const char *descr,
-              int argc, struct cmd_token *argv[]);
-
-#define DUMMY_HELPSTR \
-       "00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n" \
-       "10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n" \
-       "20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n"
-#define DUMMY_DEFUN(name, cmdstr) \
-        DEFUN (name, name ## _cmd, cmdstr, DUMMY_HELPSTR) \
-        { return dump_args(vty, #name, argc, argv); }
-
-#endif /* _COMMON_CLI_H */
diff --git a/tests/ecommunity_test.c b/tests/ecommunity_test.c
deleted file mode 100644 (file)
index 9166af6..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* 
- * Copyright (C) 2007 Sun Microsystems, Inc.
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-#include <zebra.h>
-
-#include "vty.h"
-#include "stream.h"
-#include "privs.h"
-#include "memory.h"
-#include "queue.h"
-#include "filter.h"
-
-#include "bgpd/bgpd.h"
-#include "bgpd/bgp_ecommunity.h"
-
-/* need these to link in libbgp */
-struct zebra_privs_t *bgpd_privs = NULL;
-struct thread_master *master = NULL;
-
-static int failed = 0;
-
-/* specification for a test - what the results should be */
-struct test_spec 
-{
-  const char *shouldbe; /* the string the path should parse to */
-};
-
-
-/* test segments to parse and validate, and use for other tests */
-static struct test_segment {
-  const char *name;
-  const char *desc;
-  const u_int8_t data[1024];
-  int len;
-  struct test_spec sp;
-} test_segments [] = 
-{
-  { /* 0 */
-    "ipaddr",
-    "rt 1.2.3.4:257",
-    { ECOMMUNITY_ENCODE_IP, ECOMMUNITY_ROUTE_TARGET,
-      0x1,0x2,0x3,0x4, 0x1,0x1 },
-    8,
-    { "rt 1.2.3.4:257" }
-  },
-  { /* 1 */
-    "ipaddr-so",
-    "soo 1.2.3.4:257",
-    { ECOMMUNITY_ENCODE_IP, ECOMMUNITY_SITE_ORIGIN,
-      0x1,0x2,0x3,0x4, 0x1,0x1},
-    8,
-    { "soo 1.2.3.4:257" }
-  },
-  { /* 2 */
-    "asn",
-    "rt 23456:987654321",
-    { ECOMMUNITY_ENCODE_AS, ECOMMUNITY_SITE_ORIGIN,
-      0x5b,0xa0,       0x3a,0xde,0x68,0xb1 },
-    8,
-    { "soo 23456:987654321" }
-  },
-  { /* 3 */
-    "asn4",
-    "rt 168450976:4321",
-    { ECOMMUNITY_ENCODE_AS4, ECOMMUNITY_SITE_ORIGIN,
-      0xa,0xa,0x5b,0xa0,       0x10,0xe1 },
-    8,
-    { "soo 168450976:4321" }
-  },
-  { NULL, NULL, {0}, 0, { NULL } }
-};
-
-
-/* validate the given aspath */
-static int
-validate (struct ecommunity *ecom, const struct test_spec *sp)
-{
-  int fails = 0;
-  struct ecommunity *etmp;
-  char *str1, *str2;
-    
-  printf ("got:\n  %s\n", ecommunity_str (ecom));
-  str1 = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
-  etmp = ecommunity_str2com (str1, 0, 1);
-  if (etmp)
-    str2 = ecommunity_ecom2str (etmp, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
-  else
-    str2 = NULL;
-  
-  if (strcmp (sp->shouldbe, str1))
-    {
-      failed++;
-      fails++;
-      printf ("shouldbe: %s\n%s\n", str1, sp->shouldbe);
-    }
-  if (!etmp || strcmp (str1, str2))
-    {
-      failed++;
-      fails++;
-      printf ("dogfood: in %s\n"
-              "    in->out %s\n",
-              str1, 
-              (etmp && str2) ? str2 : "NULL");
-    }
-  ecommunity_free (&etmp);
-  XFREE (MTYPE_ECOMMUNITY_STR, str1);
-  XFREE (MTYPE_ECOMMUNITY_STR, str2);
-  
-  return fails;
-}
-
-/* basic parsing test */
-static void
-parse_test (struct test_segment *t)
-{
-  struct ecommunity *ecom;
-  
-  printf ("%s: %s\n", t->name, t->desc);
-
-  ecom = ecommunity_parse ((u_int8_t *)t->data, t->len);
-
-  printf ("ecom: %s\nvalidating...:\n", ecommunity_str (ecom));
-
-  if (!validate (ecom, &t->sp))
-    printf ("OK\n");
-  else
-    printf ("failed\n");
-  
-  printf ("\n");
-  ecommunity_unintern (&ecom);
-}
-
-     
-int
-main (void)
-{
-  int i = 0;
-  ecommunity_init();
-  while (test_segments[i].name)
-    parse_test (&test_segments[i++]);
-  
-  printf ("failures: %d\n", failed);
-  //printf ("aspath count: %ld\n", aspath_count());
-  return failed;
-  //return (failed + aspath_count());
-}
diff --git a/tests/heavy-thread.c b/tests/heavy-thread.c
deleted file mode 100644 (file)
index c43fa76..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * $Id: heavy-thread.c,v 1.2 2005/04/25 16:42:24 paul Exp $
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/* This programme shows the effects of 'heavy' long-running functions
- * on the cooperative threading model, as demonstrated by heavy.c, and how
- * they can be mitigated using a background thread.
- *
- * Run it with a config file containing 'password whatever', telnet to it
- * (it defaults to port 4000) and enter the 'clear foo string' command.
- * then type whatever and observe that, unlike heavy.c, the vty interface
- * remains responsive.
- */
-#include <zebra.h>
-#include <math.h>
-
-#include "thread.h"
-#include "vty.h"
-#include "command.h"
-#include "memory.h"
-#include "log.h"
-
-#include "tests.h"
-
-extern struct thread_master *master;
-
-enum
-{
-  ITERS_FIRST = 0,
-  ITERS_ERR = 100,
-  ITERS_LATER = 400,
-  ITERS_PRINT = 10,
-  ITERS_MAX = 1000,
-};
-
-struct work_state {
-  struct vty *vty;
-  char *str;
-  int i;
-};
-
-static void
-slow_func (struct vty *vty, const char *str, const int i)
-{
-  double x = 1;
-  int j;
-  
-  for (j = 0; j < 300; j++)
-    x += sin(x)*j;
-  
-  if ((i % ITERS_LATER) == 0)
-    printf ("%s: %d, temporary error, save this somehow and do it later..\n",
-            __func__, i);
-  
-  if ((i % ITERS_ERR) == 0)
-    printf ("%s: hard error\n", __func__);
-  
-  if ((i % ITERS_PRINT) == 0)
-    printf ("%s did %d, x = %g\n", str, i, x);
-}
-
-static int
-clear_something (struct thread *thread)
-{
-  struct work_state *ws = THREAD_ARG(thread);
-  
-  /* this could be like iterating through 150k of route_table 
-   * or worse, iterating through a list of peers, to bgp_stop them with
-   * each having 150k route tables to process...
-   */
-  while (ws->i < ITERS_MAX)
-    {
-      slow_func(ws->vty, ws->str, ws->i);
-      ws->i++;
-      if (thread_should_yield(thread))
-        {
-         thread_add_background(master, clear_something, ws, 0);
-         return 0;
-        }
-    }
-  
-  /* All done! */
-  XFREE (MTYPE_TMP, ws->str);
-  XFREE (MTYPE_TMP, ws);
-  return 0;
-}
-
-DEFUN (clear_foo,
-       clear_foo_cmd,
-       "clear foo LINE...",
-       "clear command\n"
-       "arbitrary string\n")
-{
-  char *str;
-  struct work_state *ws;
-
-  if (!argc)
-    {
-      vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  
-  str = argv_concat (argv, argc, 0);
-  
-  if ((ws = XMALLOC(MTYPE_TMP, sizeof(*ws))) == NULL)
-    {
-      zlog_err ("%s: unable to allocate work_state", __func__);
-      return CMD_WARNING;
-    }
-  
-  if (!(ws->str = XSTRDUP (MTYPE_TMP, str)))
-    {
-      zlog_err ("%s: unable to xstrdup", __func__);
-      XFREE (MTYPE_TMP, ws);
-      return CMD_WARNING;
-    }
-  
-  ws->vty = vty;
-  ws->i = ITERS_FIRST;
-
-  thread_add_background(master, clear_something, ws, 0);
-
-  return CMD_SUCCESS;
-}
-
-void
-test_init()
-{
-  install_element (VIEW_NODE, &clear_foo_cmd);
-}
diff --git a/tests/heavy-wq.c b/tests/heavy-wq.c
deleted file mode 100644 (file)
index 97371fa..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/* This programme shows the effects of 'heavy' long-running functions
- * on the cooperative threading model.
- *
- * Run it with a config file containing 'password whatever', telnet to it
- * (it defaults to port 4000) and enter the 'clear foo string' command.
- * then type whatever and observe that the vty interface is unresponsive
- * for quite a period of time, due to the clear_something command
- * taking a very long time to complete.
- */
-#include <zebra.h>
-
-#include "thread.h"
-#include "vty.h"
-#include "command.h"
-#include "memory.h"
-#include "log.h"
-#include "workqueue.h"
-#include <math.h>
-
-#include "tests.h"
-
-DEFINE_MGROUP(TEST_HEAVYWQ, "heavy-wq test")
-DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE, "heavy_wq_node")
-DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE_STR, "heavy_wq_node->str")
-
-extern struct thread_master *master;
-static struct work_queue *heavy_wq;
-
-struct heavy_wq_node
-{
-  char *str;
-  int i;
-};
-
-enum
-{
-  ITERS_FIRST = 0,
-  ITERS_ERR = 100,
-  ITERS_LATER = 400,
-  ITERS_PRINT = 10,
-  ITERS_MAX = 1000,
-};
-
-static void
-heavy_wq_add (struct vty *vty, const char *str, int i)
-{
-  struct heavy_wq_node *hn;
-
-  if ((hn = XCALLOC (MTYPE_WQ_NODE, sizeof(struct heavy_wq_node))) == NULL)
-    {
-      zlog_err ("%s: unable to allocate hn", __func__);
-      return;
-    }
-  
-  hn->i = i;
-  if (!(hn->str = XSTRDUP (MTYPE_WQ_NODE_STR, str)))
-    {
-      zlog_err ("%s: unable to xstrdup", __func__);
-      XFREE (MTYPE_WQ_NODE, hn);
-      return;
-    }
-  
-  work_queue_add (heavy_wq, hn);
-  
-  return;
-}
-
-static void
-slow_func_err (struct work_queue *wq, struct work_queue_item *item)
-{
-  printf ("%s: running error function\n", __func__);
-}
-
-static void
-slow_func_del (struct work_queue *wq, void *data)
-{
-  struct heavy_wq_node *hn = data;
-  assert (hn && hn->str);
-  printf ("%s: %s\n", __func__, hn->str);
-  XFREE (MTYPE_WQ_NODE_STR, hn->str);
-  hn->str = NULL;  
-  XFREE(MTYPE_WQ_NODE, hn);
-}
-
-static wq_item_status
-slow_func (struct work_queue *wq, void *data)
-{
-  struct heavy_wq_node *hn = data;
-  double x = 1;
-  int j;
-  
-  assert (hn && hn->str);
-  
-  for (j = 0; j < 300; j++)
-    x += sin(x)*j;
-  
-  if ((hn->i % ITERS_LATER) == 0)
-    return WQ_RETRY_LATER;
-  
-  if ((hn->i % ITERS_ERR) == 0)
-    return WQ_RETRY_NOW;
-  
-  if ((hn->i % ITERS_PRINT) == 0)
-    printf ("%s did %d, x = %g\n", hn->str, hn->i, x);
-
-  return WQ_SUCCESS;
-}
-
-static void
-clear_something (struct vty *vty, const char *str)
-{
-  int i;
-  
-  /* this could be like iterating through 150k of route_table 
-   * or worse, iterating through a list of peers, to bgp_stop them with
-   * each having 150k route tables to process...
-   */
-  for (i = ITERS_FIRST; i < ITERS_MAX; i++)
-    heavy_wq_add (vty, str, i);
-}
-
-DEFUN (clear_foo,
-       clear_foo_cmd,
-       "clear foo LINE...",
-       "clear command\n"
-       "arbitrary string\n")
-{
-  char *str;
-  if (!argc)
-    {
-      vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  
-  str = argv_concat (argv, argc, 0);
-  
-  clear_something (vty, str);
-  XFREE (MTYPE_TMP, str);
-  return CMD_SUCCESS;
-}
-
-static int
-heavy_wq_init ()
-{
-  if (! (heavy_wq = work_queue_new (master, "heavy_work_queue")))
-    {
-      zlog_err ("%s: could not get new work queue!", __func__);
-      return -1;
-    }
-  
-  heavy_wq->spec.workfunc = &slow_func;
-  heavy_wq->spec.errorfunc = &slow_func_err;
-  heavy_wq->spec.del_item_data = &slow_func_del;
-  heavy_wq->spec.max_retries = 3;
-  heavy_wq->spec.hold = 1000;
-  
-  return 0;
-}
-
-void
-test_init()
-{
-  install_element (VIEW_NODE, &clear_foo_cmd);
-  heavy_wq_init();
-}
diff --git a/tests/heavy.c b/tests/heavy.c
deleted file mode 100644 (file)
index 6ba8d9a..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * $Id: heavy.c,v 1.3 2005/04/25 16:42:24 paul Exp $
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/* This programme shows the effects of 'heavy' long-running functions
- * on the cooperative threading model.
- *
- * Run it with a config file containing 'password whatever', telnet to it
- * (it defaults to port 4000) and enter the 'clear foo string' command.
- * then type whatever and observe that the vty interface is unresponsive
- * for quite a period of time, due to the clear_something command
- * taking a very long time to complete.
- */
-#include <zebra.h>
-
-#include "thread.h"
-#include "vty.h"
-#include "command.h"
-#include "memory.h"
-#include <math.h>
-
-#include "tests.h"
-
-enum
-{
-  ITERS_FIRST = 0,
-  ITERS_ERR = 100,
-  ITERS_LATER = 400,
-  ITERS_PRINT = 10,
-  ITERS_MAX = 1000,
-};
-
-static void
-slow_func (struct vty *vty, const char *str, const int i)
-{
-  double x = 1;
-  int j;
-  
-  for (j = 0; j < 300; j++)
-    x += sin(x)*j;
-  
-  if ((i % ITERS_LATER) == 0)
-    printf ("%s: %d, temporary error, save this somehow and do it later..\n", 
-            __func__, i);
-  
-  if ((i % ITERS_ERR) == 0)
-    printf ("%s: hard error\n", __func__);
-  
-  if ((i % ITERS_PRINT) == 0)
-    printf ("%s did %d, x = %g%s", str, i, x, VTY_NEWLINE);  
-}
-
-static void
-clear_something (struct vty *vty, const char *str)
-{
-  int i;
-  
-  /* this could be like iterating through 150k of route_table 
-   * or worse, iterating through a list of peers, to bgp_stop them with
-   * each having 150k route tables to process...
-   */
-  for (i = ITERS_FIRST; i < ITERS_MAX; i++)
-    slow_func (vty, str, i);
-}
-
-DEFUN (clear_foo,
-       clear_foo_cmd,
-       "clear foo LINE...",
-       "clear command\n"
-       "arbitrary string\n")
-{
-  char *str;
-  if (!argc)
-    {
-      vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  
-  str = argv_concat (argv, argc, 0);
-  
-  clear_something (vty, str);
-  XFREE (MTYPE_TMP, str);
-  return CMD_SUCCESS;
-}
-
-static void
-slow_vty_init()
-{
-  install_element (VIEW_NODE, &clear_foo_cmd);
-}
-
-void
-test_init()
-{
-  slow_vty_init();
-}
diff --git a/tests/helpers/c/main.c b/tests/helpers/c/main.c
new file mode 100644 (file)
index 0000000..b3e6e70
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * $Id: main.c,v 1.1 2005/04/25 16:42:24 paul Exp $
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include <lib/version.h>
+#include "getopt.h"
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "memory.h"
+#include "memory_vty.h"
+
+extern void test_init();
+
+struct thread_master *master;
+
+struct option longopts[] = 
+{
+  { "daemon",      no_argument,       NULL, 'd'},
+  { "config_file", required_argument, NULL, 'f'},
+  { "help",        no_argument,       NULL, 'h'},
+  { "vty_addr",    required_argument, NULL, 'A'},
+  { "vty_port",    required_argument, NULL, 'P'},
+  { "version",     no_argument,       NULL, 'v'},
+  { 0 }
+};
+
+DEFUN (daemon_exit,
+       daemon_exit_cmd,
+       "daemon-exit",
+       "Make the daemon exit\n")
+{
+  exit(0);
+}
+
+static int timer_count;
+static int
+test_timer (struct thread *thread)
+{
+  int *count = THREAD_ARG(thread);
+  
+  printf ("run %d of timer\n", (*count)++);
+  thread_add_timer (master, test_timer, count, 5);
+  return 0;
+}
+
+static void
+test_timer_init()
+{
+  thread_add_timer (master, test_timer, &timer_count, 10);
+}
+
+static void
+test_vty_init()
+{
+  install_element (VIEW_NODE, &daemon_exit_cmd);
+}
+
+/* Help information display. */
+static void
+usage (char *progname, int status)
+{
+  if (status != 0)
+    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
+  else
+    {    
+      printf ("Usage : %s [OPTION...]\n\
+Daemon which does 'slow' things.\n\n\
+-d, --daemon       Runs in daemon mode\n\
+-f, --config_file  Set configuration file name\n\
+-A, --vty_addr     Set vty's bind address\n\
+-P, --vty_port     Set vty's port number\n\
+-v, --version      Print program version\n\
+-h, --help         Display this help and exit\n\
+\n\
+Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
+    }
+  exit (status);
+}
+
+
+/* main routine. */
+int
+main (int argc, char **argv)
+{
+  char *p;
+  char *vty_addr = NULL;
+  int vty_port = 4000;
+  int daemon_mode = 0;
+  char *progname;
+  struct thread thread;
+  char *config_file = NULL;
+  
+  /* Set umask before anything for security */
+  umask (0027);
+
+  /* get program name */
+  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
+
+  /* master init. */
+  master = thread_master_create ();
+
+  while (1) 
+    {
+      int opt;
+
+      opt = getopt_long (argc, argv, "dhf:A:P:v", longopts, 0);
+    
+      if (opt == EOF)
+       break;
+
+      switch (opt) 
+       {
+       case 0:
+         break;
+        case 'f':
+          config_file = optarg;
+          break;
+       case 'd':
+         daemon_mode = 1;
+         break;
+       case 'A':
+         vty_addr = optarg;
+         break;
+       case 'P':
+          /* Deal with atoi() returning 0 on failure */
+          if (strcmp(optarg, "0") == 0)
+            {
+              vty_port = 0;
+              break;
+            } 
+          vty_port = atoi (optarg);
+          vty_port = (vty_port ? vty_port : 4000);
+         break;
+       case 'v':
+         print_version (progname);
+         exit (0);
+         break;
+       case 'h':
+         usage (progname, 0);
+         break;
+       default:
+         usage (progname, 1);
+         break;
+       }
+    }
+
+  /* Library inits. */
+  cmd_init (1);
+  vty_init (master);
+  memory_init ();
+
+  /* OSPF vty inits. */
+  test_vty_init ();
+
+  /* Change to the daemon program. */
+  if (daemon_mode && daemon (0, 0) < 0)
+    {
+      fprintf(stderr, "daemon failed: %s", strerror(errno));
+      exit (1);
+    }
+
+  /* Create VTY socket */
+  vty_serv_sock (vty_addr, vty_port, "/tmp/.heavy.sock");
+  
+  /* Configuration file read*/
+  if (!config_file)
+    usage (progname, 1);
+  vty_read_config (config_file, NULL);
+  
+  test_timer_init();
+  
+  test_init();  
+  
+  /* Fetch next active thread. */
+  while (thread_fetch (master, &thread))
+    thread_call (&thread);
+
+  /* Not reached. */
+  exit (0);
+}
+
diff --git a/tests/helpers/c/prng.c b/tests/helpers/c/prng.c
new file mode 100644 (file)
index 0000000..bdcfb07
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Very simple prng to allow for randomized tests with reproducable
+ * results.
+ *
+ * Copyright (C) 2012 by Open Source Routing.
+ * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prng.h"
+
+struct prng
+{
+  unsigned long long state1;
+  unsigned long long state2;
+};
+
+static char
+prng_bit(struct prng *prng)
+{
+  prng->state1 *= 2416;
+  prng->state1 += 374441;
+  prng->state1 %= 1771875;
+
+  if (prng->state1 % 2)
+    {
+      prng->state2 *= 84589;
+      prng->state2 += 45989;
+      prng->state2 %= 217728;
+    }
+
+  return prng->state2 % 2;
+}
+
+struct prng*
+prng_new(unsigned long long seed)
+{
+  struct prng *rv = calloc(sizeof(*rv), 1);
+  assert(rv);
+
+  rv->state1 = rv->state2 = seed;
+
+  return rv;
+}
+
+unsigned int
+prng_rand(struct prng *prng)
+{
+  unsigned int i, rv = 0;
+
+  for (i = 0; i < 32; i++)
+    {
+      rv |= prng_bit(prng);
+      rv <<= 1;
+    }
+  return rv;
+}
+
+const char *
+prng_fuzz(struct prng *prng,
+          const char *string,
+          const char *charset,
+          unsigned int operations)
+{
+  static char buf[256];
+  unsigned int charset_len;
+  unsigned int i;
+  unsigned int offset;
+  unsigned int op;
+  unsigned int character;
+
+  assert(strlen(string) < sizeof(buf));
+
+  strncpy(buf, string, sizeof(buf));
+  charset_len = strlen(charset);
+
+  for (i = 0; i < operations; i++)
+    {
+      offset = prng_rand(prng) % strlen(buf);
+      op = prng_rand(prng) % 3;
+
+      switch (op)
+        {
+        case 0:
+          /* replace */
+          character = prng_rand(prng) % charset_len;
+          buf[offset] = charset[character];
+          break;
+        case 1:
+          /* remove */
+          memmove(buf + offset, buf + offset + 1, strlen(buf) - offset);
+          break;
+        case 2:
+          /* insert */
+          assert(strlen(buf) + 1 < sizeof(buf));
+
+          memmove(buf + offset + 1, buf + offset, strlen(buf) + 1 - offset);
+          character = prng_rand(prng) % charset_len;
+          buf[offset] = charset[character];
+          break;
+        }
+    }
+  return buf;
+}
+
+void
+prng_free(struct prng *prng)
+{
+  free(prng);
+}
diff --git a/tests/helpers/c/prng.h b/tests/helpers/c/prng.h
new file mode 100644 (file)
index 0000000..cf0bacc
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Very simple prng to allow for randomized tests with reproducable
+ * results.
+ *
+ * Copyright (C) 2012 by Open Source Routing.
+ * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _PRNG_H
+#define _PRNG_H
+
+struct prng;
+
+struct prng* prng_new(unsigned long long seed);
+unsigned int prng_rand(struct prng*);
+const char * prng_fuzz(struct prng*,
+                       const char *string,
+                       const char *charset,
+                       unsigned int operations);
+void prng_free(struct prng *);
+
+#endif
diff --git a/tests/helpers/c/tests.h b/tests/helpers/c/tests.h
new file mode 100644 (file)
index 0000000..a528e55
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Test wrappers common header file
+ *
+ * Copyright (C) 2015 by David Lamparter,
+ *                    for Open Source Routing./ NetDEF, Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _QUAGGA_TESTS_H
+#define _QUAGGA_TESTS_H
+
+extern void test_init (void);
+extern void test_init_cmd (void);
+
+#endif /* _QUAGGA_TESTS_H */
diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c
new file mode 100644 (file)
index 0000000..83196e0
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * generic CLI test helper functions
+ *
+ * Copyright (C) 2015 by David Lamparter,
+ *                   for Open Source Routing / NetDEF, Inc.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "memory.h"
+#include "memory_vty.h"
+#include "log.h"
+
+#include "common_cli.h"
+
+struct thread_master *master;
+
+int dump_args(struct vty *vty, const char *descr,
+              int argc, struct cmd_token *argv[])
+{
+  int i;
+  vty_out (vty, "%s with %d args.%s", descr, argc, VTY_NEWLINE);
+  for (i = 0; i < argc; i++)
+    {
+      vty_out (vty, "[%02d]: %s%s", i, argv[i]->arg, VTY_NEWLINE);
+    }
+
+  return CMD_SUCCESS;
+}
+
+static void vty_do_exit(void)
+{
+  printf ("\nend.\n");
+  cmd_terminate ();
+  vty_terminate ();
+  thread_master_free (master);
+  closezlog (zlog_default);
+
+  log_memstats_stderr ("testcli");
+  exit (0);
+}
+
+/* main routine. */
+int
+main (int argc, char **argv)
+{
+  struct thread thread;
+
+  /* Set umask before anything for security */
+  umask (0027);
+
+  /* master init. */
+  master = thread_master_create ();
+
+  zlog_default = openzlog ("common-cli", ZLOG_NONE, 0,
+                           LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
+  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
+  zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
+  zlog_set_level (NULL, ZLOG_DEST_MONITOR, LOG_DEBUG);
+
+  /* Library inits. */
+  cmd_init (1);
+  cmd_hostname_set ("test");
+
+  vty_init (master);
+  memory_init ();
+
+  test_init ();
+
+  vty_stdio (vty_do_exit);
+
+  /* Fetch next active thread. */
+  while (thread_fetch (master, &thread))
+    thread_call (&thread);
+
+  /* Not reached. */
+  exit (0);
+}
+
diff --git a/tests/lib/cli/common_cli.h b/tests/lib/cli/common_cli.h
new file mode 100644 (file)
index 0000000..9c72b08
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * generic CLI test helper functions
+ *
+ * Copyright (C) 2015 by David Lamparter,
+ *                   for Open Source Routing / NetDEF, Inc.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _COMMON_CLI_H
+#define _COMMON_CLI_H
+
+#include "zebra.h"
+#include "vty.h"
+#include "command.h"
+
+/* function to be implemented by test */
+extern void test_init (void);
+
+/* functions provided by common cli
+ * (includes main())
+ */
+extern struct thread_master *master;
+
+extern int dump_args(struct vty *vty, const char *descr,
+              int argc, struct cmd_token *argv[]);
+
+#define DUMMY_HELPSTR \
+       "00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n" \
+       "10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n" \
+       "20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n"
+#define DUMMY_DEFUN(name, cmdstr) \
+        DEFUN (name, name ## _cmd, cmdstr, DUMMY_HELPSTR) \
+        { return dump_args(vty, #name, argc, argv); }
+
+#endif /* _COMMON_CLI_H */
diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c
new file mode 100644 (file)
index 0000000..1a31602
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * CLI/command dummy handling tester
+ *
+ * Copyright (C) 2015 by David Lamparter,
+ *                   for Open Source Routing / NetDEF, Inc.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "common_cli.h"
+
+DUMMY_DEFUN(cmd0,  "arg ipv4 A.B.C.D");
+DUMMY_DEFUN(cmd1,  "arg ipv4m A.B.C.D/M");
+DUMMY_DEFUN(cmd2,  "arg ipv6 X:X::X:X");
+DUMMY_DEFUN(cmd3,  "arg ipv6m X:X::X:X/M");
+DUMMY_DEFUN(cmd4,  "arg range (5-15)");
+DUMMY_DEFUN(cmd5,  "pat a < a|b>");
+DUMMY_DEFUN(cmd7,  "pat c <a | b|c> A.B.C.D");
+DUMMY_DEFUN(cmd8,  "pat d {  foo A.B.C.D|bar   X:X::X:X| baz }");
+DUMMY_DEFUN(cmd9,  "pat e [ WORD ]");
+DUMMY_DEFUN(cmd10, "pat f [key]");
+DUMMY_DEFUN(cmd11, "alt a WORD");
+DUMMY_DEFUN(cmd12, "alt a A.B.C.D");
+DUMMY_DEFUN(cmd13, "alt a X:X::X:X");
+
+void test_init(void)
+{
+  install_element (ENABLE_NODE, &cmd0_cmd);
+  install_element (ENABLE_NODE, &cmd1_cmd);
+  install_element (ENABLE_NODE, &cmd2_cmd);
+  install_element (ENABLE_NODE, &cmd3_cmd);
+  install_element (ENABLE_NODE, &cmd4_cmd);
+  install_element (ENABLE_NODE, &cmd5_cmd);
+  install_element (ENABLE_NODE, &cmd7_cmd);
+  install_element (ENABLE_NODE, &cmd8_cmd);
+  install_element (ENABLE_NODE, &cmd9_cmd);
+  install_element (ENABLE_NODE, &cmd10_cmd);
+  install_element (ENABLE_NODE, &cmd11_cmd);
+  install_element (ENABLE_NODE, &cmd12_cmd);
+  install_element (ENABLE_NODE, &cmd13_cmd);
+}
diff --git a/tests/lib/cli/test_cli.in b/tests/lib/cli/test_cli.in
new file mode 100644 (file)
index 0000000..5c146ef
--- /dev/null
@@ -0,0 +1,88 @@
+echo this is a  test message
+echo  foo bla  ?  baz
+echo
+
+arg ipv4 1.2.3.4
+arg ipv4 1.2.?3.4
+arg ipv4 1.2.3
+arg ipv4 1.2.3.4.5
+arg ipv4 1.a.3.4
+arg ipv4 blah
+
+arg ipv4m 1.2.3.0/24
+arg ipv4m 1.2.?3.0/24
+arg ipv4m 1.2.3/9
+arg ipv4m 1.2.3.4.5/6
+arg ipv4m 1.a.3.4
+arg ipv4m blah
+arg ipv4m 1.2.3.0/999
+arg ipv4m 1.2.3.0/a9
+arg ipv4m 1.2.3.0/9a
+
+arg ipv6 de4d:b33f::cafe
+arg ipv6 de4d:b3?3f::caf?e
+arg ipv6 de4d:b3       3f::caf?e
+arg ipv6 de4d:b33f:z::cafe
+arg ipv6 de4d:b33f:cafe:
+arg ipv6 ::
+arg ipv6 ::/
+arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0
+arg ipv6 12::34::56
+arg ipv6m dead:beef:cafe::/64
+arg ipv6m dead:be?ef:cafe:?:/64
+
+arg range 4
+arg range 5
+arg range 9?
+arg range 15
+arg range 16
+arg range -1
+arg range 99999999999999999999999999999999999999999
+
+arg ?
+
+pa     
+pat    
+
+pat a
+pat a a
+pat a ?b
+pat a c?
+pat a a x
+
+pat c a
+pat c a 1.2.3.4
+pat c b 2.3.4
+pat c c ?x
+
+pat d
+pat d  
+pat d foo 1.2.3.4
+pat d foo
+pat d noooo
+pat d bar 1::2
+pat d bar 1::2 foo 3.4.5.6
+pat d ba?z
+pat d foo 3.4.5.6 baz
+
+pat e
+pat e f
+pat e f g
+pat e 1.2.3.4
+
+pat f
+pat f foo
+pat f key
+
+alt a  a?b
+alt a 1        .2?.3.4
+alt a 1        :2?     ::?3
+
+conf t
+do pat d baz
+exit
+
+show run
+conf t
+hostname foohost
+do show run
diff --git a/tests/lib/cli/test_cli.refout b/tests/lib/cli/test_cli.refout
new file mode 100644 (file)
index 0000000..8b438ba
--- /dev/null
@@ -0,0 +1,326 @@
+test# echo this is a  test message\r
+this is a test message\r
+test# echo  foo bla  \r
+% There is no matched command.\r
+test# echo  foo bla    baz\r
+foo bla baz\r
+test# echo\r
+% Command incomplete.\r
+test# \r
+test# arg ipv4 1.2.3.4\r
+cmd0 with 3 args.\r
+[00]: arg\r
+[01]: ipv4\r
+[02]: 1.2.3.4\r
+test# arg ipv4 1.2.\r
+  A.B.C.D  02\r
+test# arg ipv4 1.2.3.4\r
+cmd0 with 3 args.\r
+[00]: arg\r
+[01]: ipv4\r
+[02]: 1.2.3.4\r
+test# arg ipv4 1.2.3\r
+% [NONE] Unknown command: arg ipv4 1.2.3\r
+test# arg ipv4 1.2.3.4.5\r
+% [NONE] Unknown command: arg ipv4 1.2.3.4.5\r
+test# arg ipv4 1.a.3.4\r
+% [NONE] Unknown command: arg ipv4 1.a.3.4\r
+test# arg ipv4 blah\r
+% [NONE] Unknown command: arg ipv4 blah\r
+test# \r
+test# arg ipv4m 1.2.3.0/24\r
+cmd1 with 3 args.\r
+[00]: arg\r
+[01]: ipv4m\r
+[02]: 1.2.3.0/24\r
+test# arg ipv4m 1.2.\r
+  A.B.C.D/M  02\r
+test# arg ipv4m 1.2.3.0/24\r
+cmd1 with 3 args.\r
+[00]: arg\r
+[01]: ipv4m\r
+[02]: 1.2.3.0/24\r
+test# arg ipv4m 1.2.3/9\r
+% [NONE] Unknown command: arg ipv4m 1.2.3/9\r
+test# arg ipv4m 1.2.3.4.5/6\r
+% [NONE] Unknown command: arg ipv4m 1.2.3.4.5/6\r
+test# arg ipv4m 1.a.3.4\r
+% [NONE] Unknown command: arg ipv4m 1.a.3.4\r
+test# arg ipv4m blah\r
+% [NONE] Unknown command: arg ipv4m blah\r
+test# arg ipv4m 1.2.3.0/999\r
+% [NONE] Unknown command: arg ipv4m 1.2.3.0/999\r
+test# arg ipv4m 1.2.3.0/a9\r
+% [NONE] Unknown command: arg ipv4m 1.2.3.0/a9\r
+test# arg ipv4m 1.2.3.0/9a\r
+% [NONE] Unknown command: arg ipv4m 1.2.3.0/9a\r
+test# \r
+test# arg ipv6 de4d:b33f::cafe\r
+cmd2 with 3 args.\r
+[00]: arg\r
+[01]: ipv6\r
+[02]: de4d:b33f::cafe\r
+test# arg ipv6 de4d:b3\r
+% There is no matched command.\r
+test# arg ipv6 de4d:b33f::caf\r
+  X:X::X:X  02\r
+test# arg ipv6 de4d:b33f::cafe\r
+cmd2 with 3 args.\r
+[00]: arg\r
+[01]: ipv6\r
+[02]: de4d:b33f::cafe\r
+test# arg ipv6 de4d:b3\r
+test# arg ipv6 de4d:b33f::caf\r
+  X:X::X:X  02\r
+test# arg ipv6 de4d:b33f::cafe\r
+cmd2 with 3 args.\r
+[00]: arg\r
+[01]: ipv6\r
+[02]: de4d:b33f::cafe\r
+test# arg ipv6 de4d:b33f:z::cafe\r
+% [NONE] Unknown command: arg ipv6 de4d:b33f:z::cafe\r
+test# arg ipv6 de4d:b33f:cafe:\r
+% [NONE] Unknown command: arg ipv6 de4d:b33f:cafe:\r
+test# arg ipv6 ::\r
+cmd2 with 3 args.\r
+[00]: arg\r
+[01]: ipv6\r
+[02]: ::\r
+test# arg ipv6 ::/\r
+% [NONE] Unknown command: arg ipv6 ::/\r
+test# arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0\r
+% [NONE] Unknown command: arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0\r
+test# arg ipv6 12::34::56\r
+% [NONE] Unknown command: arg ipv6 12::34::56\r
+test# arg ipv6m dead:beef:cafe::/64\r
+cmd3 with 3 args.\r
+[00]: arg\r
+[01]: ipv6m\r
+[02]: dead:beef:cafe::/64\r
+test# arg ipv6m dead:be\r
+  X:X::X:X/M  02\r
+test# arg ipv6m dead:beef:cafe:\r
+  X:X::X:X/M  02\r
+test# arg ipv6m dead:beef:cafe::/64\r
+cmd3 with 3 args.\r
+[00]: arg\r
+[01]: ipv6m\r
+[02]: dead:beef:cafe::/64\r
+test# \r
+test# arg range 4\r
+% [NONE] Unknown command: arg range 4\r
+test# arg range 5\r
+cmd4 with 3 args.\r
+[00]: arg\r
+[01]: range\r
+[02]: 5\r
+test# arg range 9\r
+  (5-15)  02\r
+test# arg range 9\r
+cmd4 with 3 args.\r
+[00]: arg\r
+[01]: range\r
+[02]: 9\r
+test# arg range 15\r
+cmd4 with 3 args.\r
+[00]: arg\r
+[01]: range\r
+[02]: 15\r
+test# arg range 16\r
+% [NONE] Unknown command: arg range 16\r
+test# arg range -1\r
+% [NONE] Unknown command: arg range -1\r
+test# arg range 99999999999999999999999999999999999999999\r
+% [NONE] Unknown command: arg range 99999999999999999999999999999999999999999\r
+test# \r
+test# arg \r
+  ipv4   01\r
+  ipv4m  01\r
+  ipv6   01\r
+  ipv6m  01\r
+  range  01\r
+test# arg \r
+% Command incomplete.\r
+test# \r
+test# pa\r
+test# pa\b\bpat \r
+% Command incomplete.\r
+test# pat \r
+a          c          d          e          f          \r
+test# pat \r
+% Command incomplete.\r
+test# \r
+test# pat a\r
+% Command incomplete.\r
+test# pat a a\r
+cmd5 with 3 args.\r
+[00]: pat\r
+[01]: a\r
+[02]: a\r
+test# pat a \r
+  a  02\r
+  b  03\r
+test# pat a b\r
+cmd5 with 3 args.\r
+[00]: pat\r
+[01]: a\r
+[02]: b\r
+test# pat a c\r
+% There is no matched command.\r
+test# pat a c\r
+% [NONE] Unknown command: pat a c\r
+test# pat a a x\r
+% [NONE] Unknown command: pat a a x\r
+test# \r
+test# pat c a\r
+% Command incomplete.\r
+test# pat c a 1.2.3.4\r
+cmd7 with 4 args.\r
+[00]: pat\r
+[01]: c\r
+[02]: a\r
+[03]: 1.2.3.4\r
+test# pat c b 2.3.4\r
+% [NONE] Unknown command: pat c b 2.3.4\r
+test# pat c c \r
+  A.B.C.D  05\r
+test# pat c c x\r
+% [NONE] Unknown command: pat c c x\r
+test# \r
+test# pat d\r
+% Command incomplete.\r
+test# pat d \r
+bar        baz        foo        \r
+test# pat d \r
+% Command incomplete.\r
+test# pat d foo 1.2.3.4\r
+cmd8 with 4 args.\r
+[00]: pat\r
+[01]: d\r
+[02]: foo\r
+[03]: 1.2.3.4\r
+test# pat d foo\r
+% Command incomplete.\r
+test# pat d noooo\r
+% [NONE] Unknown command: pat d noooo\r
+test# pat d bar 1::2\r
+cmd8 with 4 args.\r
+[00]: pat\r
+[01]: d\r
+[02]: bar\r
+[03]: 1::2\r
+test# pat d bar 1::2 foo 3.4.5.6\r
+cmd8 with 6 args.\r
+[00]: pat\r
+[01]: d\r
+[02]: bar\r
+[03]: 1::2\r
+[04]: foo\r
+[05]: 3.4.5.6\r
+test# pat d ba\r
+  bar  04\r
+  baz  06\r
+test# pat d baz\r
+cmd8 with 3 args.\r
+[00]: pat\r
+[01]: d\r
+[02]: baz\r
+test# pat d foo 3.4.5.6 baz\r
+cmd8 with 5 args.\r
+[00]: pat\r
+[01]: d\r
+[02]: foo\r
+[03]: 3.4.5.6\r
+[04]: baz\r
+test# \r
+test# pat e\r
+cmd9 with 2 args.\r
+[00]: pat\r
+[01]: e\r
+test# pat e f\r
+cmd9 with 3 args.\r
+[00]: pat\r
+[01]: e\r
+[02]: f\r
+test# pat e f g\r
+% [NONE] Unknown command: pat e f g\r
+test# pat e 1.2.3.4\r
+cmd9 with 3 args.\r
+[00]: pat\r
+[01]: e\r
+[02]: 1.2.3.4\r
+test# \r
+test# pat f\r
+cmd10 with 2 args.\r
+[00]: pat\r
+[01]: f\r
+test# pat f foo\r
+% [NONE] Unknown command: pat f foo\r
+test# pat f key\r
+cmd10 with 3 args.\r
+[00]: pat\r
+[01]: f\r
+[02]: key\r
+test# \r
+test# alt a \r
+test# alt a a\r
+  WORD  02\r
+test# alt a ab\r
+cmd11 with 3 args.\r
+[00]: alt\r
+[01]: a\r
+[02]: ab\r
+test# alt a 1\r
+test# alt a 1.2\r
+  A.B.C.D  02\r
+  WORD     02\r
+test# alt a 1.2.3.4\r
+cmd12 with 3 args.\r
+[00]: alt\r
+[01]: a\r
+[02]: 1.2.3.4\r
+test# alt a 1\r
+test# alt a 1:2\r
+  WORD  02\r
+test# alt a 1:2\r
+test# alt a 1:2::\r
+  WORD      02\r
+  X:X::X:X  02\r
+test# alt a 1:2::3\r
+cmd13 with 3 args.\r
+[00]: alt\r
+[01]: a\r
+[02]: 1:2::3\r
+test# \r
+test# conf t\r
+test(config)# do pat d baz\r
+cmd8 with 3 args.\r
+[00]: pat\r
+[01]: d\r
+[02]: baz\r
+test(config)# exit\r
+test# \r
+test# show run\r
+\r
+Current configuration:\r
+!\r
+hostname test\r
+!\r
+!\r
+line vty\r
+!\r
+end\r
+test# conf t\r
+test(config)# hostname foohost\r
+foohost(config)# do show run\r
+\r
+Current configuration:\r
+!\r
+hostname foohost\r
+!\r
+!\r
+line vty\r
+!\r
+end\r
+foohost(config)# 
+end.
diff --git a/tests/lib/cli/test_commands.c b/tests/lib/cli/test_commands.c
new file mode 100644 (file)
index 0000000..272e3d1
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Test code for lib/command.c
+ *
+ * Copyright (C) 2013 by Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This program reads in a list of commandlines from stdin
+ * and calls all the public functions of lib/command.c for
+ * both the given command lines and fuzzed versions thereof.
+ *
+ * The output is currently not validated but only logged. It can
+ * be diffed to find regressions between versions.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#define REALLY_NEED_PLAIN_GETOPT 1
+
+#include <zebra.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "command.h"
+#include "memory.h"
+#include "vector.h"
+#include "prng.h"
+
+extern vector cmdvec;
+extern struct cmd_node vty_node;
+extern void test_init_cmd(void); /* provided in test-commands-defun.c */
+
+struct thread_master *master; /* dummy for libfrr*/
+
+static vector test_cmds;
+static char test_buf[32768];
+
+static struct cmd_node bgp_node =
+{
+  BGP_NODE,
+  "%s(config-router)# ",
+};
+
+static struct cmd_node rip_node =
+{
+  RIP_NODE,
+  "%s(config-router)# ",
+};
+
+static struct cmd_node isis_node =
+{
+  ISIS_NODE,
+  "%s(config-router)# ",
+};
+
+static struct cmd_node interface_node =
+{
+  INTERFACE_NODE,
+  "%s(config-if)# ",
+};
+
+static struct cmd_node rmap_node =
+{
+  RMAP_NODE,
+  "%s(config-route-map)# "
+};
+
+static struct cmd_node zebra_node =
+{
+  ZEBRA_NODE,
+  "%s(config-router)# "
+};
+
+static struct cmd_node bgp_vpnv4_node =
+{
+  BGP_VPNV4_NODE,
+  "%s(config-router-af)# "
+};
+
+static struct cmd_node bgp_ipv4_node =
+{
+  BGP_IPV4_NODE,
+  "%s(config-router-af)# "
+};
+
+static struct cmd_node bgp_ipv4m_node =
+{
+  BGP_IPV4M_NODE,
+  "%s(config-router-af)# "
+};
+
+static struct cmd_node bgp_ipv6_node =
+{
+  BGP_IPV6_NODE,
+  "%s(config-router-af)# "
+};
+
+static struct cmd_node bgp_ipv6m_node =
+{
+  BGP_IPV6M_NODE,
+  "%s(config-router-af)# "
+};
+
+static struct cmd_node ospf_node =
+{
+  OSPF_NODE,
+  "%s(config-router)# "
+};
+
+static struct cmd_node ripng_node =
+{
+  RIPNG_NODE,
+  "%s(config-router)# "
+};
+
+static struct cmd_node ospf6_node =
+{
+  OSPF6_NODE,
+  "%s(config-ospf6)# "
+};
+
+static struct cmd_node keychain_node =
+{
+  KEYCHAIN_NODE,
+  "%s(config-keychain)# "
+};
+
+static struct cmd_node keychain_key_node =
+{
+  KEYCHAIN_KEY_NODE,
+  "%s(config-keychain-key)# "
+};
+
+static int
+test_callback(const struct cmd_element *cmd, struct vty *vty, int argc, struct cmd_token *argv[])
+{
+  int offset;
+  int rv;
+  int i;
+
+  offset = 0;
+  rv = snprintf(test_buf, sizeof(test_buf), "'%s'", cmd->string);
+  if (rv < 0)
+    abort();
+
+  offset += rv;
+
+  for (i = 0; i < argc; i++)
+    {
+      rv = snprintf(test_buf + offset, sizeof(test_buf) - offset, "%s'%s'",
+                    (i == 0) ? ": " : ", ", argv[i]->arg);
+      if (rv < 0)
+        abort();
+      offset += rv;
+    }
+
+  return CMD_SUCCESS;
+}
+
+static void
+test_load(void)
+{
+  char line[4096];
+
+  test_cmds = vector_init(VECTOR_MIN_SIZE);
+
+  while (fgets(line, sizeof(line), stdin) != NULL)
+    {
+      if (strlen(line))
+        line[strlen(line) - 1] = '\0';
+      if (line[0] == '#')
+        continue;
+      vector_set(test_cmds, XSTRDUP(MTYPE_STRVEC, line));
+    }
+}
+
+static void
+test_init(void)
+{
+  unsigned int node;
+  unsigned int i;
+  struct cmd_node *cnode;
+  struct cmd_element *cmd;
+
+  cmd_init(1);
+
+  install_node (&bgp_node, NULL);
+  install_node (&rip_node, NULL);
+  install_node (&interface_node, NULL);
+  install_node (&rmap_node, NULL);
+  install_node (&zebra_node, NULL);
+  install_node (&bgp_vpnv4_node, NULL);
+  install_node (&bgp_ipv4_node, NULL);
+  install_node (&bgp_ipv4m_node, NULL);
+  install_node (&bgp_ipv6_node, NULL);
+  install_node (&bgp_ipv6m_node, NULL);
+  install_node (&ospf_node, NULL);
+  install_node (&ripng_node, NULL);
+  install_node (&ospf6_node, NULL);
+  install_node (&keychain_node, NULL);
+  install_node (&keychain_key_node, NULL);
+  install_node (&isis_node, NULL);
+  install_node (&vty_node, NULL);
+
+  test_init_cmd();
+
+  for (node = 0; node < vector_active(cmdvec); node++)
+    if ((cnode = vector_slot(cmdvec, node)) != NULL)
+      for (i = 0; i < vector_active(cnode->cmd_vector); i++)
+        if ((cmd = vector_slot(cnode->cmd_vector, i)) != NULL)
+          {
+            cmd->daemon = 0;
+            cmd->func = test_callback;
+          }
+  test_load();
+  vty_init_vtysh();
+}
+
+static void
+test_terminate(void)
+{
+  unsigned int i;
+
+  vty_terminate();
+  for (i = 0; i < vector_active(test_cmds); i++)
+    XFREE(MTYPE_STRVEC, vector_slot(test_cmds, i));
+  vector_free(test_cmds);
+  cmd_terminate();
+}
+
+static void
+test_run(struct prng *prng, struct vty *vty, const char *cmd, unsigned int edit_dist, unsigned int node_index, int verbose)
+{
+  const char *test_str;
+  vector vline;
+  int ret;
+  unsigned int i;
+  char **completions;
+  unsigned int j;
+  struct cmd_node *cnode;
+  vector descriptions;
+  int appended_null;
+  int no_match;
+
+  test_str = prng_fuzz(prng, cmd, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_:. /", edit_dist);
+  vline = cmd_make_strvec(test_str);
+
+  if (vline == NULL)
+    return;
+
+  appended_null = 0;
+  for (i = 0; i < vector_active(cmdvec); i++)
+    if ((cnode = vector_slot(cmdvec, i)) != NULL)
+      {
+        if (node_index != (unsigned int)-1 && i != node_index)
+          continue;
+
+        if (appended_null)
+          {
+            vector_unset(vline, vector_active(vline) - 1);
+            appended_null = 0;
+          }
+        vty->node = cnode->node;
+        test_buf[0] = '\0';
+        ret = cmd_execute_command(vline, vty, NULL, 0);
+        no_match = (ret == CMD_ERR_NO_MATCH);
+        if (verbose || !no_match)
+          printf("execute relaxed '%s'@%d: rv==%d%s%s\n",
+                 test_str,
+                 cnode->node,
+                 ret,
+                 (test_buf[0] != '\0') ? ", " : "",
+                 test_buf);
+
+        vty->node = cnode->node;
+        test_buf[0] = '\0';
+        ret = cmd_execute_command_strict(vline, vty, NULL);
+        if (verbose || !no_match)
+          printf("execute strict '%s'@%d: rv==%d%s%s\n",
+                 test_str,
+                 cnode->node,
+                 ret,
+                 (test_buf[0] != '\0') ? ", " : "",
+                 test_buf);
+
+        if (isspace((int) test_str[strlen(test_str) - 1]))
+          {
+            vector_set (vline, NULL);
+            appended_null = 1;
+          }
+
+        vty->node = cnode->node;
+        completions = cmd_complete_command(vline, vty, &ret);
+        if (verbose || !no_match)
+          printf("complete '%s'@%d: rv==%d\n",
+                 test_str,
+                 cnode->node,
+                 ret);
+        if (completions != NULL)
+          {
+            for (j = 0; completions[j] != NULL; j++)
+              {
+                printf("  '%s'\n", completions[j]);
+                XFREE(MTYPE_TMP, completions[j]);
+              }
+            XFREE(MTYPE_TMP, completions);
+          }
+
+        vty->node = cnode->node;
+        descriptions = cmd_describe_command(vline, vty, &ret);
+        if (verbose || !no_match)
+          printf("describe '%s'@%d: rv==%d\n",
+                 test_str,
+                 cnode->node,
+                 ret);
+        if (descriptions != NULL)
+          {
+            for (j = 0; j < vector_active(descriptions); j++)
+              {
+                struct cmd_token *cmd = vector_slot(descriptions, j);
+                printf("  '%s' '%s'\n", cmd->text, cmd->desc);
+              }
+            vector_free(descriptions);
+          }
+      }
+  cmd_free_strvec(vline);
+}
+
+int
+main(int argc, char **argv)
+{
+  int opt;
+  struct prng *prng;
+  struct vty *vty;
+  unsigned int edit_distance;
+  unsigned int max_edit_distance;
+  unsigned int node_index;
+  int verbose;
+  unsigned int test_cmd;
+  unsigned int iteration;
+  unsigned int num_iterations;
+
+  max_edit_distance = 3;
+  node_index = -1;
+  verbose = 0;
+
+  while ((opt = getopt(argc, argv, "e:n:v")) != -1)
+    {
+      switch (opt)
+        {
+        case 'e':
+          max_edit_distance = atoi(optarg);
+          break;
+        case 'n':
+          node_index = atoi(optarg);
+          break;
+        case 'v':
+          verbose++;
+          break;
+        default:
+          fprintf(stderr, "Usage: %s [-e <edit_dist>] [-n <node_idx>] [-v]\n", argv[0]);
+          exit(1);
+          break;
+        }
+    }
+
+  test_init();
+  prng = prng_new(0);
+
+  vty = vty_new();
+  vty->type = VTY_TERM;
+
+  fprintf(stderr, "Progress:\n0/%u", vector_active(test_cmds));
+  for (test_cmd = 0; test_cmd < vector_active(test_cmds); test_cmd++)
+    {
+      for (edit_distance = 0;
+           edit_distance <= max_edit_distance;
+           edit_distance++)
+        {
+          num_iterations = 1 << edit_distance;
+          num_iterations *= num_iterations * num_iterations;
+
+          for (iteration = 0; iteration < num_iterations; iteration++)
+            test_run(prng, vty, vector_slot(test_cmds, test_cmd), edit_distance, node_index, verbose);
+        }
+      fprintf(stderr, "\r%u/%u", test_cmd + 1, vector_active(test_cmds));
+    }
+  fprintf(stderr, "\nDone.\n");
+
+  vty_close(vty);
+  prng_free(prng);
+  test_terminate();
+  return 0;
+}
diff --git a/tests/lib/cli/test_commands.in b/tests/lib/cli/test_commands.in
new file mode 100644 (file)
index 0000000..7fe6279
--- /dev/null
@@ -0,0 +1,216 @@
+#
+#
+# Some randomly chosen valid commands
+#
+#
+area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE
+area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1
+area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1
+area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1
+area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1
+clear bgp 1 out
+clear bgp ipv6 2001:db8::1 out
+clear bgp view VARIABLE * soft
+clear ip bgp 1.2.3.4 ipv4 multicast out
+ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig
+ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1
+network 1.0.0.0/8 area 0
+no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay
+no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay
+no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval
+no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval
+no bgp graceful-restart
+no ipv6 nd mtu 1
+no neighbor 1.2.3.4 distribute-list 1 in
+no neighbor 2001:db8::1 send-community both
+no neighbor VARIABLE maximum-prefix
+redistribute isis route-map VARIABLE metric 0 metric-type 2
+redistribute rip metric 0 route-map VARIABLE metric-type 1
+show bgp community VARIABLE local-AS no-export VARIABLE exact-match
+show bgp ipv6 community no-advertise no-export no-export no-export
+show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match
+show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match
+show bgp view VARIABLE
+show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE
+show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS
+show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise
+show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE
+show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS
+show ip bgp community no-advertise local-AS no-advertise VARIABLE
+show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match
+show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match
+show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match
+show ipv6 bgp community no-export no-export VARIABLE VARIABLE
+show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match
+show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match
+show ipv6 mbgp community local-AS local-AS no-export no-export exact-match
+show ipv6 mbgp community no-export no-export local-AS no-export exact-match
+show ipv6 ospf6 database as-external dump
+show ipv6 ospf6 database inter-prefix 1.2.3.4 detail
+show ipv6 ospf6 database intra-prefix 1.2.3.4 internal
+#
+#
+# Slightly Fuzzed commands
+#
+#
+a8ra 0 range 1.0.0.0/8 adverOise
+accept-lifetime VARIABE 1 VA6IABLE 19I3 VARIABLE 1 VARIABLE 1993
+arAea 1.2.M.4 virtual-link 1.2.3.4 dead-interval 1 dead-interval 1 dead-inter6val 1 transmit-delay 1
+area 0 virtu0al-link 1.2.3.i hello-interval 1 ello-interval 1 transmit-delay 1 retransmit-interval 1
+area 0 virtual-lin 1.2.3.4 retransmit-interval 1 tranwmit-delay 1 retransmit-interval 1 retransmit-interval 1
+area 0 virtual-link 1.2.3.4 retransmit-interal 1 trasmit-dely 1
+area 1.2.3.4 virtual-link 1.2.3.4 deadCinterval 1  dead-intervalK 1 retransmit-interval 1 dead-interval 1
+area 1.2.3.4 virtual-link 1.2.3.4 dead-intervalo I1 dead-interval 1 retransmit-interval1 dead-interval 1
+area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1
+area 1.2.3.4 virtuyl-link 1.2.3.4 dead-interval 1 dead-inervalI 1 retransmit-interval 1 dead-interval 1
+area 1.2.3.4 virual-link 1.2.34 retransmit-interval 1 dead-interval 1 dead-interva 1
+area1.2.83.4 virtual-link 1.2.3.4 retra0smit-interval 1 dead-interval 1 dead-interval 1
+clear bgAp 2001g:dbK::1
+clear ip bgp 1.2.3.4 pv4 mlticat out
+cleau bg i2001:db8::1 rsclient
+de:ug ospf6 messag2 lsreq :recv
+how ip bgp communiQy no-advertise no-adve:tise no-advertise
+ip route 1.0Q0.0/8 1.2.3.s4 reGject
+ipv6 nd prefix 2O01:db8::/32 0 infinEite off-link
+ipv6 nwd prefix 2001:db8::/32 0 infinite oUUff-link
+ipv6 route 2001:db8::/32q2001:db8:k: blackhole 1
+kshow ip rIute bgp
+matcch peer .2.30.4
+mcogin
+mhow ipv6 mbgp community o-advertise yocal-AS no-advertise
+neighbor1.2..4 attribute-unchnged next-hop
+neihbcr 2001:d b8::1 distribute-list 1 in
+nko key-tqring
+no area 0 viertual-link 1.2.3k.4 retransmit-iterval retransmit-interval retransmit-interval hello-interval
+no area 0 virtual-link 1.2.3.4 dead-intaerval dead-intervIl hello-interval retransmit-interval
+no area 0 virtual-link 1.2.3.4 retransmit-interval retransmit-intervIl dead-interval tranImit-deqlay
+no area 0 virtual-link S1.2.3.4 d-ead-interval hello-interval transmit-deay transmit-delay
+no area 1.2.3.4 virtua -link 1.2.3.4 transmit-delay hello-interval hello-interval retransmt-interval
+no area 1.2.3.4 virtual-link 1.2.3.4 dea-iterval retransmit-interva- dead-interval hello-interval
+no area 1.2.3.4 virtual-link 1.2.3.4 hello-interSval dead-interval retransmit-interval transmitdelay
+no a:rea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interSvalW dead-interval retransmit-interval hello-interval
+noarea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval trynsmit-delay hello-interval
+no area 1.2.3.4 virtual-link 1.2.3.4 transmt:delay retransmit-interval retransmit-interval dead-Mnterval
+no ares 1.2.3.4 virtual-link 1.2.3.4 dead-interval retransmit-interval dead-inesval retransmit-interval
+no ayrea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval transmi-delay hello-interval
+no bg2 grace2fuy-restart
+no debug ospk6 nter2face
+noimatch ipv6 addrMss VARIABLE
+nomStch iA next-hop prefix-list
+no neighbCr 200 :db8::1oroute-map VARIABLE export
+no neighbor VARIABLE attributeaw8changed next-hop
+no orea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval ead-interval retransmit-inteSval hello-interval
+no ospcdead-inkerval
+no redistribute kernelrote-map VARIABLE metric 0
+no redistribute s4taik metric 0
+nos Ceighbor 1.2.3.4 route-mapEVARIABLE in
+o :neighbor VAIABLE attribute-unchanged next-hop
+ooa router ip
+redistribute isis meGtric-type2 Q route-map VARIABLE
+redistribute static metric-type 1 metri 0 rowute-map VARIABLE
+set-Koveroadbit
+sh2w ipv6 mbgp  comAunity VARIABLE
+shgw bgp ipv6 community no-export VARIABLE no-xport no-expmrt
+shiow Wgp neighbors
+shoAw ip bgpipv4 unicast com6munity no-export no-export no-advertise no-export exact-match
+sho bgp view gARIABLE nyeighbors 2001:db8::1 received-routes
+shoow bgp ommunity local-AS no--export
+show6 bgp community no-advertise local4-AS no-advertise VARIABLE exact-math
+show8 bgp view VARIABLE ipv4 multicast community ARIABLE VARIABLE local-S
+show bgp cCommunity VARIABLE VOARIABL no-advertise
+show bgp cimAunity loal-AS local-AS no-export local-AS
+show bgp cmmunity n-advertise no-export local-S no-advertise
+show bgp communi0y no-export no-Cexport no-0xport no-export
+show bgp communityOlocal-A no-advertise local-WAS
+show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match
+show bgp communiy no-export no-adsvertise VARIABLOE local-AS
+show bgp communiYty no-export VARIABLE VARIABLE locali-AS exact-math
+show bgp commuUityW no-advertis local-AS no-advertise no-advertise
+show bgp commuWnity VAIABLE local-AS no-advertise n-export
+show bgp com:unity no-exportqno-export VARIABLE no-expoIrt exact-match
+show bgp ipv6 community local-AS no-expor no-xport VARIABCLE
+show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE
+show bgp ipv6 community no-advertise no6-export lcal-AS local-AS
+show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math
+show bgp ipv6 comm-unity no-advertise no-export local-AS local-kS exact-match
+show bgp ipv6 community no-export local-AS no-adertise no-adve-tie
+show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE
+show bgp naighbors 201:db8::1 rUeceived-routes
+show bgp viewVAIABLE ipv4 multicast community VARIABLE4no-export no-advertise local-AS
+show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS
+show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export
+show bgp view VARIABLE ipv4 multicast omsunity local-AS VARIABLE no-advertise nUo-export
+show bgp view VARIABLE ipv4 mutiast community no-export no-export VARIBLE no-export
+show bgp view VARIABLE ipv4 unicast 0community VARIABqLE local-AS no-export VARIABwE
+show bgp view VARIABLE ipv4 unicast communeity no-export AcRIABLE no-advertise local-AS
+show bgp view VARIABLE ipv4 unicasU comunity no-export VARIABL no-advertise
+show bgp view VARIABLE ipv6 unicast cocmmunity VARIABLE no-advet6ise VARIABLE
+show bgp view VARIABLE ipvk4 unicast communty no-advertie local-AS local-AS no-export
+show bgp view VARIALE ipv4 multicast cyommunity no-xport local-AS local-AS
+show i6 bge community no-export VARIABLE no-advegtise VARIABLE exact-match
+show iI bgp community no-advertise no-ad2vertsse VARIABLE exact-match
+show ip6osp6 database dump
+show ipA6 bgp community local-AS local-AS no-advertse lo:cal-AS
+show ip bg comunity VARIABLE lcal-AS no-advertise
+show ip bgp communityno-export2no-export no-advertise locaE-AS
+Show ip bgp community no-export loqcal-AS no-adverise no-export
+show ip bgp community no-expor VARIABLEono-export VARIAuBLE
+show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match
+show ip bgp cWmmunity no-expoWrt VARIABLE no-advertise VARIABLEexact-match
+show ip bgp ip4 nicast community no-advertise no-expoIt local-AS local-AS exact-match
+show ip bgp ipAv4 multicast community no-export no-export no-export no-advertiqe exact-mach
+show ip bgp ipv4 Aulticast community no-advertise VARIABLE no-advertisKe no-exort
+show ip bgp ipv4 meuqlticast community VARIABLE VARIABLE no-export n-export
+show ip bgp ipv4 mlticast coQmmunity localg-AS local-AS no-advertise local-AS
+show ip bgp ipv4 multicast communiy VARIABLE no-export VARIABLE no-advertise yxact-atch
+show ip bgp ipv4 unicast commu0nity local-AS no-export no-exrt VARIABLE exact-match
+show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match
+showip bgp ipv4 unicast community no-export VARIABLE no-exp-ort VAR6IABLE exact-match
+show ip bgp ipv4 unicat community no-exportlocal-AS VARIABLE no-export exa0t-match
+show ip bgp ipv4 unicst community no-advertiseG local-AS no-advertise
+show ip bgp i:v4 multicast community VARIABLE VARIABLE VARIABLE no-export eMxact-match
+show ip bgp Mv4 unicast community no-export VARIABLE VARIABLE VAoRIABLE
+show ipgexecommunity-list 1
+show ipkv6 bgp community no-export no-export VARIABL VARIBLE
+show ipv6 bgp commu2nity local-AS local-AS noEadvertise local-AS
+show ipv6 bgp communitK VARIABLE lcocal-AS no-advertie no-advertise exact-match
+show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match
+show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE
+show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match
+show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE
+show ipv6 bgp comu-ity VARIABLE local-AS no-advertise no-export exact-match
+show ipv6 bgp comunity no- export local-AS no-advertisge VARIABLE
+show ipv6 bgp ommunity sno-advcrtise VARIABLE no-export no-advertise exact-match
+show ipv6 igp community no-advertise no-advertise no-ecxpo0rt no-export
+show ipv6 mb communyty VARIABLE
+show ipv6 osp8f6 database nQtwork adv-ruter 1.2.3.4 detail
+show ipv6 ospf6 dataase type-7 adv-router 1.2.3.4 inernal
+show ipv6 ospf6 Edatabase intuer8-prefix 1.2.3.4 detail
+show ipvq6 ospf6 database as-externa detil
+show ip Wbgp ipv4 unicast community no-advertise no-exprt no-export VARIABLEK exact-match
+show ip Ybgp attribute-in ufo
+showMbgp ipv6 community ARIABLE local-AS local-AS no8advertise exact-match
+show p bgp community no-dvertise no-export no-advertiseIno-export exact-match
+show uipv6 mbgp coqmmunKty VARIABLE
+shQw ipv6 mbgp community no-advetise local-AS no-export no-export ex8ct-match
+shuw ipv6 mbgp community VARIABLyUE no-export no-export no-advertise
+shw bgp view VARIABLE ipv4 un0icast Gcommunity no-export VARIABLE no-advertise
+sow ip bgp ipv4 mulicast community no-export no-adertise no-export no-advertise
+sow ipv6 ospf6 databIase as-external adv-router 1.2.3.4
+Whow bgp view VARIAeBLE ipv4 unicast community local-AS no-advrtise no-advertise local-AS
+Wneighbor 1.2.3.4 dot-capabiliy-negotiate
+#
+#
+# Some teststrings explicitly used for keyword commands
+#
+#
+redistribute bgp
+redistribute bgp m 10
+redistribute bgp metric 10 metric-type 1
+redistribute bgp metric 10 metric 10
+redistribute bgp route-map RMAP_REDIST_BGP
+default-information originate metric-type 1 metric 10
+default-information originate always metric-type 1 metric 10
+default-information originate route-map RMAP_DEFAULT
+default-information originate route-map RMAP_DEFAULT metric 10
+default-information originate always metric-type 2 metric 23
diff --git a/tests/lib/cli/test_commands.refout b/tests/lib/cli/test_commands.refout
new file mode 100644 (file)
index 0000000..9d4a6ef
--- /dev/null
@@ -0,0 +1,1007 @@
+execute relaxed 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (authentication|) (message-digest|null) (message-digest-key|) <1-255> md5 KEY': '0', '1.2.3.4', 'authentication', 'null', 'message-digest-key', '1', 'VARIABLE'
+execute strict 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (authentication|) (message-digest|null) (message-digest-key|) <1-255> md5 KEY': '0', '1.2.3.4', 'authentication', 'null', 'message-digest-key', '1', 'VARIABLE'
+complete 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==2
+describe 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==0
+  'KEY' 'The OSPF password (key)'
+execute relaxed 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'dead-interval', '1', 'hello-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1'
+execute strict 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'dead-interval', '1', 'hello-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1'
+complete 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==2
+describe 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==0
+  '<1-65535>' 'Seconds'
+execute relaxed 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'dead-interval', '1', 'retransmit-interval', '1'
+execute strict 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'dead-interval', '1', 'retransmit-interval', '1'
+complete 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==2
+describe 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==0
+  '<1-65535>' 'Seconds'
+execute relaxed 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'hello-interval', '1', 'hello-interval', '1', 'dead-interval', '1'
+execute strict 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'hello-interval', '1', 'hello-interval', '1', 'dead-interval', '1'
+complete 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==2
+describe 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==0
+  '<1-65535>' 'Seconds'
+execute relaxed 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1', 'dead-interval', '1'
+execute strict 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1', 'dead-interval', '1'
+complete 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==2
+describe 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==0
+  '<1-65535>' 'Seconds'
+execute relaxed 'clear bgp 1 out'@4: rv==0, 'clear bgp <1-4294967295> out': '1'
+execute strict 'clear bgp 1 out'@4: rv==0, 'clear bgp <1-4294967295> out': '1'
+complete 'clear bgp 1 out'@4: rv==7
+  'out'
+describe 'clear bgp 1 out'@4: rv==0
+  'out' 'Soft reconfig outbound update'
+execute relaxed 'clear bgp ipv6 2001:db8::1 out'@4: rv==0, 'clear bgp ipv6 (A.B.C.D|X:X::X:X) out': '2001:db8::1'
+execute strict 'clear bgp ipv6 2001:db8::1 out'@4: rv==0, 'clear bgp ipv6 (A.B.C.D|X:X::X:X) out': '2001:db8::1'
+complete 'clear bgp ipv6 2001:db8::1 out'@4: rv==7
+  'out'
+describe 'clear bgp ipv6 2001:db8::1 out'@4: rv==0
+  'out' 'Soft reconfig outbound update'
+execute relaxed 'clear bgp view VARIABLE * soft'@4: rv==0, 'clear bgp view WORD * soft': 'VARIABLE'
+execute strict 'clear bgp view VARIABLE * soft'@4: rv==0, 'clear bgp view WORD * soft': 'VARIABLE'
+complete 'clear bgp view VARIABLE * soft'@4: rv==7
+  'soft'
+describe 'clear bgp view VARIABLE * soft'@4: rv==0
+  'soft' 'Soft reconfig'
+execute relaxed 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==0, 'clear ip bgp A.B.C.D ipv4 (unicast|multicast) out': '1.2.3.4', 'multicast'
+execute strict 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==0, 'clear ip bgp A.B.C.D ipv4 (unicast|multicast) out': '1.2.3.4', 'multicast'
+complete 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==7
+  'out'
+describe 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==0
+  'out' 'Soft reconfig outbound update'
+execute relaxed 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==0, 'ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)': '2001:db8::/32', 'infinite', 'infinite', 'no-autoconfig'
+execute strict 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==0, 'ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)': '2001:db8::/32', 'infinite', 'infinite', 'no-autoconfig'
+complete 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==7
+  'no-autoconfig'
+describe 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==0
+  'no-autoconfig' 'Do not use prefix for autoconfiguration'
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==0
+  '<1-255>' 'Distance value for this prefix'
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==2
+execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
+execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==2
+complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==2
+describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==2
+execute relaxed 'network 1.0.0.0/8 area 0'@23: rv==0, 'network A.B.C.D/M area (A.B.C.D|<0-4294967295>)': '1.0.0.0/8', '0'
+execute strict 'network 1.0.0.0/8 area 0'@23: rv==0, 'network A.B.C.D/M area (A.B.C.D|<0-4294967295>)': '1.0.0.0/8', '0'
+complete 'network 1.0.0.0/8 area 0'@23: rv==2
+describe 'network 1.0.0.0/8 area 0'@23: rv==0
+  '<0-4294967295>' 'OSPF area ID as a decimal value'
+  'A.B.C.D' 'OSPF area ID in IP address format'
+execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'hello-interval', 'transmit-delay'
+execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'hello-interval', 'transmit-delay'
+complete 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==7
+  'transmit-delay'
+describe 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==0
+  'transmit-delay' 'Seconds'
+execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'retransmit-interval', 'transmit-delay'
+execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'retransmit-interval', 'transmit-delay'
+complete 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==7
+  'transmit-delay'
+describe 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==0
+  'transmit-delay' 'Seconds'
+execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'retransmit-interval', 'dead-interval', 'retransmit-interval', 'hello-interval'
+execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'retransmit-interval', 'dead-interval', 'retransmit-interval', 'hello-interval'
+complete 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==7
+  'hello-interval'
+describe 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==0
+  'hello-interval' 'Link state transmit delay'
+execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'transmit-delay', 'retransmit-interval', 'retransmit-interval', 'hello-interval'
+execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'transmit-delay', 'retransmit-interval', 'retransmit-interval', 'hello-interval'
+complete 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==7
+  'hello-interval'
+describe 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==0
+  'hello-interval' 'Link state transmit delay'
+execute relaxed 'no bgp graceful-restart'@17: rv==0, 'no bgp graceful-restart'
+execute strict 'no bgp graceful-restart'@17: rv==0, 'no bgp graceful-restart'
+complete 'no bgp graceful-restart'@17: rv==7
+  'graceful-restart'
+describe 'no bgp graceful-restart'@17: rv==0
+  'graceful-restart' 'Graceful restart capability parameters'
+execute relaxed 'no bgp graceful-restart'@18: rv==0, 'no bgp graceful-restart'
+execute strict 'no bgp graceful-restart'@18: rv==2
+complete 'no bgp graceful-restart'@18: rv==2
+describe 'no bgp graceful-restart'@18: rv==2
+execute relaxed 'no bgp graceful-restart'@19: rv==0, 'no bgp graceful-restart'
+execute strict 'no bgp graceful-restart'@19: rv==2
+complete 'no bgp graceful-restart'@19: rv==2
+describe 'no bgp graceful-restart'@19: rv==2
+execute relaxed 'no bgp graceful-restart'@20: rv==0, 'no bgp graceful-restart'
+execute strict 'no bgp graceful-restart'@20: rv==2
+complete 'no bgp graceful-restart'@20: rv==2
+describe 'no bgp graceful-restart'@20: rv==2
+execute relaxed 'no bgp graceful-restart'@21: rv==0, 'no bgp graceful-restart'
+execute strict 'no bgp graceful-restart'@21: rv==2
+complete 'no bgp graceful-restart'@21: rv==2
+describe 'no bgp graceful-restart'@21: rv==2
+execute relaxed 'no bgp graceful-restart'@22: rv==0, 'no bgp graceful-restart'
+execute strict 'no bgp graceful-restart'@22: rv==2
+complete 'no bgp graceful-restart'@22: rv==2
+describe 'no bgp graceful-restart'@22: rv==2
+execute relaxed 'no ipv6 nd mtu 1'@11: rv==0, 'no ipv6 nd mtu <1-65535>': '1'
+execute strict 'no ipv6 nd mtu 1'@11: rv==0, 'no ipv6 nd mtu <1-65535>': '1'
+complete 'no ipv6 nd mtu 1'@11: rv==2
+describe 'no ipv6 nd mtu 1'@11: rv==0
+  '<1-65535>' 'MTU in bytes'
+execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+complete 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==7
+  'in'
+describe 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==0
+  'in' 'Filter incoming updates'
+execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+complete 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==7
+  'in'
+describe 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==0
+  'in' 'Filter incoming updates'
+execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+complete 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==7
+  'in'
+describe 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==0
+  'in' 'Filter incoming updates'
+execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+complete 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==7
+  'in'
+describe 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==0
+  'in' 'Filter incoming updates'
+execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+complete 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==7
+  'in'
+describe 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==0
+  'in' 'Filter incoming updates'
+execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
+complete 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==7
+  'in'
+describe 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==0
+  'in' 'Filter incoming updates'
+execute relaxed 'no neighbor 2001:db8::1 send-community both'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+execute strict 'no neighbor 2001:db8::1 send-community both'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+complete 'no neighbor 2001:db8::1 send-community both'@17: rv==7
+  'both'
+describe 'no neighbor 2001:db8::1 send-community both'@17: rv==0
+  'both' 'Send Standard and Extended Community attributes'
+execute relaxed 'no neighbor 2001:db8::1 send-community both'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+execute strict 'no neighbor 2001:db8::1 send-community both'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+complete 'no neighbor 2001:db8::1 send-community both'@18: rv==7
+  'both'
+describe 'no neighbor 2001:db8::1 send-community both'@18: rv==0
+  'both' 'Send Standard and Extended Community attributes'
+execute relaxed 'no neighbor 2001:db8::1 send-community both'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+execute strict 'no neighbor 2001:db8::1 send-community both'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+complete 'no neighbor 2001:db8::1 send-community both'@19: rv==7
+  'both'
+describe 'no neighbor 2001:db8::1 send-community both'@19: rv==0
+  'both' 'Send Standard and Extended Community attributes'
+execute relaxed 'no neighbor 2001:db8::1 send-community both'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+execute strict 'no neighbor 2001:db8::1 send-community both'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+complete 'no neighbor 2001:db8::1 send-community both'@20: rv==7
+  'both'
+describe 'no neighbor 2001:db8::1 send-community both'@20: rv==0
+  'both' 'Send Standard and Extended Community attributes'
+execute relaxed 'no neighbor 2001:db8::1 send-community both'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+execute strict 'no neighbor 2001:db8::1 send-community both'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+complete 'no neighbor 2001:db8::1 send-community both'@21: rv==7
+  'both'
+describe 'no neighbor 2001:db8::1 send-community both'@21: rv==0
+  'both' 'Send Standard and Extended Community attributes'
+execute relaxed 'no neighbor 2001:db8::1 send-community both'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+execute strict 'no neighbor 2001:db8::1 send-community both'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
+complete 'no neighbor 2001:db8::1 send-community both'@22: rv==7
+  'both'
+describe 'no neighbor 2001:db8::1 send-community both'@22: rv==0
+  'both' 'Send Standard and Extended Community attributes'
+execute relaxed 'no neighbor VARIABLE maximum-prefix'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+execute strict 'no neighbor VARIABLE maximum-prefix'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+complete 'no neighbor VARIABLE maximum-prefix'@17: rv==7
+  'maximum-prefix'
+describe 'no neighbor VARIABLE maximum-prefix'@17: rv==0
+  'maximum-prefix' 'Maximum number of prefix accept from this peer'
+execute relaxed 'no neighbor VARIABLE maximum-prefix'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+execute strict 'no neighbor VARIABLE maximum-prefix'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+complete 'no neighbor VARIABLE maximum-prefix'@18: rv==7
+  'maximum-prefix'
+describe 'no neighbor VARIABLE maximum-prefix'@18: rv==0
+  'maximum-prefix' 'Maximum number of prefix accept from this peer'
+execute relaxed 'no neighbor VARIABLE maximum-prefix'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+execute strict 'no neighbor VARIABLE maximum-prefix'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+complete 'no neighbor VARIABLE maximum-prefix'@19: rv==7
+  'maximum-prefix'
+describe 'no neighbor VARIABLE maximum-prefix'@19: rv==0
+  'maximum-prefix' 'Maximum number of prefix accept from this peer'
+execute relaxed 'no neighbor VARIABLE maximum-prefix'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+execute strict 'no neighbor VARIABLE maximum-prefix'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+complete 'no neighbor VARIABLE maximum-prefix'@20: rv==7
+  'maximum-prefix'
+describe 'no neighbor VARIABLE maximum-prefix'@20: rv==0
+  'maximum-prefix' 'Maximum number of prefix accept from this peer'
+execute relaxed 'no neighbor VARIABLE maximum-prefix'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+execute strict 'no neighbor VARIABLE maximum-prefix'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+complete 'no neighbor VARIABLE maximum-prefix'@21: rv==7
+  'maximum-prefix'
+describe 'no neighbor VARIABLE maximum-prefix'@21: rv==0
+  'maximum-prefix' 'Maximum number of prefix accept from this peer'
+execute relaxed 'no neighbor VARIABLE maximum-prefix'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+execute strict 'no neighbor VARIABLE maximum-prefix'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
+complete 'no neighbor VARIABLE maximum-prefix'@22: rv==7
+  'maximum-prefix'
+describe 'no neighbor VARIABLE maximum-prefix'@22: rv==0
+  'maximum-prefix' 'Maximum number of prefix accept from this peer'
+execute relaxed 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
+execute strict 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
+complete 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==7
+  '2'
+describe 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0
+  '2' 'Set OSPF External Type 2 metrics'
+execute relaxed 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
+execute strict 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
+complete 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==7
+  '1'
+describe 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0
+  '1' 'Set OSPF External Type 1 metrics'
+execute relaxed 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+execute strict 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+complete 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==7
+  'exact-match'
+describe 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+execute strict 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+complete 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==7
+  'exact-match'
+describe 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+execute strict 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+complete 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==7
+  'exact-match'
+describe 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
+execute strict 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
+complete 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==7
+  'no-export'
+describe 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-export' 'Do not export to next AS (well-known community)'
+execute relaxed 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
+execute strict 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
+complete 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==7
+  'no-export'
+describe 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-export' 'Do not export to next AS (well-known community)'
+execute relaxed 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
+execute strict 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
+complete 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==7
+  'no-export'
+describe 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-export' 'Do not export to next AS (well-known community)'
+execute relaxed 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
+execute strict 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
+complete 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==7
+  'exact-match'
+describe 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
+execute strict 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
+complete 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==7
+  'exact-match'
+describe 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
+execute strict 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
+complete 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==7
+  'exact-match'
+describe 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
+execute strict 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
+complete 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==7
+  'exact-match'
+describe 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
+execute strict 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
+complete 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==7
+  'exact-match'
+describe 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
+execute strict 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
+complete 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==7
+  'exact-match'
+describe 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp view VARIABLE'@1: rv==4
+execute strict 'show bgp view VARIABLE'@1: rv==4
+complete 'show bgp view VARIABLE'@1: rv==2
+describe 'show bgp view VARIABLE'@1: rv==0
+  'WORD' 'View name'
+execute relaxed 'show bgp view VARIABLE'@2: rv==0, 'show bgp view WORD': 'VARIABLE'
+execute strict 'show bgp view VARIABLE'@2: rv==0, 'show bgp view WORD': 'VARIABLE'
+complete 'show bgp view VARIABLE'@2: rv==2
+describe 'show bgp view VARIABLE'@2: rv==0
+  'WORD' 'View name'
+execute relaxed 'show bgp view VARIABLE'@4: rv==0, 'show bgp view WORD': 'VARIABLE'
+execute strict 'show bgp view VARIABLE'@4: rv==0, 'show bgp view WORD': 'VARIABLE'
+complete 'show bgp view VARIABLE'@4: rv==2
+describe 'show bgp view VARIABLE'@4: rv==0
+  'WORD' 'View name'
+execute relaxed 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
+execute strict 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
+complete 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==2
+describe 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
+execute strict 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
+complete 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==2
+describe 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
+execute strict 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
+complete 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==2
+describe 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
+complete 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==7
+  'local-AS'
+describe 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
+complete 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==7
+  'local-AS'
+describe 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
+complete 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==7
+  'local-AS'
+describe 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
+execute strict 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
+complete 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==7
+  'no-advertise'
+describe 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-advertise' 'Do not advertise to any peer (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
+execute strict 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
+complete 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==7
+  'no-advertise'
+describe 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-advertise' 'Do not advertise to any peer (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
+execute strict 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
+complete 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==7
+  'no-advertise'
+describe 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-advertise' 'Do not advertise to any peer (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+execute strict 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+complete 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==2
+describe 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+execute strict 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+complete 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==2
+describe 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+execute strict 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
+complete 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==2
+describe 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+complete 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==7
+  'local-AS'
+describe 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+complete 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==7
+  'local-AS'
+describe 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+complete 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==7
+  'local-AS'
+describe 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
+execute strict 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
+complete 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==2
+describe 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
+execute strict 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
+complete 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==2
+describe 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
+execute strict 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
+complete 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==2
+describe 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+execute strict 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+complete 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+execute strict 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+complete 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+execute strict 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
+complete 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
+execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
+complete 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
+execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
+complete 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
+execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
+complete 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
+execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
+complete 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
+execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
+complete 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
+execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
+complete 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
+execute strict 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
+complete 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==2
+describe 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
+execute strict 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
+complete 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==2
+describe 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
+execute strict 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
+complete 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==7
+  'exact-match'
+describe 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
+execute strict 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
+complete 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==7
+  'exact-match'
+describe 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
+execute strict 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
+complete 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==7
+  'exact-match'
+describe 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
+execute strict 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
+complete 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==7
+  'exact-match'
+describe 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
+execute strict 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
+complete 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==7
+  'exact-match'
+describe 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
+execute strict 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
+complete 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==7
+  'exact-match'
+describe 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
+execute strict 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
+complete 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==7
+  'exact-match'
+describe 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
+execute strict 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
+complete 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==7
+  'exact-match'
+describe 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 ospf6 database as-external dump'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
+execute strict 'show ipv6 ospf6 database as-external dump'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
+complete 'show ipv6 ospf6 database as-external dump'@2: rv==7
+  'dump'
+describe 'show ipv6 ospf6 database as-external dump'@2: rv==0
+  'dump' 'Dump LSAs'
+execute relaxed 'show ipv6 ospf6 database as-external dump'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
+execute strict 'show ipv6 ospf6 database as-external dump'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
+complete 'show ipv6 ospf6 database as-external dump'@4: rv==7
+  'dump'
+describe 'show ipv6 ospf6 database as-external dump'@4: rv==0
+  'dump' 'Dump LSAs'
+execute relaxed 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
+execute strict 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
+complete 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==7
+  'detail'
+describe 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==0
+  'detail' 'Display details of LSAs'
+execute relaxed 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
+execute strict 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
+complete 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==7
+  'detail'
+describe 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==0
+  'detail' 'Display details of LSAs'
+execute relaxed 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
+execute strict 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
+complete 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==7
+  'internal'
+describe 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==0
+  'internal' 'Display LSA's internal information'
+execute relaxed 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
+execute strict 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
+complete 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==7
+  'internal'
+describe 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==0
+  'internal' 'Display LSA's internal information'
+execute relaxed 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'hello-interval', '1', 'dead-interva', '1', 'retransmit-interval', '1', 'transmit-delay', '1'
+execute strict 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==2
+complete 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==2
+describe 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==0
+  '<1-65535>' 'Seconds'
+execute relaxed 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
+execute strict 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
+complete 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==7
+  'exact-match'
+describe 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
+execute strict 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
+complete 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==7
+  'exact-match'
+describe 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
+execute strict 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
+complete 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==7
+  'exact-match'
+describe 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
+execute strict 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
+complete 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==2
+describe 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
+execute strict 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
+complete 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==2
+describe 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
+execute strict 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
+complete 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==2
+describe 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
+execute strict 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
+complete 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==2
+describe 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
+execute strict 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
+complete 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==2
+describe 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
+execute strict 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
+complete 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==2
+describe 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
+execute strict 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
+complete 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==7
+  'local-AS'
+describe 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
+execute strict 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
+complete 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==7
+  'local-AS'
+describe 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
+execute strict 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
+complete 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==7
+  'local-AS'
+describe 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
+execute strict 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
+complete 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==2
+describe 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
+execute strict 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
+complete 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==2
+describe 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
+execute strict 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
+complete 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==2
+describe 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
+execute strict 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
+complete 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==2
+describe 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
+execute strict 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
+complete 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==2
+describe 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
+execute strict 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
+complete 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==2
+describe 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
+execute strict 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
+complete 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==2
+describe 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
+execute strict 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
+complete 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==2
+describe 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
+execute strict 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
+complete 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==2
+describe 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
+complete 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==7
+  'local-AS'
+describe 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
+complete 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==7
+  'local-AS'
+describe 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
+execute strict 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
+complete 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==7
+  'local-AS'
+describe 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'local-AS' 'Do not send outside local AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
+execute strict 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
+complete 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==7
+  'no-export'
+describe 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-export' 'Do not export to next AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
+execute strict 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
+complete 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==7
+  'no-export'
+describe 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-export' 'Do not export to next AS (well-known community)'
+execute relaxed 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
+execute strict 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
+complete 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==7
+  'no-export'
+describe 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+  'no-export' 'Do not export to next AS (well-known community)'
+execute relaxed 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
+execute strict 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
+complete 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==2
+describe 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
+execute strict 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
+complete 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==2
+describe 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
+execute strict 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
+complete 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==2
+describe 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
+execute strict 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
+complete 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==2
+describe 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
+execute strict 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
+complete 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==2
+describe 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
+execute strict 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
+complete 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==2
+describe 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
+execute strict 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
+complete 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
+execute strict 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
+complete 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
+execute strict 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
+complete 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==7
+  'exact-match'
+describe 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
+execute strict 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
+complete 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==7
+  'exact-match'
+describe 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
+execute strict 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
+complete 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==7
+  'exact-match'
+describe 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
+execute strict 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
+complete 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==2
+describe 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
+execute strict 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
+complete 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==2
+describe 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
+execute strict 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
+complete 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==7
+  'exact-match'
+describe 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
+execute strict 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
+complete 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==7
+  'exact-match'
+describe 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==0
+  'exact-match' 'Exact match of the communities'
+execute relaxed 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
+execute strict 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
+complete 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==2
+describe 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
+execute strict 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
+complete 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==2
+describe 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0
+  'AA:NN' 'Community number where AA and NN are <0-65535>'
+execute relaxed 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp)': 'bgp'
+execute strict 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp)': 'bgp'
+complete 'redistribute bgp'@14: rv==7
+  'bgp'
+describe 'redistribute bgp'@14: rv==0
+  'bgp' 'Border Gateway Protocol (BGP)'
+execute relaxed 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp)': 'bgp'
+execute strict 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp)': 'bgp'
+complete 'redistribute bgp'@15: rv==7
+  'bgp'
+describe 'redistribute bgp'@15: rv==0
+  'bgp' 'Border Gateway Protocol (BGP)'
+execute relaxed 'redistribute bgp'@16: rv==0, 'redistribute (kernel|connected|static|rip|ripng|ospf|ospf6|isis|bgp)': 'bgp'
+execute strict 'redistribute bgp'@16: rv==0, 'redistribute (kernel|connected|static|rip|ripng|ospf|ospf6|isis|bgp)': 'bgp'
+complete 'redistribute bgp'@16: rv==7
+  'bgp'
+describe 'redistribute bgp'@16: rv==0
+  'bgp' 'Border Gateway Protocol (BGP)'
+execute relaxed 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
+execute strict 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
+complete 'redistribute bgp'@23: rv==7
+  'bgp'
+describe 'redistribute bgp'@23: rv==0
+  'bgp' 'Border Gateway Protocol (BGP)'
+execute relaxed 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp)': 'bgp'
+execute strict 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp)': 'bgp'
+complete 'redistribute bgp'@24: rv==7
+  'bgp'
+describe 'redistribute bgp'@24: rv==0
+  'bgp' 'Border Gateway Protocol (BGP)'
+execute relaxed 'redistribute bgp m 10'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) metric <0-16>': 'bgp', '10'
+execute strict 'redistribute bgp m 10'@14: rv==2
+complete 'redistribute bgp m 10'@14: rv==2
+describe 'redistribute bgp m 10'@14: rv==0
+  '<0-16>' 'Metric value'
+execute relaxed 'redistribute bgp m 10'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) metric <0-16>': 'bgp', '10'
+execute strict 'redistribute bgp m 10'@15: rv==2
+complete 'redistribute bgp m 10'@15: rv==2
+describe 'redistribute bgp m 10'@15: rv==0
+  '<0-16>' 'Metric value'
+execute relaxed 'redistribute bgp m 10'@23: rv==3
+execute strict 'redistribute bgp m 10'@23: rv==2
+complete 'redistribute bgp m 10'@23: rv==3
+describe 'redistribute bgp m 10'@23: rv==3
+execute relaxed 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
+execute strict 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
+complete 'redistribute bgp metric 10 metric-type 1'@23: rv==7
+  '1'
+describe 'redistribute bgp metric 10 metric-type 1'@23: rv==0
+  '1' 'Set OSPF External Type 1 metrics'
+execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
+execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
+complete 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==2
+describe 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0
+  'WORD' 'Pointer to route-map entries'
+execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
+execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
+complete 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==2
+describe 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0
+  'WORD' 'Pointer to route-map entries'
+execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
+execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
+complete 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==2
+describe 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0
+  'WORD' 'Pointer to route-map entries'
+execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
+execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
+complete 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==2
+describe 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0
+  'WORD' 'Route map name'
+execute relaxed 'default-information originate metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '1', '(null)'
+execute strict 'default-information originate metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '1', '(null)'
+complete 'default-information originate metric-type 1 metric 10'@23: rv==2
+describe 'default-information originate metric-type 1 metric 10'@23: rv==0
+  '<0-16777214>' 'OSPF metric'
+execute relaxed 'default-information originate always metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '10', '1', '(null)'
+execute strict 'default-information originate always metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '10', '1', '(null)'
+complete 'default-information originate always metric-type 1 metric 10'@23: rv==2
+describe 'default-information originate always metric-type 1 metric 10'@23: rv==0
+  '<0-16777214>' 'OSPF metric'
+execute relaxed 'default-information originate route-map RMAP_DEFAULT'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '(null)', '(null)', 'RMAP_DEFAULT'
+execute strict 'default-information originate route-map RMAP_DEFAULT'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '(null)', '(null)', 'RMAP_DEFAULT'
+complete 'default-information originate route-map RMAP_DEFAULT'@23: rv==2
+describe 'default-information originate route-map RMAP_DEFAULT'@23: rv==0
+  'WORD' 'Pointer to route-map entries'
+execute relaxed 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '(null)', 'RMAP_DEFAULT'
+execute strict 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '(null)', 'RMAP_DEFAULT'
+complete 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==2
+describe 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==0
+  '<0-16777214>' 'OSPF metric'
+execute relaxed 'default-information originate always metric-type 2 metric 23'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '23', '2', '(null)'
+execute strict 'default-information originate always metric-type 2 metric 23'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '23', '2', '(null)'
+complete 'default-information originate always metric-type 2 metric 23'@23: rv==2
+describe 'default-information originate always metric-type 2 metric 23'@23: rv==0
+  '<0-16777214>' 'OSPF metric'
diff --git a/tests/lib/test_buffer.c b/tests/lib/test_buffer.c
new file mode 100644 (file)
index 0000000..67e4035
--- /dev/null
@@ -0,0 +1,60 @@
+/* 
+ * Copyright (C) 2004 Paul Jakma
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+#include <memory.h>
+#include <memory_vty.h>
+#include <buffer.h>
+
+struct thread_master *master;
+
+int
+main(int argc, char **argv)
+{
+  struct buffer *b1, *b2;
+  int n;
+  char junk[3];
+  char c = 'a';
+
+  memory_init();
+  
+  if ((argc != 2) || (sscanf(argv[1], "%d%1s", &n, junk) != 1))
+    {
+      fprintf(stderr, "Usage: %s <number of chars to simulate>\n", *argv);
+      return 1;
+    }
+
+  b1 = buffer_new(0);
+  b2 = buffer_new(1024);
+  
+  while (n-- > 0)
+    {
+      buffer_put(b1, &c, 1);
+      buffer_put(b2, &c, 1);
+      if (c++ == 'z')
+        c = 'a';
+      buffer_reset(b1);
+      buffer_reset(b2);
+    }
+  buffer_free(b1);
+  buffer_free(b2);
+  return 0;
+}
diff --git a/tests/lib/test_checksum.c b/tests/lib/test_checksum.c
new file mode 100644 (file)
index 0000000..53ab260
--- /dev/null
@@ -0,0 +1,550 @@
+/* 
+ * Copyright (C) 2008 Sun Microsystems, Inc.
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "checksum.h"
+
+struct thread_master *master;
+
+struct acc_vals {
+  int c0;
+  int c1;
+};
+
+struct csum_vals {
+  struct acc_vals a;
+  int x; 
+  int y;
+};
+
+static struct csum_vals ospfd_vals, isisd_vals;
+
+typedef size_t testsz_t;
+typedef uint16_t testoff_t;
+
+/* Fletcher Checksum -- Refer to RFC1008. */
+#define MODX                 4102U
+
+/* The final reduction phase.
+ * This one should be the original ospfd version 
+ */
+static u_int16_t 
+reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off)
+{
+#define x vals->x
+#define y vals->y
+#define c0 vals->a.c0
+#define c1 vals->a.c1
+
+  x = ((len - off - 1) * c0 - c1) % 255;
+  
+  if (x <= 0)
+    x += 255;
+  y = 510 - c0 - x;
+  if (y > 255)
+    y -= 255;
+
+   /* take care endian issue. */
+   return htons ((x << 8) + y); 
+#undef x
+#undef y
+#undef c0
+#undef c1
+}
+
+/* slightly different concatenation */
+static u_int16_t 
+reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off)
+{
+#define x vals->x
+#define y vals->y
+#define c0 vals->a.c0
+#define c1 vals->a.c1
+
+  x = ((len - off - 1) * c0 - c1) % 255;
+  if (x <= 0)
+    x += 255;
+  y = 510 - c0 - x;
+  if (y > 255)
+    y -= 255;
+
+   /* take care endian issue. */
+   return htons ((x << 8) | (y & 0xff)); 
+#undef x
+#undef y
+#undef c0
+#undef c1
+}
+
+/* original isisd version */
+static u_int16_t 
+reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off)
+{
+#define x vals->x
+#define y vals->y
+#define c0 vals->a.c0
+#define c1 vals->a.c1
+  u_int32_t mul;
+  
+  mul = (len - off)*(c0);
+  x = mul - c0 - c1;
+  y = c1 - mul - 1;
+
+  if (y > 0)
+    y++;
+  if (x < 0)
+    x--;
+
+  x %= 255;
+  y %= 255;
+
+  if (x == 0)
+    x = 255;
+  if (y == 0)
+    y = 1;
+
+  return htons ((x << 8) | (y & 0xff));
+
+#undef x
+#undef y
+#undef c0
+#undef c1
+}
+
+/* Is the -1 in y wrong perhaps? */
+static u_int16_t 
+reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off)
+{
+#define x vals->x
+#define y vals->y
+#define c0 vals->a.c0
+#define c1 vals->a.c1
+  u_int32_t mul;
+  
+  mul = (len - off)*(c0);
+  x = mul - c0 - c1;
+  y = c1 - mul;
+
+  if (y > 0)
+    y++;
+  if (x < 0)
+    x--;
+
+  x %= 255;
+  y %= 255;
+
+  if (x == 0)
+    x = 255;
+  if (y == 0)
+    y = 1;
+
+  return htons ((x << 8) | (y & 0xff));
+
+#undef x
+#undef y
+#undef c0
+#undef c1
+}
+
+/* Move the mods yp */
+static u_int16_t 
+reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off)
+{
+#define x vals->x
+#define y vals->y
+#define c0 vals->a.c0
+#define c1 vals->a.c1
+  u_int32_t mul;
+  
+  mul = (len - off)*(c0);
+  x = mul - c1 - c0;
+  y = c1 - mul - 1;
+
+  x %= 255;
+  y %= 255;
+
+  if (y > 0)
+    y++;
+  if (x < 0)
+    x--;
+
+  if (x == 0)
+    x = 255;
+  if (y == 0)
+    y = 1;
+
+  return htons ((x << 8) | (y & 0xff));
+
+#undef x
+#undef y
+#undef c0
+#undef c1
+}
+
+/* Move the mods up + fix y */
+static u_int16_t 
+reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off)
+{
+#define x vals->x
+#define y vals->y
+#define c0 vals->a.c0
+#define c1 vals->a.c1
+  u_int32_t mul;
+  
+  mul = (len - off)*(c0);
+  x = mul - c0 - c1;
+  y = c1 - mul;
+
+  x %= 255;
+  y %= 255;
+
+  if (y > 0)
+    y++;
+  if (x < 0)
+    x--;
+
+  if (x == 0)
+    x = 255;
+  if (y == 0)
+    y = 1;
+
+  return htons ((x << 8) | (y & 0xff));
+
+#undef x
+#undef y
+#undef c0
+#undef c1
+}
+
+struct reductions_t {
+  const char *name;
+  u_int16_t (*f) (struct csum_vals *, testsz_t, testoff_t);
+} reducts[] = {
+  { .name = "ospfd",           .f = reduce_ospfd },
+  { .name = "ospfd-1",         .f = reduce_ospfd1 },
+  { .name = "isisd",           .f = reduce_isisd },
+  { .name = "isisd-yfix",      .f = reduce_isisd_yfix },
+  { .name = "isisd-mod",       .f = reduce_isisd_mod },
+  { .name = "isisd-mody",      .f = reduce_isisd_mody },
+  { NULL, NULL },
+};
+
+/* The original ospfd checksum */
+static u_int16_t
+ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off)
+{
+  u_char *sp, *ep, *p, *q;
+  int c0 = 0, c1 = 0;
+  int x, y;
+  u_int16_t checksum, *csum;
+
+  csum = (u_int16_t *) (buffer + off);
+  *(csum) = 0;
+  
+  sp = buffer;
+
+  for (ep = sp + len; sp < ep; sp = q)
+    {
+      q = sp + MODX;
+      if (q > ep)
+        q = ep;
+      for (p = sp; p < q; p++)
+        {
+          c0 += *p;
+          c1 += c0;
+        }
+      c0 %= 255;
+      c1 %= 255;
+    }
+  
+  ospfd_vals.a.c0 = c0;
+  ospfd_vals.a.c1 = c1;
+  
+  //printf ("%s: len %u, off %u, c0 %d, c1 %d\n",
+  //        __func__, len, off, c0, c1);
+
+  x = ((int)(len - off - 1) * (int)c0 - (int)c1) % 255;
+  
+  if (x <= 0)
+    x += 255;
+  y = 510 - c0 - x;
+  if (y > 255)
+    y -= 255;
+  
+  ospfd_vals.x = x;
+  ospfd_vals.y = y;
+  
+  buffer[off] = x;
+  buffer[off + 1] = y;
+  
+  /* take care endian issue. */
+  checksum = htons ((x << 8) | (y & 0xff));
+
+  return (checksum);
+}
+
+/* the original, broken isisd checksum */
+static u_int16_t
+iso_csum_create (u_char * buffer, testsz_t len, testoff_t off)
+{
+
+  u_int8_t *p;
+  int x;
+  int y;
+  u_int32_t mul;
+  u_int32_t c0;
+  u_int32_t c1;
+  u_int16_t checksum, *csum;
+  int i, init_len, partial_len;
+
+  checksum = 0;
+  
+  csum = (u_int16_t *) (buffer + off);
+  *(csum) = checksum;
+  
+  p = buffer;
+  c0 = 0;
+  c1 = 0;
+  init_len = len;
+  
+  while (len != 0)
+    {
+      partial_len = MIN(len, MODX);
+
+      for (i = 0; i < partial_len; i++)
+       {
+         c0 = c0 + *(p++);
+         c1 += c0;
+       }
+
+      c0 = c0 % 255;
+      c1 = c1 % 255;
+
+      len -= partial_len;
+    }
+
+  isisd_vals.a.c0 = c0;
+  isisd_vals.a.c1 = c1;
+  
+  mul = (init_len - off) * c0;
+
+  x = mul - c1 - c0;
+  y = c1 - mul - 1;
+
+  if (y > 0)
+    y++;
+  if (x < 0)
+    x--;
+
+  x %= 255;
+  y %= 255;
+
+  if (x == 0)
+    x = 255;
+  if (y == 0)
+    y = 1;
+  
+  isisd_vals.x = x;
+  isisd_vals.y = y;
+  
+  checksum = htons((x << 8) | (y & 0xFF));
+  
+  *(csum) = checksum;
+  
+  /* return the checksum for user usage */
+  return checksum;
+}
+
+static int
+verify (u_char * buffer, testsz_t len)
+{
+  u_int8_t *p;
+  u_int32_t c0;
+  u_int32_t c1;
+  int i, partial_len;
+  p = buffer;
+
+  c0 = 0;
+  c1 = 0;
+
+  while (len)
+    {
+      partial_len = MIN(len, 5803U);
+
+      for (i = 0; i < partial_len; i++)
+        {
+          c0 = c0 + *(p++);
+          c1 += c0;
+        }
+      c0 = c0 % 255;
+      c1 = c1 % 255;
+
+      len -= partial_len;
+    }
+
+  if (c0 == 0 && c1 == 0)
+    return 0;
+
+  return 1;
+}
+
+static int  /* return checksum in low-order 16 bits */
+in_cksum_optimized(void *parg, int nbytes)
+{
+       u_short *ptr = parg;
+       register long           sum;            /* assumes long == 32 bits */
+       register u_short        answer;         /* assumes u_short == 16 bits */
+       register int count;
+       /*
+        * Our algorithm is simple, using a 32-bit accumulator (sum),
+        * we add sequential 16-bit words to it, and at the end, fold back
+        * all the carry bits from the top 16 bits into the lower 16 bits.
+        */
+
+       sum = 0;
+       count = nbytes >> 1; /* div by 2 */
+       for(ptr--; count; --count)
+         sum += *++ptr;
+
+       if (nbytes & 1) /* Odd */
+         sum += *(u_char *)(++ptr);   /* one byte only */
+
+       /*
+        * Add back carry outs from top 16 bits to low 16 bits.
+        */
+
+       sum  = (sum >> 16) + (sum & 0xffff);    /* add high-16 to low-16 */
+       sum += (sum >> 16);                     /* add carry */
+       answer = ~sum;          /* ones-complement, then truncate to 16 bits */
+       return(answer);
+}
+
+
+static int /* return checksum in low-order 16 bits */
+in_cksum_rfc(void *parg, int count)
+/* from RFC 1071 */
+{
+       u_short *addr = parg;
+       /* Compute Internet Checksum for "count" bytes
+        *         beginning at location "addr".
+        */
+       register long  sum = 0;
+
+       while (count > 1)  {
+         /*  This is the inner loop */
+         sum += *addr++;
+         count -= 2;
+       }
+       /*  Add left-over byte, if any */
+       if (count > 0) {
+         sum += *(u_char *)addr;
+       }
+
+       /*  Fold 32-bit sum to 16 bits */
+       while (sum>>16)
+           sum = (sum & 0xffff) + (sum >> 16);
+       return ~sum;
+}
+
+
+int
+main(int argc, char **argv)
+{
+/* 60017 65629 702179 */
+#define MAXDATALEN 60017
+#define BUFSIZE MAXDATALEN + sizeof(u_int16_t)
+  u_char buffer[BUFSIZE];
+  int exercise = 0;
+#define EXERCISESTEP 257
+  
+  srandom (time (NULL));
+  
+  while (1) {
+    u_int16_t ospfd, isisd, lib, in_csum, in_csum_res, in_csum_rfc;
+    int i,j;
+
+    exercise += EXERCISESTEP;
+    exercise %= MAXDATALEN;
+    
+    for (i = 0; i < exercise; i += sizeof (long int)) {
+      long int rand = random ();
+      
+      for (j = sizeof (long int); j > 0; j--)
+        buffer[i + (sizeof (long int) - j)] = (rand >> (j * 8)) & 0xff;
+    }
+    
+    in_csum = in_cksum(buffer, exercise);
+    in_csum_res = in_cksum_optimized(buffer, exercise);
+    in_csum_rfc = in_cksum_rfc(buffer, exercise);
+    if (in_csum_res != in_csum || in_csum != in_csum_rfc)
+      printf ("verify: in_chksum failed in_csum:%x, in_csum_res:%x,"
+             "in_csum_rfc %x, len:%d\n", 
+             in_csum, in_csum_res, in_csum_rfc, exercise);
+
+    ospfd = ospfd_checksum (buffer, exercise + sizeof(u_int16_t), exercise);
+    if (verify (buffer, exercise + sizeof(u_int16_t)))
+      printf ("verify: ospfd failed\n");
+    isisd = iso_csum_create (buffer, exercise + sizeof(u_int16_t), exercise);
+    if (verify (buffer, exercise + sizeof(u_int16_t)))
+      printf ("verify: isisd failed\n");
+    lib = fletcher_checksum (buffer, exercise + sizeof(u_int16_t), exercise);
+    if (verify (buffer, exercise + sizeof(u_int16_t)))
+      printf ("verify: lib failed\n");
+    
+    if (ospfd != lib) {
+      printf ("Mismatch in values at size %u\n"
+              "ospfd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n"
+              "isisd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n"
+              "lib: 0x%04x\n",
+              exercise,
+              ospfd, ospfd_vals.a.c0, ospfd_vals.a.c1, ospfd_vals.x, ospfd_vals.y,
+              isisd, isisd_vals.a.c0, isisd_vals.a.c1, isisd_vals.x, isisd_vals.y,
+              lib
+              );
+      
+      /* Investigate reduction phase discrepencies */
+      if (ospfd_vals.a.c0 == isisd_vals.a.c0
+          && ospfd_vals.a.c1 == isisd_vals.a.c1) {
+        printf ("\n");
+        for (i = 0; reducts[i].name != NULL; i++) {    
+          ospfd = reducts[i].f (&ospfd_vals,
+                                exercise + sizeof (u_int16_t),
+                                exercise);
+          printf ("%20s: x: %02x, y %02x, checksum 0x%04x\n",
+                  reducts[i].name, ospfd_vals.x & 0xff, ospfd_vals.y & 0xff, ospfd);
+        }
+      }
+              
+      printf ("\n  u_char testdata [] = {\n  ");
+      for (i = 0; i < exercise; i++) {
+        printf ("0x%02x,%s",
+                buffer[i],
+                (i + 1) % 8 ? " " : "\n  ");
+      }
+      printf ("\n}\n");
+      exit (1);
+    }
+  }
+}
diff --git a/tests/lib/test_heavy.c b/tests/lib/test_heavy.c
new file mode 100644 (file)
index 0000000..6ba8d9a
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * $Id: heavy.c,v 1.3 2005/04/25 16:42:24 paul Exp $
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* This programme shows the effects of 'heavy' long-running functions
+ * on the cooperative threading model.
+ *
+ * Run it with a config file containing 'password whatever', telnet to it
+ * (it defaults to port 4000) and enter the 'clear foo string' command.
+ * then type whatever and observe that the vty interface is unresponsive
+ * for quite a period of time, due to the clear_something command
+ * taking a very long time to complete.
+ */
+#include <zebra.h>
+
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "memory.h"
+#include <math.h>
+
+#include "tests.h"
+
+enum
+{
+  ITERS_FIRST = 0,
+  ITERS_ERR = 100,
+  ITERS_LATER = 400,
+  ITERS_PRINT = 10,
+  ITERS_MAX = 1000,
+};
+
+static void
+slow_func (struct vty *vty, const char *str, const int i)
+{
+  double x = 1;
+  int j;
+  
+  for (j = 0; j < 300; j++)
+    x += sin(x)*j;
+  
+  if ((i % ITERS_LATER) == 0)
+    printf ("%s: %d, temporary error, save this somehow and do it later..\n", 
+            __func__, i);
+  
+  if ((i % ITERS_ERR) == 0)
+    printf ("%s: hard error\n", __func__);
+  
+  if ((i % ITERS_PRINT) == 0)
+    printf ("%s did %d, x = %g%s", str, i, x, VTY_NEWLINE);  
+}
+
+static void
+clear_something (struct vty *vty, const char *str)
+{
+  int i;
+  
+  /* this could be like iterating through 150k of route_table 
+   * or worse, iterating through a list of peers, to bgp_stop them with
+   * each having 150k route tables to process...
+   */
+  for (i = ITERS_FIRST; i < ITERS_MAX; i++)
+    slow_func (vty, str, i);
+}
+
+DEFUN (clear_foo,
+       clear_foo_cmd,
+       "clear foo LINE...",
+       "clear command\n"
+       "arbitrary string\n")
+{
+  char *str;
+  if (!argc)
+    {
+      vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  
+  str = argv_concat (argv, argc, 0);
+  
+  clear_something (vty, str);
+  XFREE (MTYPE_TMP, str);
+  return CMD_SUCCESS;
+}
+
+static void
+slow_vty_init()
+{
+  install_element (VIEW_NODE, &clear_foo_cmd);
+}
+
+void
+test_init()
+{
+  slow_vty_init();
+}
diff --git a/tests/lib/test_heavy_thread.c b/tests/lib/test_heavy_thread.c
new file mode 100644 (file)
index 0000000..c43fa76
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * $Id: heavy-thread.c,v 1.2 2005/04/25 16:42:24 paul Exp $
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* This programme shows the effects of 'heavy' long-running functions
+ * on the cooperative threading model, as demonstrated by heavy.c, and how
+ * they can be mitigated using a background thread.
+ *
+ * Run it with a config file containing 'password whatever', telnet to it
+ * (it defaults to port 4000) and enter the 'clear foo string' command.
+ * then type whatever and observe that, unlike heavy.c, the vty interface
+ * remains responsive.
+ */
+#include <zebra.h>
+#include <math.h>
+
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "memory.h"
+#include "log.h"
+
+#include "tests.h"
+
+extern struct thread_master *master;
+
+enum
+{
+  ITERS_FIRST = 0,
+  ITERS_ERR = 100,
+  ITERS_LATER = 400,
+  ITERS_PRINT = 10,
+  ITERS_MAX = 1000,
+};
+
+struct work_state {
+  struct vty *vty;
+  char *str;
+  int i;
+};
+
+static void
+slow_func (struct vty *vty, const char *str, const int i)
+{
+  double x = 1;
+  int j;
+  
+  for (j = 0; j < 300; j++)
+    x += sin(x)*j;
+  
+  if ((i % ITERS_LATER) == 0)
+    printf ("%s: %d, temporary error, save this somehow and do it later..\n",
+            __func__, i);
+  
+  if ((i % ITERS_ERR) == 0)
+    printf ("%s: hard error\n", __func__);
+  
+  if ((i % ITERS_PRINT) == 0)
+    printf ("%s did %d, x = %g\n", str, i, x);
+}
+
+static int
+clear_something (struct thread *thread)
+{
+  struct work_state *ws = THREAD_ARG(thread);
+  
+  /* this could be like iterating through 150k of route_table 
+   * or worse, iterating through a list of peers, to bgp_stop them with
+   * each having 150k route tables to process...
+   */
+  while (ws->i < ITERS_MAX)
+    {
+      slow_func(ws->vty, ws->str, ws->i);
+      ws->i++;
+      if (thread_should_yield(thread))
+        {
+         thread_add_background(master, clear_something, ws, 0);
+         return 0;
+        }
+    }
+  
+  /* All done! */
+  XFREE (MTYPE_TMP, ws->str);
+  XFREE (MTYPE_TMP, ws);
+  return 0;
+}
+
+DEFUN (clear_foo,
+       clear_foo_cmd,
+       "clear foo LINE...",
+       "clear command\n"
+       "arbitrary string\n")
+{
+  char *str;
+  struct work_state *ws;
+
+  if (!argc)
+    {
+      vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  
+  str = argv_concat (argv, argc, 0);
+  
+  if ((ws = XMALLOC(MTYPE_TMP, sizeof(*ws))) == NULL)
+    {
+      zlog_err ("%s: unable to allocate work_state", __func__);
+      return CMD_WARNING;
+    }
+  
+  if (!(ws->str = XSTRDUP (MTYPE_TMP, str)))
+    {
+      zlog_err ("%s: unable to xstrdup", __func__);
+      XFREE (MTYPE_TMP, ws);
+      return CMD_WARNING;
+    }
+  
+  ws->vty = vty;
+  ws->i = ITERS_FIRST;
+
+  thread_add_background(master, clear_something, ws, 0);
+
+  return CMD_SUCCESS;
+}
+
+void
+test_init()
+{
+  install_element (VIEW_NODE, &clear_foo_cmd);
+}
diff --git a/tests/lib/test_heavy_wq.c b/tests/lib/test_heavy_wq.c
new file mode 100644 (file)
index 0000000..97371fa
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* This programme shows the effects of 'heavy' long-running functions
+ * on the cooperative threading model.
+ *
+ * Run it with a config file containing 'password whatever', telnet to it
+ * (it defaults to port 4000) and enter the 'clear foo string' command.
+ * then type whatever and observe that the vty interface is unresponsive
+ * for quite a period of time, due to the clear_something command
+ * taking a very long time to complete.
+ */
+#include <zebra.h>
+
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "memory.h"
+#include "log.h"
+#include "workqueue.h"
+#include <math.h>
+
+#include "tests.h"
+
+DEFINE_MGROUP(TEST_HEAVYWQ, "heavy-wq test")
+DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE, "heavy_wq_node")
+DEFINE_MTYPE_STATIC(TEST_HEAVYWQ, WQ_NODE_STR, "heavy_wq_node->str")
+
+extern struct thread_master *master;
+static struct work_queue *heavy_wq;
+
+struct heavy_wq_node
+{
+  char *str;
+  int i;
+};
+
+enum
+{
+  ITERS_FIRST = 0,
+  ITERS_ERR = 100,
+  ITERS_LATER = 400,
+  ITERS_PRINT = 10,
+  ITERS_MAX = 1000,
+};
+
+static void
+heavy_wq_add (struct vty *vty, const char *str, int i)
+{
+  struct heavy_wq_node *hn;
+
+  if ((hn = XCALLOC (MTYPE_WQ_NODE, sizeof(struct heavy_wq_node))) == NULL)
+    {
+      zlog_err ("%s: unable to allocate hn", __func__);
+      return;
+    }
+  
+  hn->i = i;
+  if (!(hn->str = XSTRDUP (MTYPE_WQ_NODE_STR, str)))
+    {
+      zlog_err ("%s: unable to xstrdup", __func__);
+      XFREE (MTYPE_WQ_NODE, hn);
+      return;
+    }
+  
+  work_queue_add (heavy_wq, hn);
+  
+  return;
+}
+
+static void
+slow_func_err (struct work_queue *wq, struct work_queue_item *item)
+{
+  printf ("%s: running error function\n", __func__);
+}
+
+static void
+slow_func_del (struct work_queue *wq, void *data)
+{
+  struct heavy_wq_node *hn = data;
+  assert (hn && hn->str);
+  printf ("%s: %s\n", __func__, hn->str);
+  XFREE (MTYPE_WQ_NODE_STR, hn->str);
+  hn->str = NULL;  
+  XFREE(MTYPE_WQ_NODE, hn);
+}
+
+static wq_item_status
+slow_func (struct work_queue *wq, void *data)
+{
+  struct heavy_wq_node *hn = data;
+  double x = 1;
+  int j;
+  
+  assert (hn && hn->str);
+  
+  for (j = 0; j < 300; j++)
+    x += sin(x)*j;
+  
+  if ((hn->i % ITERS_LATER) == 0)
+    return WQ_RETRY_LATER;
+  
+  if ((hn->i % ITERS_ERR) == 0)
+    return WQ_RETRY_NOW;
+  
+  if ((hn->i % ITERS_PRINT) == 0)
+    printf ("%s did %d, x = %g\n", hn->str, hn->i, x);
+
+  return WQ_SUCCESS;
+}
+
+static void
+clear_something (struct vty *vty, const char *str)
+{
+  int i;
+  
+  /* this could be like iterating through 150k of route_table 
+   * or worse, iterating through a list of peers, to bgp_stop them with
+   * each having 150k route tables to process...
+   */
+  for (i = ITERS_FIRST; i < ITERS_MAX; i++)
+    heavy_wq_add (vty, str, i);
+}
+
+DEFUN (clear_foo,
+       clear_foo_cmd,
+       "clear foo LINE...",
+       "clear command\n"
+       "arbitrary string\n")
+{
+  char *str;
+  if (!argc)
+    {
+      vty_out (vty, "%% string argument required%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  
+  str = argv_concat (argv, argc, 0);
+  
+  clear_something (vty, str);
+  XFREE (MTYPE_TMP, str);
+  return CMD_SUCCESS;
+}
+
+static int
+heavy_wq_init ()
+{
+  if (! (heavy_wq = work_queue_new (master, "heavy_work_queue")))
+    {
+      zlog_err ("%s: could not get new work queue!", __func__);
+      return -1;
+    }
+  
+  heavy_wq->spec.workfunc = &slow_func;
+  heavy_wq->spec.errorfunc = &slow_func_err;
+  heavy_wq->spec.del_item_data = &slow_func_del;
+  heavy_wq->spec.max_retries = 3;
+  heavy_wq->spec.hold = 1000;
+  
+  return 0;
+}
+
+void
+test_init()
+{
+  install_element (VIEW_NODE, &clear_foo_cmd);
+  heavy_wq_init();
+}
diff --git a/tests/lib/test_memory.c b/tests/lib/test_memory.c
new file mode 100644 (file)
index 0000000..6849b9d
--- /dev/null
@@ -0,0 +1,125 @@
+/* 
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+#include <memory.h>
+
+DEFINE_MGROUP(TEST_MEMORY, "memory test")
+DEFINE_MTYPE_STATIC(TEST_MEMORY, TEST, "generic test mtype")
+
+/* Memory torture tests
+ *
+ * Tests below are generic but comments are focused on interaction with
+ * Paul's proposed memory 'quick' cache, which may never be included in
+ * CVS
+ */
+
+struct thread_master *master;
+
+#if 0 /* set to 1 to use system alloc directly */
+#undef XMALLOC
+#undef XCALLOC
+#undef XREALLOC
+#undef XFREE
+#define XMALLOC(T,S) malloc((S))
+#define XCALLOC(T,S) calloc(1, (S))
+#define XREALLOC(T,P,S) realloc((P),(S))
+#define XFREE(T,P) free((P))
+#endif
+
+#define TIMES 10
+
+int
+main(int argc, char **argv)
+{
+  void *a[10];
+  int i;
+
+  printf ("malloc x, malloc x, free, malloc x, free free\n\n");
+  /* simple case, test cache */
+  for (i = 0; i < TIMES; i++)
+    {
+      a[0] = XMALLOC (MTYPE_TEST, 1024);
+      memset (a[0], 1, 1024);
+      a[1] = XMALLOC (MTYPE_TEST, 1024);
+      memset (a[1], 1, 1024);
+      XFREE(MTYPE_TEST, a[0]); /* should go to cache */
+      a[0] = XMALLOC (MTYPE_TEST, 1024); /* should be satisfied from cache */
+      XFREE(MTYPE_TEST, a[0]);
+      XFREE(MTYPE_TEST, a[1]);
+    }
+  
+  printf ("malloc x, malloc y, free x, malloc y, free free\n\n");
+  /* cache should go invalid, valid, invalid, etc.. */
+  for (i = 0; i < TIMES; i++)
+    {
+      a[0] = XMALLOC (MTYPE_TEST, 512);
+      memset (a[0], 1, 512);
+      a[1] = XMALLOC (MTYPE_TEST, 1024); /* invalidate cache */
+      memset (a[1], 1, 1024);
+      XFREE(MTYPE_TEST, a[0]);
+      a[0] = XMALLOC (MTYPE_TEST, 1024);
+      XFREE(MTYPE_TEST, a[0]);
+      XFREE(MTYPE_TEST, a[1]);
+      /* cache should become valid again on next request */
+    }
+
+  printf ("calloc\n\n");
+  /* test calloc */
+  for (i = 0; i < TIMES; i++)
+    {
+      a[0] = XCALLOC (MTYPE_TEST, 1024);
+      memset (a[0], 1, 1024);
+      a[1] = XCALLOC (MTYPE_TEST, 512); /* invalidate cache */
+      memset (a[1], 1, 512);
+      XFREE(MTYPE_TEST, a[1]);
+      XFREE(MTYPE_TEST, a[0]);
+      /* alloc == 0, cache can become valid again on next request */
+    }
+  
+  printf ("calloc and realloc\n\n");
+  /* check calloc + realloc */
+  for (i = 0; i < TIMES; i++)
+    {
+      printf ("calloc a0 1024\n");
+      a[0] = XCALLOC (MTYPE_TEST, 1024);
+      memset (a[0], 1, 1024/2);
+      
+      printf ("calloc 1 1024\n");
+      a[1] = XCALLOC (MTYPE_TEST, 1024);
+      memset (a[1], 1, 1024/2);
+      
+      printf ("realloc 0 1024\n");
+      a[3] = XREALLOC (MTYPE_TEST, a[0], 2048); /* invalidate cache */
+      if (a[3] != NULL)
+        a[0] = a[3];
+      memset (a[0], 1, 1024);
+      
+      printf ("calloc 2 512\n");
+      a[2] = XCALLOC (MTYPE_TEST, 512);
+      memset (a[2], 1, 512);
+      
+      printf ("free 1 0 2\n");
+      XFREE(MTYPE_TEST, a[1]);
+      XFREE(MTYPE_TEST, a[0]);
+      XFREE(MTYPE_TEST, a[2]);
+      /* alloc == 0, cache valid next request */
+    }
+  return 0;
+}
diff --git a/tests/lib/test_nexthop_iter.c b/tests/lib/test_nexthop_iter.c
new file mode 100644 (file)
index 0000000..2503793
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Recursive Nexthop Iterator test.
+ * This tests the ALL_NEXTHOPS_RO macro.
+ *
+ * Copyright (C) 2012 by Open Source Routing.
+ * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+#include "zebra/rib.h"
+#include "prng.h"
+
+struct thread_master *master;
+static int verbose;
+
+static void
+str_append(char **buf, const char *repr)
+{
+  if (*buf)
+    {
+      *buf = realloc(*buf, strlen(*buf) + strlen(repr) + 1);
+      assert(*buf);
+      strncpy((*buf) + strlen(*buf), repr, strlen(repr) + 1);
+    }
+  else
+    {
+      *buf = strdup(repr);
+      assert(*buf);
+    }
+}
+
+static void
+str_appendf(char **buf, const char *format, ...)
+{
+  va_list ap;
+  int rv;
+  char *pbuf;
+
+  va_start(ap, format);
+  rv = vasprintf(&pbuf, format, ap);
+  va_end(ap);
+  assert(rv >= 0);
+
+  str_append(buf, pbuf);
+  free(pbuf);
+}
+
+/* This structure contains a nexthop chain
+ * and its expected representation */
+struct nexthop_chain
+{
+  /* Head of the chain */
+  struct nexthop *head;
+  /* Last nexthop in top chain */
+  struct nexthop *current_top;
+  /* Last nexthop in current recursive chain */
+  struct nexthop *current_recursive;
+  /* Expected string representation. */
+  char *repr;
+};
+
+static struct nexthop_chain*
+nexthop_chain_new(void)
+{
+  struct nexthop_chain *rv;
+
+  rv = calloc(sizeof(*rv), 1);
+  assert(rv);
+  return rv;
+}
+
+static void
+nexthop_chain_add_top(struct nexthop_chain *nc)
+{
+  struct nexthop *nh;
+
+  nh = calloc(sizeof(*nh), 1);
+  assert(nh);
+
+  if (nc->head)
+    {
+      nc->current_top->next = nh;
+      nh->prev = nc->current_top;
+      nc->current_top = nh;
+    }
+  else
+    {
+      nc->head = nc->current_top = nh;
+    }
+  nc->current_recursive = NULL;
+  str_appendf(&nc->repr, "%p\n", nh);
+}
+
+static void
+nexthop_chain_add_recursive(struct nexthop_chain *nc)
+{
+  struct nexthop *nh;
+
+  nh = calloc(sizeof(*nh), 1);
+  assert(nh);
+
+  assert(nc->current_top);
+  if (nc->current_recursive)
+    {
+      nc->current_recursive->next = nh;
+      nh->prev = nc->current_recursive;
+      nc->current_recursive = nh;
+    }
+  else
+    {
+      SET_FLAG(nc->current_top->flags, NEXTHOP_FLAG_RECURSIVE);
+      nc->current_top->resolved = nh;
+      nc->current_recursive = nh;
+    }
+  str_appendf(&nc->repr, "  %p\n", nh);
+}
+
+static void
+nexthop_chain_clear(struct nexthop_chain *nc)
+{
+  struct nexthop *tcur, *tnext;
+
+  for (tcur = nc->head; tcur; tcur = tnext)
+    {
+      tnext = tcur->next;
+      if (CHECK_FLAG(tcur->flags, NEXTHOP_FLAG_RECURSIVE))
+        {
+          struct nexthop *rcur, *rnext;
+          for (rcur = tcur->resolved; rcur; rcur = rnext)
+            {
+              rnext = rcur->next;
+              free(rcur);
+            }
+        }
+      free(tcur);
+    }
+  nc->head = nc->current_top = nc->current_recursive = NULL;
+  free(nc->repr);
+  nc->repr = NULL;
+}
+
+static void
+nexthop_chain_free(struct nexthop_chain *nc)
+{
+  if (!nc)
+    return;
+  nexthop_chain_clear(nc);
+  free(nc);
+}
+
+/* This function builds a string representation of
+ * the nexthop chain using the ALL_NEXTHOPS_RO macro.
+ * It verifies that the ALL_NEXTHOPS_RO macro iterated
+ * correctly over the nexthop chain by comparing the
+ * generated representation with the expected representation.
+ */
+static void
+nexthop_chain_verify_iter(struct nexthop_chain *nc)
+{
+  struct nexthop *nh, *tnh;
+  int recursing;
+  char *repr = NULL;
+
+  for (ALL_NEXTHOPS_RO(nc->head, nh, tnh, recursing))
+    {
+      if (recursing)
+        str_appendf(&repr, "  %p\n", nh);
+      else
+        str_appendf(&repr, "%p\n", nh);
+    }
+
+  if (repr && verbose)
+    printf("===\n%s", repr);
+  assert((!repr && !nc->repr) || (repr && nc->repr && !strcmp(repr, nc->repr)));
+  free(repr);
+}
+
+/* This test run builds a simple nexthop chain
+ * with some recursive nexthops and verifies that
+ * the iterator works correctly in each stage along
+ * the way.
+ */
+static void
+test_run_first(void)
+{
+  struct nexthop_chain *nc;
+
+  nc = nexthop_chain_new();
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_top(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_top(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_recursive(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_recursive(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_top(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_top(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_top(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_recursive(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_recursive(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_add_recursive(nc);
+  nexthop_chain_verify_iter(nc);
+
+  nexthop_chain_free(nc);
+}
+
+/* This test run builds numerous random
+ * nexthop chain configurations and verifies
+ * that the iterator correctly progresses
+ * through each. */
+static void
+test_run_prng(void)
+{
+  struct nexthop_chain *nc;
+  struct prng *prng;
+  int i;
+
+  nc = nexthop_chain_new();
+  prng = prng_new(0);
+
+  for (i = 0; i < 1000000; i++)
+    {
+      switch (prng_rand(prng) % 10)
+        {
+        case 0:
+          nexthop_chain_clear(nc);
+          break;
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+          nexthop_chain_add_top(nc);
+          break;
+        case 6:
+        case 7:
+        case 8:
+        case 9:
+          if (nc->current_top)
+            nexthop_chain_add_recursive(nc);
+          break;
+        }
+      nexthop_chain_verify_iter(nc);
+    }
+  nexthop_chain_free(nc);
+  prng_free(prng);
+}
+
+int main(int argc, char **argv)
+{
+  if (argc >= 2 && !strcmp("-v", argv[1]))
+    verbose = 1;
+  test_run_first();
+  printf("Simple test passed.\n");
+  test_run_prng();
+  printf("PRNG test passed.\n");
+}
diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c
new file mode 100644 (file)
index 0000000..c6ccc28
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * $Id: test-privs.c,v 1.1 2005/10/11 03:48:28 paul Exp $
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include <lib/version.h>
+#include "getopt.h"
+#include "privs.h"
+#include "memory.h"
+#include "memory_vty.h"
+
+zebra_capabilities_t _caps_p [] = 
+{
+  ZCAP_NET_RAW,
+  ZCAP_BIND,
+  ZCAP_NET_ADMIN,
+  ZCAP_DAC_OVERRIDE,
+};
+
+struct zebra_privs_t test_privs =
+{
+#if defined(FRR_USER) && defined(FRR_GROUP)
+  .user = FRR_USER,
+  .group = FRR_GROUP,
+#endif
+#if defined(VTY_GROUP)
+  .vty_group = VTY_GROUP,
+#endif
+  .caps_p = _caps_p,
+  .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
+  .cap_num_i = 0
+};
+
+struct option longopts[] = 
+{
+  { "help",        no_argument,       NULL, 'h'},
+  { "user",        required_argument, NULL, 'u'},
+  { "group",       required_argument, NULL, 'g'},
+  { 0 }
+};
+
+/* Help information display. */
+static void
+usage (char *progname, int status)
+{
+  if (status != 0)
+    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
+  else
+    {    
+      printf ("Usage : %s [OPTION...]\n\
+Daemon which does 'slow' things.\n\n\
+-u, --user         User to run as\n\
+-g, --group        Group to run as\n\
+-h, --help         Display this help and exit\n\
+\n\
+Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
+    }
+  exit (status);
+}
+
+struct thread_master *master;
+/* main routine. */
+int
+main (int argc, char **argv)
+{
+  char *p;
+  char *progname;
+  struct zprivs_ids_t ids;
+  
+  /* Set umask before anything for security */
+  umask (0027);
+
+  /* get program name */
+  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
+
+  while (1) 
+    {
+      int opt;
+
+      opt = getopt_long (argc, argv, "hu:g:", longopts, 0);
+    
+      if (opt == EOF)
+       break;
+
+      switch (opt) 
+       {
+       case 0:
+         break;
+        case 'u':
+          test_privs.user = optarg;
+          break;
+        case 'g':
+          test_privs.group = optarg;
+          break;
+       case 'h':
+         usage (progname, 0);
+         break;
+       default:
+         usage (progname, 1);
+         break;
+       }
+    }
+
+  /* Library inits. */
+  memory_init ();
+  zprivs_init (&test_privs);
+
+#define PRIV_STATE() \
+  ((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered")
+  
+  printf ("%s\n", PRIV_STATE());
+  test_privs.change(ZPRIVS_RAISE);
+  
+  printf ("%s\n", PRIV_STATE());
+  test_privs.change(ZPRIVS_LOWER);
+  
+  printf ("%s\n", PRIV_STATE());
+  zprivs_get_ids (&ids);  
+  
+  /* terminate privileges */
+  zprivs_terminate(&test_privs);
+  
+  /* but these should continue to work... */
+  printf ("%s\n", PRIV_STATE());
+  test_privs.change(ZPRIVS_RAISE);
+  
+  printf ("%s\n", PRIV_STATE());
+  test_privs.change(ZPRIVS_LOWER);
+  
+  printf ("%s\n", PRIV_STATE());
+  zprivs_get_ids (&ids);  
+  
+  printf ("terminating\n");
+  return 0;
+}
diff --git a/tests/lib/test_segv.c b/tests/lib/test_segv.c
new file mode 100644 (file)
index 0000000..1810c5f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * SEGV / backtrace handling test.
+ *
+ * copied from test-sig.c
+ *
+ * Copyright (C) 2013 by David Lamparter, Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+#include <sigevent.h>
+#include "lib/log.h"
+#include "lib/memory.h"
+
+struct quagga_signal_t sigs[] = 
+{
+};
+
+struct thread_master *master;
+
+static int
+threadfunc (struct thread *thread)
+{
+  int *null = NULL;
+  *null += 1;
+  return 0;
+}
+
+int
+main (void)
+{
+  master = thread_master_create ();
+  signal_init (master, array_size(sigs), sigs);
+
+  zlog_default = openzlog("testsegv", ZLOG_NONE, 0,
+                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
+  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
+  zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
+  zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
+
+  thread_execute (master, threadfunc, 0, 0);
+
+  exit (0);
+}
diff --git a/tests/lib/test_sig.c b/tests/lib/test_sig.c
new file mode 100644 (file)
index 0000000..4a04240
--- /dev/null
@@ -0,0 +1,78 @@
+/* 
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+#include <sigevent.h>
+#include "lib/log.h"
+#include "lib/memory.h"
+
+static void
+sighup (void)
+{
+  printf ("processed hup\n");
+}
+
+static void
+sigusr1 (void)
+{
+  printf ("processed usr1\n");
+}
+
+static void
+sigusr2 (void)
+{
+  printf ("processed usr2\n");
+}
+
+struct quagga_signal_t sigs[] = 
+{
+  {
+    .signal = SIGHUP,
+    .handler = &sighup,
+  },
+  {
+    .signal = SIGUSR1,
+    .handler = &sigusr1,
+  },
+  {
+    .signal = SIGUSR2,
+    .handler = &sigusr2,
+  }
+};
+
+struct thread_master *master;
+struct thread t;
+
+int
+main (void)
+{
+  master = thread_master_create ();
+  signal_init (master, array_size(sigs), sigs);
+  
+  zlog_default = openzlog("testsig", ZLOG_NONE, 0,
+                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
+  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
+  zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
+  zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
+  
+  while (thread_fetch (master, &t))
+    thread_call (&t);
+
+  exit (0);
+}
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c
new file mode 100644 (file)
index 0000000..cfc2deb
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * Test srcdest table for correctness.
+ *
+ * Copyright (C) 2017 by David Lamparter & Christian Franke,
+ *                       Open Source Routing / NetDEF Inc.
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FRR; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "hash.h"
+#include "memory.h"
+#include "prefix.h"
+#include "prng.h"
+#include "srcdest_table.h"
+#include "table.h"
+
+/* Copied from ripngd/ripng_nexthop.h - maybe the whole s6_addr32 thing
+ * should be added by autoconf if not present?
+ */
+#ifndef s6_addr32
+#if defined(SUNOS_5)
+/* Some SunOS define s6_addr32 only to kernel */
+#define s6_addr32 _S6_un._S6_u32
+#else
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif /* SUNOS_5 */
+#endif /*s6_addr32*/
+
+struct thread_master *master;
+
+/* This structure is copied from lib/srcdest_table.c to which it is
+ * private as far as other parts of Quagga are concerned.
+ */
+struct srcdest_rnode
+{
+  /* must be first in structure for casting to/from route_node */
+  ROUTE_NODE_FIELDS;
+
+  struct route_table *src_table;
+};
+
+struct test_state
+{
+  struct route_table *table;
+  struct hash *log;
+};
+
+static char *
+format_srcdest(const struct prefix_ipv6 *dst_p,
+               const struct prefix_ipv6 *src_p)
+{
+  char dst_str[BUFSIZ];
+  char src_str[BUFSIZ];
+  char *rv;
+  int ec;
+
+  prefix2str((const struct prefix*)dst_p, dst_str, sizeof(dst_str));
+  if (src_p && src_p->prefixlen)
+    prefix2str((const struct prefix*)src_p, src_str, sizeof(src_str));
+  else
+    src_str[0] = '\0';
+
+  ec = asprintf(&rv, "%s%s%s", dst_str,
+                (src_str[0] != '\0') ? " from " : "",
+                src_str);
+
+  assert(ec > 0);
+  return rv;
+}
+
+static unsigned int log_key(void *data)
+{
+  struct prefix *hash_entry = data;
+  struct prefix_ipv6 *dst_p = (struct prefix_ipv6*) &hash_entry[0];
+  struct prefix_ipv6 *src_p = (struct prefix_ipv6*) &hash_entry[1];
+  unsigned int hash = 0;
+  unsigned int i;
+
+  hash = (hash * 33) ^ (unsigned int)dst_p->prefixlen;
+  for (i = 0; i < 4; i++)
+    hash = (hash * 33) ^ (unsigned int)dst_p->prefix.s6_addr32[i];
+
+  hash = (hash * 33) ^ (unsigned int)src_p->prefixlen;
+  if (src_p->prefixlen)
+    for (i = 0; i < 4; i++)
+      hash = (hash * 33) ^ (unsigned int)src_p->prefix.s6_addr32[i];
+
+  return hash;
+}
+
+static int
+log_cmp(const void *a, const void *b)
+{
+  if (a == NULL && b != NULL)
+    return 0;
+  if (b == NULL && a != NULL)
+    return 0;
+
+  return !memcmp(a, b, 2 * sizeof(struct prefix));
+}
+
+static void
+log_free(void *data)
+{
+  XFREE(MTYPE_TMP, data);
+}
+
+static void *
+log_alloc(void *data)
+{
+  void *rv = XMALLOC(MTYPE_TMP, 2 * sizeof(struct prefix));
+  memcpy(rv, data, 2 * sizeof(struct prefix));
+  return rv;
+}
+
+static struct test_state *
+test_state_new(void)
+{
+  struct test_state *rv;
+
+  rv = XCALLOC(MTYPE_TMP, sizeof(*rv));
+  assert(rv);
+
+  rv->table = srcdest_table_init();
+  assert(rv->table);
+
+  rv->log = hash_create(log_key, log_cmp);
+  return rv;
+}
+
+static void
+test_state_free(struct test_state *test)
+{
+  route_table_finish(test->table);
+  hash_clean(test->log, log_free);
+  hash_free(test->log);
+  XFREE(MTYPE_TMP, test);
+}
+
+static void
+test_state_add_route(struct test_state *test,
+                     struct prefix_ipv6 *dst_p,
+                     struct prefix_ipv6 *src_p)
+{
+  struct route_node *rn = srcdest_rnode_get(
+      test->table, (struct prefix*)dst_p, src_p
+  );
+  struct prefix hash_entry[2];
+
+  memset(hash_entry, 0, sizeof(hash_entry));
+  memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
+  memcpy(&hash_entry[1], src_p, sizeof(*src_p));
+
+  if (rn->info) {
+    route_unlock_node(rn);
+    assert(hash_lookup(test->log, hash_entry) != NULL);
+    return;
+  } else {
+    assert(hash_lookup(test->log, hash_entry) == NULL);
+  }
+
+  rn->info = (void*) 0xdeadbeef;
+  hash_get(test->log, hash_entry, log_alloc);
+};
+
+static void
+test_state_del_route(struct test_state *test,
+                    struct prefix_ipv6 *dst_p,
+                    struct prefix_ipv6 *src_p)
+{
+  struct route_node *rn = srcdest_rnode_lookup(
+      test->table, (struct prefix*)dst_p, src_p
+  );
+  struct prefix hash_entry[2];
+
+  memset(hash_entry, 0, sizeof(hash_entry));
+  memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
+  memcpy(&hash_entry[1], src_p, sizeof(*src_p));
+
+  if (!rn) {
+    assert(!hash_lookup(test->log, hash_entry));
+    return;
+  }
+
+  assert(rn->info == (void*)0xdeadbeef);
+  rn->info = NULL;
+  route_unlock_node(rn);
+  route_unlock_node(rn);
+
+  struct prefix *hash_entry_intern = hash_release(test->log, hash_entry);
+  assert(hash_entry_intern != NULL);
+  XFREE(MTYPE_TMP, hash_entry_intern);
+}
+
+static void
+verify_log(struct hash_backet* backet, void *arg)
+{
+  struct test_state *test = arg;
+  struct prefix *hash_entry = backet->data;
+  struct prefix *dst_p = &hash_entry[0];
+  struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1];
+  struct route_node *rn = srcdest_rnode_lookup(test->table, dst_p, src_p);
+
+  assert(rn);
+  assert(rn->info == (void*)0xdeadbeef);
+
+  route_unlock_node(rn);
+}
+
+static void
+dump_log(struct hash_backet* backet, void *arg)
+{
+  struct prefix *hash_entry = backet->data;
+  struct prefix_ipv6 *dst_p = (struct prefix_ipv6*)&hash_entry[0];
+  struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1];
+  char *route_id = format_srcdest(dst_p, src_p);
+
+  fprintf(stderr, "  %s\n", route_id);
+  free(route_id);
+}
+
+static void
+test_dump(struct test_state *test)
+{
+  fprintf(stderr, "Contents of hash table:\n");
+  hash_iterate(test->log, dump_log, test);
+  fprintf(stderr, "\n");
+}
+
+static void
+test_failed(struct test_state *test, const char *message,
+            struct prefix_ipv6 *dst_p, struct prefix_ipv6 *src_p)
+{
+  char *route_id = format_srcdest(dst_p, src_p);
+
+  fprintf(stderr, "Test failed. Error: %s\n", message);
+  fprintf(stderr, "Route in question: %s\n", route_id);
+  free(route_id);
+
+  test_dump(test);
+  assert(3 == 4);
+}
+
+static void
+test_state_verify(struct test_state *test)
+{
+  struct route_node *rn;
+  struct prefix hash_entry[2];
+
+  memset(hash_entry, 0, sizeof(hash_entry));
+
+  /* Verify that there are no elements in the table which have never
+   * been added */
+  for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn))
+    {
+      struct prefix_ipv6 *dst_p, *src_p;
+
+      /* While we are iterating, we hold a lock on the current route_node,
+       * so all the lock counts we check for take that into account; in idle
+       * state all the numbers will be exactly one less.
+       *
+       * Also this makes quite some assumptions based on the current
+       * implementation details of route_table and srcdest_table - another
+       * valid implementation might trigger assertions here.
+       */
+
+      if (rnode_is_dstnode(rn))
+        {
+          struct srcdest_rnode *srn = (struct srcdest_rnode *)rn;
+          unsigned int expected_lock = 1; /* We are in the loop */
+
+          if (rn->info != NULL) /* The route node is not internal */
+            expected_lock++;
+          if (srn->src_table != NULL) /* There's a source table associated with rn */
+            expected_lock++;
+
+          if (rn->lock != expected_lock)
+            test_failed(test, "Dest rnode lock count doesn't match expected count!",
+                        (struct prefix_ipv6*)&rn->p, NULL);
+        }
+      else
+        {
+          unsigned int expected_lock = 1; /* We are in the loop */
+
+          if (rn->info != NULL) /* The route node is not internal */
+            expected_lock++;
+
+          if (rn->lock != expected_lock)
+            {
+              struct prefix_ipv6 *dst_p, *src_p;
+              srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p,
+                                         (struct prefix**)&src_p);
+
+              test_failed(test, "Src rnode lock count doesn't match expected count!",
+                          dst_p, src_p);
+            }
+        }
+
+      if (!rn->info)
+        continue;
+
+      assert(rn->info == (void*)0xdeadbeef);
+
+      srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p, (struct prefix**)&src_p);
+      memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
+      if (src_p)
+        memcpy(&hash_entry[1], src_p, sizeof(*src_p));
+      else
+        memset(&hash_entry[1], 0, sizeof(hash_entry[1]));
+
+      if (hash_lookup(test->log, hash_entry) == NULL)
+        test_failed(test, "Route is missing in hash", dst_p, src_p);
+    }
+
+  /* Verify that all added elements are still in the table */
+  hash_iterate(test->log, verify_log, test);
+}
+
+static void
+get_rand_prefix(struct prng *prng, struct prefix_ipv6 *p)
+{
+  int i;
+
+  memset(p, 0, sizeof(*p));
+
+  for (i = 0; i < 4; i++)
+    p->prefix.s6_addr32[i] = prng_rand(prng);
+  p->prefixlen = prng_rand(prng) % 129;
+  p->family = AF_INET6;
+
+  apply_mask((struct prefix*)p);
+}
+
+static void
+get_rand_prefix_pair(struct prng *prng, struct prefix_ipv6 *dst_p,
+                     struct prefix_ipv6 *src_p)
+{
+  get_rand_prefix(prng, dst_p);
+  if ((prng_rand(prng) % 4) == 0)
+    {
+      get_rand_prefix(prng, src_p);
+      if (src_p->prefixlen)
+        return;
+    }
+
+  memset(src_p, 0, sizeof(*src_p));
+}
+
+static void
+test_state_add_rand_route(struct test_state *test,
+                          struct prng *prng)
+{
+  struct prefix_ipv6 dst_p, src_p;
+
+  get_rand_prefix_pair(prng, &dst_p, &src_p);
+  test_state_add_route(test, &dst_p, &src_p);
+}
+
+static void
+test_state_del_rand_route(struct test_state *test,
+                          struct prng *prng)
+{
+  struct prefix_ipv6 dst_p, src_p;
+
+  get_rand_prefix_pair(prng, &dst_p, &src_p);
+  test_state_del_route(test, &dst_p, &src_p);
+}
+
+static void
+test_state_del_one_route(struct test_state *test,
+                        struct prng *prng)
+{
+  unsigned int which_route = prng_rand(prng) % test->log->count;
+  struct route_node *rn;
+  struct prefix *dst_p, *src_p;
+  struct prefix_ipv6 dst6_p, src6_p;
+
+  for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn))
+    {
+      if (!rn->info)
+        continue;
+      if (!which_route) {
+        route_unlock_node(rn);
+        break;
+      }
+      which_route--;
+    }
+
+  assert(rn);
+  srcdest_rnode_prefixes(rn, &dst_p, &src_p);
+  memcpy(&dst6_p, dst_p, sizeof(dst6_p));
+  if (src_p)
+    memcpy(&src6_p, src_p, sizeof(src6_p));
+  else
+    memset(&src6_p, 0, sizeof(src6_p));
+
+  test_state_del_route(test, &dst6_p, &src6_p);
+}
+
+static void
+run_prng_test(void)
+{
+  struct test_state *test = test_state_new();
+  struct prng *prng = prng_new(0);
+  size_t i;
+
+  for (i = 0; i < 1000; i++)
+    {
+      switch (prng_rand(prng) % 10)
+        {
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+          test_state_add_rand_route(test, prng);
+          break;
+        case 5:
+        case 6:
+        case 7:
+          test_state_del_one_route(test, prng);
+          break;
+        case 8:
+        case 9:
+          test_state_del_rand_route(test, prng);
+          break;
+        }
+      test_state_verify(test);
+    }
+
+  prng_free(prng);
+  test_state_free(test);
+}
+
+int main(int argc, char *argv[])
+{
+  run_prng_test();
+  printf("PRNG Test successful.\n");
+  return 0;
+}
diff --git a/tests/lib/test_stream.c b/tests/lib/test_stream.c
new file mode 100644 (file)
index 0000000..3ac45eb
--- /dev/null
@@ -0,0 +1,76 @@
+/* Simple stream test.
+ * 
+ * Copyright (C) 2006 Sun Microsystems, Inc.
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+#include <stream.h>
+#include <thread.h>
+
+static unsigned long long ham = 0xdeadbeefdeadbeef;
+struct thread_master *master;
+
+static void
+print_stream (struct stream *s)
+{
+  size_t getp = stream_get_getp (s);
+  
+  printf ("endp: %zu, readable: %zu, writeable: %zu\n",
+          stream_get_endp (s),
+          STREAM_READABLE (s),
+          STREAM_WRITEABLE (s));
+  
+  while (STREAM_READABLE (s))
+    {
+      printf ("0x%x ", *stream_pnt (s));
+      stream_forward_getp (s, 1);
+    }
+  
+  printf ("\n");
+  
+  /* put getp back to where it was */
+  stream_set_getp (s, getp);
+}
+
+int
+main (void)
+{
+  struct stream *s;
+  
+  s = stream_new (1024);
+  
+  stream_putc (s, ham);
+  stream_putw (s, ham);
+  stream_putl (s, ham);
+  stream_putq (s, ham);
+  
+  print_stream (s);
+  
+  stream_resize (s, stream_get_endp (s));
+  
+  print_stream (s);
+  
+  printf ("c: 0x%hhx\n", stream_getc (s));
+  printf ("w: 0x%hx\n", stream_getw (s));
+  printf ("l: 0x%x\n", stream_getl (s));
+  printf ("q: 0x%" PRIx64 "\n", stream_getq (s));
+  
+  return 0;
+}
diff --git a/tests/lib/test_stream.refout b/tests/lib/test_stream.refout
new file mode 100644 (file)
index 0000000..cf52e13
--- /dev/null
@@ -0,0 +1,8 @@
+endp: 15, readable: 15, writeable: 1009
+0xef 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 
+endp: 15, readable: 15, writeable: 0
+0xef 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 0xde 0xad 0xbe 0xef 
+c: 0xef
+w: 0xbeef
+l: 0xdeadbeef
+q: 0xdeadbeefdeadbeef
diff --git a/tests/lib/test_table.c b/tests/lib/test_table.c
new file mode 100644 (file)
index 0000000..4042e1a
--- /dev/null
@@ -0,0 +1,554 @@
+/*
+ * Routing table test
+ * Copyright (C) 2012 OSR.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include "prefix.h"
+#include "table.h"
+
+/*
+ * test_node_t
+ *
+ * Information that is kept for each node in the radix tree.
+ */
+typedef struct test_node_t_
+{
+
+  /*
+   * Human readable representation of the string. Allocated using
+   * malloc()/dup().
+   */
+  char *prefix_str;
+} test_node_t;
+
+struct thread_master *master;
+
+/*
+ * add_node
+ *
+ * Add the given prefix (passed in as a string) to the given table.
+ */
+static void
+add_node (struct route_table *table, const char *prefix_str)
+{
+  struct prefix_ipv4 p;
+  test_node_t *node;
+  struct route_node *rn;
+
+  assert (prefix_str);
+
+  if (str2prefix_ipv4 (prefix_str, &p) <= 0)
+    {
+      assert (0);
+    }
+
+  rn = route_node_get (table, (struct prefix *) &p);
+  if (rn->info)
+    {
+      assert (0);
+      return;
+    }
+
+  node = malloc (sizeof (test_node_t));
+  assert (node);
+  node->prefix_str = strdup (prefix_str);
+  assert (node->prefix_str);
+  rn->info = node;
+}
+
+/*
+ * add_nodes
+ *
+ * Convenience function to add a bunch of nodes together.
+ *
+ * The arguments must be prefixes in string format, with a NULL as the
+ * last argument.
+ */
+static void
+add_nodes (struct route_table *table, ...)
+{
+  va_list arglist;
+  char *prefix;
+
+  va_start (arglist, table);
+
+  prefix = va_arg (arglist, char *);
+  while (prefix)
+    {
+      add_node (table, prefix);
+      prefix = va_arg (arglist, char *);
+    }
+
+  va_end (arglist);
+}
+
+/*
+ * print_subtree
+ *
+ * Recursive function to print a route node and its children.
+ *
+ * @see print_table
+ */
+static void
+print_subtree (struct route_node *rn, const char *legend, int indent_level)
+{
+  char buf[PREFIX2STR_BUFFER];
+  int i;
+
+  /*
+   * Print this node first.
+   */
+  for (i = 0; i < indent_level; i++)
+    {
+      printf ("  ");
+    }
+
+  prefix2str (&rn->p, buf, sizeof (buf));
+  printf ("%s: %s", legend, buf);
+  if (!rn->info)
+    {
+      printf (" (internal)");
+    }
+  printf ("\n");
+  if (rn->l_left)
+    {
+      print_subtree (rn->l_left, "Left", indent_level + 1);
+    }
+  if (rn->l_right)
+    {
+      print_subtree (rn->l_right, "Right", indent_level + 1);
+    }
+}
+
+/*
+ * print_table
+ *
+ * Function that prints out the internal structure of a route table.
+ */
+static void
+print_table (struct route_table *table)
+{
+  struct route_node *rn;
+
+  rn = table->top;
+
+  if (!rn)
+    {
+      printf ("<Empty Table>\n");
+      return;
+    }
+
+  print_subtree (rn, "Top", 0);
+}
+
+/*
+ * clear_table
+ *
+ * Remove all nodes from the given table.
+ */
+static void
+clear_table (struct route_table *table)
+{
+  route_table_iter_t iter;
+  struct route_node *rn;
+  test_node_t *node;
+
+  route_table_iter_init (&iter, table);
+
+  while ((rn = route_table_iter_next (&iter)))
+    {
+      node = rn->info;
+      if (!node)
+       {
+         continue;
+       }
+      rn->info = NULL;
+      route_unlock_node (rn);
+      free (node->prefix_str);
+      free (node);
+    }
+
+  route_table_iter_cleanup (&iter);
+
+  assert (table->top == NULL);
+}
+
+/*
+ * verify_next_by_iterating
+ *
+ * Iterate over the tree to make sure that the first prefix after
+ * target_pfx is the expected one. Note that target_pfx may not be
+ * present in the tree.
+ */
+static void
+verify_next_by_iterating (struct route_table *table,
+                         struct prefix *target_pfx, struct prefix *next_pfx)
+{
+  route_table_iter_t iter;
+  struct route_node *rn;
+
+  route_table_iter_init (&iter, table);
+  while ((rn = route_table_iter_next (&iter)))
+    {
+      if (route_table_prefix_iter_cmp (&rn->p, target_pfx) > 0)
+       {
+         assert (!prefix_cmp (&rn->p, next_pfx));
+         break;
+       }
+    }
+
+  if (!rn)
+    {
+      assert (!next_pfx);
+    }
+
+  route_table_iter_cleanup (&iter);
+}
+
+/*
+ * verify_next
+ *
+ * Verifies that route_table_get_next() returns the expected result
+ * (result) for the prefix string 'target'.
+ */
+static void
+verify_next (struct route_table *table, const char *target, const char *next)
+{
+  struct prefix_ipv4 target_pfx, next_pfx;
+  struct route_node *rn;
+  char result_buf[PREFIX2STR_BUFFER];
+
+  if (str2prefix_ipv4 (target, &target_pfx) <= 0)
+    {
+      assert (0);
+    }
+
+  rn = route_table_get_next (table, (struct prefix *) &target_pfx);
+  if (rn)
+    {
+      prefix2str (&rn->p, result_buf, sizeof (result_buf));
+    }
+  else
+    {
+      snprintf (result_buf, sizeof (result_buf), "(Null)");
+    }
+
+  printf ("\n");
+  print_table (table);
+  printf ("Verifying successor of %s. Expected: %s, Result: %s\n", target,
+         next ? next : "(Null)", result_buf);
+
+  if (!rn)
+    {
+      assert (!next);
+      verify_next_by_iterating (table, (struct prefix *) &target_pfx, NULL);
+      return;
+    }
+
+  assert (next);
+
+  if (str2prefix_ipv4 (next, &next_pfx) <= 0)
+    {
+      assert (0);
+    }
+
+  if (prefix_cmp (&rn->p, (struct prefix *) &next_pfx))
+    {
+      assert (0);
+    }
+  route_unlock_node (rn);
+
+  verify_next_by_iterating (table, (struct prefix *) &target_pfx,
+                           (struct prefix *) &next_pfx);
+}
+
+/*
+ * test_get_next
+ */
+static void
+test_get_next (void)
+{
+  struct route_table *table;
+
+  printf ("\n\nTesting route_table_get_next()\n");
+  table = route_table_init ();
+
+  /*
+   * Target exists in tree, but has no successor.
+   */
+  add_nodes (table, "1.0.1.0/24", NULL);
+  verify_next (table, "1.0.1.0/24", NULL);
+  clear_table (table);
+
+  /*
+   * Target exists in tree, and there is a node in its left subtree.
+   */
+  add_nodes (table, "1.0.1.0/24", "1.0.1.0/25", NULL);
+  verify_next (table, "1.0.1.0/24", "1.0.1.0/25");
+  clear_table (table);
+
+  /*
+   * Target exists in tree, and there is a node in its right subtree.
+   */
+  add_nodes (table, "1.0.1.0/24", "1.0.1.128/25", NULL);
+  verify_next (table, "1.0.1.0/24", "1.0.1.128/25");
+  clear_table (table);
+
+  /*
+   * Target exists in the tree, next node is outside subtree.
+   */
+  add_nodes (table, "1.0.1.0/24", "1.1.0.0/16", NULL);
+  verify_next (table, "1.0.1.0/24", "1.1.0.0/16");
+  clear_table (table);
+
+  /*
+   * The target node does not exist in the tree for all the test cases
+   * below this point.
+   */
+
+  /*
+   * There is no successor in the tree.
+   */
+  add_nodes (table, "1.0.0.0/16", NULL);
+  verify_next (table, "1.0.1.0/24", NULL);
+  clear_table (table);
+
+  /*
+   * There exists a node that would be in the target's left subtree.
+   */
+  add_nodes (table, "1.0.0.0/16", "1.0.1.0/25", NULL);
+  verify_next (table, "1.0.1.0/24", "1.0.1.0/25");
+  clear_table (table);
+
+  /*
+   * There exists a node would be in the target's right subtree.
+   */
+  add_nodes (table, "1.0.0.0/16", "1.0.1.128/25", NULL);
+  verify_next (table, "1.0.1.0/24", "1.0.1.128/25");
+  clear_table (table);
+
+  /*
+   * A search for the target reaches a node where there are no child
+   * nodes in the direction of the target (left), but the node has a
+   * right child.
+   */
+  add_nodes (table, "1.0.0.0/16", "1.0.128.0/17", NULL);
+  verify_next (table, "1.0.0.0/17", "1.0.128.0/17");
+  clear_table (table);
+
+  /*
+   * A search for the target reaches a node with no children. We have
+   * to go upwards in the tree to find a successor.
+   */
+  add_nodes (table, "1.0.0.0/16", "1.0.0.0/24", "1.0.1.0/24",
+            "1.0.128.0/17", NULL);
+  verify_next (table, "1.0.1.0/25", "1.0.128.0/17");
+  clear_table (table);
+
+  /*
+   * A search for the target reaches a node where neither the node nor
+   * the target prefix contain each other.
+   *
+   * In first case below the node succeeds the target.
+   *
+   * In the second case, the node comes before the target, so we have
+   * to go up the tree looking for a successor.
+   */
+  add_nodes (table, "1.0.0.0/16", "1.0.1.0/24", NULL);
+  verify_next (table, "1.0.0.0/24", "1.0.1.0/24");
+  clear_table (table);
+
+  add_nodes (table, "1.0.0.0/16", "1.0.0.0/24", "1.0.1.0/25",
+            "1.0.128.0/17", NULL);
+  verify_next (table, "1.0.1.128/25", "1.0.128.0/17");
+  clear_table (table);
+
+  route_table_finish (table);
+}
+
+/*
+ * verify_prefix_iter_cmp
+ */
+static void
+verify_prefix_iter_cmp (const char *p1, const char *p2, int exp_result)
+{
+  struct prefix_ipv4 p1_pfx, p2_pfx;
+  int result;
+
+  if (str2prefix_ipv4 (p1, &p1_pfx) <= 0)
+    {
+      assert (0);
+    }
+
+  if (str2prefix_ipv4 (p2, &p2_pfx) <= 0)
+    {
+      assert (0);
+    }
+
+  result = route_table_prefix_iter_cmp ((struct prefix *) &p1_pfx,
+                                       (struct prefix *) &p2_pfx);
+
+  printf ("Verifying cmp(%s, %s) returns %d\n", p1, p2, exp_result);
+
+  assert (exp_result == result);
+
+  /*
+   * Also check the reverse comparision.
+   */
+  result = route_table_prefix_iter_cmp ((struct prefix *) &p2_pfx,
+                                       (struct prefix *) &p1_pfx);
+
+  if (exp_result)
+    {
+      exp_result = -exp_result;
+    }
+
+  printf ("Verifying cmp(%s, %s) returns %d\n", p1, p2, exp_result);
+  assert (result == exp_result);
+}
+
+/*
+ * test_prefix_iter_cmp
+ *
+ * Tests comparision of prefixes according to order of iteration.
+ */
+static void
+test_prefix_iter_cmp ()
+{
+  printf ("\n\nTesting route_table_prefix_iter_cmp()\n");
+
+  verify_prefix_iter_cmp ("1.0.0.0/8", "1.0.0.0/8", 0);
+
+  verify_prefix_iter_cmp ("1.0.0.0/8", "1.0.0.0/16", -1);
+
+  verify_prefix_iter_cmp ("1.0.0.0/16", "1.128.0.0/16", -1);
+}
+
+/*
+ * verify_iter_with_pause
+ *
+ * Iterates over a tree using two methods: 'normal' iteration, and an
+ * iterator that pauses at each node. Verifies that the two methods
+ * yield the same results.
+ */
+static void
+verify_iter_with_pause (struct route_table *table)
+{
+  unsigned long num_nodes;
+  struct route_node *rn, *iter_rn;
+  route_table_iter_t iter_space;
+  route_table_iter_t *iter = &iter_space;
+
+  route_table_iter_init (iter, table);
+  num_nodes = 0;
+
+  for (rn = route_top (table); rn; rn = route_next (rn))
+    {
+      num_nodes++;
+      route_table_iter_pause (iter);
+
+      assert (iter->current == NULL);
+      if (route_table_iter_started (iter))
+       {
+         assert (iter->state == RT_ITER_STATE_PAUSED);
+       }
+      else
+       {
+         assert (rn == table->top);
+         assert (iter->state == RT_ITER_STATE_INIT);
+       }
+
+      iter_rn = route_table_iter_next (iter);
+
+      /*
+       * Make sure both iterations return the same node.
+       */
+      assert (rn == iter_rn);
+    }
+
+  assert (num_nodes == route_table_count (table));
+
+  route_table_iter_pause (iter);
+  iter_rn = route_table_iter_next (iter);
+
+  assert (iter_rn == NULL);
+  assert (iter->state == RT_ITER_STATE_DONE);
+
+  assert (route_table_iter_next (iter) == NULL);
+  assert (iter->state == RT_ITER_STATE_DONE);
+
+  route_table_iter_cleanup (iter);
+
+  print_table (table);
+  printf ("Verified pausing iteration on tree with %lu nodes\n", num_nodes);
+}
+
+/*
+ * test_iter_pause
+ */
+static void
+test_iter_pause (void)
+{
+  struct route_table *table;
+  int i, num_prefixes;
+  const char *prefixes[] = {
+    "1.0.1.0/24",
+    "1.0.1.0/25",
+    "1.0.1.128/25",
+    "1.0.2.0/24",
+    "2.0.0.0/8"
+  };
+
+  num_prefixes = sizeof (prefixes) / sizeof (prefixes[0]);
+
+  printf ("\n\nTesting that route_table_iter_pause() works as expected\n");
+  table = route_table_init ();
+  for (i = 0; i < num_prefixes; i++)
+    {
+      add_nodes (table, prefixes[i], NULL);
+    }
+
+  verify_iter_with_pause (table);
+
+  clear_table (table);
+  route_table_finish (table);
+}
+
+/*
+ * run_tests
+ */
+static void
+run_tests (void)
+{
+  test_prefix_iter_cmp ();
+  test_get_next ();
+  test_iter_pause ();
+}
+
+/*
+ * main
+ */
+int
+main (void)
+{
+  run_tests ();
+}
diff --git a/tests/lib/test_timer_correctness.c b/tests/lib/test_timer_correctness.c
new file mode 100644 (file)
index 0000000..e523929
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Test program to verify that scheduled timers are executed in the
+ * correct order.
+ *
+ * Copyright (C) 2013 by Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "memory.h"
+#include "pqueue.h"
+#include "prng.h"
+#include "thread.h"
+
+#define SCHEDULE_TIMERS 800
+#define REMOVE_TIMERS   200
+
+#define TIMESTR_LEN strlen("4294967296.999999")
+
+struct thread_master *master;
+
+static size_t log_buf_len;
+static size_t log_buf_pos;
+static char *log_buf;
+
+static size_t expected_buf_len;
+static size_t expected_buf_pos;
+static char *expected_buf;
+
+static struct prng *prng;
+
+static struct thread **timers;
+
+static int timers_pending;
+
+static void terminate_test(void)
+{
+  int exit_code;
+
+  if (strcmp(log_buf, expected_buf))
+    {
+      fprintf(stderr, "Expected output and received output differ.\n");
+      fprintf(stderr, "---Expected output: ---\n%s", expected_buf);
+      fprintf(stderr, "---Actual output: ---\n%s", log_buf);
+      exit_code = 1;
+    }
+  else
+    {
+      printf("Expected output and actual output match.\n");
+      exit_code = 0;
+    }
+
+  thread_master_free(master);
+  XFREE(MTYPE_TMP, log_buf);
+  XFREE(MTYPE_TMP, expected_buf);
+  prng_free(prng);
+  XFREE(MTYPE_TMP, timers);
+
+  exit(exit_code);
+}
+
+static int timer_func(struct thread *thread)
+{
+  int rv;
+
+  rv = snprintf(log_buf + log_buf_pos, log_buf_len - log_buf_pos,
+                "%s\n", (char*)thread->arg);
+  assert(rv >= 0);
+  log_buf_pos += rv;
+  assert(log_buf_pos < log_buf_len);
+  XFREE(MTYPE_TMP, thread->arg);
+
+  timers_pending--;
+  if (!timers_pending)
+    terminate_test();
+
+  return 0;
+}
+
+static int cmp_timeval(const void* a, const void *b)
+{
+  const struct timeval *ta = *(struct timeval * const *)a;
+  const struct timeval *tb = *(struct timeval * const *)b;
+
+  if (timercmp(ta, tb, <))
+    return -1;
+  if (timercmp(ta, tb, >))
+    return 1;
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  int i, j;
+  struct thread t;
+  struct timeval **alarms;
+
+  master = thread_master_create();
+
+  log_buf_len = SCHEDULE_TIMERS * (TIMESTR_LEN + 1) + 1;
+  log_buf_pos = 0;
+  log_buf = XMALLOC(MTYPE_TMP, log_buf_len);
+
+  expected_buf_len = SCHEDULE_TIMERS * (TIMESTR_LEN + 1) + 1;
+  expected_buf_pos = 0;
+  expected_buf = XMALLOC(MTYPE_TMP, expected_buf_len);
+
+  prng = prng_new(0);
+
+  timers = XMALLOC(MTYPE_TMP, SCHEDULE_TIMERS * sizeof(*timers));
+
+  for (i = 0; i < SCHEDULE_TIMERS; i++)
+    {
+      long interval_msec;
+      int ret;
+      char *arg;
+
+      /* Schedule timers to expire in 0..5 seconds */
+      interval_msec = prng_rand(prng) % 5000;
+      arg = XMALLOC(MTYPE_TMP, TIMESTR_LEN + 1);
+      timers[i] = thread_add_timer_msec(master, timer_func, arg, interval_msec);
+      ret = snprintf(arg, TIMESTR_LEN + 1, "%lld.%06lld",
+                     (long long)timers[i]->u.sands.tv_sec,
+                     (long long)timers[i]->u.sands.tv_usec);
+      assert(ret > 0);
+      assert((size_t)ret < TIMESTR_LEN + 1);
+      timers_pending++;
+    }
+
+  for (i = 0; i < REMOVE_TIMERS; i++)
+    {
+      int index;
+
+      index = prng_rand(prng) % SCHEDULE_TIMERS;
+      if (!timers[index])
+        continue;
+
+      XFREE(MTYPE_TMP, timers[index]->arg);
+      thread_cancel(timers[index]);
+      timers[index] = NULL;
+      timers_pending--;
+    }
+
+  /* We create an array of pointers to the alarm times and sort
+   * that array. That sorted array is used to generate a string
+   * representing the expected "output" of the timers when they
+   * are run. */
+  j = 0;
+  alarms = XMALLOC(MTYPE_TMP, timers_pending * sizeof(*alarms));
+  for (i = 0; i < SCHEDULE_TIMERS; i++)
+    {
+      if (!timers[i])
+        continue;
+      alarms[j++] = &timers[i]->u.sands;
+    }
+  qsort(alarms, j, sizeof(*alarms), cmp_timeval);
+  for (i = 0; i < j; i++)
+    {
+      int ret;
+
+      ret = snprintf(expected_buf + expected_buf_pos,
+                     expected_buf_len - expected_buf_pos,
+                     "%lld.%06lld\n",
+                     (long long)alarms[i]->tv_sec,
+                     (long long)alarms[i]->tv_usec);
+      assert(ret > 0);
+      expected_buf_pos += ret;
+      assert(expected_buf_pos < expected_buf_len);
+    }
+  XFREE(MTYPE_TMP, alarms);
+
+  while (thread_fetch(master, &t))
+    thread_call(&t);
+
+  return 0;
+}
diff --git a/tests/lib/test_timer_performance.c b/tests/lib/test_timer_performance.c
new file mode 100644 (file)
index 0000000..a7d09be
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Test program which measures the time it takes to schedule and
+ * remove timers.
+ *
+ * Copyright (C) 2013 by Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This file is part of Quagga
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "thread.h"
+#include "pqueue.h"
+#include "prng.h"
+
+#define SCHEDULE_TIMERS 1000000
+#define REMOVE_TIMERS    500000
+
+struct thread_master *master;
+
+static int dummy_func(struct thread *thread)
+{
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  struct prng *prng;
+  int i;
+  struct thread **timers;
+  struct timeval tv_start, tv_lap, tv_stop;
+  unsigned long t_schedule, t_remove;
+
+  master = thread_master_create();
+  prng = prng_new(0);
+  timers = calloc(SCHEDULE_TIMERS, sizeof(*timers));
+
+  /* create thread structures so they won't be allocated during the
+   * time measurement */
+  for (i = 0; i < SCHEDULE_TIMERS; i++)
+    timers[i] = thread_add_timer_msec(master, dummy_func, NULL, 0);
+  for (i = 0; i < SCHEDULE_TIMERS; i++)
+    thread_cancel(timers[i]);
+
+  monotime(&tv_start);
+
+  for (i = 0; i < SCHEDULE_TIMERS; i++)
+    {
+      long interval_msec;
+
+      interval_msec = prng_rand(prng) % (100 * SCHEDULE_TIMERS);
+      timers[i] = thread_add_timer_msec(master, dummy_func,
+                                        NULL, interval_msec);
+    }
+
+  monotime(&tv_lap);
+
+  for (i = 0; i < REMOVE_TIMERS; i++)
+    {
+      int index;
+
+      index = prng_rand(prng) % SCHEDULE_TIMERS;
+      if (timers[index])
+        thread_cancel(timers[index]);
+      timers[index] = NULL;
+    }
+
+  monotime(&tv_stop);
+
+  t_schedule = 1000 * (tv_lap.tv_sec - tv_start.tv_sec);
+  t_schedule += (tv_lap.tv_usec - tv_start.tv_usec) / 1000;
+
+  t_remove = 1000 * (tv_stop.tv_sec - tv_lap.tv_sec);
+  t_remove += (tv_stop.tv_usec - tv_lap.tv_usec) / 1000;
+
+  printf("Scheduling %d random timers took %ld.%03ld seconds.\n",
+         SCHEDULE_TIMERS, t_schedule/1000, t_schedule%1000);
+  printf("Removing %d random timers took %ld.%03ld seconds.\n",
+         REMOVE_TIMERS, t_remove/1000, t_remove%1000);
+  fflush(stdout);
+
+  free(timers);
+  thread_master_free(master);
+  prng_free(prng);
+  return 0;
+}
diff --git a/tests/main.c b/tests/main.c
deleted file mode 100644 (file)
index b3e6e70..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * $Id: main.c,v 1.1 2005/04/25 16:42:24 paul Exp $
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include <lib/version.h>
-#include "getopt.h"
-#include "thread.h"
-#include "vty.h"
-#include "command.h"
-#include "memory.h"
-#include "memory_vty.h"
-
-extern void test_init();
-
-struct thread_master *master;
-
-struct option longopts[] = 
-{
-  { "daemon",      no_argument,       NULL, 'd'},
-  { "config_file", required_argument, NULL, 'f'},
-  { "help",        no_argument,       NULL, 'h'},
-  { "vty_addr",    required_argument, NULL, 'A'},
-  { "vty_port",    required_argument, NULL, 'P'},
-  { "version",     no_argument,       NULL, 'v'},
-  { 0 }
-};
-
-DEFUN (daemon_exit,
-       daemon_exit_cmd,
-       "daemon-exit",
-       "Make the daemon exit\n")
-{
-  exit(0);
-}
-
-static int timer_count;
-static int
-test_timer (struct thread *thread)
-{
-  int *count = THREAD_ARG(thread);
-  
-  printf ("run %d of timer\n", (*count)++);
-  thread_add_timer (master, test_timer, count, 5);
-  return 0;
-}
-
-static void
-test_timer_init()
-{
-  thread_add_timer (master, test_timer, &timer_count, 10);
-}
-
-static void
-test_vty_init()
-{
-  install_element (VIEW_NODE, &daemon_exit_cmd);
-}
-
-/* Help information display. */
-static void
-usage (char *progname, int status)
-{
-  if (status != 0)
-    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
-  else
-    {    
-      printf ("Usage : %s [OPTION...]\n\
-Daemon which does 'slow' things.\n\n\
--d, --daemon       Runs in daemon mode\n\
--f, --config_file  Set configuration file name\n\
--A, --vty_addr     Set vty's bind address\n\
--P, --vty_port     Set vty's port number\n\
--v, --version      Print program version\n\
--h, --help         Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
-    }
-  exit (status);
-}
-
-
-/* main routine. */
-int
-main (int argc, char **argv)
-{
-  char *p;
-  char *vty_addr = NULL;
-  int vty_port = 4000;
-  int daemon_mode = 0;
-  char *progname;
-  struct thread thread;
-  char *config_file = NULL;
-  
-  /* Set umask before anything for security */
-  umask (0027);
-
-  /* get program name */
-  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
-  /* master init. */
-  master = thread_master_create ();
-
-  while (1) 
-    {
-      int opt;
-
-      opt = getopt_long (argc, argv, "dhf:A:P:v", longopts, 0);
-    
-      if (opt == EOF)
-       break;
-
-      switch (opt) 
-       {
-       case 0:
-         break;
-        case 'f':
-          config_file = optarg;
-          break;
-       case 'd':
-         daemon_mode = 1;
-         break;
-       case 'A':
-         vty_addr = optarg;
-         break;
-       case 'P':
-          /* Deal with atoi() returning 0 on failure */
-          if (strcmp(optarg, "0") == 0)
-            {
-              vty_port = 0;
-              break;
-            } 
-          vty_port = atoi (optarg);
-          vty_port = (vty_port ? vty_port : 4000);
-         break;
-       case 'v':
-         print_version (progname);
-         exit (0);
-         break;
-       case 'h':
-         usage (progname, 0);
-         break;
-       default:
-         usage (progname, 1);
-         break;
-       }
-    }
-
-  /* Library inits. */
-  cmd_init (1);
-  vty_init (master);
-  memory_init ();
-
-  /* OSPF vty inits. */
-  test_vty_init ();
-
-  /* Change to the daemon program. */
-  if (daemon_mode && daemon (0, 0) < 0)
-    {
-      fprintf(stderr, "daemon failed: %s", strerror(errno));
-      exit (1);
-    }
-
-  /* Create VTY socket */
-  vty_serv_sock (vty_addr, vty_port, "/tmp/.heavy.sock");
-  
-  /* Configuration file read*/
-  if (!config_file)
-    usage (progname, 1);
-  vty_read_config (config_file, NULL);
-  
-  test_timer_init();
-  
-  test_init();  
-  
-  /* Fetch next active thread. */
-  while (thread_fetch (master, &thread))
-    thread_call (&thread);
-
-  /* Not reached. */
-  exit (0);
-}
-
diff --git a/tests/prng.c b/tests/prng.c
deleted file mode 100644 (file)
index bdcfb07..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Very simple prng to allow for randomized tests with reproducable
- * results.
- *
- * Copyright (C) 2012 by Open Source Routing.
- * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "prng.h"
-
-struct prng
-{
-  unsigned long long state1;
-  unsigned long long state2;
-};
-
-static char
-prng_bit(struct prng *prng)
-{
-  prng->state1 *= 2416;
-  prng->state1 += 374441;
-  prng->state1 %= 1771875;
-
-  if (prng->state1 % 2)
-    {
-      prng->state2 *= 84589;
-      prng->state2 += 45989;
-      prng->state2 %= 217728;
-    }
-
-  return prng->state2 % 2;
-}
-
-struct prng*
-prng_new(unsigned long long seed)
-{
-  struct prng *rv = calloc(sizeof(*rv), 1);
-  assert(rv);
-
-  rv->state1 = rv->state2 = seed;
-
-  return rv;
-}
-
-unsigned int
-prng_rand(struct prng *prng)
-{
-  unsigned int i, rv = 0;
-
-  for (i = 0; i < 32; i++)
-    {
-      rv |= prng_bit(prng);
-      rv <<= 1;
-    }
-  return rv;
-}
-
-const char *
-prng_fuzz(struct prng *prng,
-          const char *string,
-          const char *charset,
-          unsigned int operations)
-{
-  static char buf[256];
-  unsigned int charset_len;
-  unsigned int i;
-  unsigned int offset;
-  unsigned int op;
-  unsigned int character;
-
-  assert(strlen(string) < sizeof(buf));
-
-  strncpy(buf, string, sizeof(buf));
-  charset_len = strlen(charset);
-
-  for (i = 0; i < operations; i++)
-    {
-      offset = prng_rand(prng) % strlen(buf);
-      op = prng_rand(prng) % 3;
-
-      switch (op)
-        {
-        case 0:
-          /* replace */
-          character = prng_rand(prng) % charset_len;
-          buf[offset] = charset[character];
-          break;
-        case 1:
-          /* remove */
-          memmove(buf + offset, buf + offset + 1, strlen(buf) - offset);
-          break;
-        case 2:
-          /* insert */
-          assert(strlen(buf) + 1 < sizeof(buf));
-
-          memmove(buf + offset + 1, buf + offset, strlen(buf) + 1 - offset);
-          character = prng_rand(prng) % charset_len;
-          buf[offset] = charset[character];
-          break;
-        }
-    }
-  return buf;
-}
-
-void
-prng_free(struct prng *prng)
-{
-  free(prng);
-}
diff --git a/tests/prng.h b/tests/prng.h
deleted file mode 100644 (file)
index cf0bacc..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Very simple prng to allow for randomized tests with reproducable
- * results.
- *
- * Copyright (C) 2012 by Open Source Routing.
- * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-#ifndef _PRNG_H
-#define _PRNG_H
-
-struct prng;
-
-struct prng* prng_new(unsigned long long seed);
-unsigned int prng_rand(struct prng*);
-const char * prng_fuzz(struct prng*,
-                       const char *string,
-                       const char *charset,
-                       unsigned int operations);
-void prng_free(struct prng *);
-
-#endif
diff --git a/tests/table_test.c b/tests/table_test.c
deleted file mode 100644 (file)
index 4042e1a..0000000
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * Routing table test
- * Copyright (C) 2012 OSR.
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include "prefix.h"
-#include "table.h"
-
-/*
- * test_node_t
- *
- * Information that is kept for each node in the radix tree.
- */
-typedef struct test_node_t_
-{
-
-  /*
-   * Human readable representation of the string. Allocated using
-   * malloc()/dup().
-   */
-  char *prefix_str;
-} test_node_t;
-
-struct thread_master *master;
-
-/*
- * add_node
- *
- * Add the given prefix (passed in as a string) to the given table.
- */
-static void
-add_node (struct route_table *table, const char *prefix_str)
-{
-  struct prefix_ipv4 p;
-  test_node_t *node;
-  struct route_node *rn;
-
-  assert (prefix_str);
-
-  if (str2prefix_ipv4 (prefix_str, &p) <= 0)
-    {
-      assert (0);
-    }
-
-  rn = route_node_get (table, (struct prefix *) &p);
-  if (rn->info)
-    {
-      assert (0);
-      return;
-    }
-
-  node = malloc (sizeof (test_node_t));
-  assert (node);
-  node->prefix_str = strdup (prefix_str);
-  assert (node->prefix_str);
-  rn->info = node;
-}
-
-/*
- * add_nodes
- *
- * Convenience function to add a bunch of nodes together.
- *
- * The arguments must be prefixes in string format, with a NULL as the
- * last argument.
- */
-static void
-add_nodes (struct route_table *table, ...)
-{
-  va_list arglist;
-  char *prefix;
-
-  va_start (arglist, table);
-
-  prefix = va_arg (arglist, char *);
-  while (prefix)
-    {
-      add_node (table, prefix);
-      prefix = va_arg (arglist, char *);
-    }
-
-  va_end (arglist);
-}
-
-/*
- * print_subtree
- *
- * Recursive function to print a route node and its children.
- *
- * @see print_table
- */
-static void
-print_subtree (struct route_node *rn, const char *legend, int indent_level)
-{
-  char buf[PREFIX2STR_BUFFER];
-  int i;
-
-  /*
-   * Print this node first.
-   */
-  for (i = 0; i < indent_level; i++)
-    {
-      printf ("  ");
-    }
-
-  prefix2str (&rn->p, buf, sizeof (buf));
-  printf ("%s: %s", legend, buf);
-  if (!rn->info)
-    {
-      printf (" (internal)");
-    }
-  printf ("\n");
-  if (rn->l_left)
-    {
-      print_subtree (rn->l_left, "Left", indent_level + 1);
-    }
-  if (rn->l_right)
-    {
-      print_subtree (rn->l_right, "Right", indent_level + 1);
-    }
-}
-
-/*
- * print_table
- *
- * Function that prints out the internal structure of a route table.
- */
-static void
-print_table (struct route_table *table)
-{
-  struct route_node *rn;
-
-  rn = table->top;
-
-  if (!rn)
-    {
-      printf ("<Empty Table>\n");
-      return;
-    }
-
-  print_subtree (rn, "Top", 0);
-}
-
-/*
- * clear_table
- *
- * Remove all nodes from the given table.
- */
-static void
-clear_table (struct route_table *table)
-{
-  route_table_iter_t iter;
-  struct route_node *rn;
-  test_node_t *node;
-
-  route_table_iter_init (&iter, table);
-
-  while ((rn = route_table_iter_next (&iter)))
-    {
-      node = rn->info;
-      if (!node)
-       {
-         continue;
-       }
-      rn->info = NULL;
-      route_unlock_node (rn);
-      free (node->prefix_str);
-      free (node);
-    }
-
-  route_table_iter_cleanup (&iter);
-
-  assert (table->top == NULL);
-}
-
-/*
- * verify_next_by_iterating
- *
- * Iterate over the tree to make sure that the first prefix after
- * target_pfx is the expected one. Note that target_pfx may not be
- * present in the tree.
- */
-static void
-verify_next_by_iterating (struct route_table *table,
-                         struct prefix *target_pfx, struct prefix *next_pfx)
-{
-  route_table_iter_t iter;
-  struct route_node *rn;
-
-  route_table_iter_init (&iter, table);
-  while ((rn = route_table_iter_next (&iter)))
-    {
-      if (route_table_prefix_iter_cmp (&rn->p, target_pfx) > 0)
-       {
-         assert (!prefix_cmp (&rn->p, next_pfx));
-         break;
-       }
-    }
-
-  if (!rn)
-    {
-      assert (!next_pfx);
-    }
-
-  route_table_iter_cleanup (&iter);
-}
-
-/*
- * verify_next
- *
- * Verifies that route_table_get_next() returns the expected result
- * (result) for the prefix string 'target'.
- */
-static void
-verify_next (struct route_table *table, const char *target, const char *next)
-{
-  struct prefix_ipv4 target_pfx, next_pfx;
-  struct route_node *rn;
-  char result_buf[PREFIX2STR_BUFFER];
-
-  if (str2prefix_ipv4 (target, &target_pfx) <= 0)
-    {
-      assert (0);
-    }
-
-  rn = route_table_get_next (table, (struct prefix *) &target_pfx);
-  if (rn)
-    {
-      prefix2str (&rn->p, result_buf, sizeof (result_buf));
-    }
-  else
-    {
-      snprintf (result_buf, sizeof (result_buf), "(Null)");
-    }
-
-  printf ("\n");
-  print_table (table);
-  printf ("Verifying successor of %s. Expected: %s, Result: %s\n", target,
-         next ? next : "(Null)", result_buf);
-
-  if (!rn)
-    {
-      assert (!next);
-      verify_next_by_iterating (table, (struct prefix *) &target_pfx, NULL);
-      return;
-    }
-
-  assert (next);
-
-  if (str2prefix_ipv4 (next, &next_pfx) <= 0)
-    {
-      assert (0);
-    }
-
-  if (prefix_cmp (&rn->p, (struct prefix *) &next_pfx))
-    {
-      assert (0);
-    }
-  route_unlock_node (rn);
-
-  verify_next_by_iterating (table, (struct prefix *) &target_pfx,
-                           (struct prefix *) &next_pfx);
-}
-
-/*
- * test_get_next
- */
-static void
-test_get_next (void)
-{
-  struct route_table *table;
-
-  printf ("\n\nTesting route_table_get_next()\n");
-  table = route_table_init ();
-
-  /*
-   * Target exists in tree, but has no successor.
-   */
-  add_nodes (table, "1.0.1.0/24", NULL);
-  verify_next (table, "1.0.1.0/24", NULL);
-  clear_table (table);
-
-  /*
-   * Target exists in tree, and there is a node in its left subtree.
-   */
-  add_nodes (table, "1.0.1.0/24", "1.0.1.0/25", NULL);
-  verify_next (table, "1.0.1.0/24", "1.0.1.0/25");
-  clear_table (table);
-
-  /*
-   * Target exists in tree, and there is a node in its right subtree.
-   */
-  add_nodes (table, "1.0.1.0/24", "1.0.1.128/25", NULL);
-  verify_next (table, "1.0.1.0/24", "1.0.1.128/25");
-  clear_table (table);
-
-  /*
-   * Target exists in the tree, next node is outside subtree.
-   */
-  add_nodes (table, "1.0.1.0/24", "1.1.0.0/16", NULL);
-  verify_next (table, "1.0.1.0/24", "1.1.0.0/16");
-  clear_table (table);
-
-  /*
-   * The target node does not exist in the tree for all the test cases
-   * below this point.
-   */
-
-  /*
-   * There is no successor in the tree.
-   */
-  add_nodes (table, "1.0.0.0/16", NULL);
-  verify_next (table, "1.0.1.0/24", NULL);
-  clear_table (table);
-
-  /*
-   * There exists a node that would be in the target's left subtree.
-   */
-  add_nodes (table, "1.0.0.0/16", "1.0.1.0/25", NULL);
-  verify_next (table, "1.0.1.0/24", "1.0.1.0/25");
-  clear_table (table);
-
-  /*
-   * There exists a node would be in the target's right subtree.
-   */
-  add_nodes (table, "1.0.0.0/16", "1.0.1.128/25", NULL);
-  verify_next (table, "1.0.1.0/24", "1.0.1.128/25");
-  clear_table (table);
-
-  /*
-   * A search for the target reaches a node where there are no child
-   * nodes in the direction of the target (left), but the node has a
-   * right child.
-   */
-  add_nodes (table, "1.0.0.0/16", "1.0.128.0/17", NULL);
-  verify_next (table, "1.0.0.0/17", "1.0.128.0/17");
-  clear_table (table);
-
-  /*
-   * A search for the target reaches a node with no children. We have
-   * to go upwards in the tree to find a successor.
-   */
-  add_nodes (table, "1.0.0.0/16", "1.0.0.0/24", "1.0.1.0/24",
-            "1.0.128.0/17", NULL);
-  verify_next (table, "1.0.1.0/25", "1.0.128.0/17");
-  clear_table (table);
-
-  /*
-   * A search for the target reaches a node where neither the node nor
-   * the target prefix contain each other.
-   *
-   * In first case below the node succeeds the target.
-   *
-   * In the second case, the node comes before the target, so we have
-   * to go up the tree looking for a successor.
-   */
-  add_nodes (table, "1.0.0.0/16", "1.0.1.0/24", NULL);
-  verify_next (table, "1.0.0.0/24", "1.0.1.0/24");
-  clear_table (table);
-
-  add_nodes (table, "1.0.0.0/16", "1.0.0.0/24", "1.0.1.0/25",
-            "1.0.128.0/17", NULL);
-  verify_next (table, "1.0.1.128/25", "1.0.128.0/17");
-  clear_table (table);
-
-  route_table_finish (table);
-}
-
-/*
- * verify_prefix_iter_cmp
- */
-static void
-verify_prefix_iter_cmp (const char *p1, const char *p2, int exp_result)
-{
-  struct prefix_ipv4 p1_pfx, p2_pfx;
-  int result;
-
-  if (str2prefix_ipv4 (p1, &p1_pfx) <= 0)
-    {
-      assert (0);
-    }
-
-  if (str2prefix_ipv4 (p2, &p2_pfx) <= 0)
-    {
-      assert (0);
-    }
-
-  result = route_table_prefix_iter_cmp ((struct prefix *) &p1_pfx,
-                                       (struct prefix *) &p2_pfx);
-
-  printf ("Verifying cmp(%s, %s) returns %d\n", p1, p2, exp_result);
-
-  assert (exp_result == result);
-
-  /*
-   * Also check the reverse comparision.
-   */
-  result = route_table_prefix_iter_cmp ((struct prefix *) &p2_pfx,
-                                       (struct prefix *) &p1_pfx);
-
-  if (exp_result)
-    {
-      exp_result = -exp_result;
-    }
-
-  printf ("Verifying cmp(%s, %s) returns %d\n", p1, p2, exp_result);
-  assert (result == exp_result);
-}
-
-/*
- * test_prefix_iter_cmp
- *
- * Tests comparision of prefixes according to order of iteration.
- */
-static void
-test_prefix_iter_cmp ()
-{
-  printf ("\n\nTesting route_table_prefix_iter_cmp()\n");
-
-  verify_prefix_iter_cmp ("1.0.0.0/8", "1.0.0.0/8", 0);
-
-  verify_prefix_iter_cmp ("1.0.0.0/8", "1.0.0.0/16", -1);
-
-  verify_prefix_iter_cmp ("1.0.0.0/16", "1.128.0.0/16", -1);
-}
-
-/*
- * verify_iter_with_pause
- *
- * Iterates over a tree using two methods: 'normal' iteration, and an
- * iterator that pauses at each node. Verifies that the two methods
- * yield the same results.
- */
-static void
-verify_iter_with_pause (struct route_table *table)
-{
-  unsigned long num_nodes;
-  struct route_node *rn, *iter_rn;
-  route_table_iter_t iter_space;
-  route_table_iter_t *iter = &iter_space;
-
-  route_table_iter_init (iter, table);
-  num_nodes = 0;
-
-  for (rn = route_top (table); rn; rn = route_next (rn))
-    {
-      num_nodes++;
-      route_table_iter_pause (iter);
-
-      assert (iter->current == NULL);
-      if (route_table_iter_started (iter))
-       {
-         assert (iter->state == RT_ITER_STATE_PAUSED);
-       }
-      else
-       {
-         assert (rn == table->top);
-         assert (iter->state == RT_ITER_STATE_INIT);
-       }
-
-      iter_rn = route_table_iter_next (iter);
-
-      /*
-       * Make sure both iterations return the same node.
-       */
-      assert (rn == iter_rn);
-    }
-
-  assert (num_nodes == route_table_count (table));
-
-  route_table_iter_pause (iter);
-  iter_rn = route_table_iter_next (iter);
-
-  assert (iter_rn == NULL);
-  assert (iter->state == RT_ITER_STATE_DONE);
-
-  assert (route_table_iter_next (iter) == NULL);
-  assert (iter->state == RT_ITER_STATE_DONE);
-
-  route_table_iter_cleanup (iter);
-
-  print_table (table);
-  printf ("Verified pausing iteration on tree with %lu nodes\n", num_nodes);
-}
-
-/*
- * test_iter_pause
- */
-static void
-test_iter_pause (void)
-{
-  struct route_table *table;
-  int i, num_prefixes;
-  const char *prefixes[] = {
-    "1.0.1.0/24",
-    "1.0.1.0/25",
-    "1.0.1.128/25",
-    "1.0.2.0/24",
-    "2.0.0.0/8"
-  };
-
-  num_prefixes = sizeof (prefixes) / sizeof (prefixes[0]);
-
-  printf ("\n\nTesting that route_table_iter_pause() works as expected\n");
-  table = route_table_init ();
-  for (i = 0; i < num_prefixes; i++)
-    {
-      add_nodes (table, prefixes[i], NULL);
-    }
-
-  verify_iter_with_pause (table);
-
-  clear_table (table);
-  route_table_finish (table);
-}
-
-/*
- * run_tests
- */
-static void
-run_tests (void)
-{
-  test_prefix_iter_cmp ();
-  test_get_next ();
-  test_iter_pause ();
-}
-
-/*
- * main
- */
-int
-main (void)
-{
-  run_tests ();
-}
diff --git a/tests/test-buffer.c b/tests/test-buffer.c
deleted file mode 100644 (file)
index 67e4035..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 
- * Copyright (C) 2004 Paul Jakma
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-#include <memory.h>
-#include <memory_vty.h>
-#include <buffer.h>
-
-struct thread_master *master;
-
-int
-main(int argc, char **argv)
-{
-  struct buffer *b1, *b2;
-  int n;
-  char junk[3];
-  char c = 'a';
-
-  memory_init();
-  
-  if ((argc != 2) || (sscanf(argv[1], "%d%1s", &n, junk) != 1))
-    {
-      fprintf(stderr, "Usage: %s <number of chars to simulate>\n", *argv);
-      return 1;
-    }
-
-  b1 = buffer_new(0);
-  b2 = buffer_new(1024);
-  
-  while (n-- > 0)
-    {
-      buffer_put(b1, &c, 1);
-      buffer_put(b2, &c, 1);
-      if (c++ == 'z')
-        c = 'a';
-      buffer_reset(b1);
-      buffer_reset(b2);
-    }
-  buffer_free(b1);
-  buffer_free(b2);
-  return 0;
-}
diff --git a/tests/test-checksum.c b/tests/test-checksum.c
deleted file mode 100644 (file)
index 53ab260..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-/* 
- * Copyright (C) 2008 Sun Microsystems, Inc.
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "checksum.h"
-
-struct thread_master *master;
-
-struct acc_vals {
-  int c0;
-  int c1;
-};
-
-struct csum_vals {
-  struct acc_vals a;
-  int x; 
-  int y;
-};
-
-static struct csum_vals ospfd_vals, isisd_vals;
-
-typedef size_t testsz_t;
-typedef uint16_t testoff_t;
-
-/* Fletcher Checksum -- Refer to RFC1008. */
-#define MODX                 4102U
-
-/* The final reduction phase.
- * This one should be the original ospfd version 
- */
-static u_int16_t 
-reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off)
-{
-#define x vals->x
-#define y vals->y
-#define c0 vals->a.c0
-#define c1 vals->a.c1
-
-  x = ((len - off - 1) * c0 - c1) % 255;
-  
-  if (x <= 0)
-    x += 255;
-  y = 510 - c0 - x;
-  if (y > 255)
-    y -= 255;
-
-   /* take care endian issue. */
-   return htons ((x << 8) + y); 
-#undef x
-#undef y
-#undef c0
-#undef c1
-}
-
-/* slightly different concatenation */
-static u_int16_t 
-reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off)
-{
-#define x vals->x
-#define y vals->y
-#define c0 vals->a.c0
-#define c1 vals->a.c1
-
-  x = ((len - off - 1) * c0 - c1) % 255;
-  if (x <= 0)
-    x += 255;
-  y = 510 - c0 - x;
-  if (y > 255)
-    y -= 255;
-
-   /* take care endian issue. */
-   return htons ((x << 8) | (y & 0xff)); 
-#undef x
-#undef y
-#undef c0
-#undef c1
-}
-
-/* original isisd version */
-static u_int16_t 
-reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off)
-{
-#define x vals->x
-#define y vals->y
-#define c0 vals->a.c0
-#define c1 vals->a.c1
-  u_int32_t mul;
-  
-  mul = (len - off)*(c0);
-  x = mul - c0 - c1;
-  y = c1 - mul - 1;
-
-  if (y > 0)
-    y++;
-  if (x < 0)
-    x--;
-
-  x %= 255;
-  y %= 255;
-
-  if (x == 0)
-    x = 255;
-  if (y == 0)
-    y = 1;
-
-  return htons ((x << 8) | (y & 0xff));
-
-#undef x
-#undef y
-#undef c0
-#undef c1
-}
-
-/* Is the -1 in y wrong perhaps? */
-static u_int16_t 
-reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off)
-{
-#define x vals->x
-#define y vals->y
-#define c0 vals->a.c0
-#define c1 vals->a.c1
-  u_int32_t mul;
-  
-  mul = (len - off)*(c0);
-  x = mul - c0 - c1;
-  y = c1 - mul;
-
-  if (y > 0)
-    y++;
-  if (x < 0)
-    x--;
-
-  x %= 255;
-  y %= 255;
-
-  if (x == 0)
-    x = 255;
-  if (y == 0)
-    y = 1;
-
-  return htons ((x << 8) | (y & 0xff));
-
-#undef x
-#undef y
-#undef c0
-#undef c1
-}
-
-/* Move the mods yp */
-static u_int16_t 
-reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off)
-{
-#define x vals->x
-#define y vals->y
-#define c0 vals->a.c0
-#define c1 vals->a.c1
-  u_int32_t mul;
-  
-  mul = (len - off)*(c0);
-  x = mul - c1 - c0;
-  y = c1 - mul - 1;
-
-  x %= 255;
-  y %= 255;
-
-  if (y > 0)
-    y++;
-  if (x < 0)
-    x--;
-
-  if (x == 0)
-    x = 255;
-  if (y == 0)
-    y = 1;
-
-  return htons ((x << 8) | (y & 0xff));
-
-#undef x
-#undef y
-#undef c0
-#undef c1
-}
-
-/* Move the mods up + fix y */
-static u_int16_t 
-reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off)
-{
-#define x vals->x
-#define y vals->y
-#define c0 vals->a.c0
-#define c1 vals->a.c1
-  u_int32_t mul;
-  
-  mul = (len - off)*(c0);
-  x = mul - c0 - c1;
-  y = c1 - mul;
-
-  x %= 255;
-  y %= 255;
-
-  if (y > 0)
-    y++;
-  if (x < 0)
-    x--;
-
-  if (x == 0)
-    x = 255;
-  if (y == 0)
-    y = 1;
-
-  return htons ((x << 8) | (y & 0xff));
-
-#undef x
-#undef y
-#undef c0
-#undef c1
-}
-
-struct reductions_t {
-  const char *name;
-  u_int16_t (*f) (struct csum_vals *, testsz_t, testoff_t);
-} reducts[] = {
-  { .name = "ospfd",           .f = reduce_ospfd },
-  { .name = "ospfd-1",         .f = reduce_ospfd1 },
-  { .name = "isisd",           .f = reduce_isisd },
-  { .name = "isisd-yfix",      .f = reduce_isisd_yfix },
-  { .name = "isisd-mod",       .f = reduce_isisd_mod },
-  { .name = "isisd-mody",      .f = reduce_isisd_mody },
-  { NULL, NULL },
-};
-
-/* The original ospfd checksum */
-static u_int16_t
-ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off)
-{
-  u_char *sp, *ep, *p, *q;
-  int c0 = 0, c1 = 0;
-  int x, y;
-  u_int16_t checksum, *csum;
-
-  csum = (u_int16_t *) (buffer + off);
-  *(csum) = 0;
-  
-  sp = buffer;
-
-  for (ep = sp + len; sp < ep; sp = q)
-    {
-      q = sp + MODX;
-      if (q > ep)
-        q = ep;
-      for (p = sp; p < q; p++)
-        {
-          c0 += *p;
-          c1 += c0;
-        }
-      c0 %= 255;
-      c1 %= 255;
-    }
-  
-  ospfd_vals.a.c0 = c0;
-  ospfd_vals.a.c1 = c1;
-  
-  //printf ("%s: len %u, off %u, c0 %d, c1 %d\n",
-  //        __func__, len, off, c0, c1);
-
-  x = ((int)(len - off - 1) * (int)c0 - (int)c1) % 255;
-  
-  if (x <= 0)
-    x += 255;
-  y = 510 - c0 - x;
-  if (y > 255)
-    y -= 255;
-  
-  ospfd_vals.x = x;
-  ospfd_vals.y = y;
-  
-  buffer[off] = x;
-  buffer[off + 1] = y;
-  
-  /* take care endian issue. */
-  checksum = htons ((x << 8) | (y & 0xff));
-
-  return (checksum);
-}
-
-/* the original, broken isisd checksum */
-static u_int16_t
-iso_csum_create (u_char * buffer, testsz_t len, testoff_t off)
-{
-
-  u_int8_t *p;
-  int x;
-  int y;
-  u_int32_t mul;
-  u_int32_t c0;
-  u_int32_t c1;
-  u_int16_t checksum, *csum;
-  int i, init_len, partial_len;
-
-  checksum = 0;
-  
-  csum = (u_int16_t *) (buffer + off);
-  *(csum) = checksum;
-  
-  p = buffer;
-  c0 = 0;
-  c1 = 0;
-  init_len = len;
-  
-  while (len != 0)
-    {
-      partial_len = MIN(len, MODX);
-
-      for (i = 0; i < partial_len; i++)
-       {
-         c0 = c0 + *(p++);
-         c1 += c0;
-       }
-
-      c0 = c0 % 255;
-      c1 = c1 % 255;
-
-      len -= partial_len;
-    }
-
-  isisd_vals.a.c0 = c0;
-  isisd_vals.a.c1 = c1;
-  
-  mul = (init_len - off) * c0;
-
-  x = mul - c1 - c0;
-  y = c1 - mul - 1;
-
-  if (y > 0)
-    y++;
-  if (x < 0)
-    x--;
-
-  x %= 255;
-  y %= 255;
-
-  if (x == 0)
-    x = 255;
-  if (y == 0)
-    y = 1;
-  
-  isisd_vals.x = x;
-  isisd_vals.y = y;
-  
-  checksum = htons((x << 8) | (y & 0xFF));
-  
-  *(csum) = checksum;
-  
-  /* return the checksum for user usage */
-  return checksum;
-}
-
-static int
-verify (u_char * buffer, testsz_t len)
-{
-  u_int8_t *p;
-  u_int32_t c0;
-  u_int32_t c1;
-  int i, partial_len;
-  p = buffer;
-
-  c0 = 0;
-  c1 = 0;
-
-  while (len)
-    {
-      partial_len = MIN(len, 5803U);
-
-      for (i = 0; i < partial_len; i++)
-        {
-          c0 = c0 + *(p++);
-          c1 += c0;
-        }
-      c0 = c0 % 255;
-      c1 = c1 % 255;
-
-      len -= partial_len;
-    }
-
-  if (c0 == 0 && c1 == 0)
-    return 0;
-
-  return 1;
-}
-
-static int  /* return checksum in low-order 16 bits */
-in_cksum_optimized(void *parg, int nbytes)
-{
-       u_short *ptr = parg;
-       register long           sum;            /* assumes long == 32 bits */
-       register u_short        answer;         /* assumes u_short == 16 bits */
-       register int count;
-       /*
-        * Our algorithm is simple, using a 32-bit accumulator (sum),
-        * we add sequential 16-bit words to it, and at the end, fold back
-        * all the carry bits from the top 16 bits into the lower 16 bits.
-        */
-
-       sum = 0;
-       count = nbytes >> 1; /* div by 2 */
-       for(ptr--; count; --count)
-         sum += *++ptr;
-
-       if (nbytes & 1) /* Odd */
-         sum += *(u_char *)(++ptr);   /* one byte only */
-
-       /*
-        * Add back carry outs from top 16 bits to low 16 bits.
-        */
-
-       sum  = (sum >> 16) + (sum & 0xffff);    /* add high-16 to low-16 */
-       sum += (sum >> 16);                     /* add carry */
-       answer = ~sum;          /* ones-complement, then truncate to 16 bits */
-       return(answer);
-}
-
-
-static int /* return checksum in low-order 16 bits */
-in_cksum_rfc(void *parg, int count)
-/* from RFC 1071 */
-{
-       u_short *addr = parg;
-       /* Compute Internet Checksum for "count" bytes
-        *         beginning at location "addr".
-        */
-       register long  sum = 0;
-
-       while (count > 1)  {
-         /*  This is the inner loop */
-         sum += *addr++;
-         count -= 2;
-       }
-       /*  Add left-over byte, if any */
-       if (count > 0) {
-         sum += *(u_char *)addr;
-       }
-
-       /*  Fold 32-bit sum to 16 bits */
-       while (sum>>16)
-           sum = (sum & 0xffff) + (sum >> 16);
-       return ~sum;
-}
-
-
-int
-main(int argc, char **argv)
-{
-/* 60017 65629 702179 */
-#define MAXDATALEN 60017
-#define BUFSIZE MAXDATALEN + sizeof(u_int16_t)
-  u_char buffer[BUFSIZE];
-  int exercise = 0;
-#define EXERCISESTEP 257
-  
-  srandom (time (NULL));
-  
-  while (1) {
-    u_int16_t ospfd, isisd, lib, in_csum, in_csum_res, in_csum_rfc;
-    int i,j;
-
-    exercise += EXERCISESTEP;
-    exercise %= MAXDATALEN;
-    
-    for (i = 0; i < exercise; i += sizeof (long int)) {
-      long int rand = random ();
-      
-      for (j = sizeof (long int); j > 0; j--)
-        buffer[i + (sizeof (long int) - j)] = (rand >> (j * 8)) & 0xff;
-    }
-    
-    in_csum = in_cksum(buffer, exercise);
-    in_csum_res = in_cksum_optimized(buffer, exercise);
-    in_csum_rfc = in_cksum_rfc(buffer, exercise);
-    if (in_csum_res != in_csum || in_csum != in_csum_rfc)
-      printf ("verify: in_chksum failed in_csum:%x, in_csum_res:%x,"
-             "in_csum_rfc %x, len:%d\n", 
-             in_csum, in_csum_res, in_csum_rfc, exercise);
-
-    ospfd = ospfd_checksum (buffer, exercise + sizeof(u_int16_t), exercise);
-    if (verify (buffer, exercise + sizeof(u_int16_t)))
-      printf ("verify: ospfd failed\n");
-    isisd = iso_csum_create (buffer, exercise + sizeof(u_int16_t), exercise);
-    if (verify (buffer, exercise + sizeof(u_int16_t)))
-      printf ("verify: isisd failed\n");
-    lib = fletcher_checksum (buffer, exercise + sizeof(u_int16_t), exercise);
-    if (verify (buffer, exercise + sizeof(u_int16_t)))
-      printf ("verify: lib failed\n");
-    
-    if (ospfd != lib) {
-      printf ("Mismatch in values at size %u\n"
-              "ospfd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n"
-              "isisd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n"
-              "lib: 0x%04x\n",
-              exercise,
-              ospfd, ospfd_vals.a.c0, ospfd_vals.a.c1, ospfd_vals.x, ospfd_vals.y,
-              isisd, isisd_vals.a.c0, isisd_vals.a.c1, isisd_vals.x, isisd_vals.y,
-              lib
-              );
-      
-      /* Investigate reduction phase discrepencies */
-      if (ospfd_vals.a.c0 == isisd_vals.a.c0
-          && ospfd_vals.a.c1 == isisd_vals.a.c1) {
-        printf ("\n");
-        for (i = 0; reducts[i].name != NULL; i++) {    
-          ospfd = reducts[i].f (&ospfd_vals,
-                                exercise + sizeof (u_int16_t),
-                                exercise);
-          printf ("%20s: x: %02x, y %02x, checksum 0x%04x\n",
-                  reducts[i].name, ospfd_vals.x & 0xff, ospfd_vals.y & 0xff, ospfd);
-        }
-      }
-              
-      printf ("\n  u_char testdata [] = {\n  ");
-      for (i = 0; i < exercise; i++) {
-        printf ("0x%02x,%s",
-                buffer[i],
-                (i + 1) % 8 ? " " : "\n  ");
-      }
-      printf ("\n}\n");
-      exit (1);
-    }
-  }
-}
diff --git a/tests/test-cli.c b/tests/test-cli.c
deleted file mode 100644 (file)
index 0590eec..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * CLI/command dummy handling tester
- *
- * Copyright (C) 2015 by David Lamparter,
- *                   for Open Source Routing / NetDEF, Inc.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include "common-cli.h"
-
-DUMMY_DEFUN(cmd0,  "arg ipv4 A.B.C.D");
-DUMMY_DEFUN(cmd1,  "arg ipv4m A.B.C.D/M");
-DUMMY_DEFUN(cmd2,  "arg ipv6 X:X::X:X");
-DUMMY_DEFUN(cmd3,  "arg ipv6m X:X::X:X/M");
-DUMMY_DEFUN(cmd4,  "arg range (5-15)");
-DUMMY_DEFUN(cmd5,  "pat a < a|b>");
-DUMMY_DEFUN(cmd7,  "pat c <a | b|c> A.B.C.D");
-DUMMY_DEFUN(cmd8,  "pat d {  foo A.B.C.D|bar   X:X::X:X| baz }");
-DUMMY_DEFUN(cmd9,  "pat e [ WORD ]");
-DUMMY_DEFUN(cmd10, "pat f [key]");
-DUMMY_DEFUN(cmd11, "alt a WORD");
-DUMMY_DEFUN(cmd12, "alt a A.B.C.D");
-DUMMY_DEFUN(cmd13, "alt a X:X::X:X");
-
-void test_init(void)
-{
-  install_element (ENABLE_NODE, &cmd0_cmd);
-  install_element (ENABLE_NODE, &cmd1_cmd);
-  install_element (ENABLE_NODE, &cmd2_cmd);
-  install_element (ENABLE_NODE, &cmd3_cmd);
-  install_element (ENABLE_NODE, &cmd4_cmd);
-  install_element (ENABLE_NODE, &cmd5_cmd);
-  install_element (ENABLE_NODE, &cmd7_cmd);
-  install_element (ENABLE_NODE, &cmd8_cmd);
-  install_element (ENABLE_NODE, &cmd9_cmd);
-  install_element (ENABLE_NODE, &cmd10_cmd);
-  install_element (ENABLE_NODE, &cmd11_cmd);
-  install_element (ENABLE_NODE, &cmd12_cmd);
-  install_element (ENABLE_NODE, &cmd13_cmd);
-}
diff --git a/tests/test-commands.c b/tests/test-commands.c
deleted file mode 100644 (file)
index 272e3d1..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Test code for lib/command.c
- *
- * Copyright (C) 2013 by Open Source Routing.
- * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This program reads in a list of commandlines from stdin
- * and calls all the public functions of lib/command.c for
- * both the given command lines and fuzzed versions thereof.
- *
- * The output is currently not validated but only logged. It can
- * be diffed to find regressions between versions.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#define REALLY_NEED_PLAIN_GETOPT 1
-
-#include <zebra.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "command.h"
-#include "memory.h"
-#include "vector.h"
-#include "prng.h"
-
-extern vector cmdvec;
-extern struct cmd_node vty_node;
-extern void test_init_cmd(void); /* provided in test-commands-defun.c */
-
-struct thread_master *master; /* dummy for libfrr*/
-
-static vector test_cmds;
-static char test_buf[32768];
-
-static struct cmd_node bgp_node =
-{
-  BGP_NODE,
-  "%s(config-router)# ",
-};
-
-static struct cmd_node rip_node =
-{
-  RIP_NODE,
-  "%s(config-router)# ",
-};
-
-static struct cmd_node isis_node =
-{
-  ISIS_NODE,
-  "%s(config-router)# ",
-};
-
-static struct cmd_node interface_node =
-{
-  INTERFACE_NODE,
-  "%s(config-if)# ",
-};
-
-static struct cmd_node rmap_node =
-{
-  RMAP_NODE,
-  "%s(config-route-map)# "
-};
-
-static struct cmd_node zebra_node =
-{
-  ZEBRA_NODE,
-  "%s(config-router)# "
-};
-
-static struct cmd_node bgp_vpnv4_node =
-{
-  BGP_VPNV4_NODE,
-  "%s(config-router-af)# "
-};
-
-static struct cmd_node bgp_ipv4_node =
-{
-  BGP_IPV4_NODE,
-  "%s(config-router-af)# "
-};
-
-static struct cmd_node bgp_ipv4m_node =
-{
-  BGP_IPV4M_NODE,
-  "%s(config-router-af)# "
-};
-
-static struct cmd_node bgp_ipv6_node =
-{
-  BGP_IPV6_NODE,
-  "%s(config-router-af)# "
-};
-
-static struct cmd_node bgp_ipv6m_node =
-{
-  BGP_IPV6M_NODE,
-  "%s(config-router-af)# "
-};
-
-static struct cmd_node ospf_node =
-{
-  OSPF_NODE,
-  "%s(config-router)# "
-};
-
-static struct cmd_node ripng_node =
-{
-  RIPNG_NODE,
-  "%s(config-router)# "
-};
-
-static struct cmd_node ospf6_node =
-{
-  OSPF6_NODE,
-  "%s(config-ospf6)# "
-};
-
-static struct cmd_node keychain_node =
-{
-  KEYCHAIN_NODE,
-  "%s(config-keychain)# "
-};
-
-static struct cmd_node keychain_key_node =
-{
-  KEYCHAIN_KEY_NODE,
-  "%s(config-keychain-key)# "
-};
-
-static int
-test_callback(const struct cmd_element *cmd, struct vty *vty, int argc, struct cmd_token *argv[])
-{
-  int offset;
-  int rv;
-  int i;
-
-  offset = 0;
-  rv = snprintf(test_buf, sizeof(test_buf), "'%s'", cmd->string);
-  if (rv < 0)
-    abort();
-
-  offset += rv;
-
-  for (i = 0; i < argc; i++)
-    {
-      rv = snprintf(test_buf + offset, sizeof(test_buf) - offset, "%s'%s'",
-                    (i == 0) ? ": " : ", ", argv[i]->arg);
-      if (rv < 0)
-        abort();
-      offset += rv;
-    }
-
-  return CMD_SUCCESS;
-}
-
-static void
-test_load(void)
-{
-  char line[4096];
-
-  test_cmds = vector_init(VECTOR_MIN_SIZE);
-
-  while (fgets(line, sizeof(line), stdin) != NULL)
-    {
-      if (strlen(line))
-        line[strlen(line) - 1] = '\0';
-      if (line[0] == '#')
-        continue;
-      vector_set(test_cmds, XSTRDUP(MTYPE_STRVEC, line));
-    }
-}
-
-static void
-test_init(void)
-{
-  unsigned int node;
-  unsigned int i;
-  struct cmd_node *cnode;
-  struct cmd_element *cmd;
-
-  cmd_init(1);
-
-  install_node (&bgp_node, NULL);
-  install_node (&rip_node, NULL);
-  install_node (&interface_node, NULL);
-  install_node (&rmap_node, NULL);
-  install_node (&zebra_node, NULL);
-  install_node (&bgp_vpnv4_node, NULL);
-  install_node (&bgp_ipv4_node, NULL);
-  install_node (&bgp_ipv4m_node, NULL);
-  install_node (&bgp_ipv6_node, NULL);
-  install_node (&bgp_ipv6m_node, NULL);
-  install_node (&ospf_node, NULL);
-  install_node (&ripng_node, NULL);
-  install_node (&ospf6_node, NULL);
-  install_node (&keychain_node, NULL);
-  install_node (&keychain_key_node, NULL);
-  install_node (&isis_node, NULL);
-  install_node (&vty_node, NULL);
-
-  test_init_cmd();
-
-  for (node = 0; node < vector_active(cmdvec); node++)
-    if ((cnode = vector_slot(cmdvec, node)) != NULL)
-      for (i = 0; i < vector_active(cnode->cmd_vector); i++)
-        if ((cmd = vector_slot(cnode->cmd_vector, i)) != NULL)
-          {
-            cmd->daemon = 0;
-            cmd->func = test_callback;
-          }
-  test_load();
-  vty_init_vtysh();
-}
-
-static void
-test_terminate(void)
-{
-  unsigned int i;
-
-  vty_terminate();
-  for (i = 0; i < vector_active(test_cmds); i++)
-    XFREE(MTYPE_STRVEC, vector_slot(test_cmds, i));
-  vector_free(test_cmds);
-  cmd_terminate();
-}
-
-static void
-test_run(struct prng *prng, struct vty *vty, const char *cmd, unsigned int edit_dist, unsigned int node_index, int verbose)
-{
-  const char *test_str;
-  vector vline;
-  int ret;
-  unsigned int i;
-  char **completions;
-  unsigned int j;
-  struct cmd_node *cnode;
-  vector descriptions;
-  int appended_null;
-  int no_match;
-
-  test_str = prng_fuzz(prng, cmd, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_:. /", edit_dist);
-  vline = cmd_make_strvec(test_str);
-
-  if (vline == NULL)
-    return;
-
-  appended_null = 0;
-  for (i = 0; i < vector_active(cmdvec); i++)
-    if ((cnode = vector_slot(cmdvec, i)) != NULL)
-      {
-        if (node_index != (unsigned int)-1 && i != node_index)
-          continue;
-
-        if (appended_null)
-          {
-            vector_unset(vline, vector_active(vline) - 1);
-            appended_null = 0;
-          }
-        vty->node = cnode->node;
-        test_buf[0] = '\0';
-        ret = cmd_execute_command(vline, vty, NULL, 0);
-        no_match = (ret == CMD_ERR_NO_MATCH);
-        if (verbose || !no_match)
-          printf("execute relaxed '%s'@%d: rv==%d%s%s\n",
-                 test_str,
-                 cnode->node,
-                 ret,
-                 (test_buf[0] != '\0') ? ", " : "",
-                 test_buf);
-
-        vty->node = cnode->node;
-        test_buf[0] = '\0';
-        ret = cmd_execute_command_strict(vline, vty, NULL);
-        if (verbose || !no_match)
-          printf("execute strict '%s'@%d: rv==%d%s%s\n",
-                 test_str,
-                 cnode->node,
-                 ret,
-                 (test_buf[0] != '\0') ? ", " : "",
-                 test_buf);
-
-        if (isspace((int) test_str[strlen(test_str) - 1]))
-          {
-            vector_set (vline, NULL);
-            appended_null = 1;
-          }
-
-        vty->node = cnode->node;
-        completions = cmd_complete_command(vline, vty, &ret);
-        if (verbose || !no_match)
-          printf("complete '%s'@%d: rv==%d\n",
-                 test_str,
-                 cnode->node,
-                 ret);
-        if (completions != NULL)
-          {
-            for (j = 0; completions[j] != NULL; j++)
-              {
-                printf("  '%s'\n", completions[j]);
-                XFREE(MTYPE_TMP, completions[j]);
-              }
-            XFREE(MTYPE_TMP, completions);
-          }
-
-        vty->node = cnode->node;
-        descriptions = cmd_describe_command(vline, vty, &ret);
-        if (verbose || !no_match)
-          printf("describe '%s'@%d: rv==%d\n",
-                 test_str,
-                 cnode->node,
-                 ret);
-        if (descriptions != NULL)
-          {
-            for (j = 0; j < vector_active(descriptions); j++)
-              {
-                struct cmd_token *cmd = vector_slot(descriptions, j);
-                printf("  '%s' '%s'\n", cmd->text, cmd->desc);
-              }
-            vector_free(descriptions);
-          }
-      }
-  cmd_free_strvec(vline);
-}
-
-int
-main(int argc, char **argv)
-{
-  int opt;
-  struct prng *prng;
-  struct vty *vty;
-  unsigned int edit_distance;
-  unsigned int max_edit_distance;
-  unsigned int node_index;
-  int verbose;
-  unsigned int test_cmd;
-  unsigned int iteration;
-  unsigned int num_iterations;
-
-  max_edit_distance = 3;
-  node_index = -1;
-  verbose = 0;
-
-  while ((opt = getopt(argc, argv, "e:n:v")) != -1)
-    {
-      switch (opt)
-        {
-        case 'e':
-          max_edit_distance = atoi(optarg);
-          break;
-        case 'n':
-          node_index = atoi(optarg);
-          break;
-        case 'v':
-          verbose++;
-          break;
-        default:
-          fprintf(stderr, "Usage: %s [-e <edit_dist>] [-n <node_idx>] [-v]\n", argv[0]);
-          exit(1);
-          break;
-        }
-    }
-
-  test_init();
-  prng = prng_new(0);
-
-  vty = vty_new();
-  vty->type = VTY_TERM;
-
-  fprintf(stderr, "Progress:\n0/%u", vector_active(test_cmds));
-  for (test_cmd = 0; test_cmd < vector_active(test_cmds); test_cmd++)
-    {
-      for (edit_distance = 0;
-           edit_distance <= max_edit_distance;
-           edit_distance++)
-        {
-          num_iterations = 1 << edit_distance;
-          num_iterations *= num_iterations * num_iterations;
-
-          for (iteration = 0; iteration < num_iterations; iteration++)
-            test_run(prng, vty, vector_slot(test_cmds, test_cmd), edit_distance, node_index, verbose);
-        }
-      fprintf(stderr, "\r%u/%u", test_cmd + 1, vector_active(test_cmds));
-    }
-  fprintf(stderr, "\nDone.\n");
-
-  vty_close(vty);
-  prng_free(prng);
-  test_terminate();
-  return 0;
-}
diff --git a/tests/test-memory.c b/tests/test-memory.c
deleted file mode 100644 (file)
index 6849b9d..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/* 
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-#include <memory.h>
-
-DEFINE_MGROUP(TEST_MEMORY, "memory test")
-DEFINE_MTYPE_STATIC(TEST_MEMORY, TEST, "generic test mtype")
-
-/* Memory torture tests
- *
- * Tests below are generic but comments are focused on interaction with
- * Paul's proposed memory 'quick' cache, which may never be included in
- * CVS
- */
-
-struct thread_master *master;
-
-#if 0 /* set to 1 to use system alloc directly */
-#undef XMALLOC
-#undef XCALLOC
-#undef XREALLOC
-#undef XFREE
-#define XMALLOC(T,S) malloc((S))
-#define XCALLOC(T,S) calloc(1, (S))
-#define XREALLOC(T,P,S) realloc((P),(S))
-#define XFREE(T,P) free((P))
-#endif
-
-#define TIMES 10
-
-int
-main(int argc, char **argv)
-{
-  void *a[10];
-  int i;
-
-  printf ("malloc x, malloc x, free, malloc x, free free\n\n");
-  /* simple case, test cache */
-  for (i = 0; i < TIMES; i++)
-    {
-      a[0] = XMALLOC (MTYPE_TEST, 1024);
-      memset (a[0], 1, 1024);
-      a[1] = XMALLOC (MTYPE_TEST, 1024);
-      memset (a[1], 1, 1024);
-      XFREE(MTYPE_TEST, a[0]); /* should go to cache */
-      a[0] = XMALLOC (MTYPE_TEST, 1024); /* should be satisfied from cache */
-      XFREE(MTYPE_TEST, a[0]);
-      XFREE(MTYPE_TEST, a[1]);
-    }
-  
-  printf ("malloc x, malloc y, free x, malloc y, free free\n\n");
-  /* cache should go invalid, valid, invalid, etc.. */
-  for (i = 0; i < TIMES; i++)
-    {
-      a[0] = XMALLOC (MTYPE_TEST, 512);
-      memset (a[0], 1, 512);
-      a[1] = XMALLOC (MTYPE_TEST, 1024); /* invalidate cache */
-      memset (a[1], 1, 1024);
-      XFREE(MTYPE_TEST, a[0]);
-      a[0] = XMALLOC (MTYPE_TEST, 1024);
-      XFREE(MTYPE_TEST, a[0]);
-      XFREE(MTYPE_TEST, a[1]);
-      /* cache should become valid again on next request */
-    }
-
-  printf ("calloc\n\n");
-  /* test calloc */
-  for (i = 0; i < TIMES; i++)
-    {
-      a[0] = XCALLOC (MTYPE_TEST, 1024);
-      memset (a[0], 1, 1024);
-      a[1] = XCALLOC (MTYPE_TEST, 512); /* invalidate cache */
-      memset (a[1], 1, 512);
-      XFREE(MTYPE_TEST, a[1]);
-      XFREE(MTYPE_TEST, a[0]);
-      /* alloc == 0, cache can become valid again on next request */
-    }
-  
-  printf ("calloc and realloc\n\n");
-  /* check calloc + realloc */
-  for (i = 0; i < TIMES; i++)
-    {
-      printf ("calloc a0 1024\n");
-      a[0] = XCALLOC (MTYPE_TEST, 1024);
-      memset (a[0], 1, 1024/2);
-      
-      printf ("calloc 1 1024\n");
-      a[1] = XCALLOC (MTYPE_TEST, 1024);
-      memset (a[1], 1, 1024/2);
-      
-      printf ("realloc 0 1024\n");
-      a[3] = XREALLOC (MTYPE_TEST, a[0], 2048); /* invalidate cache */
-      if (a[3] != NULL)
-        a[0] = a[3];
-      memset (a[0], 1, 1024);
-      
-      printf ("calloc 2 512\n");
-      a[2] = XCALLOC (MTYPE_TEST, 512);
-      memset (a[2], 1, 512);
-      
-      printf ("free 1 0 2\n");
-      XFREE(MTYPE_TEST, a[1]);
-      XFREE(MTYPE_TEST, a[0]);
-      XFREE(MTYPE_TEST, a[2]);
-      /* alloc == 0, cache valid next request */
-    }
-  return 0;
-}
diff --git a/tests/test-nexthop-iter.c b/tests/test-nexthop-iter.c
deleted file mode 100644 (file)
index 2503793..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Recursive Nexthop Iterator test.
- * This tests the ALL_NEXTHOPS_RO macro.
- *
- * Copyright (C) 2012 by Open Source Routing.
- * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-#include "zebra/rib.h"
-#include "prng.h"
-
-struct thread_master *master;
-static int verbose;
-
-static void
-str_append(char **buf, const char *repr)
-{
-  if (*buf)
-    {
-      *buf = realloc(*buf, strlen(*buf) + strlen(repr) + 1);
-      assert(*buf);
-      strncpy((*buf) + strlen(*buf), repr, strlen(repr) + 1);
-    }
-  else
-    {
-      *buf = strdup(repr);
-      assert(*buf);
-    }
-}
-
-static void
-str_appendf(char **buf, const char *format, ...)
-{
-  va_list ap;
-  int rv;
-  char *pbuf;
-
-  va_start(ap, format);
-  rv = vasprintf(&pbuf, format, ap);
-  va_end(ap);
-  assert(rv >= 0);
-
-  str_append(buf, pbuf);
-  free(pbuf);
-}
-
-/* This structure contains a nexthop chain
- * and its expected representation */
-struct nexthop_chain
-{
-  /* Head of the chain */
-  struct nexthop *head;
-  /* Last nexthop in top chain */
-  struct nexthop *current_top;
-  /* Last nexthop in current recursive chain */
-  struct nexthop *current_recursive;
-  /* Expected string representation. */
-  char *repr;
-};
-
-static struct nexthop_chain*
-nexthop_chain_new(void)
-{
-  struct nexthop_chain *rv;
-
-  rv = calloc(sizeof(*rv), 1);
-  assert(rv);
-  return rv;
-}
-
-static void
-nexthop_chain_add_top(struct nexthop_chain *nc)
-{
-  struct nexthop *nh;
-
-  nh = calloc(sizeof(*nh), 1);
-  assert(nh);
-
-  if (nc->head)
-    {
-      nc->current_top->next = nh;
-      nh->prev = nc->current_top;
-      nc->current_top = nh;
-    }
-  else
-    {
-      nc->head = nc->current_top = nh;
-    }
-  nc->current_recursive = NULL;
-  str_appendf(&nc->repr, "%p\n", nh);
-}
-
-static void
-nexthop_chain_add_recursive(struct nexthop_chain *nc)
-{
-  struct nexthop *nh;
-
-  nh = calloc(sizeof(*nh), 1);
-  assert(nh);
-
-  assert(nc->current_top);
-  if (nc->current_recursive)
-    {
-      nc->current_recursive->next = nh;
-      nh->prev = nc->current_recursive;
-      nc->current_recursive = nh;
-    }
-  else
-    {
-      SET_FLAG(nc->current_top->flags, NEXTHOP_FLAG_RECURSIVE);
-      nc->current_top->resolved = nh;
-      nc->current_recursive = nh;
-    }
-  str_appendf(&nc->repr, "  %p\n", nh);
-}
-
-static void
-nexthop_chain_clear(struct nexthop_chain *nc)
-{
-  struct nexthop *tcur, *tnext;
-
-  for (tcur = nc->head; tcur; tcur = tnext)
-    {
-      tnext = tcur->next;
-      if (CHECK_FLAG(tcur->flags, NEXTHOP_FLAG_RECURSIVE))
-        {
-          struct nexthop *rcur, *rnext;
-          for (rcur = tcur->resolved; rcur; rcur = rnext)
-            {
-              rnext = rcur->next;
-              free(rcur);
-            }
-        }
-      free(tcur);
-    }
-  nc->head = nc->current_top = nc->current_recursive = NULL;
-  free(nc->repr);
-  nc->repr = NULL;
-}
-
-static void
-nexthop_chain_free(struct nexthop_chain *nc)
-{
-  if (!nc)
-    return;
-  nexthop_chain_clear(nc);
-  free(nc);
-}
-
-/* This function builds a string representation of
- * the nexthop chain using the ALL_NEXTHOPS_RO macro.
- * It verifies that the ALL_NEXTHOPS_RO macro iterated
- * correctly over the nexthop chain by comparing the
- * generated representation with the expected representation.
- */
-static void
-nexthop_chain_verify_iter(struct nexthop_chain *nc)
-{
-  struct nexthop *nh, *tnh;
-  int recursing;
-  char *repr = NULL;
-
-  for (ALL_NEXTHOPS_RO(nc->head, nh, tnh, recursing))
-    {
-      if (recursing)
-        str_appendf(&repr, "  %p\n", nh);
-      else
-        str_appendf(&repr, "%p\n", nh);
-    }
-
-  if (repr && verbose)
-    printf("===\n%s", repr);
-  assert((!repr && !nc->repr) || (repr && nc->repr && !strcmp(repr, nc->repr)));
-  free(repr);
-}
-
-/* This test run builds a simple nexthop chain
- * with some recursive nexthops and verifies that
- * the iterator works correctly in each stage along
- * the way.
- */
-static void
-test_run_first(void)
-{
-  struct nexthop_chain *nc;
-
-  nc = nexthop_chain_new();
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_top(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_top(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_recursive(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_recursive(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_top(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_top(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_top(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_recursive(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_recursive(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_add_recursive(nc);
-  nexthop_chain_verify_iter(nc);
-
-  nexthop_chain_free(nc);
-}
-
-/* This test run builds numerous random
- * nexthop chain configurations and verifies
- * that the iterator correctly progresses
- * through each. */
-static void
-test_run_prng(void)
-{
-  struct nexthop_chain *nc;
-  struct prng *prng;
-  int i;
-
-  nc = nexthop_chain_new();
-  prng = prng_new(0);
-
-  for (i = 0; i < 1000000; i++)
-    {
-      switch (prng_rand(prng) % 10)
-        {
-        case 0:
-          nexthop_chain_clear(nc);
-          break;
-        case 1:
-        case 2:
-        case 3:
-        case 4:
-        case 5:
-          nexthop_chain_add_top(nc);
-          break;
-        case 6:
-        case 7:
-        case 8:
-        case 9:
-          if (nc->current_top)
-            nexthop_chain_add_recursive(nc);
-          break;
-        }
-      nexthop_chain_verify_iter(nc);
-    }
-  nexthop_chain_free(nc);
-  prng_free(prng);
-}
-
-int main(int argc, char **argv)
-{
-  if (argc >= 2 && !strcmp("-v", argv[1]))
-    verbose = 1;
-  test_run_first();
-  printf("Simple test passed.\n");
-  test_run_prng();
-  printf("PRNG test passed.\n");
-}
diff --git a/tests/test-privs.c b/tests/test-privs.c
deleted file mode 100644 (file)
index c6ccc28..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * $Id: test-privs.c,v 1.1 2005/10/11 03:48:28 paul Exp $
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include <lib/version.h>
-#include "getopt.h"
-#include "privs.h"
-#include "memory.h"
-#include "memory_vty.h"
-
-zebra_capabilities_t _caps_p [] = 
-{
-  ZCAP_NET_RAW,
-  ZCAP_BIND,
-  ZCAP_NET_ADMIN,
-  ZCAP_DAC_OVERRIDE,
-};
-
-struct zebra_privs_t test_privs =
-{
-#if defined(FRR_USER) && defined(FRR_GROUP)
-  .user = FRR_USER,
-  .group = FRR_GROUP,
-#endif
-#if defined(VTY_GROUP)
-  .vty_group = VTY_GROUP,
-#endif
-  .caps_p = _caps_p,
-  .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
-  .cap_num_i = 0
-};
-
-struct option longopts[] = 
-{
-  { "help",        no_argument,       NULL, 'h'},
-  { "user",        required_argument, NULL, 'u'},
-  { "group",       required_argument, NULL, 'g'},
-  { 0 }
-};
-
-/* Help information display. */
-static void
-usage (char *progname, int status)
-{
-  if (status != 0)
-    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
-  else
-    {    
-      printf ("Usage : %s [OPTION...]\n\
-Daemon which does 'slow' things.\n\n\
--u, --user         User to run as\n\
--g, --group        Group to run as\n\
--h, --help         Display this help and exit\n\
-\n\
-Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
-    }
-  exit (status);
-}
-
-struct thread_master *master;
-/* main routine. */
-int
-main (int argc, char **argv)
-{
-  char *p;
-  char *progname;
-  struct zprivs_ids_t ids;
-  
-  /* Set umask before anything for security */
-  umask (0027);
-
-  /* get program name */
-  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
-
-  while (1) 
-    {
-      int opt;
-
-      opt = getopt_long (argc, argv, "hu:g:", longopts, 0);
-    
-      if (opt == EOF)
-       break;
-
-      switch (opt) 
-       {
-       case 0:
-         break;
-        case 'u':
-          test_privs.user = optarg;
-          break;
-        case 'g':
-          test_privs.group = optarg;
-          break;
-       case 'h':
-         usage (progname, 0);
-         break;
-       default:
-         usage (progname, 1);
-         break;
-       }
-    }
-
-  /* Library inits. */
-  memory_init ();
-  zprivs_init (&test_privs);
-
-#define PRIV_STATE() \
-  ((test_privs.current_state() == ZPRIVS_RAISED) ? "Raised" : "Lowered")
-  
-  printf ("%s\n", PRIV_STATE());
-  test_privs.change(ZPRIVS_RAISE);
-  
-  printf ("%s\n", PRIV_STATE());
-  test_privs.change(ZPRIVS_LOWER);
-  
-  printf ("%s\n", PRIV_STATE());
-  zprivs_get_ids (&ids);  
-  
-  /* terminate privileges */
-  zprivs_terminate(&test_privs);
-  
-  /* but these should continue to work... */
-  printf ("%s\n", PRIV_STATE());
-  test_privs.change(ZPRIVS_RAISE);
-  
-  printf ("%s\n", PRIV_STATE());
-  test_privs.change(ZPRIVS_LOWER);
-  
-  printf ("%s\n", PRIV_STATE());
-  zprivs_get_ids (&ids);  
-  
-  printf ("terminating\n");
-  return 0;
-}
diff --git a/tests/test-segv.c b/tests/test-segv.c
deleted file mode 100644 (file)
index 1810c5f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SEGV / backtrace handling test.
- *
- * copied from test-sig.c
- *
- * Copyright (C) 2013 by David Lamparter, Open Source Routing.
- * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-#include <sigevent.h>
-#include "lib/log.h"
-#include "lib/memory.h"
-
-struct quagga_signal_t sigs[] = 
-{
-};
-
-struct thread_master *master;
-
-static int
-threadfunc (struct thread *thread)
-{
-  int *null = NULL;
-  *null += 1;
-  return 0;
-}
-
-int
-main (void)
-{
-  master = thread_master_create ();
-  signal_init (master, array_size(sigs), sigs);
-
-  zlog_default = openzlog("testsegv", ZLOG_NONE, 0,
-                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
-  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
-  zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
-  zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
-
-  thread_execute (master, threadfunc, 0, 0);
-
-  exit (0);
-}
diff --git a/tests/test-sig.c b/tests/test-sig.c
deleted file mode 100644 (file)
index 4a04240..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-#include <sigevent.h>
-#include "lib/log.h"
-#include "lib/memory.h"
-
-static void
-sighup (void)
-{
-  printf ("processed hup\n");
-}
-
-static void
-sigusr1 (void)
-{
-  printf ("processed usr1\n");
-}
-
-static void
-sigusr2 (void)
-{
-  printf ("processed usr2\n");
-}
-
-struct quagga_signal_t sigs[] = 
-{
-  {
-    .signal = SIGHUP,
-    .handler = &sighup,
-  },
-  {
-    .signal = SIGUSR1,
-    .handler = &sigusr1,
-  },
-  {
-    .signal = SIGUSR2,
-    .handler = &sigusr2,
-  }
-};
-
-struct thread_master *master;
-struct thread t;
-
-int
-main (void)
-{
-  master = thread_master_create ();
-  signal_init (master, array_size(sigs), sigs);
-  
-  zlog_default = openzlog("testsig", ZLOG_NONE, 0,
-                          LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
-  zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
-  zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
-  zlog_set_level (NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
-  
-  while (thread_fetch (master, &t))
-    thread_call (&t);
-
-  exit (0);
-}
diff --git a/tests/test-srcdest-table.c b/tests/test-srcdest-table.c
deleted file mode 100644 (file)
index cfc2deb..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Test srcdest table for correctness.
- *
- * Copyright (C) 2017 by David Lamparter & Christian Franke,
- *                       Open Source Routing / NetDEF Inc.
- *
- * This file is part of FreeRangeRouting (FRR)
- *
- * FRR is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * FRR is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with FRR; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include "hash.h"
-#include "memory.h"
-#include "prefix.h"
-#include "prng.h"
-#include "srcdest_table.h"
-#include "table.h"
-
-/* Copied from ripngd/ripng_nexthop.h - maybe the whole s6_addr32 thing
- * should be added by autoconf if not present?
- */
-#ifndef s6_addr32
-#if defined(SUNOS_5)
-/* Some SunOS define s6_addr32 only to kernel */
-#define s6_addr32 _S6_un._S6_u32
-#else
-#define s6_addr32 __u6_addr.__u6_addr32
-#endif /* SUNOS_5 */
-#endif /*s6_addr32*/
-
-struct thread_master *master;
-
-/* This structure is copied from lib/srcdest_table.c to which it is
- * private as far as other parts of Quagga are concerned.
- */
-struct srcdest_rnode
-{
-  /* must be first in structure for casting to/from route_node */
-  ROUTE_NODE_FIELDS;
-
-  struct route_table *src_table;
-};
-
-struct test_state
-{
-  struct route_table *table;
-  struct hash *log;
-};
-
-static char *
-format_srcdest(const struct prefix_ipv6 *dst_p,
-               const struct prefix_ipv6 *src_p)
-{
-  char dst_str[BUFSIZ];
-  char src_str[BUFSIZ];
-  char *rv;
-  int ec;
-
-  prefix2str((const struct prefix*)dst_p, dst_str, sizeof(dst_str));
-  if (src_p && src_p->prefixlen)
-    prefix2str((const struct prefix*)src_p, src_str, sizeof(src_str));
-  else
-    src_str[0] = '\0';
-
-  ec = asprintf(&rv, "%s%s%s", dst_str,
-                (src_str[0] != '\0') ? " from " : "",
-                src_str);
-
-  assert(ec > 0);
-  return rv;
-}
-
-static unsigned int log_key(void *data)
-{
-  struct prefix *hash_entry = data;
-  struct prefix_ipv6 *dst_p = (struct prefix_ipv6*) &hash_entry[0];
-  struct prefix_ipv6 *src_p = (struct prefix_ipv6*) &hash_entry[1];
-  unsigned int hash = 0;
-  unsigned int i;
-
-  hash = (hash * 33) ^ (unsigned int)dst_p->prefixlen;
-  for (i = 0; i < 4; i++)
-    hash = (hash * 33) ^ (unsigned int)dst_p->prefix.s6_addr32[i];
-
-  hash = (hash * 33) ^ (unsigned int)src_p->prefixlen;
-  if (src_p->prefixlen)
-    for (i = 0; i < 4; i++)
-      hash = (hash * 33) ^ (unsigned int)src_p->prefix.s6_addr32[i];
-
-  return hash;
-}
-
-static int
-log_cmp(const void *a, const void *b)
-{
-  if (a == NULL && b != NULL)
-    return 0;
-  if (b == NULL && a != NULL)
-    return 0;
-
-  return !memcmp(a, b, 2 * sizeof(struct prefix));
-}
-
-static void
-log_free(void *data)
-{
-  XFREE(MTYPE_TMP, data);
-}
-
-static void *
-log_alloc(void *data)
-{
-  void *rv = XMALLOC(MTYPE_TMP, 2 * sizeof(struct prefix));
-  memcpy(rv, data, 2 * sizeof(struct prefix));
-  return rv;
-}
-
-static struct test_state *
-test_state_new(void)
-{
-  struct test_state *rv;
-
-  rv = XCALLOC(MTYPE_TMP, sizeof(*rv));
-  assert(rv);
-
-  rv->table = srcdest_table_init();
-  assert(rv->table);
-
-  rv->log = hash_create(log_key, log_cmp);
-  return rv;
-}
-
-static void
-test_state_free(struct test_state *test)
-{
-  route_table_finish(test->table);
-  hash_clean(test->log, log_free);
-  hash_free(test->log);
-  XFREE(MTYPE_TMP, test);
-}
-
-static void
-test_state_add_route(struct test_state *test,
-                     struct prefix_ipv6 *dst_p,
-                     struct prefix_ipv6 *src_p)
-{
-  struct route_node *rn = srcdest_rnode_get(
-      test->table, (struct prefix*)dst_p, src_p
-  );
-  struct prefix hash_entry[2];
-
-  memset(hash_entry, 0, sizeof(hash_entry));
-  memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
-  memcpy(&hash_entry[1], src_p, sizeof(*src_p));
-
-  if (rn->info) {
-    route_unlock_node(rn);
-    assert(hash_lookup(test->log, hash_entry) != NULL);
-    return;
-  } else {
-    assert(hash_lookup(test->log, hash_entry) == NULL);
-  }
-
-  rn->info = (void*) 0xdeadbeef;
-  hash_get(test->log, hash_entry, log_alloc);
-};
-
-static void
-test_state_del_route(struct test_state *test,
-                    struct prefix_ipv6 *dst_p,
-                    struct prefix_ipv6 *src_p)
-{
-  struct route_node *rn = srcdest_rnode_lookup(
-      test->table, (struct prefix*)dst_p, src_p
-  );
-  struct prefix hash_entry[2];
-
-  memset(hash_entry, 0, sizeof(hash_entry));
-  memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
-  memcpy(&hash_entry[1], src_p, sizeof(*src_p));
-
-  if (!rn) {
-    assert(!hash_lookup(test->log, hash_entry));
-    return;
-  }
-
-  assert(rn->info == (void*)0xdeadbeef);
-  rn->info = NULL;
-  route_unlock_node(rn);
-  route_unlock_node(rn);
-
-  struct prefix *hash_entry_intern = hash_release(test->log, hash_entry);
-  assert(hash_entry_intern != NULL);
-  XFREE(MTYPE_TMP, hash_entry_intern);
-}
-
-static void
-verify_log(struct hash_backet* backet, void *arg)
-{
-  struct test_state *test = arg;
-  struct prefix *hash_entry = backet->data;
-  struct prefix *dst_p = &hash_entry[0];
-  struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1];
-  struct route_node *rn = srcdest_rnode_lookup(test->table, dst_p, src_p);
-
-  assert(rn);
-  assert(rn->info == (void*)0xdeadbeef);
-
-  route_unlock_node(rn);
-}
-
-static void
-dump_log(struct hash_backet* backet, void *arg)
-{
-  struct prefix *hash_entry = backet->data;
-  struct prefix_ipv6 *dst_p = (struct prefix_ipv6*)&hash_entry[0];
-  struct prefix_ipv6 *src_p = (struct prefix_ipv6*)&hash_entry[1];
-  char *route_id = format_srcdest(dst_p, src_p);
-
-  fprintf(stderr, "  %s\n", route_id);
-  free(route_id);
-}
-
-static void
-test_dump(struct test_state *test)
-{
-  fprintf(stderr, "Contents of hash table:\n");
-  hash_iterate(test->log, dump_log, test);
-  fprintf(stderr, "\n");
-}
-
-static void
-test_failed(struct test_state *test, const char *message,
-            struct prefix_ipv6 *dst_p, struct prefix_ipv6 *src_p)
-{
-  char *route_id = format_srcdest(dst_p, src_p);
-
-  fprintf(stderr, "Test failed. Error: %s\n", message);
-  fprintf(stderr, "Route in question: %s\n", route_id);
-  free(route_id);
-
-  test_dump(test);
-  assert(3 == 4);
-}
-
-static void
-test_state_verify(struct test_state *test)
-{
-  struct route_node *rn;
-  struct prefix hash_entry[2];
-
-  memset(hash_entry, 0, sizeof(hash_entry));
-
-  /* Verify that there are no elements in the table which have never
-   * been added */
-  for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn))
-    {
-      struct prefix_ipv6 *dst_p, *src_p;
-
-      /* While we are iterating, we hold a lock on the current route_node,
-       * so all the lock counts we check for take that into account; in idle
-       * state all the numbers will be exactly one less.
-       *
-       * Also this makes quite some assumptions based on the current
-       * implementation details of route_table and srcdest_table - another
-       * valid implementation might trigger assertions here.
-       */
-
-      if (rnode_is_dstnode(rn))
-        {
-          struct srcdest_rnode *srn = (struct srcdest_rnode *)rn;
-          unsigned int expected_lock = 1; /* We are in the loop */
-
-          if (rn->info != NULL) /* The route node is not internal */
-            expected_lock++;
-          if (srn->src_table != NULL) /* There's a source table associated with rn */
-            expected_lock++;
-
-          if (rn->lock != expected_lock)
-            test_failed(test, "Dest rnode lock count doesn't match expected count!",
-                        (struct prefix_ipv6*)&rn->p, NULL);
-        }
-      else
-        {
-          unsigned int expected_lock = 1; /* We are in the loop */
-
-          if (rn->info != NULL) /* The route node is not internal */
-            expected_lock++;
-
-          if (rn->lock != expected_lock)
-            {
-              struct prefix_ipv6 *dst_p, *src_p;
-              srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p,
-                                         (struct prefix**)&src_p);
-
-              test_failed(test, "Src rnode lock count doesn't match expected count!",
-                          dst_p, src_p);
-            }
-        }
-
-      if (!rn->info)
-        continue;
-
-      assert(rn->info == (void*)0xdeadbeef);
-
-      srcdest_rnode_prefixes(rn, (struct prefix**)&dst_p, (struct prefix**)&src_p);
-      memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
-      if (src_p)
-        memcpy(&hash_entry[1], src_p, sizeof(*src_p));
-      else
-        memset(&hash_entry[1], 0, sizeof(hash_entry[1]));
-
-      if (hash_lookup(test->log, hash_entry) == NULL)
-        test_failed(test, "Route is missing in hash", dst_p, src_p);
-    }
-
-  /* Verify that all added elements are still in the table */
-  hash_iterate(test->log, verify_log, test);
-}
-
-static void
-get_rand_prefix(struct prng *prng, struct prefix_ipv6 *p)
-{
-  int i;
-
-  memset(p, 0, sizeof(*p));
-
-  for (i = 0; i < 4; i++)
-    p->prefix.s6_addr32[i] = prng_rand(prng);
-  p->prefixlen = prng_rand(prng) % 129;
-  p->family = AF_INET6;
-
-  apply_mask((struct prefix*)p);
-}
-
-static void
-get_rand_prefix_pair(struct prng *prng, struct prefix_ipv6 *dst_p,
-                     struct prefix_ipv6 *src_p)
-{
-  get_rand_prefix(prng, dst_p);
-  if ((prng_rand(prng) % 4) == 0)
-    {
-      get_rand_prefix(prng, src_p);
-      if (src_p->prefixlen)
-        return;
-    }
-
-  memset(src_p, 0, sizeof(*src_p));
-}
-
-static void
-test_state_add_rand_route(struct test_state *test,
-                          struct prng *prng)
-{
-  struct prefix_ipv6 dst_p, src_p;
-
-  get_rand_prefix_pair(prng, &dst_p, &src_p);
-  test_state_add_route(test, &dst_p, &src_p);
-}
-
-static void
-test_state_del_rand_route(struct test_state *test,
-                          struct prng *prng)
-{
-  struct prefix_ipv6 dst_p, src_p;
-
-  get_rand_prefix_pair(prng, &dst_p, &src_p);
-  test_state_del_route(test, &dst_p, &src_p);
-}
-
-static void
-test_state_del_one_route(struct test_state *test,
-                        struct prng *prng)
-{
-  unsigned int which_route = prng_rand(prng) % test->log->count;
-  struct route_node *rn;
-  struct prefix *dst_p, *src_p;
-  struct prefix_ipv6 dst6_p, src6_p;
-
-  for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn))
-    {
-      if (!rn->info)
-        continue;
-      if (!which_route) {
-        route_unlock_node(rn);
-        break;
-      }
-      which_route--;
-    }
-
-  assert(rn);
-  srcdest_rnode_prefixes(rn, &dst_p, &src_p);
-  memcpy(&dst6_p, dst_p, sizeof(dst6_p));
-  if (src_p)
-    memcpy(&src6_p, src_p, sizeof(src6_p));
-  else
-    memset(&src6_p, 0, sizeof(src6_p));
-
-  test_state_del_route(test, &dst6_p, &src6_p);
-}
-
-static void
-run_prng_test(void)
-{
-  struct test_state *test = test_state_new();
-  struct prng *prng = prng_new(0);
-  size_t i;
-
-  for (i = 0; i < 1000; i++)
-    {
-      switch (prng_rand(prng) % 10)
-        {
-        case 0:
-        case 1:
-        case 2:
-        case 3:
-        case 4:
-          test_state_add_rand_route(test, prng);
-          break;
-        case 5:
-        case 6:
-        case 7:
-          test_state_del_one_route(test, prng);
-          break;
-        case 8:
-        case 9:
-          test_state_del_rand_route(test, prng);
-          break;
-        }
-      test_state_verify(test);
-    }
-
-  prng_free(prng);
-  test_state_free(test);
-}
-
-int main(int argc, char *argv[])
-{
-  run_prng_test();
-  printf("PRNG Test successful.\n");
-  return 0;
-}
diff --git a/tests/test-stream.c b/tests/test-stream.c
deleted file mode 100644 (file)
index 3ac45eb..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Simple stream test.
- * 
- * Copyright (C) 2006 Sun Microsystems, Inc.
- *
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
- */
-
-#include <zebra.h>
-#include <stream.h>
-#include <thread.h>
-
-static unsigned long long ham = 0xdeadbeefdeadbeef;
-struct thread_master *master;
-
-static void
-print_stream (struct stream *s)
-{
-  size_t getp = stream_get_getp (s);
-  
-  printf ("endp: %zu, readable: %zu, writeable: %zu\n",
-          stream_get_endp (s),
-          STREAM_READABLE (s),
-          STREAM_WRITEABLE (s));
-  
-  while (STREAM_READABLE (s))
-    {
-      printf ("0x%x ", *stream_pnt (s));
-      stream_forward_getp (s, 1);
-    }
-  
-  printf ("\n");
-  
-  /* put getp back to where it was */
-  stream_set_getp (s, getp);
-}
-
-int
-main (void)
-{
-  struct stream *s;
-  
-  s = stream_new (1024);
-  
-  stream_putc (s, ham);
-  stream_putw (s, ham);
-  stream_putl (s, ham);
-  stream_putq (s, ham);
-  
-  print_stream (s);
-  
-  stream_resize (s, stream_get_endp (s));
-  
-  print_stream (s);
-  
-  printf ("c: 0x%hhx\n", stream_getc (s));
-  printf ("w: 0x%hx\n", stream_getw (s));
-  printf ("l: 0x%x\n", stream_getl (s));
-  printf ("q: 0x%" PRIx64 "\n", stream_getq (s));
-  
-  return 0;
-}
diff --git a/tests/test-timer-correctness.c b/tests/test-timer-correctness.c
deleted file mode 100644 (file)
index e523929..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Test program to verify that scheduled timers are executed in the
- * correct order.
- *
- * Copyright (C) 2013 by Open Source Routing.
- * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include <stdio.h>
-#include <unistd.h>
-
-#include "memory.h"
-#include "pqueue.h"
-#include "prng.h"
-#include "thread.h"
-
-#define SCHEDULE_TIMERS 800
-#define REMOVE_TIMERS   200
-
-#define TIMESTR_LEN strlen("4294967296.999999")
-
-struct thread_master *master;
-
-static size_t log_buf_len;
-static size_t log_buf_pos;
-static char *log_buf;
-
-static size_t expected_buf_len;
-static size_t expected_buf_pos;
-static char *expected_buf;
-
-static struct prng *prng;
-
-static struct thread **timers;
-
-static int timers_pending;
-
-static void terminate_test(void)
-{
-  int exit_code;
-
-  if (strcmp(log_buf, expected_buf))
-    {
-      fprintf(stderr, "Expected output and received output differ.\n");
-      fprintf(stderr, "---Expected output: ---\n%s", expected_buf);
-      fprintf(stderr, "---Actual output: ---\n%s", log_buf);
-      exit_code = 1;
-    }
-  else
-    {
-      printf("Expected output and actual output match.\n");
-      exit_code = 0;
-    }
-
-  thread_master_free(master);
-  XFREE(MTYPE_TMP, log_buf);
-  XFREE(MTYPE_TMP, expected_buf);
-  prng_free(prng);
-  XFREE(MTYPE_TMP, timers);
-
-  exit(exit_code);
-}
-
-static int timer_func(struct thread *thread)
-{
-  int rv;
-
-  rv = snprintf(log_buf + log_buf_pos, log_buf_len - log_buf_pos,
-                "%s\n", (char*)thread->arg);
-  assert(rv >= 0);
-  log_buf_pos += rv;
-  assert(log_buf_pos < log_buf_len);
-  XFREE(MTYPE_TMP, thread->arg);
-
-  timers_pending--;
-  if (!timers_pending)
-    terminate_test();
-
-  return 0;
-}
-
-static int cmp_timeval(const void* a, const void *b)
-{
-  const struct timeval *ta = *(struct timeval * const *)a;
-  const struct timeval *tb = *(struct timeval * const *)b;
-
-  if (timercmp(ta, tb, <))
-    return -1;
-  if (timercmp(ta, tb, >))
-    return 1;
-  return 0;
-}
-
-int main(int argc, char **argv)
-{
-  int i, j;
-  struct thread t;
-  struct timeval **alarms;
-
-  master = thread_master_create();
-
-  log_buf_len = SCHEDULE_TIMERS * (TIMESTR_LEN + 1) + 1;
-  log_buf_pos = 0;
-  log_buf = XMALLOC(MTYPE_TMP, log_buf_len);
-
-  expected_buf_len = SCHEDULE_TIMERS * (TIMESTR_LEN + 1) + 1;
-  expected_buf_pos = 0;
-  expected_buf = XMALLOC(MTYPE_TMP, expected_buf_len);
-
-  prng = prng_new(0);
-
-  timers = XMALLOC(MTYPE_TMP, SCHEDULE_TIMERS * sizeof(*timers));
-
-  for (i = 0; i < SCHEDULE_TIMERS; i++)
-    {
-      long interval_msec;
-      int ret;
-      char *arg;
-
-      /* Schedule timers to expire in 0..5 seconds */
-      interval_msec = prng_rand(prng) % 5000;
-      arg = XMALLOC(MTYPE_TMP, TIMESTR_LEN + 1);
-      timers[i] = thread_add_timer_msec(master, timer_func, arg, interval_msec);
-      ret = snprintf(arg, TIMESTR_LEN + 1, "%lld.%06lld",
-                     (long long)timers[i]->u.sands.tv_sec,
-                     (long long)timers[i]->u.sands.tv_usec);
-      assert(ret > 0);
-      assert((size_t)ret < TIMESTR_LEN + 1);
-      timers_pending++;
-    }
-
-  for (i = 0; i < REMOVE_TIMERS; i++)
-    {
-      int index;
-
-      index = prng_rand(prng) % SCHEDULE_TIMERS;
-      if (!timers[index])
-        continue;
-
-      XFREE(MTYPE_TMP, timers[index]->arg);
-      thread_cancel(timers[index]);
-      timers[index] = NULL;
-      timers_pending--;
-    }
-
-  /* We create an array of pointers to the alarm times and sort
-   * that array. That sorted array is used to generate a string
-   * representing the expected "output" of the timers when they
-   * are run. */
-  j = 0;
-  alarms = XMALLOC(MTYPE_TMP, timers_pending * sizeof(*alarms));
-  for (i = 0; i < SCHEDULE_TIMERS; i++)
-    {
-      if (!timers[i])
-        continue;
-      alarms[j++] = &timers[i]->u.sands;
-    }
-  qsort(alarms, j, sizeof(*alarms), cmp_timeval);
-  for (i = 0; i < j; i++)
-    {
-      int ret;
-
-      ret = snprintf(expected_buf + expected_buf_pos,
-                     expected_buf_len - expected_buf_pos,
-                     "%lld.%06lld\n",
-                     (long long)alarms[i]->tv_sec,
-                     (long long)alarms[i]->tv_usec);
-      assert(ret > 0);
-      expected_buf_pos += ret;
-      assert(expected_buf_pos < expected_buf_len);
-    }
-  XFREE(MTYPE_TMP, alarms);
-
-  while (thread_fetch(master, &t))
-    thread_call(&t);
-
-  return 0;
-}
diff --git a/tests/test-timer-performance.c b/tests/test-timer-performance.c
deleted file mode 100644 (file)
index a7d09be..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Test program which measures the time it takes to schedule and
- * remove timers.
- *
- * Copyright (C) 2013 by Open Source Routing.
- * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <zebra.h>
-
-#include <stdio.h>
-#include <unistd.h>
-
-#include "thread.h"
-#include "pqueue.h"
-#include "prng.h"
-
-#define SCHEDULE_TIMERS 1000000
-#define REMOVE_TIMERS    500000
-
-struct thread_master *master;
-
-static int dummy_func(struct thread *thread)
-{
-  return 0;
-}
-
-int main(int argc, char **argv)
-{
-  struct prng *prng;
-  int i;
-  struct thread **timers;
-  struct timeval tv_start, tv_lap, tv_stop;
-  unsigned long t_schedule, t_remove;
-
-  master = thread_master_create();
-  prng = prng_new(0);
-  timers = calloc(SCHEDULE_TIMERS, sizeof(*timers));
-
-  /* create thread structures so they won't be allocated during the
-   * time measurement */
-  for (i = 0; i < SCHEDULE_TIMERS; i++)
-    timers[i] = thread_add_timer_msec(master, dummy_func, NULL, 0);
-  for (i = 0; i < SCHEDULE_TIMERS; i++)
-    thread_cancel(timers[i]);
-
-  monotime(&tv_start);
-
-  for (i = 0; i < SCHEDULE_TIMERS; i++)
-    {
-      long interval_msec;
-
-      interval_msec = prng_rand(prng) % (100 * SCHEDULE_TIMERS);
-      timers[i] = thread_add_timer_msec(master, dummy_func,
-                                        NULL, interval_msec);
-    }
-
-  monotime(&tv_lap);
-
-  for (i = 0; i < REMOVE_TIMERS; i++)
-    {
-      int index;
-
-      index = prng_rand(prng) % SCHEDULE_TIMERS;
-      if (timers[index])
-        thread_cancel(timers[index]);
-      timers[index] = NULL;
-    }
-
-  monotime(&tv_stop);
-
-  t_schedule = 1000 * (tv_lap.tv_sec - tv_start.tv_sec);
-  t_schedule += (tv_lap.tv_usec - tv_start.tv_usec) / 1000;
-
-  t_remove = 1000 * (tv_stop.tv_sec - tv_lap.tv_sec);
-  t_remove += (tv_stop.tv_usec - tv_lap.tv_usec) / 1000;
-
-  printf("Scheduling %d random timers took %ld.%03ld seconds.\n",
-         SCHEDULE_TIMERS, t_schedule/1000, t_schedule%1000);
-  printf("Removing %d random timers took %ld.%03ld seconds.\n",
-         REMOVE_TIMERS, t_remove/1000, t_remove%1000);
-  fflush(stdout);
-
-  free(timers);
-  thread_master_free(master);
-  prng_free(prng);
-  return 0;
-}
diff --git a/tests/testcli.in b/tests/testcli.in
deleted file mode 100644 (file)
index 5c146ef..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-echo this is a  test message
-echo  foo bla  ?  baz
-echo
-
-arg ipv4 1.2.3.4
-arg ipv4 1.2.?3.4
-arg ipv4 1.2.3
-arg ipv4 1.2.3.4.5
-arg ipv4 1.a.3.4
-arg ipv4 blah
-
-arg ipv4m 1.2.3.0/24
-arg ipv4m 1.2.?3.0/24
-arg ipv4m 1.2.3/9
-arg ipv4m 1.2.3.4.5/6
-arg ipv4m 1.a.3.4
-arg ipv4m blah
-arg ipv4m 1.2.3.0/999
-arg ipv4m 1.2.3.0/a9
-arg ipv4m 1.2.3.0/9a
-
-arg ipv6 de4d:b33f::cafe
-arg ipv6 de4d:b3?3f::caf?e
-arg ipv6 de4d:b3       3f::caf?e
-arg ipv6 de4d:b33f:z::cafe
-arg ipv6 de4d:b33f:cafe:
-arg ipv6 ::
-arg ipv6 ::/
-arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0
-arg ipv6 12::34::56
-arg ipv6m dead:beef:cafe::/64
-arg ipv6m dead:be?ef:cafe:?:/64
-
-arg range 4
-arg range 5
-arg range 9?
-arg range 15
-arg range 16
-arg range -1
-arg range 99999999999999999999999999999999999999999
-
-arg ?
-
-pa     
-pat    
-
-pat a
-pat a a
-pat a ?b
-pat a c?
-pat a a x
-
-pat c a
-pat c a 1.2.3.4
-pat c b 2.3.4
-pat c c ?x
-
-pat d
-pat d  
-pat d foo 1.2.3.4
-pat d foo
-pat d noooo
-pat d bar 1::2
-pat d bar 1::2 foo 3.4.5.6
-pat d ba?z
-pat d foo 3.4.5.6 baz
-
-pat e
-pat e f
-pat e f g
-pat e 1.2.3.4
-
-pat f
-pat f foo
-pat f key
-
-alt a  a?b
-alt a 1        .2?.3.4
-alt a 1        :2?     ::?3
-
-conf t
-do pat d baz
-exit
-
-show run
-conf t
-hostname foohost
-do show run
diff --git a/tests/testcli.refout b/tests/testcli.refout
deleted file mode 100644 (file)
index 8b438ba..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-test# echo this is a  test message\r
-this is a test message\r
-test# echo  foo bla  \r
-% There is no matched command.\r
-test# echo  foo bla    baz\r
-foo bla baz\r
-test# echo\r
-% Command incomplete.\r
-test# \r
-test# arg ipv4 1.2.3.4\r
-cmd0 with 3 args.\r
-[00]: arg\r
-[01]: ipv4\r
-[02]: 1.2.3.4\r
-test# arg ipv4 1.2.\r
-  A.B.C.D  02\r
-test# arg ipv4 1.2.3.4\r
-cmd0 with 3 args.\r
-[00]: arg\r
-[01]: ipv4\r
-[02]: 1.2.3.4\r
-test# arg ipv4 1.2.3\r
-% [NONE] Unknown command: arg ipv4 1.2.3\r
-test# arg ipv4 1.2.3.4.5\r
-% [NONE] Unknown command: arg ipv4 1.2.3.4.5\r
-test# arg ipv4 1.a.3.4\r
-% [NONE] Unknown command: arg ipv4 1.a.3.4\r
-test# arg ipv4 blah\r
-% [NONE] Unknown command: arg ipv4 blah\r
-test# \r
-test# arg ipv4m 1.2.3.0/24\r
-cmd1 with 3 args.\r
-[00]: arg\r
-[01]: ipv4m\r
-[02]: 1.2.3.0/24\r
-test# arg ipv4m 1.2.\r
-  A.B.C.D/M  02\r
-test# arg ipv4m 1.2.3.0/24\r
-cmd1 with 3 args.\r
-[00]: arg\r
-[01]: ipv4m\r
-[02]: 1.2.3.0/24\r
-test# arg ipv4m 1.2.3/9\r
-% [NONE] Unknown command: arg ipv4m 1.2.3/9\r
-test# arg ipv4m 1.2.3.4.5/6\r
-% [NONE] Unknown command: arg ipv4m 1.2.3.4.5/6\r
-test# arg ipv4m 1.a.3.4\r
-% [NONE] Unknown command: arg ipv4m 1.a.3.4\r
-test# arg ipv4m blah\r
-% [NONE] Unknown command: arg ipv4m blah\r
-test# arg ipv4m 1.2.3.0/999\r
-% [NONE] Unknown command: arg ipv4m 1.2.3.0/999\r
-test# arg ipv4m 1.2.3.0/a9\r
-% [NONE] Unknown command: arg ipv4m 1.2.3.0/a9\r
-test# arg ipv4m 1.2.3.0/9a\r
-% [NONE] Unknown command: arg ipv4m 1.2.3.0/9a\r
-test# \r
-test# arg ipv6 de4d:b33f::cafe\r
-cmd2 with 3 args.\r
-[00]: arg\r
-[01]: ipv6\r
-[02]: de4d:b33f::cafe\r
-test# arg ipv6 de4d:b3\r
-% There is no matched command.\r
-test# arg ipv6 de4d:b33f::caf\r
-  X:X::X:X  02\r
-test# arg ipv6 de4d:b33f::cafe\r
-cmd2 with 3 args.\r
-[00]: arg\r
-[01]: ipv6\r
-[02]: de4d:b33f::cafe\r
-test# arg ipv6 de4d:b3\r
-test# arg ipv6 de4d:b33f::caf\r
-  X:X::X:X  02\r
-test# arg ipv6 de4d:b33f::cafe\r
-cmd2 with 3 args.\r
-[00]: arg\r
-[01]: ipv6\r
-[02]: de4d:b33f::cafe\r
-test# arg ipv6 de4d:b33f:z::cafe\r
-% [NONE] Unknown command: arg ipv6 de4d:b33f:z::cafe\r
-test# arg ipv6 de4d:b33f:cafe:\r
-% [NONE] Unknown command: arg ipv6 de4d:b33f:cafe:\r
-test# arg ipv6 ::\r
-cmd2 with 3 args.\r
-[00]: arg\r
-[01]: ipv6\r
-[02]: ::\r
-test# arg ipv6 ::/\r
-% [NONE] Unknown command: arg ipv6 ::/\r
-test# arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0\r
-% [NONE] Unknown command: arg ipv6 1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0:1:2:3:4:5:6:7:8:9:0\r
-test# arg ipv6 12::34::56\r
-% [NONE] Unknown command: arg ipv6 12::34::56\r
-test# arg ipv6m dead:beef:cafe::/64\r
-cmd3 with 3 args.\r
-[00]: arg\r
-[01]: ipv6m\r
-[02]: dead:beef:cafe::/64\r
-test# arg ipv6m dead:be\r
-  X:X::X:X/M  02\r
-test# arg ipv6m dead:beef:cafe:\r
-  X:X::X:X/M  02\r
-test# arg ipv6m dead:beef:cafe::/64\r
-cmd3 with 3 args.\r
-[00]: arg\r
-[01]: ipv6m\r
-[02]: dead:beef:cafe::/64\r
-test# \r
-test# arg range 4\r
-% [NONE] Unknown command: arg range 4\r
-test# arg range 5\r
-cmd4 with 3 args.\r
-[00]: arg\r
-[01]: range\r
-[02]: 5\r
-test# arg range 9\r
-  (5-15)  02\r
-test# arg range 9\r
-cmd4 with 3 args.\r
-[00]: arg\r
-[01]: range\r
-[02]: 9\r
-test# arg range 15\r
-cmd4 with 3 args.\r
-[00]: arg\r
-[01]: range\r
-[02]: 15\r
-test# arg range 16\r
-% [NONE] Unknown command: arg range 16\r
-test# arg range -1\r
-% [NONE] Unknown command: arg range -1\r
-test# arg range 99999999999999999999999999999999999999999\r
-% [NONE] Unknown command: arg range 99999999999999999999999999999999999999999\r
-test# \r
-test# arg \r
-  ipv4   01\r
-  ipv4m  01\r
-  ipv6   01\r
-  ipv6m  01\r
-  range  01\r
-test# arg \r
-% Command incomplete.\r
-test# \r
-test# pa\r
-test# pa\b\bpat \r
-% Command incomplete.\r
-test# pat \r
-a          c          d          e          f          \r
-test# pat \r
-% Command incomplete.\r
-test# \r
-test# pat a\r
-% Command incomplete.\r
-test# pat a a\r
-cmd5 with 3 args.\r
-[00]: pat\r
-[01]: a\r
-[02]: a\r
-test# pat a \r
-  a  02\r
-  b  03\r
-test# pat a b\r
-cmd5 with 3 args.\r
-[00]: pat\r
-[01]: a\r
-[02]: b\r
-test# pat a c\r
-% There is no matched command.\r
-test# pat a c\r
-% [NONE] Unknown command: pat a c\r
-test# pat a a x\r
-% [NONE] Unknown command: pat a a x\r
-test# \r
-test# pat c a\r
-% Command incomplete.\r
-test# pat c a 1.2.3.4\r
-cmd7 with 4 args.\r
-[00]: pat\r
-[01]: c\r
-[02]: a\r
-[03]: 1.2.3.4\r
-test# pat c b 2.3.4\r
-% [NONE] Unknown command: pat c b 2.3.4\r
-test# pat c c \r
-  A.B.C.D  05\r
-test# pat c c x\r
-% [NONE] Unknown command: pat c c x\r
-test# \r
-test# pat d\r
-% Command incomplete.\r
-test# pat d \r
-bar        baz        foo        \r
-test# pat d \r
-% Command incomplete.\r
-test# pat d foo 1.2.3.4\r
-cmd8 with 4 args.\r
-[00]: pat\r
-[01]: d\r
-[02]: foo\r
-[03]: 1.2.3.4\r
-test# pat d foo\r
-% Command incomplete.\r
-test# pat d noooo\r
-% [NONE] Unknown command: pat d noooo\r
-test# pat d bar 1::2\r
-cmd8 with 4 args.\r
-[00]: pat\r
-[01]: d\r
-[02]: bar\r
-[03]: 1::2\r
-test# pat d bar 1::2 foo 3.4.5.6\r
-cmd8 with 6 args.\r
-[00]: pat\r
-[01]: d\r
-[02]: bar\r
-[03]: 1::2\r
-[04]: foo\r
-[05]: 3.4.5.6\r
-test# pat d ba\r
-  bar  04\r
-  baz  06\r
-test# pat d baz\r
-cmd8 with 3 args.\r
-[00]: pat\r
-[01]: d\r
-[02]: baz\r
-test# pat d foo 3.4.5.6 baz\r
-cmd8 with 5 args.\r
-[00]: pat\r
-[01]: d\r
-[02]: foo\r
-[03]: 3.4.5.6\r
-[04]: baz\r
-test# \r
-test# pat e\r
-cmd9 with 2 args.\r
-[00]: pat\r
-[01]: e\r
-test# pat e f\r
-cmd9 with 3 args.\r
-[00]: pat\r
-[01]: e\r
-[02]: f\r
-test# pat e f g\r
-% [NONE] Unknown command: pat e f g\r
-test# pat e 1.2.3.4\r
-cmd9 with 3 args.\r
-[00]: pat\r
-[01]: e\r
-[02]: 1.2.3.4\r
-test# \r
-test# pat f\r
-cmd10 with 2 args.\r
-[00]: pat\r
-[01]: f\r
-test# pat f foo\r
-% [NONE] Unknown command: pat f foo\r
-test# pat f key\r
-cmd10 with 3 args.\r
-[00]: pat\r
-[01]: f\r
-[02]: key\r
-test# \r
-test# alt a \r
-test# alt a a\r
-  WORD  02\r
-test# alt a ab\r
-cmd11 with 3 args.\r
-[00]: alt\r
-[01]: a\r
-[02]: ab\r
-test# alt a 1\r
-test# alt a 1.2\r
-  A.B.C.D  02\r
-  WORD     02\r
-test# alt a 1.2.3.4\r
-cmd12 with 3 args.\r
-[00]: alt\r
-[01]: a\r
-[02]: 1.2.3.4\r
-test# alt a 1\r
-test# alt a 1:2\r
-  WORD  02\r
-test# alt a 1:2\r
-test# alt a 1:2::\r
-  WORD      02\r
-  X:X::X:X  02\r
-test# alt a 1:2::3\r
-cmd13 with 3 args.\r
-[00]: alt\r
-[01]: a\r
-[02]: 1:2::3\r
-test# \r
-test# conf t\r
-test(config)# do pat d baz\r
-cmd8 with 3 args.\r
-[00]: pat\r
-[01]: d\r
-[02]: baz\r
-test(config)# exit\r
-test# \r
-test# show run\r
-\r
-Current configuration:\r
-!\r
-hostname test\r
-!\r
-!\r
-line vty\r
-!\r
-end\r
-test# conf t\r
-test(config)# hostname foohost\r
-foohost(config)# do show run\r
-\r
-Current configuration:\r
-!\r
-hostname foohost\r
-!\r
-!\r
-line vty\r
-!\r
-end\r
-foohost(config)# 
-end.
diff --git a/tests/testcommands.in b/tests/testcommands.in
deleted file mode 100644 (file)
index 7fe6279..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-#
-#
-# Some randomly chosen valid commands
-#
-#
-area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE
-area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1
-area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1
-area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1
-area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1
-clear bgp 1 out
-clear bgp ipv6 2001:db8::1 out
-clear bgp view VARIABLE * soft
-clear ip bgp 1.2.3.4 ipv4 multicast out
-ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig
-ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1
-network 1.0.0.0/8 area 0
-no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay
-no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay
-no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval
-no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval
-no bgp graceful-restart
-no ipv6 nd mtu 1
-no neighbor 1.2.3.4 distribute-list 1 in
-no neighbor 2001:db8::1 send-community both
-no neighbor VARIABLE maximum-prefix
-redistribute isis route-map VARIABLE metric 0 metric-type 2
-redistribute rip metric 0 route-map VARIABLE metric-type 1
-show bgp community VARIABLE local-AS no-export VARIABLE exact-match
-show bgp ipv6 community no-advertise no-export no-export no-export
-show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match
-show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match
-show bgp view VARIABLE
-show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE
-show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS
-show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise
-show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE
-show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS
-show ip bgp community no-advertise local-AS no-advertise VARIABLE
-show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match
-show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match
-show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match
-show ipv6 bgp community no-export no-export VARIABLE VARIABLE
-show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match
-show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match
-show ipv6 mbgp community local-AS local-AS no-export no-export exact-match
-show ipv6 mbgp community no-export no-export local-AS no-export exact-match
-show ipv6 ospf6 database as-external dump
-show ipv6 ospf6 database inter-prefix 1.2.3.4 detail
-show ipv6 ospf6 database intra-prefix 1.2.3.4 internal
-#
-#
-# Slightly Fuzzed commands
-#
-#
-a8ra 0 range 1.0.0.0/8 adverOise
-accept-lifetime VARIABE 1 VA6IABLE 19I3 VARIABLE 1 VARIABLE 1993
-arAea 1.2.M.4 virtual-link 1.2.3.4 dead-interval 1 dead-interval 1 dead-inter6val 1 transmit-delay 1
-area 0 virtu0al-link 1.2.3.i hello-interval 1 ello-interval 1 transmit-delay 1 retransmit-interval 1
-area 0 virtual-lin 1.2.3.4 retransmit-interval 1 tranwmit-delay 1 retransmit-interval 1 retransmit-interval 1
-area 0 virtual-link 1.2.3.4 retransmit-interal 1 trasmit-dely 1
-area 1.2.3.4 virtual-link 1.2.3.4 deadCinterval 1  dead-intervalK 1 retransmit-interval 1 dead-interval 1
-area 1.2.3.4 virtual-link 1.2.3.4 dead-intervalo I1 dead-interval 1 retransmit-interval1 dead-interval 1
-area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1
-area 1.2.3.4 virtuyl-link 1.2.3.4 dead-interval 1 dead-inervalI 1 retransmit-interval 1 dead-interval 1
-area 1.2.3.4 virual-link 1.2.34 retransmit-interval 1 dead-interval 1 dead-interva 1
-area1.2.83.4 virtual-link 1.2.3.4 retra0smit-interval 1 dead-interval 1 dead-interval 1
-clear bgAp 2001g:dbK::1
-clear ip bgp 1.2.3.4 pv4 mlticat out
-cleau bg i2001:db8::1 rsclient
-de:ug ospf6 messag2 lsreq :recv
-how ip bgp communiQy no-advertise no-adve:tise no-advertise
-ip route 1.0Q0.0/8 1.2.3.s4 reGject
-ipv6 nd prefix 2O01:db8::/32 0 infinEite off-link
-ipv6 nwd prefix 2001:db8::/32 0 infinite oUUff-link
-ipv6 route 2001:db8::/32q2001:db8:k: blackhole 1
-kshow ip rIute bgp
-matcch peer .2.30.4
-mcogin
-mhow ipv6 mbgp community o-advertise yocal-AS no-advertise
-neighbor1.2..4 attribute-unchnged next-hop
-neihbcr 2001:d b8::1 distribute-list 1 in
-nko key-tqring
-no area 0 viertual-link 1.2.3k.4 retransmit-iterval retransmit-interval retransmit-interval hello-interval
-no area 0 virtual-link 1.2.3.4 dead-intaerval dead-intervIl hello-interval retransmit-interval
-no area 0 virtual-link 1.2.3.4 retransmit-interval retransmit-intervIl dead-interval tranImit-deqlay
-no area 0 virtual-link S1.2.3.4 d-ead-interval hello-interval transmit-deay transmit-delay
-no area 1.2.3.4 virtua -link 1.2.3.4 transmit-delay hello-interval hello-interval retransmt-interval
-no area 1.2.3.4 virtual-link 1.2.3.4 dea-iterval retransmit-interva- dead-interval hello-interval
-no area 1.2.3.4 virtual-link 1.2.3.4 hello-interSval dead-interval retransmit-interval transmitdelay
-no a:rea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interSvalW dead-interval retransmit-interval hello-interval
-noarea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval trynsmit-delay hello-interval
-no area 1.2.3.4 virtual-link 1.2.3.4 transmt:delay retransmit-interval retransmit-interval dead-Mnterval
-no ares 1.2.3.4 virtual-link 1.2.3.4 dead-interval retransmit-interval dead-inesval retransmit-interval
-no ayrea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval transmi-delay hello-interval
-no bg2 grace2fuy-restart
-no debug ospk6 nter2face
-noimatch ipv6 addrMss VARIABLE
-nomStch iA next-hop prefix-list
-no neighbCr 200 :db8::1oroute-map VARIABLE export
-no neighbor VARIABLE attributeaw8changed next-hop
-no orea 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval ead-interval retransmit-inteSval hello-interval
-no ospcdead-inkerval
-no redistribute kernelrote-map VARIABLE metric 0
-no redistribute s4taik metric 0
-nos Ceighbor 1.2.3.4 route-mapEVARIABLE in
-o :neighbor VAIABLE attribute-unchanged next-hop
-ooa router ip
-redistribute isis meGtric-type2 Q route-map VARIABLE
-redistribute static metric-type 1 metri 0 rowute-map VARIABLE
-set-Koveroadbit
-sh2w ipv6 mbgp  comAunity VARIABLE
-shgw bgp ipv6 community no-export VARIABLE no-xport no-expmrt
-shiow Wgp neighbors
-shoAw ip bgpipv4 unicast com6munity no-export no-export no-advertise no-export exact-match
-sho bgp view gARIABLE nyeighbors 2001:db8::1 received-routes
-shoow bgp ommunity local-AS no--export
-show6 bgp community no-advertise local4-AS no-advertise VARIABLE exact-math
-show8 bgp view VARIABLE ipv4 multicast community ARIABLE VARIABLE local-S
-show bgp cCommunity VARIABLE VOARIABL no-advertise
-show bgp cimAunity loal-AS local-AS no-export local-AS
-show bgp cmmunity n-advertise no-export local-S no-advertise
-show bgp communi0y no-export no-Cexport no-0xport no-export
-show bgp communityOlocal-A no-advertise local-WAS
-show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match
-show bgp communiy no-export no-adsvertise VARIABLOE local-AS
-show bgp communiYty no-export VARIABLE VARIABLE locali-AS exact-math
-show bgp commuUityW no-advertis local-AS no-advertise no-advertise
-show bgp commuWnity VAIABLE local-AS no-advertise n-export
-show bgp com:unity no-exportqno-export VARIABLE no-expoIrt exact-match
-show bgp ipv6 community local-AS no-expor no-xport VARIABCLE
-show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE
-show bgp ipv6 community no-advertise no6-export lcal-AS local-AS
-show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math
-show bgp ipv6 comm-unity no-advertise no-export local-AS local-kS exact-match
-show bgp ipv6 community no-export local-AS no-adertise no-adve-tie
-show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE
-show bgp naighbors 201:db8::1 rUeceived-routes
-show bgp viewVAIABLE ipv4 multicast community VARIABLE4no-export no-advertise local-AS
-show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS
-show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export
-show bgp view VARIABLE ipv4 multicast omsunity local-AS VARIABLE no-advertise nUo-export
-show bgp view VARIABLE ipv4 mutiast community no-export no-export VARIBLE no-export
-show bgp view VARIABLE ipv4 unicast 0community VARIABqLE local-AS no-export VARIABwE
-show bgp view VARIABLE ipv4 unicast communeity no-export AcRIABLE no-advertise local-AS
-show bgp view VARIABLE ipv4 unicasU comunity no-export VARIABL no-advertise
-show bgp view VARIABLE ipv6 unicast cocmmunity VARIABLE no-advet6ise VARIABLE
-show bgp view VARIABLE ipvk4 unicast communty no-advertie local-AS local-AS no-export
-show bgp view VARIALE ipv4 multicast cyommunity no-xport local-AS local-AS
-show i6 bge community no-export VARIABLE no-advegtise VARIABLE exact-match
-show iI bgp community no-advertise no-ad2vertsse VARIABLE exact-match
-show ip6osp6 database dump
-show ipA6 bgp community local-AS local-AS no-advertse lo:cal-AS
-show ip bg comunity VARIABLE lcal-AS no-advertise
-show ip bgp communityno-export2no-export no-advertise locaE-AS
-Show ip bgp community no-export loqcal-AS no-adverise no-export
-show ip bgp community no-expor VARIABLEono-export VARIAuBLE
-show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match
-show ip bgp cWmmunity no-expoWrt VARIABLE no-advertise VARIABLEexact-match
-show ip bgp ip4 nicast community no-advertise no-expoIt local-AS local-AS exact-match
-show ip bgp ipAv4 multicast community no-export no-export no-export no-advertiqe exact-mach
-show ip bgp ipv4 Aulticast community no-advertise VARIABLE no-advertisKe no-exort
-show ip bgp ipv4 meuqlticast community VARIABLE VARIABLE no-export n-export
-show ip bgp ipv4 mlticast coQmmunity localg-AS local-AS no-advertise local-AS
-show ip bgp ipv4 multicast communiy VARIABLE no-export VARIABLE no-advertise yxact-atch
-show ip bgp ipv4 unicast commu0nity local-AS no-export no-exrt VARIABLE exact-match
-show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match
-showip bgp ipv4 unicast community no-export VARIABLE no-exp-ort VAR6IABLE exact-match
-show ip bgp ipv4 unicat community no-exportlocal-AS VARIABLE no-export exa0t-match
-show ip bgp ipv4 unicst community no-advertiseG local-AS no-advertise
-show ip bgp i:v4 multicast community VARIABLE VARIABLE VARIABLE no-export eMxact-match
-show ip bgp Mv4 unicast community no-export VARIABLE VARIABLE VAoRIABLE
-show ipgexecommunity-list 1
-show ipkv6 bgp community no-export no-export VARIABL VARIBLE
-show ipv6 bgp commu2nity local-AS local-AS noEadvertise local-AS
-show ipv6 bgp communitK VARIABLE lcocal-AS no-advertie no-advertise exact-match
-show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match
-show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE
-show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match
-show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE
-show ipv6 bgp comu-ity VARIABLE local-AS no-advertise no-export exact-match
-show ipv6 bgp comunity no- export local-AS no-advertisge VARIABLE
-show ipv6 bgp ommunity sno-advcrtise VARIABLE no-export no-advertise exact-match
-show ipv6 igp community no-advertise no-advertise no-ecxpo0rt no-export
-show ipv6 mb communyty VARIABLE
-show ipv6 osp8f6 database nQtwork adv-ruter 1.2.3.4 detail
-show ipv6 ospf6 dataase type-7 adv-router 1.2.3.4 inernal
-show ipv6 ospf6 Edatabase intuer8-prefix 1.2.3.4 detail
-show ipvq6 ospf6 database as-externa detil
-show ip Wbgp ipv4 unicast community no-advertise no-exprt no-export VARIABLEK exact-match
-show ip Ybgp attribute-in ufo
-showMbgp ipv6 community ARIABLE local-AS local-AS no8advertise exact-match
-show p bgp community no-dvertise no-export no-advertiseIno-export exact-match
-show uipv6 mbgp coqmmunKty VARIABLE
-shQw ipv6 mbgp community no-advetise local-AS no-export no-export ex8ct-match
-shuw ipv6 mbgp community VARIABLyUE no-export no-export no-advertise
-shw bgp view VARIABLE ipv4 un0icast Gcommunity no-export VARIABLE no-advertise
-sow ip bgp ipv4 mulicast community no-export no-adertise no-export no-advertise
-sow ipv6 ospf6 databIase as-external adv-router 1.2.3.4
-Whow bgp view VARIAeBLE ipv4 unicast community local-AS no-advrtise no-advertise local-AS
-Wneighbor 1.2.3.4 dot-capabiliy-negotiate
-#
-#
-# Some teststrings explicitly used for keyword commands
-#
-#
-redistribute bgp
-redistribute bgp m 10
-redistribute bgp metric 10 metric-type 1
-redistribute bgp metric 10 metric 10
-redistribute bgp route-map RMAP_REDIST_BGP
-default-information originate metric-type 1 metric 10
-default-information originate always metric-type 1 metric 10
-default-information originate route-map RMAP_DEFAULT
-default-information originate route-map RMAP_DEFAULT metric 10
-default-information originate always metric-type 2 metric 23
diff --git a/tests/testcommands.refout b/tests/testcommands.refout
deleted file mode 100644 (file)
index 9d4a6ef..0000000
+++ /dev/null
@@ -1,1007 +0,0 @@
-execute relaxed 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (authentication|) (message-digest|null) (message-digest-key|) <1-255> md5 KEY': '0', '1.2.3.4', 'authentication', 'null', 'message-digest-key', '1', 'VARIABLE'
-execute strict 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (authentication|) (message-digest|null) (message-digest-key|) <1-255> md5 KEY': '0', '1.2.3.4', 'authentication', 'null', 'message-digest-key', '1', 'VARIABLE'
-complete 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==2
-describe 'area 0 virtual-link 1.2.3.4 authentication null message-digest-key 1 md5 VARIABLE'@23: rv==0
-  'KEY' 'The OSPF password (key)'
-execute relaxed 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'dead-interval', '1', 'hello-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1'
-execute strict 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'dead-interval', '1', 'hello-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1'
-complete 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==2
-describe 'area 0 virtual-link 1.2.3.4 dead-interval 1 hello-interval 1 retransmit-interval 1 transmit-delay 1'@23: rv==0
-  '<1-65535>' 'Seconds'
-execute relaxed 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'dead-interval', '1', 'retransmit-interval', '1'
-execute strict 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '0', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'dead-interval', '1', 'retransmit-interval', '1'
-complete 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==2
-describe 'area 0 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 dead-interval 1 retransmit-interval 1'@23: rv==0
-  '<1-65535>' 'Seconds'
-execute relaxed 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'hello-interval', '1', 'hello-interval', '1', 'dead-interval', '1'
-execute strict 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'hello-interval', '1', 'hello-interval', '1', 'dead-interval', '1'
-complete 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==2
-describe 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 hello-interval 1 dead-interval 1'@23: rv==0
-  '<1-65535>' 'Seconds'
-execute relaxed 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1', 'dead-interval', '1'
-execute strict 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'retransmit-interval', '1', 'retransmit-interval', '1', 'transmit-delay', '1', 'dead-interval', '1'
-complete 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==2
-describe 'area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval 1 retransmit-interval 1 transmit-delay 1 dead-interval 1'@23: rv==0
-  '<1-65535>' 'Seconds'
-execute relaxed 'clear bgp 1 out'@4: rv==0, 'clear bgp <1-4294967295> out': '1'
-execute strict 'clear bgp 1 out'@4: rv==0, 'clear bgp <1-4294967295> out': '1'
-complete 'clear bgp 1 out'@4: rv==7
-  'out'
-describe 'clear bgp 1 out'@4: rv==0
-  'out' 'Soft reconfig outbound update'
-execute relaxed 'clear bgp ipv6 2001:db8::1 out'@4: rv==0, 'clear bgp ipv6 (A.B.C.D|X:X::X:X) out': '2001:db8::1'
-execute strict 'clear bgp ipv6 2001:db8::1 out'@4: rv==0, 'clear bgp ipv6 (A.B.C.D|X:X::X:X) out': '2001:db8::1'
-complete 'clear bgp ipv6 2001:db8::1 out'@4: rv==7
-  'out'
-describe 'clear bgp ipv6 2001:db8::1 out'@4: rv==0
-  'out' 'Soft reconfig outbound update'
-execute relaxed 'clear bgp view VARIABLE * soft'@4: rv==0, 'clear bgp view WORD * soft': 'VARIABLE'
-execute strict 'clear bgp view VARIABLE * soft'@4: rv==0, 'clear bgp view WORD * soft': 'VARIABLE'
-complete 'clear bgp view VARIABLE * soft'@4: rv==7
-  'soft'
-describe 'clear bgp view VARIABLE * soft'@4: rv==0
-  'soft' 'Soft reconfig'
-execute relaxed 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==0, 'clear ip bgp A.B.C.D ipv4 (unicast|multicast) out': '1.2.3.4', 'multicast'
-execute strict 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==0, 'clear ip bgp A.B.C.D ipv4 (unicast|multicast) out': '1.2.3.4', 'multicast'
-complete 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==7
-  'out'
-describe 'clear ip bgp 1.2.3.4 ipv4 multicast out'@4: rv==0
-  'out' 'Soft reconfig outbound update'
-execute relaxed 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==0, 'ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)': '2001:db8::/32', 'infinite', 'infinite', 'no-autoconfig'
-execute strict 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==0, 'ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)': '2001:db8::/32', 'infinite', 'infinite', 'no-autoconfig'
-complete 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==7
-  'no-autoconfig'
-describe 'ipv6 nd prefix 2001:db8::/32 infinite infinite no-autoconfig'@11: rv==0
-  'no-autoconfig' 'Do not use prefix for autoconfiguration'
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@5: rv==0
-  '<1-255>' 'Distance value for this prefix'
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@9: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@10: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@11: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@12: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@14: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@15: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@16: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@17: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@18: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@19: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@20: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@21: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@22: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@23: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@24: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@25: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@35: rv==2
-execute relaxed 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==0, 'ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>': '2001:db8::/32', '2001:db8::1', 'VARIABLE', '1'
-execute strict 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==2
-complete 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==2
-describe 'ipv6 route 2001:db8::/32 2001:db8::1 VARIABLE 1'@40: rv==2
-execute relaxed 'network 1.0.0.0/8 area 0'@23: rv==0, 'network A.B.C.D/M area (A.B.C.D|<0-4294967295>)': '1.0.0.0/8', '0'
-execute strict 'network 1.0.0.0/8 area 0'@23: rv==0, 'network A.B.C.D/M area (A.B.C.D|<0-4294967295>)': '1.0.0.0/8', '0'
-complete 'network 1.0.0.0/8 area 0'@23: rv==2
-describe 'network 1.0.0.0/8 area 0'@23: rv==0
-  '<0-4294967295>' 'OSPF area ID as a decimal value'
-  'A.B.C.D' 'OSPF area ID in IP address format'
-execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'hello-interval', 'transmit-delay'
-execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'hello-interval', 'transmit-delay'
-complete 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==7
-  'transmit-delay'
-describe 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval hello-interval transmit-delay'@23: rv==0
-  'transmit-delay' 'Seconds'
-execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'retransmit-interval', 'transmit-delay'
-execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'hello-interval', 'dead-interval', 'retransmit-interval', 'transmit-delay'
-complete 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==7
-  'transmit-delay'
-describe 'no area 1.2.3.4 virtual-link 1.2.3.4 hello-interval dead-interval retransmit-interval transmit-delay'@23: rv==0
-  'transmit-delay' 'Seconds'
-execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'retransmit-interval', 'dead-interval', 'retransmit-interval', 'hello-interval'
-execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'retransmit-interval', 'dead-interval', 'retransmit-interval', 'hello-interval'
-complete 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==7
-  'hello-interval'
-describe 'no area 1.2.3.4 virtual-link 1.2.3.4 retransmit-interval dead-interval retransmit-interval hello-interval'@23: rv==0
-  'hello-interval' 'Link state transmit delay'
-execute relaxed 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'transmit-delay', 'retransmit-interval', 'retransmit-interval', 'hello-interval'
-execute strict 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==0, 'no area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval) (hello-interval|retransmit-interval|transmit-delay|dead-interval)': '1.2.3.4', '1.2.3.4', 'transmit-delay', 'retransmit-interval', 'retransmit-interval', 'hello-interval'
-complete 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==7
-  'hello-interval'
-describe 'no area 1.2.3.4 virtual-link 1.2.3.4 transmit-delay retransmit-interval retransmit-interval hello-interval'@23: rv==0
-  'hello-interval' 'Link state transmit delay'
-execute relaxed 'no bgp graceful-restart'@17: rv==0, 'no bgp graceful-restart'
-execute strict 'no bgp graceful-restart'@17: rv==0, 'no bgp graceful-restart'
-complete 'no bgp graceful-restart'@17: rv==7
-  'graceful-restart'
-describe 'no bgp graceful-restart'@17: rv==0
-  'graceful-restart' 'Graceful restart capability parameters'
-execute relaxed 'no bgp graceful-restart'@18: rv==0, 'no bgp graceful-restart'
-execute strict 'no bgp graceful-restart'@18: rv==2
-complete 'no bgp graceful-restart'@18: rv==2
-describe 'no bgp graceful-restart'@18: rv==2
-execute relaxed 'no bgp graceful-restart'@19: rv==0, 'no bgp graceful-restart'
-execute strict 'no bgp graceful-restart'@19: rv==2
-complete 'no bgp graceful-restart'@19: rv==2
-describe 'no bgp graceful-restart'@19: rv==2
-execute relaxed 'no bgp graceful-restart'@20: rv==0, 'no bgp graceful-restart'
-execute strict 'no bgp graceful-restart'@20: rv==2
-complete 'no bgp graceful-restart'@20: rv==2
-describe 'no bgp graceful-restart'@20: rv==2
-execute relaxed 'no bgp graceful-restart'@21: rv==0, 'no bgp graceful-restart'
-execute strict 'no bgp graceful-restart'@21: rv==2
-complete 'no bgp graceful-restart'@21: rv==2
-describe 'no bgp graceful-restart'@21: rv==2
-execute relaxed 'no bgp graceful-restart'@22: rv==0, 'no bgp graceful-restart'
-execute strict 'no bgp graceful-restart'@22: rv==2
-complete 'no bgp graceful-restart'@22: rv==2
-describe 'no bgp graceful-restart'@22: rv==2
-execute relaxed 'no ipv6 nd mtu 1'@11: rv==0, 'no ipv6 nd mtu <1-65535>': '1'
-execute strict 'no ipv6 nd mtu 1'@11: rv==0, 'no ipv6 nd mtu <1-65535>': '1'
-complete 'no ipv6 nd mtu 1'@11: rv==2
-describe 'no ipv6 nd mtu 1'@11: rv==0
-  '<1-65535>' 'MTU in bytes'
-execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-complete 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==7
-  'in'
-describe 'no neighbor 1.2.3.4 distribute-list 1 in'@17: rv==0
-  'in' 'Filter incoming updates'
-execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-complete 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==7
-  'in'
-describe 'no neighbor 1.2.3.4 distribute-list 1 in'@18: rv==0
-  'in' 'Filter incoming updates'
-execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-complete 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==7
-  'in'
-describe 'no neighbor 1.2.3.4 distribute-list 1 in'@19: rv==0
-  'in' 'Filter incoming updates'
-execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-complete 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==7
-  'in'
-describe 'no neighbor 1.2.3.4 distribute-list 1 in'@20: rv==0
-  'in' 'Filter incoming updates'
-execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-complete 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==7
-  'in'
-describe 'no neighbor 1.2.3.4 distribute-list 1 in'@21: rv==0
-  'in' 'Filter incoming updates'
-execute relaxed 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-execute strict 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) distribute-list (<1-199>|<1300-2699>|WORD) (in|out)': '1.2.3.4', '1', 'in'
-complete 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==7
-  'in'
-describe 'no neighbor 1.2.3.4 distribute-list 1 in'@22: rv==0
-  'in' 'Filter incoming updates'
-execute relaxed 'no neighbor 2001:db8::1 send-community both'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-execute strict 'no neighbor 2001:db8::1 send-community both'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-complete 'no neighbor 2001:db8::1 send-community both'@17: rv==7
-  'both'
-describe 'no neighbor 2001:db8::1 send-community both'@17: rv==0
-  'both' 'Send Standard and Extended Community attributes'
-execute relaxed 'no neighbor 2001:db8::1 send-community both'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-execute strict 'no neighbor 2001:db8::1 send-community both'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-complete 'no neighbor 2001:db8::1 send-community both'@18: rv==7
-  'both'
-describe 'no neighbor 2001:db8::1 send-community both'@18: rv==0
-  'both' 'Send Standard and Extended Community attributes'
-execute relaxed 'no neighbor 2001:db8::1 send-community both'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-execute strict 'no neighbor 2001:db8::1 send-community both'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-complete 'no neighbor 2001:db8::1 send-community both'@19: rv==7
-  'both'
-describe 'no neighbor 2001:db8::1 send-community both'@19: rv==0
-  'both' 'Send Standard and Extended Community attributes'
-execute relaxed 'no neighbor 2001:db8::1 send-community both'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-execute strict 'no neighbor 2001:db8::1 send-community both'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-complete 'no neighbor 2001:db8::1 send-community both'@20: rv==7
-  'both'
-describe 'no neighbor 2001:db8::1 send-community both'@20: rv==0
-  'both' 'Send Standard and Extended Community attributes'
-execute relaxed 'no neighbor 2001:db8::1 send-community both'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-execute strict 'no neighbor 2001:db8::1 send-community both'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-complete 'no neighbor 2001:db8::1 send-community both'@21: rv==7
-  'both'
-describe 'no neighbor 2001:db8::1 send-community both'@21: rv==0
-  'both' 'Send Standard and Extended Community attributes'
-execute relaxed 'no neighbor 2001:db8::1 send-community both'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-execute strict 'no neighbor 2001:db8::1 send-community both'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) send-community (both|extended|standard)': '2001:db8::1', 'both'
-complete 'no neighbor 2001:db8::1 send-community both'@22: rv==7
-  'both'
-describe 'no neighbor 2001:db8::1 send-community both'@22: rv==0
-  'both' 'Send Standard and Extended Community attributes'
-execute relaxed 'no neighbor VARIABLE maximum-prefix'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-execute strict 'no neighbor VARIABLE maximum-prefix'@17: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-complete 'no neighbor VARIABLE maximum-prefix'@17: rv==7
-  'maximum-prefix'
-describe 'no neighbor VARIABLE maximum-prefix'@17: rv==0
-  'maximum-prefix' 'Maximum number of prefix accept from this peer'
-execute relaxed 'no neighbor VARIABLE maximum-prefix'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-execute strict 'no neighbor VARIABLE maximum-prefix'@18: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-complete 'no neighbor VARIABLE maximum-prefix'@18: rv==7
-  'maximum-prefix'
-describe 'no neighbor VARIABLE maximum-prefix'@18: rv==0
-  'maximum-prefix' 'Maximum number of prefix accept from this peer'
-execute relaxed 'no neighbor VARIABLE maximum-prefix'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-execute strict 'no neighbor VARIABLE maximum-prefix'@19: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-complete 'no neighbor VARIABLE maximum-prefix'@19: rv==7
-  'maximum-prefix'
-describe 'no neighbor VARIABLE maximum-prefix'@19: rv==0
-  'maximum-prefix' 'Maximum number of prefix accept from this peer'
-execute relaxed 'no neighbor VARIABLE maximum-prefix'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-execute strict 'no neighbor VARIABLE maximum-prefix'@20: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-complete 'no neighbor VARIABLE maximum-prefix'@20: rv==7
-  'maximum-prefix'
-describe 'no neighbor VARIABLE maximum-prefix'@20: rv==0
-  'maximum-prefix' 'Maximum number of prefix accept from this peer'
-execute relaxed 'no neighbor VARIABLE maximum-prefix'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-execute strict 'no neighbor VARIABLE maximum-prefix'@21: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-complete 'no neighbor VARIABLE maximum-prefix'@21: rv==7
-  'maximum-prefix'
-describe 'no neighbor VARIABLE maximum-prefix'@21: rv==0
-  'maximum-prefix' 'Maximum number of prefix accept from this peer'
-execute relaxed 'no neighbor VARIABLE maximum-prefix'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-execute strict 'no neighbor VARIABLE maximum-prefix'@22: rv==0, 'no neighbor (A.B.C.D|X:X::X:X|WORD) maximum-prefix': 'VARIABLE'
-complete 'no neighbor VARIABLE maximum-prefix'@22: rv==7
-  'maximum-prefix'
-describe 'no neighbor VARIABLE maximum-prefix'@22: rv==0
-  'maximum-prefix' 'Maximum number of prefix accept from this peer'
-execute relaxed 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
-execute strict 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
-complete 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==7
-  '2'
-describe 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0
-  '2' 'Set OSPF External Type 2 metrics'
-execute relaxed 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
-execute strict 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
-complete 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==7
-  '1'
-describe 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0
-  '1' 'Set OSPF External Type 1 metrics'
-execute relaxed 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-execute strict 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-complete 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==7
-  'exact-match'
-describe 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-execute strict 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-complete 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==7
-  'exact-match'
-describe 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-execute strict 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-complete 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==7
-  'exact-match'
-describe 'show bgp community VARIABLE local-AS no-export VARIABLE exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
-execute strict 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
-complete 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==7
-  'no-export'
-describe 'show bgp ipv6 community no-advertise no-export no-export no-export'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-export' 'Do not export to next AS (well-known community)'
-execute relaxed 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
-execute strict 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
-complete 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==7
-  'no-export'
-describe 'show bgp ipv6 community no-advertise no-export no-export no-export'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-export' 'Do not export to next AS (well-known community)'
-execute relaxed 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
-execute strict 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-export', 'no-export', 'no-export'
-complete 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==7
-  'no-export'
-describe 'show bgp ipv6 community no-advertise no-export no-export no-export'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-export' 'Do not export to next AS (well-known community)'
-execute relaxed 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
-execute strict 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
-complete 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==7
-  'exact-match'
-describe 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
-execute strict 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
-complete 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==7
-  'exact-match'
-describe 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
-execute strict 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'local-AS', 'no-advertise'
-complete 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==7
-  'exact-match'
-describe 'show bgp ipv6 community VARIABLE local-AS local-AS no-advertise exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
-execute strict 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
-complete 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==7
-  'exact-match'
-describe 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
-execute strict 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
-complete 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==7
-  'exact-match'
-describe 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
-execute strict 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'VARIABLE', 'local-AS'
-complete 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==7
-  'exact-match'
-describe 'show bgp ipv6 community VARIABLE local-AS VARIABLE local-AS exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp view VARIABLE'@1: rv==4
-execute strict 'show bgp view VARIABLE'@1: rv==4
-complete 'show bgp view VARIABLE'@1: rv==2
-describe 'show bgp view VARIABLE'@1: rv==0
-  'WORD' 'View name'
-execute relaxed 'show bgp view VARIABLE'@2: rv==0, 'show bgp view WORD': 'VARIABLE'
-execute strict 'show bgp view VARIABLE'@2: rv==0, 'show bgp view WORD': 'VARIABLE'
-complete 'show bgp view VARIABLE'@2: rv==2
-describe 'show bgp view VARIABLE'@2: rv==0
-  'WORD' 'View name'
-execute relaxed 'show bgp view VARIABLE'@4: rv==0, 'show bgp view WORD': 'VARIABLE'
-execute strict 'show bgp view VARIABLE'@4: rv==0, 'show bgp view WORD': 'VARIABLE'
-complete 'show bgp view VARIABLE'@4: rv==2
-describe 'show bgp view VARIABLE'@4: rv==0
-  'WORD' 'View name'
-execute relaxed 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
-execute strict 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
-complete 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==2
-describe 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
-execute strict 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
-complete 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==2
-describe 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
-execute strict 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'no-export', 'no-export', 'local-AS', 'VARIABLE'
-complete 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==2
-describe 'show bgp view VARIABLE ipv4 multicast community no-export no-export local-AS VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
-complete 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==7
-  'local-AS'
-describe 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
-complete 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==7
-  'local-AS'
-describe 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertise', 'no-advertise', 'local-AS'
-complete 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==7
-  'local-AS'
-describe 'show bgp view VARIABLE ipv4 unicast community local-AS no-advertise no-advertise local-AS'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
-execute strict 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
-complete 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==7
-  'no-advertise'
-describe 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-advertise' 'Do not advertise to any peer (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
-execute strict 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
-complete 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==7
-  'no-advertise'
-describe 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-advertise' 'Do not advertise to any peer (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
-execute strict 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'no-export', 'VARIABLE', 'no-advertise'
-complete 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==7
-  'no-advertise'
-describe 'show bgp view VARIABLE ipv4 unicast community no-export VARIABLE no-advertise'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-advertise' 'Do not advertise to any peer (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-execute strict 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-complete 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==2
-describe 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-execute strict 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-complete 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==2
-describe 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-execute strict 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'unicast', 'VARIABLE', 'local-AS', 'no-export', 'VARIABLE'
-complete 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==2
-describe 'show bgp view VARIABLE ipv4 unicast community VARIABLE local-AS no-export VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-complete 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==7
-  'local-AS'
-describe 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-complete 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==7
-  'local-AS'
-describe 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv6', 'multicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-complete 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==7
-  'local-AS'
-describe 'show bgp view VARIABLE ipv6 multicast community no-advertise VARIABLE no-advertise local-AS'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
-execute strict 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
-complete 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==2
-describe 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
-execute strict 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
-complete 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==2
-describe 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
-execute strict 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'local-AS', 'no-advertise', 'VARIABLE'
-complete 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==2
-describe 'show ip bgp community no-advertise local-AS no-advertise VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-execute strict 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-complete 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-execute strict 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-complete 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-execute strict 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'VARIABLE', 'no-advertise', 'local-AS'
-complete 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-advertise VARIABLE no-advertise local-AS exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
-execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
-complete 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
-execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
-complete 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
-execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'local-AS', 'VARIABLE'
-complete 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-export VARIABLE local-AS VARIABLE exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
-execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
-complete 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
-execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
-complete 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
-execute strict 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-export', 'VARIABLE', 'no-export', 'local-AS'
-complete 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-export VARIABLE no-export local-AS exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
-execute strict 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
-complete 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==2
-describe 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
-execute strict 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'no-export', 'VARIABLE', 'VARIABLE'
-complete 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==2
-describe 'show ipv6 bgp community no-export no-export VARIABLE VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
-execute strict 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
-complete 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==7
-  'exact-match'
-describe 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
-execute strict 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABLE', 'local-AS', 'no-advertise', 'no-advertise'
-complete 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==7
-  'exact-match'
-describe 'show ipv6 bgp community VARIABLE local-AS no-advertise no-advertise exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
-execute strict 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
-complete 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==7
-  'exact-match'
-describe 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
-execute strict 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'local-AS', 'VARIABLE'
-complete 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==7
-  'exact-match'
-describe 'show ipv6 mbgp community local-AS local-AS local-AS VARIABLE exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
-execute strict 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
-complete 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==7
-  'exact-match'
-describe 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
-execute strict 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'local-AS', 'local-AS', 'no-export', 'no-export'
-complete 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==7
-  'exact-match'
-describe 'show ipv6 mbgp community local-AS local-AS no-export no-export exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
-execute strict 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
-complete 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==7
-  'exact-match'
-describe 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
-execute strict 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==0, 'show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'no-export', 'no-export', 'local-AS', 'no-export'
-complete 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==7
-  'exact-match'
-describe 'show ipv6 mbgp community no-export no-export local-AS no-export exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 ospf6 database as-external dump'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
-execute strict 'show ipv6 ospf6 database as-external dump'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
-complete 'show ipv6 ospf6 database as-external dump'@2: rv==7
-  'dump'
-describe 'show ipv6 ospf6 database as-external dump'@2: rv==0
-  'dump' 'Dump LSAs'
-execute relaxed 'show ipv6 ospf6 database as-external dump'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
-execute strict 'show ipv6 ospf6 database as-external dump'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) (detail|dump|internal)': 'as-external', 'dump'
-complete 'show ipv6 ospf6 database as-external dump'@4: rv==7
-  'dump'
-describe 'show ipv6 ospf6 database as-external dump'@4: rv==0
-  'dump' 'Dump LSAs'
-execute relaxed 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
-execute strict 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
-complete 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==7
-  'detail'
-describe 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@2: rv==0
-  'detail' 'Display details of LSAs'
-execute relaxed 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
-execute strict 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'inter-prefix', '1.2.3.4', 'detail'
-complete 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==7
-  'detail'
-describe 'show ipv6 ospf6 database inter-prefix 1.2.3.4 detail'@4: rv==0
-  'detail' 'Display details of LSAs'
-execute relaxed 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
-execute strict 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
-complete 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==7
-  'internal'
-describe 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@2: rv==0
-  'internal' 'Display LSA's internal information'
-execute relaxed 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
-execute strict 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==0, 'show ipv6 ospf6 database (router|network|inter-prefix|inter-router|as-external|group-membership|type-7|link|intra-prefix) A.B.C.D (detail|dump|internal)': 'intra-prefix', '1.2.3.4', 'internal'
-complete 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==7
-  'internal'
-describe 'show ipv6 ospf6 database intra-prefix 1.2.3.4 internal'@4: rv==0
-  'internal' 'Display LSA's internal information'
-execute relaxed 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==0, 'area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535> (hello-interval|retransmit-interval|transmit-delay|dead-interval) <1-65535>': '1.2.3.4', '1.2.3.4', 'hello-interval', '1', 'dead-interva', '1', 'retransmit-interval', '1', 'transmit-delay', '1'
-execute strict 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==2
-complete 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==2
-describe 'area 1.2.3.4 virtual-link 1.2.3.4 hello-interval 1 dead-interva 1 retransmit-interval 1 transmit-delay 1'@23: rv==0
-  '<1-65535>' 'Seconds'
-execute relaxed 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
-execute strict 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
-complete 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==7
-  'exact-match'
-describe 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
-execute strict 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
-complete 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==7
-  'exact-match'
-describe 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
-execute strict 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==0, 'show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABL', 'no-agdvertise', 'locl-AS', 'no-advertise'
-complete 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==7
-  'exact-match'
-describe 'show bgp community VARIABL no-agdvertise locl-AS no-advertise exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
-execute strict 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
-complete 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==2
-describe 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
-execute strict 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
-complete 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==2
-describe 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
-execute strict 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'local-AS', 'no-expor', 'no-xport', 'VARIABCLE'
-complete 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==2
-describe 'show bgp ipv6 community local-AS no-expor no-xport VARIABCLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
-execute strict 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
-complete 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==2
-describe 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
-execute strict 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
-complete 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==2
-describe 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
-execute strict 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-adsertise', 'local-AS', 'no8-advertise', 'VARIABLE'
-complete 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==2
-describe 'show bgp ipv6 community no-adsertise local-AS no8-advertise VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
-execute strict 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
-complete 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==7
-  'local-AS'
-describe 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
-execute strict 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
-complete 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==7
-  'local-AS'
-describe 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
-execute strict 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no6-export', 'lcal-AS', 'local-AS'
-complete 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==7
-  'local-AS'
-describe 'show bgp ipv6 community no-advertise no6-export lcal-AS local-AS'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
-execute strict 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
-complete 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==2
-describe 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
-execute strict 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
-complete 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==2
-describe 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
-execute strict 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-advertise', 'no-advertise', 'no-advertiseno-xport', 'exact-math'
-complete 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==2
-describe 'show bgp ipv6 community no-advertise no-advertise no-advertiseno-xport exact-math'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
-execute strict 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
-complete 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==2
-describe 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
-execute strict 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
-complete 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==2
-describe 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
-execute strict 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'local-AS', 'no-adertise', 'no-adve-tie'
-complete 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==2
-describe 'show bgp ipv6 community no-export local-AS no-adertise no-adve-tie'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
-execute strict 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
-complete 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==2
-describe 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
-execute strict 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
-complete 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==2
-describe 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
-execute strict 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==0, 'show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'yno-advertis', 'VAyRIABLE', 'no-advertise', 'VARIABLE'
-complete 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==2
-describe 'show bgp ipv6 community yno-advertis VAyRIABLE no-advertise VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
-complete 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==7
-  'local-AS'
-describe 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
-complete 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==7
-  'local-AS'
-describe 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
-execute strict 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VAR0IABLE', 'ipv4', 'unicast', 'local-AS', 'no-advertie', 'no-advertise', 'local-AS'
-complete 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==7
-  'local-AS'
-describe 'show bgp view VAR0IABLE ipv4 unicast community local-AS no-advertie no-advertise local-AS'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'local-AS' 'Do not send outside local AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
-execute strict 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
-complete 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==7
-  'no-export'
-describe 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-export' 'Do not export to next AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
-execute strict 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
-complete 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==7
-  'no-export'
-describe 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-export' 'Do not export to next AS (well-known community)'
-execute relaxed 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
-execute strict 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==0, 'show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLE', 'ipv4', 'multicast', 'local-AS', 'VARIABLE', 'loqal-AS', 'no-export'
-complete 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==7
-  'no-export'
-describe 'show bgp view VARIABLE ipv4 multicast community local-AS VARIABLE loqal-AS no-export'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-  'no-export' 'Do not export to next AS (well-known community)'
-execute relaxed 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
-execute strict 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
-complete 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==2
-describe 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
-execute strict 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
-complete 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==2
-describe 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
-execute strict 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-expor', 'VARIABLEono-export', 'VARIAuBLE'
-complete 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==2
-describe 'show ip bgp community no-expor VARIABLEono-export VARIAuBLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
-execute strict 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
-complete 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==2
-describe 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@1: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
-execute strict 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
-complete 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==2
-describe 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
-execute strict 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==0, 'show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'VARIABLElocal-AS', 'no-advertise', 'local-AS', 'xack-match'
-complete 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==2
-describe 'show ip bgp community VARIABLElocal-AS no-advertise local-AS xack-match'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
-execute strict 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
-complete 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@1: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
-execute strict 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
-complete 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
-execute strict 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==0, 'show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'unicast', 'no-advertise', 'no-export', 'no-advrtWise', 'mno-export'
-complete 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==7
-  'exact-match'
-describe 'show ip bgp ipv4 unicast community no-advertise no-export no-advrtWise mno-export exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
-execute strict 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
-complete 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==7
-  'exact-match'
-describe 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
-execute strict 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'noeexport', 'VARIABLE', 'VARIABLE', 'no-aMdverise'
-complete 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==7
-  'exact-match'
-describe 'show ipv6 bgp community noeexport VARIABLE VARIABLE no-aMdverise exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
-execute strict 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
-complete 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==2
-describe 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
-execute strict 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'no-export', 'loal-AS', 'noK-advertise', 'VARIABLE'
-complete 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==2
-describe 'show ipv6 bgp community no-export loal-AS noK-advertise VARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
-execute strict 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
-complete 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==7
-  'exact-match'
-describe 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@2: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
-execute strict 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match': 'VARIABaE', 'no-export', 'no-adertise', 'lo0cal-AS'
-complete 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==7
-  'exact-match'
-describe 'show ipv6 bgp community VARIABaE no-export no-adertise lo0cal-AS exact-match'@4: rv==0
-  'exact-match' 'Exact match of the communities'
-execute relaxed 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
-execute strict 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
-complete 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==2
-describe 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@2: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
-execute strict 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0, 'show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)': 'wARIBLE', 'VARIABLE', '8ARIABLE'
-complete 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==2
-describe 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0
-  'AA:NN' 'Community number where AA and NN are <0-65535>'
-execute relaxed 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp)': 'bgp'
-execute strict 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp)': 'bgp'
-complete 'redistribute bgp'@14: rv==7
-  'bgp'
-describe 'redistribute bgp'@14: rv==0
-  'bgp' 'Border Gateway Protocol (BGP)'
-execute relaxed 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp)': 'bgp'
-execute strict 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp)': 'bgp'
-complete 'redistribute bgp'@15: rv==7
-  'bgp'
-describe 'redistribute bgp'@15: rv==0
-  'bgp' 'Border Gateway Protocol (BGP)'
-execute relaxed 'redistribute bgp'@16: rv==0, 'redistribute (kernel|connected|static|rip|ripng|ospf|ospf6|isis|bgp)': 'bgp'
-execute strict 'redistribute bgp'@16: rv==0, 'redistribute (kernel|connected|static|rip|ripng|ospf|ospf6|isis|bgp)': 'bgp'
-complete 'redistribute bgp'@16: rv==7
-  'bgp'
-describe 'redistribute bgp'@16: rv==0
-  'bgp' 'Border Gateway Protocol (BGP)'
-execute relaxed 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
-execute strict 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
-complete 'redistribute bgp'@23: rv==7
-  'bgp'
-describe 'redistribute bgp'@23: rv==0
-  'bgp' 'Border Gateway Protocol (BGP)'
-execute relaxed 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp)': 'bgp'
-execute strict 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp)': 'bgp'
-complete 'redistribute bgp'@24: rv==7
-  'bgp'
-describe 'redistribute bgp'@24: rv==0
-  'bgp' 'Border Gateway Protocol (BGP)'
-execute relaxed 'redistribute bgp m 10'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) metric <0-16>': 'bgp', '10'
-execute strict 'redistribute bgp m 10'@14: rv==2
-complete 'redistribute bgp m 10'@14: rv==2
-describe 'redistribute bgp m 10'@14: rv==0
-  '<0-16>' 'Metric value'
-execute relaxed 'redistribute bgp m 10'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) metric <0-16>': 'bgp', '10'
-execute strict 'redistribute bgp m 10'@15: rv==2
-complete 'redistribute bgp m 10'@15: rv==2
-describe 'redistribute bgp m 10'@15: rv==0
-  '<0-16>' 'Metric value'
-execute relaxed 'redistribute bgp m 10'@23: rv==3
-execute strict 'redistribute bgp m 10'@23: rv==2
-complete 'redistribute bgp m 10'@23: rv==3
-describe 'redistribute bgp m 10'@23: rv==3
-execute relaxed 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
-execute strict 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
-complete 'redistribute bgp metric 10 metric-type 1'@23: rv==7
-  '1'
-describe 'redistribute bgp metric 10 metric-type 1'@23: rv==0
-  '1' 'Set OSPF External Type 1 metrics'
-execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
-execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
-complete 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==2
-describe 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0
-  'WORD' 'Pointer to route-map entries'
-execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
-execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
-complete 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==2
-describe 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0
-  'WORD' 'Pointer to route-map entries'
-execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
-execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
-complete 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==2
-describe 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0
-  'WORD' 'Pointer to route-map entries'
-execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
-execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
-complete 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==2
-describe 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0
-  'WORD' 'Route map name'
-execute relaxed 'default-information originate metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '1', '(null)'
-execute strict 'default-information originate metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '1', '(null)'
-complete 'default-information originate metric-type 1 metric 10'@23: rv==2
-describe 'default-information originate metric-type 1 metric 10'@23: rv==0
-  '<0-16777214>' 'OSPF metric'
-execute relaxed 'default-information originate always metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '10', '1', '(null)'
-execute strict 'default-information originate always metric-type 1 metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '10', '1', '(null)'
-complete 'default-information originate always metric-type 1 metric 10'@23: rv==2
-describe 'default-information originate always metric-type 1 metric 10'@23: rv==0
-  '<0-16777214>' 'OSPF metric'
-execute relaxed 'default-information originate route-map RMAP_DEFAULT'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '(null)', '(null)', 'RMAP_DEFAULT'
-execute strict 'default-information originate route-map RMAP_DEFAULT'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '(null)', '(null)', 'RMAP_DEFAULT'
-complete 'default-information originate route-map RMAP_DEFAULT'@23: rv==2
-describe 'default-information originate route-map RMAP_DEFAULT'@23: rv==0
-  'WORD' 'Pointer to route-map entries'
-execute relaxed 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '(null)', 'RMAP_DEFAULT'
-execute strict 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': '(null)', '10', '(null)', 'RMAP_DEFAULT'
-complete 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==2
-describe 'default-information originate route-map RMAP_DEFAULT metric 10'@23: rv==0
-  '<0-16777214>' 'OSPF metric'
-execute relaxed 'default-information originate always metric-type 2 metric 23'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '23', '2', '(null)'
-execute strict 'default-information originate always metric-type 2 metric 23'@23: rv==0, 'default-information originate {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'always', '23', '2', '(null)'
-complete 'default-information originate always metric-type 2 metric 23'@23: rv==2
-describe 'default-information originate always metric-type 2 metric 23'@23: rv==0
-  '<0-16777214>' 'OSPF metric'
diff --git a/tests/tests.h b/tests/tests.h
deleted file mode 100644 (file)
index a528e55..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Test wrappers common header file
- *
- * Copyright (C) 2015 by David Lamparter,
- *                    for Open Source Routing./ NetDEF, Inc.
- *
- * This file is part of Quagga
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#ifndef _QUAGGA_TESTS_H
-#define _QUAGGA_TESTS_H
-
-extern void test_init (void);
-extern void test_init_cmd (void);
-
-#endif /* _QUAGGA_TESTS_H */