version 1.1.1.3, 2013/07/21 23:54:40
|
version 1.1.1.4, 2016/11/02 10:09:12
|
Line 1
|
Line 1
|
|
/* |
|
* 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 <zebra.h> |
|
|
#include "vty.h" |
#include "vty.h" |
#include "stream.h" |
#include "stream.h" |
#include "privs.h" |
#include "privs.h" |
#include "memory.h" |
#include "memory.h" |
|
#include "filter.h" |
|
|
#include "bgpd/bgpd.h" |
#include "bgpd/bgpd.h" |
#include "bgpd/bgp_attr.h" |
#include "bgpd/bgp_attr.h" |
#include "bgpd/bgp_open.h" |
#include "bgpd/bgp_open.h" |
#include "bgpd/bgp_debug.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_RESET "\x1b[0m" |
#define VT100_RED "\x1b[31m" |
#define VT100_RED "\x1b[31m" |
Line 286 static struct test_segment {
|
Line 312 static struct test_segment {
|
SHOULD_ERR, |
SHOULD_ERR, |
AFI_IP, SAFI_UNICAST, VALID_AFI, |
AFI_IP, SAFI_UNICAST, VALID_AFI, |
}, |
}, |
{ "IPv4-MLVPN", | { "IPv4-VPNv4", |
"IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, 3 NLRIs", | "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs", |
{ |
{ |
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, |
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, |
/* nexthop bytes */ 12, |
/* 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, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
|
}, |
|
{ "IPv4-VPNv4-bogus-plen", |
|
"IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len", |
|
{ |
|
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, |
|
/* nexthop bytes */ 12, |
/* RD */ 0, 0, 1, 2, |
/* RD */ 0, 0, 1, 2, |
0, 0xff, 3, 4, |
0, 0xff, 3, 4, |
/* Nexthop */ 192, 168, 0, 1, |
/* Nexthop */ 192, 168, 0, 1, |
Line 299 static struct test_segment {
|
Line 351 static struct test_segment {
|
17, 10, 2, 3, /* 10.2.3/17 */ |
17, 10, 2, 3, /* 10.2.3/17 */ |
0, /* 0/0 */ |
0, /* 0/0 */ |
}, |
}, |
(4 + 12 + 1 + 3 + 4 + 1), | (3 + 1 + 3*4 + 1 + 3 + 4 + 1), |
| SHOULD_ERR, |
| AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
| }, |
| { "IPv4-VPNv4-plen1-short", |
| "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short", |
| { |
| /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
| }, |
| { "IPv4-VPNv4-plen1-long", |
| "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long", |
| { |
| /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
| }, |
| { "IPv4-VPNv4-plenn-long", |
| "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long", |
| { |
| /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
| }, |
| { "IPv4-VPNv4-plenn-short", |
| "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short", |
| { |
| /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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, SAFI_MPLS_LABELED_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, SAFI_MPLS_LABELED_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, |
SHOULD_PARSE, |
AFI_IP, SAFI_UNICAST, VALID_AFI, | AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
}, |
}, |
|
{ "IPv4-VPNv4-0-nlri", |
|
"IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus", |
|
{ |
|
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_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, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
|
}, |
|
|
/* From bug #385 */ |
/* From bug #385 */ |
{ "IPv6-bug", |
{ "IPv6-bug", |
"IPv6, global nexthop, 1 default NLRI", |
"IPv6, global nexthop, 1 default NLRI", |
Line 409 static struct test_segment mp_unreach_segments [] =
|
Line 620 static struct test_segment mp_unreach_segments [] =
|
SHOULD_ERR, |
SHOULD_ERR, |
AFI_IP, SAFI_UNICAST, VALID_AFI, |
AFI_IP, SAFI_UNICAST, VALID_AFI, |
}, |
}, |
{ "IPv4-unreach-MLVPN", | { "IPv4-unreach-VPNv4", |
"IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", |
"IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", |
{ |
{ |
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, |
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN, |
/* nexthop bytes */ 12, | /* NLRI tuples */ 88 + 16, |
/* RD */ 0, 0, 1, 2, | 0, 1, 2, /* tag */ |
0, 0xff, 3, 4, | /* rd, 8 octets */ |
/* Nexthop */ 192, 168, 0, 1, | 0, 0, /* RD_TYPE_AS */ |
/* SNPA (defunct, MBZ) */ 0x0, | 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */ |
/* NLRI tuples */ 16, 10, 1, /* 10.1/16 */ | 10, 1, /* 10.1/16 */ |
17, 10, 2, 3, /* 10.2.3/17 */ | 88 + 17, |
0, /* 0/0 */ | 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 + 3 + 4 + 1), | (3 + (1+3+8+2) + (1+3+8+3)), |
SHOULD_PARSE, |
SHOULD_PARSE, |
AFI_IP, SAFI_UNICAST, VALID_AFI, | AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI, |
}, |
}, |
{ NULL, NULL, {0}, 0, 0} |
{ 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; |
|
|
|
if (!parse_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 ("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 */ |
/* basic parsing test */ |
static void |
static void |
parse_test (struct peer *peer, struct test_segment *t, int type) |
parse_test (struct peer *peer, struct test_segment *t, int type) |
{ |
{ |
int ret; | int parse_ret = 0, nlri_ret = 0; |
int oldfailed = failed; | |
struct attr attr = { }; |
struct attr attr = { }; |
struct bgp_nlri nlri = { }; |
struct bgp_nlri nlri = { }; |
struct bgp_attr_parser_args attr_args = { |
struct bgp_attr_parser_args attr_args = { |
Line 443 parse_test (struct peer *peer, struct test_segment *t,
|
Line 700 parse_test (struct peer *peer, struct test_segment *t,
|
.length = t->len, |
.length = t->len, |
.total = 1, |
.total = 1, |
.attr = &attr, |
.attr = &attr, |
.type = BGP_ATTR_MP_REACH_NLRI, | .type = type, |
.flags = BGP_ATTR_FLAG_OPTIONAL, |
.flags = BGP_ATTR_FLAG_OPTIONAL, |
.startp = BGP_INPUT_PNT (peer), |
.startp = BGP_INPUT_PNT (peer), |
}; |
}; |
Line 457 parse_test (struct peer *peer, struct test_segment *t,
|
Line 714 parse_test (struct peer *peer, struct test_segment *t,
|
|
|
printf ("%s: %s\n", t->name, t->desc); |
printf ("%s: %s\n", t->name, t->desc); |
|
|
|
|
if (type == BGP_ATTR_MP_REACH_NLRI) |
if (type == BGP_ATTR_MP_REACH_NLRI) |
ret = bgp_mp_reach_parse (&attr_args, &nlri); | parse_ret = bgp_mp_reach_parse (&attr_args, &nlri); |
else |
else |
ret = bgp_mp_unreach_parse (&attr_args, &nlri); | parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri); |
| |
if (!ret) | if (parse_ret == 0 && t->afi_valid == VALID_AFI) |
| assert (nlri.afi == t->afi && nlri.safi == t->safi); |
| |
| if (!parse_ret) |
{ |
{ |
safi_t safi = t->safi; | if (type == BGP_ATTR_MP_REACH_NLRI) |
| nlri_ret = bgp_nlri_parse (peer, &attr, &nlri); |
if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid) | else |
failed++; | nlri_ret = bgp_nlri_parse (peer, NULL, &nlri); |
| |
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"); | handle_result (peer, t, parse_ret, nlri_ret); |
| |
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 struct bgp *bgp; |
Line 516 main (void)
|
Line 756 main (void)
|
master = thread_master_create (); |
master = thread_master_create (); |
bgp_master_init (); |
bgp_master_init (); |
bgp_option_set (BGP_OPT_NO_LISTEN); |
bgp_option_set (BGP_OPT_NO_LISTEN); |
|
bgp_attr_init (); |
|
bgp_address_init (); |
|
|
if (fileno (stdout) >= 0) |
if (fileno (stdout) >= 0) |
tty = isatty (fileno (stdout)); |
tty = isatty (fileno (stdout)); |
Line 524 main (void)
|
Line 766 main (void)
|
return -1; |
return -1; |
|
|
peer = peer_create_accept (bgp); |
peer = peer_create_accept (bgp); |
peer->host = "foo"; | peer->host = (char *)"foo"; |
| peer->status = Established; |
|
|
for (i = AFI_IP; i < AFI_MAX; i++) |
for (i = AFI_IP; i < AFI_MAX; i++) |
for (j = SAFI_UNICAST; j < SAFI_MAX; j++) |
for (j = SAFI_UNICAST; j < SAFI_MAX; j++) |