diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:16:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:16:35 +0000 |
commit | e2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch) | |
tree | f0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /tests/bgpd/test_capability.c | |
parent | Initial commit. (diff) | |
download | frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip |
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/bgpd/test_capability.c')
-rw-r--r-- | tests/bgpd/test_capability.c | 984 |
1 files changed, 984 insertions, 0 deletions
diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c new file mode 100644 index 0000000..9d3d0ec --- /dev/null +++ b/tests/bgpd/test_capability.c @@ -0,0 +1,984 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2007 Sun Microsystems, Inc. + */ + +#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 "frr_pthread.h" + +#include "bgpd/bgpd.c" +#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 = {}; +struct event_loop *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 uint8_t 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; + iana_afi_t afi; + iana_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, + IANA_AFI_IPV4, + IANA_SAFI_UNICAST, + VALID_AFI, + }, + { + "MPv6", + "MP IPv6/Uni", + {0x1, 0x4, 0x0, 0x2, 0x0, 0x1}, + 6, + SHOULD_PARSE, + 0, + 1, + IANA_AFI_IPV6, + IANA_SAFI_UNICAST, + VALID_AFI, + }, + /* 5 */ + { + "MP2", + "MP IP/Multicast", + {CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2}, + 6, + SHOULD_PARSE, + 0, + 1, + IANA_AFI_IPV4, + IANA_SAFI_MULTICAST, + VALID_AFI, + }, + /* 6 */ + { + "MP3", + "MP IP6/MPLS-labeled VPN", + {CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80}, + 6, + SHOULD_PARSE, + 0, + 1, + IANA_AFI_IPV6, + 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, + IANA_AFI_IPV6, + IANA_SAFI_MPLS_VPN, + VALID_AFI, + }, + /* 8 */ + { + "MP6", + "MP IP4/MPLS-labeled VPN", + {CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80}, + 6, + SHOULD_PARSE, + 0, + 1, + IANA_AFI_IPV4, + 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, + IANA_AFI_IPV4, + IANA_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, + }, + { + "Role", + "Role capability", + { + /* hdr */ 0x9, 0x1, + 0x1, + }, + 3, + SHOULD_PARSE, + }, + { + "Role-long", + "Role capability, but too long", + { + /* hdr */ 0x9, 0x4, + 0x0, 0x0, 0x0, 0x1, + }, + 6, + SHOULD_ERR, + }, + { + "Role-empty", + "Role capability, but empty.", + { + /* hdr */ 0x9, 0x0, + }, + 2, + SHOULD_ERR, + }, + {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->curr); + stream_put(peer->curr, NULL, RANDOM_FUZZ); + stream_set_getp(peer->curr, RANDOM_FUZZ); + + switch (type) { + case CAPABILITY: + stream_putc(peer->curr, BGP_OPEN_OPT_CAP); + stream_putc(peer->curr, 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->curr, t->data, t->len); + + printf("%s: %s\n", t->name, t->desc); + + switch (type) { + case CAPABILITY: + len += 2; /* to cover the OPT-Param header */ + _FALLTHROUGH + 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->curr) == RANDOM_FUZZ); + + ret = bgp_open_option_parse(peer, len, &capability); + break; + case DYNCAP: + ret = bgp_capability_receive(peer->connection, peer, t->len); + break; + default: + printf("unknown type %u\n", type); + exit(1); + } + + if (ret != BGP_Stop && t->validate_afi) { + afi_t afi; + safi_t safi; + + /* Convert AFI, SAFI to internal values, check. */ + if (bgp_map_afi_safi_iana2int(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++; + } + + /* + * Some of the functions used return BGP_Stop on error and some return + * -1. If we have -1, keep it; if we have BGP_Stop, transform it to the + * correct pass/fail code + */ + if (ret != -1) + ret = (ret == BGP_Stop) ? -1 : 0; + + printf("parsed?: %s\n", ret ? "no" : "yes"); + + if (ret != t->parses) { + printf("t->parses: %d\nret: %d\n", t->parses, ret); + 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 = event_master_create(NULL); + bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); + vrf_init(NULL, NULL, NULL, NULL); + bgp_option_set(BGP_OPT_NO_LISTEN); + + frr_pthread_init(); + bgp_pthreads_init(); + bgp_pth_ka->running = true; + + if (fileno(stdout) >= 0) + tty = isatty(fileno(stdout)); + + if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT, NULL, + ASNOTATION_PLAIN) < 0) + 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; + } + + peer->curr = stream_new(BGP_MAX_PACKET_SIZE); + + 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->connection = bgp_peer_connection_new(peer); + peer->connection->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; +} |