mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-02 18:56:53 +00:00

This patch implements the 'update-groups' functionality in BGP. This is a function that can significantly improve BGP performance for Update generation and resultant network convergence. BGP Updates are formed for "groups" of peers and then replicated and sent out to each peer rather than being formed for each peer. Thus major BGP operations related to outbound policy application, adj-out maintenance and actual Update packet formation are optimized. BGP update-groups dynamically groups peers together based on configuration as well as run-time criteria. Thus, it is more flexible than update-formation based on peer-groups, which relies on operator configuration. [Note that peer-group based update formation has been introduced into BGP by Cumulus but is currently intended only for specific releases.] From 11098af65b2b8f9535484703e7f40330a71cbae4 Mon Sep 17 00:00:00 2001 Subject: [PATCH] updgrp commits
544 lines
17 KiB
C
544 lines
17 KiB
C
#include <zebra.h>
|
|
|
|
#include "vty.h"
|
|
#include "stream.h"
|
|
#include "privs.h"
|
|
#include "memory.h"
|
|
#include "queue.h"
|
|
|
|
#include "bgpd/bgpd.h"
|
|
#include "bgpd/bgp_attr.h"
|
|
#include "bgpd/bgp_open.h"
|
|
#include "bgpd/bgp_debug.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-MLVPN",
|
|
"IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, 3 NLRIs",
|
|
{
|
|
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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 */
|
|
},
|
|
(4 + 12 + 1 + 3 + 4 + 1),
|
|
SHOULD_PARSE,
|
|
AFI_IP, SAFI_UNICAST, 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-MLVPN",
|
|
"IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs",
|
|
{
|
|
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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 + 3 + 4 + 1),
|
|
SHOULD_PARSE,
|
|
AFI_IP, SAFI_UNICAST, VALID_AFI,
|
|
},
|
|
{ NULL, NULL, {0}, 0, 0}
|
|
};
|
|
|
|
|
|
/* basic parsing test */
|
|
static void
|
|
parse_test (struct peer *peer, struct test_segment *t, int type)
|
|
{
|
|
int ret;
|
|
int oldfailed = failed;
|
|
struct attr attr = { };
|
|
struct bgp_nlri nlri = { };
|
|
struct bgp_attr_parser_args attr_args = {
|
|
.peer = peer,
|
|
.length = t->len,
|
|
.total = 1,
|
|
.attr = &attr,
|
|
.type = BGP_ATTR_MP_REACH_NLRI,
|
|
.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)
|
|
ret = bgp_mp_reach_parse (&attr_args, &nlri);
|
|
else
|
|
ret = bgp_mp_unreach_parse (&attr_args, &nlri);
|
|
|
|
if (!ret)
|
|
{
|
|
safi_t safi = t->safi;
|
|
|
|
if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
|
|
failed++;
|
|
|
|
printf ("MP: %u/%u (%u): recv %u, nego %u\n",
|
|
t->afi, t->safi, safi,
|
|
peer->afc_recv[t->afi][safi],
|
|
peer->afc_nego[t->afi][safi]);
|
|
}
|
|
|
|
printf ("parsed?: %s\n", ret ? "no" : "yes");
|
|
|
|
if ((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");
|
|
}
|
|
|
|
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;
|
|
|
|
master = thread_master_create ();
|
|
bgp_master_init ();
|
|
bgp_option_set (BGP_OPT_NO_LISTEN);
|
|
|
|
if (fileno (stdout) >= 0)
|
|
tty = isatty (fileno (stdout));
|
|
|
|
if (bgp_get (&bgp, &asn, NULL))
|
|
return -1;
|
|
|
|
peer = peer_create_accept (bgp);
|
|
peer->host = "foo";
|
|
|
|
for (i = AFI_IP; i < AFI_MAX; i++)
|
|
for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
|
|
{
|
|
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;
|
|
}
|