Merge branch 'master' into cleanup

This commit is contained in:
Donald Sharp 2017-01-13 14:48:16 -05:00 committed by GitHub
commit 9aa7f43f7e
58 changed files with 2092 additions and 3651 deletions

1
.gitignore vendored
View File

@ -41,6 +41,7 @@ build
m4/*.m4
!m4/ax_sys_weak_alias.m4
!m4/ax_compare_version.m4
!m4/ax_prog_perl_modules.m4
debian/autoreconf.after
debian/autoreconf.before
debian/files

6
README
View File

@ -1,9 +1,9 @@
Quagga is free software that manages various IPv4 and IPv6 routing
Free Range Routing is free software that manages various IPv4 and IPv6 routing
protocols.
Currently Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
Currently Free Range Routing supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
RIPv2, RIPng, PIM-SSM and LDP as well as very early support for IS-IS.
See the file REPORTING-BUGS to report bugs.
Quagga is free software. See the file COPYING for copying conditions.
Free Range Routing is free software. See the file COPYING for copying conditions.

View File

@ -1849,8 +1849,8 @@ int
bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
struct bgp_nlri *mp_update)
{
afi_t afi;
safi_t safi;
afi_t pkt_afi, afi;
safi_t pkt_safi, safi;
bgp_size_t nlri_len;
size_t start;
struct stream *s;
@ -1874,8 +1874,20 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
}
/* Load AFI, SAFI. */
afi = stream_getw (s);
safi = stream_getc (s);
pkt_afi = stream_getw (s);
pkt_safi = stream_getc (s);
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
/* Log if AFI or SAFI is unrecognized. This is not an error unless
* the attribute is otherwise malformed.
*/
if (bgp_debug_update(peer, NULL, NULL, 0))
zlog_debug ("%s: MP_REACH received AFI %u or SAFI %u is unrecognized",
peer->host, pkt_afi, pkt_safi);
return BGP_ATTR_PARSE_ERROR;
}
/* Get nexthop length. */
attre->mp_nexthop_len = stream_getc (s);
@ -1988,8 +2000,8 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
struct bgp_nlri *mp_withdraw)
{
struct stream *s;
afi_t afi;
safi_t safi;
afi_t pkt_afi, afi;
safi_t pkt_safi, safi;
u_int16_t withdraw_len;
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@ -2001,9 +2013,21 @@ bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
afi = stream_getw (s);
safi = stream_getc (s);
pkt_afi = stream_getw (s);
pkt_safi = stream_getc (s);
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
/* Log if AFI or SAFI is unrecognized. This is not an error unless
* the attribute is otherwise malformed.
*/
if (bgp_debug_update(peer, NULL, NULL, 0))
zlog_debug ("%s: MP_UNREACH received AFI %u or SAFI %u is unrecognized",
peer->host, pkt_afi, pkt_safi);
return BGP_ATTR_PARSE_ERROR;
}
withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
mp_withdraw->afi = afi;
@ -2624,6 +2648,8 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
struct attr *attr)
{
size_t sizep;
afi_t pkt_afi;
safi_t pkt_safi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
@ -2631,8 +2657,12 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
sizep = stream_get_endp (s);
stream_putw (s, 0); /* Marker: Attribute length. */
stream_putw (s, afi);
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
stream_putw (s, pkt_afi); /* AFI */
stream_putc (s, pkt_safi); /* SAFI */
/* Nexthop */
switch (nh_afi)
@ -3249,6 +3279,8 @@ size_t
bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
{
unsigned long attrlen_pnt;
afi_t pkt_afi;
safi_t pkt_safi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
@ -3257,8 +3289,12 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
attrlen_pnt = stream_get_endp (s);
stream_putw (s, 0); /* Length of this attribute. */
stream_putw (s, afi);
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
stream_putw (s, pkt_afi);
stream_putc (s, pkt_safi);
return attrlen_pnt;
}

View File

@ -79,9 +79,13 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
if (hdr->code == CAPABILITY_CODE_MP)
{
afi_t afi;
safi_t safi;
bgp_map_afi_safi_iana2int (ntohs(mpc.afi), mpc.safi, &afi, &safi);
if (use_json)
{
switch (ntohs (mpc.afi))
switch (afi)
{
case AFI_IP:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv4");
@ -93,7 +97,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
json_object_int_add(json_cap, "capabilityErrorMultiProtocolAfiUnknown", ntohs (mpc.afi));
break;
}
switch (mpc.safi)
switch (safi)
{
case SAFI_UNICAST:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "unicast");
@ -101,7 +105,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
case SAFI_MULTICAST:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "multicast");
break;
case SAFI_MPLS_LABELED_VPN:
case SAFI_MPLS_VPN:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN");
break;
case SAFI_ENCAP:
@ -115,7 +119,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
else
{
vty_out (vty, " Capability error for: Multi protocol ");
switch (ntohs (mpc.afi))
switch (afi)
{
case AFI_IP:
vty_out (vty, "AFI IPv4, ");
@ -127,7 +131,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
break;
}
switch (mpc.safi)
switch (safi)
{
case SAFI_UNICAST:
vty_out (vty, "SAFI Unicast");
@ -135,7 +139,7 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, jso
case SAFI_MULTICAST:
vty_out (vty, "SAFI Multicast");
break;
case SAFI_MPLS_LABELED_VPN:
case SAFI_MPLS_VPN:
vty_out (vty, "SAFI MPLS-labeled VPN");
break;
case SAFI_ENCAP:
@ -178,35 +182,6 @@ bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
mpc->safi = stream_getc (s);
}
int
bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
{
switch (afi)
{
case AFI_IP:
case AFI_IP6:
switch (*safi)
{
/* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */
case SAFI_MPLS_LABELED_VPN:
*safi = SAFI_MPLS_VPN;
case SAFI_UNICAST:
case SAFI_MULTICAST:
case SAFI_MPLS_VPN:
case SAFI_ENCAP:
return 1;
}
break;
case AFI_ETHER:
default:
break;
}
zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
return 0;
}
/* Set negotiated capability value. */
static int
bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
@ -228,7 +203,8 @@ bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
peer->host, mpc.afi, mpc.safi);
if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (mpc.afi, mpc.safi, &mpc.afi, &mpc.safi))
return -1;
/* Now safi remapped, and afi/safi are valid array indices */
@ -271,8 +247,8 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
{
struct stream *s = BGP_INPUT (peer);
struct capability_orf_entry entry;
afi_t afi;
safi_t safi;
afi_t pkt_afi, afi;
safi_t pkt_safi, safi;
u_char type;
u_char mode;
u_int16_t sm_cap = 0; /* capability send-mode receive */
@ -282,22 +258,25 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
/* ORF Entry header */
bgp_capability_mp_data (s, &entry.mpc);
entry.num = stream_getc (s);
afi = entry.mpc.afi;
safi = entry.mpc.safi;
pkt_afi = entry.mpc.afi;
pkt_safi = entry.mpc.safi;
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
peer->host, entry.mpc.afi, entry.mpc.safi);
/* Check AFI and SAFI. */
if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
zlog_info ("%s Addr-family %d/%d not supported."
" Ignoring the ORF capability",
peer->host, entry.mpc.afi, entry.mpc.safi);
peer->host, pkt_afi, pkt_safi);
return 0;
}
entry.mpc.afi = afi;
entry.mpc.safi = safi;
/* validate number field */
if (CAPABILITY_CODE_ORF_LEN + (entry.num * 2) > hdr->length)
{
@ -321,7 +300,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
case ORF_MODE_RECEIVE:
break;
default:
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
/* ORF Type and afi/safi error checks */
@ -334,7 +313,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
case ORF_TYPE_PREFIX:
break;
default:
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
break;
@ -344,12 +323,12 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
case ORF_TYPE_PREFIX_OLD:
break;
default:
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
break;
default:
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
@ -358,7 +337,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
|| (afi == AFI_IP && safi == SAFI_MULTICAST)
|| (afi == AFI_IP6 && safi == SAFI_UNICAST)))
{
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
@ -367,7 +346,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
" as %s for afi/safi: %d/%d",
peer->host, LOOKUP (orf_type_str, type),
LOOKUP (orf_mode_str, mode),
entry.mpc.afi, safi);
pkt_afi, pkt_safi);
if (hdr->code == CAPABILITY_CODE_ORF)
{
@ -381,7 +360,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
}
else
{
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
bgp_capability_orf_not_support (peer, pkt_afi, pkt_safi, type, mode);
continue;
}
@ -437,23 +416,26 @@ bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
while (stream_get_getp (s) + 4 <= end)
{
afi_t afi = stream_getw (s);
safi_t safi = stream_getc (s);
afi_t afi;
safi_t safi;
afi_t pkt_afi = stream_getw (s);
safi_t pkt_safi = stream_getc (s);
u_char flag = stream_getc (s);
if (!bgp_afi_safi_valid_indices (afi, &safi))
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
" Ignore the Graceful Restart capability for this AFI/SAFI",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
}
else if (!peer->afc[afi][safi])
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
" Ignore the Graceful Restart capability",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
}
else
{
@ -512,22 +494,25 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
while (stream_get_getp (s) + 4 <= end)
{
afi_t afi = stream_getw (s);
safi_t safi = stream_getc (s);
afi_t afi;
safi_t safi;
afi_t pkt_afi = stream_getw (s);
safi_t pkt_safi = stream_getc (s);
u_char send_receive = stream_getc (s);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
peer->host, afi, safi,
peer->host, pkt_afi, pkt_safi,
(send_receive & BGP_ADDPATH_RX) ? ", receive" : "",
(send_receive & BGP_ADDPATH_TX) ? ", transmit" : "");
if (!bgp_afi_safi_valid_indices (afi, &safi))
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
" Ignore the Addpath Attribute for this AFI/SAFI",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
continue;
}
else if (!peer->afc[afi][safi])
@ -535,7 +520,7 @@ bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
" Ignore the AddPath capability for this AFI/SAFI",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
continue;
}
@ -565,20 +550,21 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
while (stream_get_getp (s) + 6 <= end)
{
afi_t afi = stream_getw (s);
safi_t safi = stream_getw (s);
afi_t nh_afi = stream_getw (s);
afi_t afi, pkt_afi = stream_getw (s);
safi_t safi, pkt_safi = stream_getw (s);
afi_t nh_afi, pkt_nh_afi = stream_getw (s);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Received with afi/safi/next-hop afi: %u/%u/%u",
peer->host, afi, safi, nh_afi);
peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
if (!bgp_afi_safi_valid_indices (afi, &safi))
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
" Ignore the ENHE Attribute for this AFI/SAFI",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
continue;
}
@ -587,11 +573,13 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
* possibilities, so we ignore other values with a log. Also, only
* Unicast SAFI is currently supported (and expected).
*/
nh_afi = afi_iana2int (pkt_nh_afi);
if (afi != AFI_IP || safi != SAFI_UNICAST || nh_afi != AFI_IP6)
{
zlog_warn ("%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
"in Extended Next-hop capability, ignoring",
peer->host, afi, safi, nh_afi);
peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
continue;
}
@ -1174,9 +1162,11 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer,
unsigned long orfp;
unsigned long numberp;
int number_of_orfs = 0;
afi_t pkt_afi;
safi_t pkt_safi;
if (safi == SAFI_MPLS_VPN)
safi = SAFI_MPLS_LABELED_VPN;
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
stream_putc (s, BGP_OPEN_OPT_CAP);
capp = stream_get_endp (s); /* Set Capability Len Pointer */
@ -1184,9 +1174,9 @@ bgp_open_capability_orf (struct stream *s, struct peer *peer,
stream_putc (s, code); /* Capability Code */
orfp = stream_get_endp (s); /* Set ORF Len Pointer */
stream_putc (s, 0); /* ORF Length */
stream_putw (s, afi);
stream_putw (s, pkt_afi);
stream_putc (s, 0);
stream_putc (s, safi);
stream_putc (s, pkt_safi);
numberp = stream_get_endp (s); /* Set Number Pointer */
stream_putc (s, 0); /* Number of ORFs */
@ -1235,8 +1225,8 @@ bgp_open_capability (struct stream *s, struct peer *peer)
{
u_char len;
unsigned long cp, capp, rcapp;
afi_t afi;
safi_t safi;
afi_t afi, pkt_afi;
safi_t safi, pkt_safi;
as_t local_as;
u_int32_t restart_time;
u_char afi_safi_count = 0;
@ -1254,55 +1244,29 @@ bgp_open_capability (struct stream *s, struct peer *peer)
|| CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
return;
/* IPv4 unicast. */
if (peer->afc[AFI_IP][SAFI_UNICAST])
{
peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, SAFI_UNICAST);
}
/* IPv4 multicast. */
if (peer->afc[AFI_IP][SAFI_MULTICAST])
{
peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, SAFI_MULTICAST);
}
/* IPv4 VPN */
if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, SAFI_MPLS_LABELED_VPN);
}
/* ENCAP */
if (peer->afc[AFI_IP][SAFI_ENCAP])
{
peer->afc_adv[AFI_IP][SAFI_ENCAP] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, SAFI_ENCAP);
}
/* Currently supporting RFC-5549 for Link-Local peering only */
/* MP capability for configured AFI, SAFI */
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
{
if (peer->afc[afi][safi])
{
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
peer->afc_adv[afi][safi] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, pkt_afi);
stream_putc (s, 0);
stream_putc (s, pkt_safi);
}
}
/* Extended nexthop capability - currently supporting RFC-5549 for
* Link-Local peering only
*/
if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE) &&
peer->su.sa.sa_family == AF_INET6 &&
IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
@ -1322,54 +1286,6 @@ bgp_open_capability (struct stream *s, struct peer *peer)
if (CHECK_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_RCV))
SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_NEGO);
}
/* IPv6 unicast. */
if (peer->afc[AFI_IP6][SAFI_UNICAST])
{
peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP6);
stream_putc (s, 0);
stream_putc (s, SAFI_UNICAST);
}
/* IPv6 multicast. */
if (peer->afc[AFI_IP6][SAFI_MULTICAST])
{
peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP6);
stream_putc (s, 0);
stream_putc (s, SAFI_MULTICAST);
}
/* IPv6 VPN. */
if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
{
peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP6);
stream_putc (s, 0);
stream_putc (s, SAFI_MPLS_LABELED_VPN);
}
/* IPv6 ENCAP. */
if (peer->afc[AFI_IP6][SAFI_ENCAP])
{
peer->afc_adv[AFI_IP6][SAFI_ENCAP] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP6);
stream_putc (s, 0);
stream_putc (s, SAFI_ENCAP);
}
/* Route refresh. */
SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
@ -1418,8 +1334,11 @@ bgp_open_capability (struct stream *s, struct peer *peer)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (peer->afc[afi][safi])
{
stream_putw (s, afi);
stream_putc (s, safi);
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
stream_putw (s, pkt_afi);
stream_putc (s, pkt_safi);
if (adv_addpath_tx)
{
@ -1533,8 +1452,10 @@ bgp_open_capability (struct stream *s, struct peer *peer)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (peer->afc[afi][safi])
{
stream_putw (s, afi);
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
stream_putw (s, pkt_afi);
stream_putc (s, pkt_safi);
if (bgp_flag_check(peer->bgp, BGP_FLAG_GR_PRESERVE_FWD))
stream_putc (s, RESTART_F_BIT);
else

View File

@ -115,6 +115,5 @@ extern int bgp_open_option_parse (struct peer *, u_char, int *);
extern void bgp_open_capability (struct stream *, struct peer *);
extern void bgp_capability_vty_out (struct vty *, struct peer *, u_char, json_object *);
extern as_t peek_for_as4_capability (struct peer *, u_char);
extern int bgp_afi_safi_valid_indices (afi_t, safi_t *);
#endif /* _QUAGGA_BGP_OPEN_H */

View File

@ -147,6 +147,8 @@ static struct stream *
bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
{
struct stream *s;
afi_t pkt_afi;
safi_t pkt_safi;
if (DISABLE_BGP_ANNOUNCE)
return NULL;
@ -169,13 +171,16 @@ bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
}
else
{
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
/* Total Path Attribute Length */
stream_putw (s, 6);
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
stream_putc (s, 3);
stream_putw (s, afi);
stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
stream_putw (s, pkt_afi);
stream_putc (s, pkt_safi);
}
bgp_packet_set_size (s);
@ -690,15 +695,16 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
struct stream *s;
struct bgp_filter *filter;
int orf_refresh = 0;
afi_t pkt_afi;
safi_t pkt_safi;
if (DISABLE_BGP_ANNOUNCE)
return;
filter = &peer->filter[afi][safi];
/* Adjust safi code. */
if (safi == SAFI_MPLS_VPN)
safi = SAFI_MPLS_LABELED_VPN;
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
s = stream_new (BGP_MAX_PACKET_SIZE);
@ -709,9 +715,9 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
/* Encode Route Refresh message. */
stream_putw (s, afi);
stream_putw (s, pkt_afi);
stream_putc (s, 0);
stream_putc (s, safi);
stream_putc (s, pkt_safi);
if (orf_type == ORF_TYPE_PREFIX
|| orf_type == ORF_TYPE_PREFIX_OLD)
@ -734,7 +740,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
peer->host, orf_type,
(when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
afi, safi);
pkt_afi, pkt_safi);
}
else
{
@ -746,7 +752,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
peer->host, orf_type,
(when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
afi, safi);
pkt_afi, pkt_safi);
}
/* Total ORF Entry Len. */
@ -761,7 +767,7 @@ bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
{
if (! orf_refresh)
zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
}
/* Add packet to the peer. */
@ -776,10 +782,11 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
int capability_code, int action)
{
struct stream *s;
afi_t pkt_afi;
safi_t pkt_safi;
/* Adjust safi code. */
if (safi == SAFI_MPLS_VPN)
safi = SAFI_MPLS_LABELED_VPN;
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
s = stream_new (BGP_MAX_PACKET_SIZE);
@ -792,14 +799,14 @@ bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
stream_putc (s, action);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, afi);
stream_putw (s, pkt_afi);
stream_putc (s, 0);
stream_putc (s, safi);
stream_putc (s, pkt_safi);
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
peer->host, action == CAPABILITY_ACTION_SET ?
"Advertising" : "Removing", afi, safi);
"Advertising" : "Removing", pkt_afi, pkt_safi);
}
/* Set packet size. */
@ -1329,7 +1336,6 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
case SAFI_MULTICAST:
return bgp_nlri_parse_ip (peer, attr, packet);
case SAFI_MPLS_VPN:
case SAFI_MPLS_LABELED_VPN:
return bgp_nlri_parse_vpn (peer, attr, packet);
case SAFI_ENCAP:
return bgp_nlri_parse_encap (peer, attr, packet);
@ -1508,26 +1514,6 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
if (!nlris[i].nlri)
continue;
/* We use afi and safi as indices into tables and what not. It would
* be impossible, at this time, to support unknown afi/safis. And
* anyway, the peer needs to be configured to enable the afi/safi
* explicitly which requires UI support.
*
* Ignore unknown afi/safi NLRIs.
*
* Note: This means nlri[x].afi/safi still can not be trusted for
* indexing later in this function!
*
* Note2: This will also remap the wire code-point for VPN safi to the
* internal safi_t point, as needs be.
*/
if(!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
{
zlog_info ("%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
peer->host, nlris[i].afi, nlris[i].safi);
continue;
}
/* NLRI is processed iff the peer if configured for the specific afi/safi */
if (!peer->afc[nlris[i].afi][nlris[i].safi])
{
@ -1586,9 +1572,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
safi = SAFI_UNICAST;
}
else if (attr.flag & ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI)
&& nlris[NLRI_MP_WITHDRAW].length == 0
&& bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
&nlris[NLRI_MP_WITHDRAW].safi))
&& nlris[NLRI_MP_WITHDRAW].length == 0)
{
afi = nlris[NLRI_MP_WITHDRAW].afi;
safi = nlris[NLRI_MP_WITHDRAW].safi;
@ -1727,8 +1711,8 @@ bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
static void
bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
{
afi_t afi;
safi_t safi;
afi_t pkt_afi, afi;
safi_t pkt_safi, safi;
struct stream *s;
struct peer_af *paf;
struct update_group *updgrp;
@ -1757,28 +1741,22 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
s = peer->ibuf;
/* Parse packet. */
afi = stream_getw (s);
pkt_afi = stream_getw (s);
(void)stream_getc (s);
safi = stream_getc (s);
pkt_safi = stream_getc (s);
if (bgp_debug_update(peer, NULL, NULL, 0))
zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
/* Check AFI and SAFI. */
if ((afi != AFI_IP && afi != AFI_IP6)
|| (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
&& safi != SAFI_MPLS_LABELED_VPN))
/* Convert AFI, SAFI to internal values and check. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
zlog_info ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
peer->host, afi, safi);
peer->host, pkt_afi, pkt_safi);
return;
}
/* Adjust safi code. */
if (safi == SAFI_MPLS_LABELED_VPN)
safi = SAFI_MPLS_VPN;
if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
{
u_char *end;
@ -1954,8 +1932,8 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
struct capability_mp_data mpc;
struct capability_header *hdr;
u_char action;
afi_t afi;
safi_t safi;
afi_t pkt_afi, afi;
safi_t pkt_safi, safi;
end = pnt + length;
@ -1999,18 +1977,19 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
/* We know MP Capability Code. */
if (hdr->code == CAPABILITY_CODE_MP)
{
afi = ntohs (mpc.afi);
safi = mpc.safi;
pkt_afi = ntohs (mpc.afi);
pkt_safi = mpc.safi;
/* Ignore capability when override-capability is set. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
continue;
if (!bgp_afi_safi_valid_indices (afi, &safi))
/* Convert AFI, SAFI to internal values. */
if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
"(%u/%u)", peer->host, afi, safi);
"(%u/%u)", peer->host, pkt_afi, pkt_safi);
continue;
}
@ -2020,7 +1999,7 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
peer->host,
action == CAPABILITY_ACTION_SET
? "Advertising" : "Removing",
ntohs(mpc.afi) , mpc.safi);
pkt_afi, pkt_safi);
if (action == CAPABILITY_ACTION_SET)
{

View File

@ -2113,6 +2113,9 @@ int
bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
safi_t safi, int always)
{
afi_t pkt_afi;
safi_t pkt_safi;
if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
return 0;
@ -2130,15 +2133,15 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
return 0;
/* Convert AFI, SAFI to values for packet. */
pkt_afi = afi_int2iana (afi);
pkt_safi = safi_int2iana (safi);
{
u_int8_t ndata[7];
if (safi == SAFI_MPLS_VPN)
safi = SAFI_MPLS_LABELED_VPN;
ndata[0] = (afi >> 8);
ndata[1] = afi;
ndata[2] = safi;
ndata[0] = (pkt_afi >> 8);
ndata[1] = pkt_afi;
ndata[2] = pkt_safi;
ndata[3] = (peer->pmax[afi][safi] >> 24);
ndata[4] = (peer->pmax[afi][safi] >> 16);
ndata[5] = (peer->pmax[afi][safi] >> 8);

View File

@ -2944,12 +2944,14 @@ DEFUN (neighbor_local_as,
int idx_number = 3;
struct peer *peer;
int ret;
as_t as;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
ret = peer_local_as_set (peer, atoi (argv[idx_number]->arg), 0, 0);
VTY_GET_INTEGER_RANGE ("Local AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
ret = peer_local_as_set (peer, as, 0, 0);
return bgp_vty_return (vty, ret);
}
@ -2966,12 +2968,14 @@ DEFUN (neighbor_local_as_no_prepend,
int idx_number = 3;
struct peer *peer;
int ret;
as_t as;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
ret = peer_local_as_set (peer, atoi (argv[idx_number]->arg), 1, 0);
VTY_GET_INTEGER_RANGE ("Local AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
ret = peer_local_as_set (peer, as, 1, 0);
return bgp_vty_return (vty, ret);
}
@ -2989,12 +2993,14 @@ DEFUN (neighbor_local_as_no_prepend_replace_as,
int idx_number = 3;
struct peer *peer;
int ret;
as_t as;
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
ret = peer_local_as_set (peer, atoi (argv[idx_number]->arg), 1, 1);
VTY_GET_INTEGER_RANGE ("Local AS", as, argv[idx_number]->arg, 1, BGP_AS4_MAX);
ret = peer_local_as_set (peer, as, 1, 1);
return bgp_vty_return (vty, ret);
}

View File

@ -651,6 +651,35 @@ bgp_listen_limit_unset (struct bgp *bgp)
return 0;
}
int
bgp_map_afi_safi_iana2int (afi_t pkt_afi, safi_t pkt_safi,
afi_t *afi, safi_t *safi)
{
/* Map from IANA values to internal values, return error if
* values are unrecognized.
*/
*afi = afi_iana2int (pkt_afi);
*safi = safi_iana2int (pkt_safi);
if (*afi == AFI_MAX || *safi == SAFI_MAX)
return -1;
return 0;
}
int
bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi,
afi_t *pkt_afi, safi_t *pkt_safi)
{
/* Map from internal values to IANA values, return error if
* internal values are bad (unexpected).
*/
if (afi == AFI_MAX || safi == SAFI_MAX)
return -1;
*pkt_afi = afi_int2iana (afi);
*pkt_safi = safi_int2iana (safi);
return 0;
}
struct peer_af *
peer_af_create (struct peer *peer, afi_t afi, safi_t safi)
{

View File

@ -1078,10 +1078,6 @@ struct bgp_nlri
#define BGP_DEFAULT_RESTART_TIME 120
#define BGP_DEFAULT_STALEPATH_TIME 360
/* RFC4364 */
#define SAFI_MPLS_LABELED_VPN 128
#define BGP_SAFI_VPN 128
/* BGP uptime string length. */
#define BGP_UPTIME_LEN 25
@ -1358,6 +1354,13 @@ extern void bgp_route_map_terminate(void);
extern int peer_cmp (struct peer *p1, struct peer *p2);
extern int
bgp_map_afi_safi_iana2int (afi_t pkt_afi, safi_t pkt_safi,
afi_t *afi, safi_t *safi);
extern int
bgp_map_afi_safi_int2iana (afi_t afi, safi_t safi,
afi_t *pkt_afi, safi_t *pkt_safi);
extern struct peer_af * peer_af_create (struct peer *, afi_t, safi_t);
extern struct peer_af * peer_af_find (struct peer *, afi_t, safi_t);
extern int peer_af_delete (struct peer *, afi_t, safi_t);

View File

@ -4086,7 +4086,6 @@ rfapiBgpInfoFilteredImportFunction (safi_t safi)
switch (safi)
{
case SAFI_MPLS_VPN:
case BGP_SAFI_VPN:
return rfapiBgpInfoFilteredImportVPN;
case SAFI_ENCAP:
@ -4203,7 +4202,7 @@ rfapiProcessUpdate (
label);
}
if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPN)
if (safi == SAFI_MPLS_VPN)
{
vnc_direct_bgp_rh_add_route (bgp, afi, p, peer, attr);
}
@ -4332,7 +4331,7 @@ rfapiProcessWithdraw (
}
/* TBD the deletion should happen after the lifetime expires */
if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPN)
if (safi == SAFI_MPLS_VPN)
vnc_direct_bgp_rh_del_route (bgp, afi, p, peer);
if (safi == SAFI_MPLS_VPN)

View File

@ -292,6 +292,8 @@ if test $ac_cv_lib_json_c_json_object_get = no; then
fi
fi
AX_PROG_PERL_MODULES(XML::LibXML, , AC_MSG_ERROR(XML::LibXML perl module is needed to compile))
AC_ARG_ENABLE([dev_build],
AS_HELP_STRING([--enable-dev-build], [build for development]))

View File

@ -544,6 +544,14 @@ lsp_update (struct isis_lsp *lsp, struct stream *stream,
if (dnode)
dnode_destroy (dict_delete (area->lspdb[level - 1], dnode));
if (lsp->own_lsp)
{
zlog_err("ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP",
area->area_tag, rawlspid_print(lsp->lsp_header->lsp_id));
lsp_clear_data(lsp);
lsp->own_lsp = 0;
}
/* rebuild the lsp data */
lsp_update_data (lsp, stream, area, level);

2
ldpd/.gitignore vendored
View File

@ -15,4 +15,4 @@ TAGS
.arch-ids
*~
*.loT
ldp_vty_cmds.c

View File

@ -9,6 +9,8 @@ AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = libldp.a
sbin_PROGRAMS = ldpd
BUILT_SOURCES = ldp_vty_cmds.c
libldp_a_SOURCES = \
accept.c address.c adjacency.c control.c hello.c init.c interface.c \
keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
@ -19,6 +21,9 @@ libldp_a_SOURCES = \
noinst_HEADERS = \
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h
ldp_vty_cmds.c: $(srcdir)/ldp_vty.xml $(srcdir)/../tools/xml2cli.pl
@PERL@ $(srcdir)/../tools/xml2cli.pl $(srcdir)/ldp_vty.xml > $@
ldpd_SOURCES = ldpd.c
ldpd_LDADD = libldp.a ../lib/libzebra.la @LIBCAP@

View File

@ -25,12 +25,55 @@
#include "ldpe.h"
#include "log.h"
static __inline int adj_compare(struct adj *, struct adj *);
static int adj_itimer(struct thread *);
static void tnbr_del(struct tnbr *);
static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
static void tnbr_del(struct ldpd_conf *, struct tnbr *);
static int tnbr_hello_timer(struct thread *);
static void tnbr_start_hello_timer(struct tnbr *);
static void tnbr_stop_hello_timer(struct tnbr *);
RB_GENERATE(global_adj_head, adj, global_entry, adj_compare)
RB_GENERATE(nbr_adj_head, adj, nbr_entry, adj_compare)
RB_GENERATE(ia_adj_head, adj, ia_entry, adj_compare)
RB_GENERATE(tnbr_head, tnbr, entry, tnbr_compare)
static __inline int
adj_compare(struct adj *a, struct adj *b)
{
if (a->source.type < b->source.type)
return (-1);
if (a->source.type > b->source.type)
return (1);
switch (a->source.type) {
case HELLO_LINK:
if (strcmp(a->source.link.ia->iface->name,
b->source.link.ia->iface->name) < 0)
return (-1);
if (strcmp(a->source.link.ia->iface->name,
b->source.link.ia->iface->name) > 0)
return (1);
if (a->source.link.ia->af < b->source.link.ia->af)
return (-1);
if (a->source.link.ia->af > b->source.link.ia->af)
return (1);
return (ldp_addrcmp(a->source.link.ia->af,
&a->source.link.src_addr, &b->source.link.src_addr));
case HELLO_TARGETED:
if (a->source.target->af < b->source.target->af)
return (-1);
if (a->source.target->af > b->source.target->af)
return (1);
return (ldp_addrcmp(a->source.target->af,
&a->source.target->addr, &b->source.target->addr));
default:
fatalx("adj_get_af: unknown hello type");
}
return (0);
}
struct adj *
adj_new(struct in_addr lsr_id, struct hello_source *source,
union ldpd_addr *addr)
@ -48,11 +91,11 @@ adj_new(struct in_addr lsr_id, struct hello_source *source,
adj->source = *source;
adj->trans_addr = *addr;
LIST_INSERT_HEAD(&global.adj_list, adj, global_entry);
RB_INSERT(global_adj_head, &global.adj_tree, adj);
switch (source->type) {
case HELLO_LINK:
LIST_INSERT_HEAD(&source->link.ia->adj_list, adj, ia_entry);
RB_INSERT(ia_adj_head, &source->link.ia->adj_tree, adj);
break;
case HELLO_TARGETED:
source->target->adj = adj;
@ -70,12 +113,12 @@ adj_del_single(struct adj *adj)
adj_stop_itimer(adj);
LIST_REMOVE(adj, global_entry);
RB_REMOVE(global_adj_head, &global.adj_tree, adj);
if (adj->nbr)
LIST_REMOVE(adj, nbr_entry);
RB_REMOVE(nbr_adj_head, &adj->nbr->adj_tree, adj);
switch (adj->source.type) {
case HELLO_LINK:
LIST_REMOVE(adj, ia_entry);
RB_REMOVE(ia_adj_head, &adj->source.link.ia->adj_tree, adj);
break;
case HELLO_TARGETED:
adj->source.target->adj = NULL;
@ -99,7 +142,7 @@ adj_del(struct adj *adj, uint32_t notif_status)
* then delete it.
*/
if (nbr && nbr_adj_count(nbr, nbr->af) == 0) {
LIST_FOREACH_SAFE(adj, &nbr->adj_list, nbr_entry, atmp)
RB_FOREACH_SAFE(adj, nbr_adj_head, &nbr->adj_tree, atmp)
adj_del_single(adj);
session_shutdown(nbr, notif_status, 0, 0);
nbr_del(nbr);
@ -109,27 +152,9 @@ adj_del(struct adj *adj, uint32_t notif_status)
struct adj *
adj_find(struct hello_source *source)
{
struct adj *adj;
LIST_FOREACH(adj, &global.adj_list, global_entry) {
if (adj->source.type != source->type)
continue;
switch (source->type) {
case HELLO_LINK:
if (ldp_addrcmp(source->link.ia->af,
&adj->source.link.src_addr,
&source->link.src_addr) == 0)
return (adj);
break;
case HELLO_TARGETED:
if (adj->source.target == source->target)
return (adj);
break;
}
}
return (NULL);
struct adj adj;
adj.source = *source;
return (RB_FIND(global_adj_head, &global.adj_tree, &adj));
}
int
@ -161,7 +186,7 @@ adj_itimer(struct thread *thread)
if (!(adj->source.target->flags & F_TNBR_CONFIGURED) &&
adj->source.target->pw_count == 0) {
/* remove dynamic targeted neighbor */
tnbr_del(adj->source.target);
tnbr_del(leconf, adj->source.target);
return (0);
}
adj->source.target->adj = NULL;
@ -188,6 +213,17 @@ adj_stop_itimer(struct adj *adj)
/* targeted neighbors */
static __inline int
tnbr_compare(struct tnbr *a, struct tnbr *b)
{
if (a->af < b->af)
return (-1);
if (a->af > b->af)
return (1);
return (ldp_addrcmp(a->af, &a->addr, &b->addr));
}
struct tnbr *
tnbr_new(int af, union ldpd_addr *addr)
{
@ -204,34 +240,30 @@ tnbr_new(int af, union ldpd_addr *addr)
}
static void
tnbr_del(struct tnbr *tnbr)
tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
{
tnbr_stop_hello_timer(tnbr);
if (tnbr->adj)
adj_del(tnbr->adj, S_SHUTDOWN);
LIST_REMOVE(tnbr, entry);
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr);
}
struct tnbr *
tnbr_find(struct ldpd_conf *xconf, int af, union ldpd_addr *addr)
{
struct tnbr *tnbr;
LIST_FOREACH(tnbr, &xconf->tnbr_list, entry)
if (af == tnbr->af &&
ldp_addrcmp(af, addr, &tnbr->addr) == 0)
return (tnbr);
return (NULL);
struct tnbr tnbr;
tnbr.af = af;
tnbr.addr = *addr;
return (RB_FIND(tnbr_head, &xconf->tnbr_tree, &tnbr));
}
struct tnbr *
tnbr_check(struct tnbr *tnbr)
tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
{
if (!(tnbr->flags & (F_TNBR_CONFIGURED|F_TNBR_DYNAMIC)) &&
tnbr->pw_count == 0) {
tnbr_del(tnbr);
tnbr_del(xconf, tnbr);
return (NULL);
}
@ -276,7 +308,7 @@ tnbr_update_all(int af)
struct tnbr *tnbr;
/* update targeted neighbors */
LIST_FOREACH(tnbr, &leconf->tnbr_list, entry)
RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree)
if (tnbr->af == af || af == AF_UNSPEC)
tnbr_update(tnbr);
}

View File

@ -261,7 +261,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
!((flags & F_HELLO_REQ_TARG))) {
tnbr->flags &= ~F_TNBR_DYNAMIC;
tnbr = tnbr_check(tnbr);
tnbr = tnbr_check(leconf, tnbr);
}
if (!tnbr) {
@ -273,7 +273,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
tnbr = tnbr_new(af, src);
tnbr->flags |= F_TNBR_DYNAMIC;
tnbr_update(tnbr);
LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
}
source.type = HELLO_TARGETED;
@ -364,7 +364,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
adj = adj_new(lsr_id, &source, &trans_addr);
if (nbr) {
adj->nbr = nbr;
LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
}
}

View File

@ -26,6 +26,7 @@
#include "sockopt.h"
static __inline int iface_compare(struct iface *, struct iface *);
static struct if_addr *if_addr_new(struct kaddr *);
static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *);
static int if_start(struct iface *, int);
@ -39,6 +40,14 @@ static int if_leave_ipv4_group(struct iface *, struct in_addr *);
static int if_join_ipv6_group(struct iface *, struct in6_addr *);
static int if_leave_ipv6_group(struct iface *, struct in6_addr *);
RB_GENERATE(iface_head, iface, entry, iface_compare)
static __inline int
iface_compare(struct iface *a, struct iface *b)
{
return (strcmp(a->name, b->name));
}
struct iface *
if_new(struct kif *kif)
{
@ -57,30 +66,18 @@ if_new(struct kif *kif)
iface->ipv4.iface = iface;
iface->ipv4.enabled = 0;
iface->ipv4.state = IF_STA_DOWN;
LIST_INIT(&iface->ipv4.adj_list);
RB_INIT(&iface->ipv4.adj_tree);
/* ipv6 */
iface->ipv6.af = AF_INET6;
iface->ipv6.iface = iface;
iface->ipv6.enabled = 0;
iface->ipv6.state = IF_STA_DOWN;
LIST_INIT(&iface->ipv6.adj_list);
RB_INIT(&iface->ipv6.adj_tree);
return (iface);
}
struct iface *
if_lookup(struct ldpd_conf *xconf, unsigned short ifindex)
{
struct iface *iface;
LIST_FOREACH(iface, &xconf->iface_list, entry)
if (iface->ifindex == ifindex)
return (iface);
return (NULL);
}
void
if_exit(struct iface *iface)
{
@ -100,17 +97,25 @@ if_exit(struct iface *iface)
}
struct iface *
if_lookup_name(struct ldpd_conf *xconf, const char *ifname)
if_lookup(struct ldpd_conf *xconf, unsigned short ifindex)
{
struct iface *iface;
LIST_FOREACH(iface, &xconf->iface_list, entry)
if (strcmp(iface->name, ifname) == 0)
RB_FOREACH(iface, iface_head, &xconf->iface_tree)
if (iface->ifindex == ifindex)
return (iface);
return (NULL);
}
struct iface *
if_lookup_name(struct ldpd_conf *xconf, const char *ifname)
{
struct iface iface;
strlcpy(iface.name, ifname, sizeof(iface.name));
return (RB_FIND(iface_head, &xconf->iface_tree, &iface));
}
void
if_update_info(struct iface *iface, struct kif *kif)
{
@ -288,7 +293,7 @@ if_reset(struct iface *iface, int af)
ia = iface_af_get(iface, af);
if_stop_hello_timer(ia);
while ((adj = LIST_FIRST(&ia->adj_list)) != NULL)
while ((adj = RB_ROOT(&ia->adj_tree)) != NULL)
adj_del(adj, S_SHUTDOWN);
/* try to cleanup */
@ -380,7 +385,7 @@ if_update_all(int af)
{
struct iface *iface;
LIST_FOREACH(iface, &leconf->iface_list, entry)
RB_FOREACH(iface, iface_head, &leconf->iface_tree)
if_update(iface, af);
}
@ -460,7 +465,7 @@ if_to_ctl(struct iface_af *ia)
ictl.uptime = 0;
ictl.adj_cnt = 0;
LIST_FOREACH(adj, &ia->adj_list, ia_entry)
RB_FOREACH(adj, ia_adj_head, &ia->adj_tree)
ictl.adj_cnt++;
return (&ictl);

View File

@ -26,7 +26,20 @@
#include "lde.h"
#include "log.h"
static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
static __inline int l2vpn_compare(struct l2vpn *, struct l2vpn *);
static __inline int l2vpn_if_compare(struct l2vpn_if *, struct l2vpn_if *);
static __inline int l2vpn_pw_compare(struct l2vpn_pw *, struct l2vpn_pw *);
RB_GENERATE(l2vpn_head, l2vpn, entry, l2vpn_compare)
RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare)
RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare)
static __inline int
l2vpn_compare(struct l2vpn *a, struct l2vpn *b)
{
return (strcmp(a->name, b->name));
}
struct l2vpn *
l2vpn_new(const char *name)
@ -42,9 +55,9 @@ l2vpn_new(const char *name)
l2vpn->mtu = DEFAULT_L2VPN_MTU;
l2vpn->pw_type = DEFAULT_PW_TYPE;
LIST_INIT(&l2vpn->if_list);
LIST_INIT(&l2vpn->pw_list);
LIST_INIT(&l2vpn->pw_inactive_list);
RB_INIT(&l2vpn->if_tree);
RB_INIT(&l2vpn->pw_tree);
RB_INIT(&l2vpn->pw_inactive_tree);
return (l2vpn);
}
@ -52,13 +65,9 @@ l2vpn_new(const char *name)
struct l2vpn *
l2vpn_find(struct ldpd_conf *xconf, const char *name)
{
struct l2vpn *l2vpn;
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry)
if (strcmp(l2vpn->name, name) == 0)
return (l2vpn);
return (NULL);
struct l2vpn l2vpn;
strlcpy(l2vpn.name, name, sizeof(l2vpn.name));
return (RB_FIND(l2vpn_head, &xconf->l2vpn_tree, &l2vpn));
}
void
@ -67,16 +76,16 @@ l2vpn_del(struct l2vpn *l2vpn)
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) {
LIST_REMOVE(lif, entry);
while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) {
LIST_REMOVE(pw, entry);
while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw);
}
while ((pw = LIST_FIRST(&l2vpn->pw_inactive_list)) != NULL) {
LIST_REMOVE(pw, entry);
while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
}
@ -88,7 +97,7 @@ l2vpn_init(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
l2vpn_pw_init(pw);
}
@ -97,10 +106,16 @@ l2vpn_exit(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
l2vpn_pw_exit(pw);
}
static __inline int
l2vpn_if_compare(struct l2vpn_if *a, struct l2vpn_if *b)
{
return (strcmp(a->ifname, b->ifname));
}
struct l2vpn_if *
l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
{
@ -122,7 +137,7 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
{
struct l2vpn_if *lif;
LIST_FOREACH(lif, &l2vpn->if_list, entry)
RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
if (lif->ifindex == ifindex)
return (lif);
@ -132,15 +147,16 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
struct l2vpn_if *
l2vpn_if_find_name(struct l2vpn *l2vpn, const char *ifname)
{
struct l2vpn_if *lif;
LIST_FOREACH(lif, &l2vpn->if_list, entry)
if (strcmp(lif->ifname, ifname) == 0)
return (lif);
return (NULL);
struct l2vpn_if lif;
strlcpy(lif.ifname, ifname, sizeof(lif.ifname));
return (RB_FIND(l2vpn_if_head, &l2vpn->if_tree, &lif));
}
static __inline int
l2vpn_pw_compare(struct l2vpn_pw *a, struct l2vpn_pw *b)
{
return (strcmp(a->ifname, b->ifname));
}
struct l2vpn_pw *
l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
@ -162,10 +178,10 @@ l2vpn_pw_find(struct l2vpn *l2vpn, unsigned int ifindex)
{
struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
if (pw->ifindex == ifindex)
return (pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
if (pw->ifindex == ifindex)
return (pw);
@ -176,15 +192,13 @@ struct l2vpn_pw *
l2vpn_pw_find_name(struct l2vpn *l2vpn, const char *ifname)
{
struct l2vpn_pw *pw;
struct l2vpn_pw s;
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
if (strcmp(pw->ifname, ifname) == 0)
return (pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
if (strcmp(pw->ifname, ifname) == 0)
return (pw);
return (NULL);
strlcpy(s.ifname, ifname, sizeof(s.ifname));
pw = RB_FIND(l2vpn_pw_head, &l2vpn->pw_tree, &s);
if (pw)
return (pw);
return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_inactive_tree, &s));
}
void
@ -399,8 +413,8 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr)
struct fec_node *fn;
struct fec_nh *fnh;
LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) {
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr))
continue;
@ -428,8 +442,8 @@ l2vpn_pw_ctl(pid_t pid)
struct l2vpn_pw *pw;
static struct ctl_pw pwctl;
LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry)
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
memset(&pwctl, 0, sizeof(pwctl));
strlcpy(pwctl.l2vpn_name, pw->l2vpn->name,
sizeof(pwctl.l2vpn_name));
@ -459,7 +473,7 @@ l2vpn_binding_ctl(pid_t pid)
fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL &&
LIST_EMPTY(&fn->downstream))
RB_EMPTY(&fn->downstream))
continue;
memset(&pwctl, 0, sizeof(pwctl));
@ -477,7 +491,7 @@ l2vpn_binding_ctl(pid_t pid)
} else
pwctl.local_label = NO_LABEL;
LIST_FOREACH(me, &fn->downstream, entry)
RB_FOREACH(me, lde_map_head, &fn->downstream)
if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr)
break;
@ -508,7 +522,7 @@ ldpe_l2vpn_init(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldpe_l2vpn_pw_init(pw);
}
@ -517,7 +531,7 @@ ldpe_l2vpn_exit(struct l2vpn *l2vpn)
{
struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldpe_l2vpn_pw_exit(pw);
}
@ -530,7 +544,7 @@ ldpe_l2vpn_pw_init(struct l2vpn_pw *pw)
if (tnbr == NULL) {
tnbr = tnbr_new(pw->af, &pw->addr);
tnbr_update(tnbr);
LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
}
tnbr->pw_count++;
@ -544,6 +558,6 @@ ldpe_l2vpn_pw_exit(struct l2vpn_pw *pw)
tnbr = tnbr_find(leconf, pw->af, &pw->addr);
if (tnbr) {
tnbr->pw_count--;
tnbr_check(tnbr);
tnbr_check(leconf, tnbr);
}
}

View File

@ -45,12 +45,14 @@ static struct lde_nbr *lde_nbr_find(uint32_t);
static void lde_nbr_clear(void);
static void lde_nbr_addr_update(struct lde_nbr *,
struct lde_addr *, int);
static __inline int lde_map_compare(struct lde_map *, struct lde_map *);
static void lde_map_free(void *);
static int lde_address_add(struct lde_nbr *, struct lde_addr *);
static int lde_address_del(struct lde_nbr *, struct lde_addr *);
static void lde_address_list_free(struct lde_nbr *);
RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare)
struct ldpd_conf *ldeconf;
struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
@ -471,10 +473,10 @@ lde_dispatch_parent(struct thread *thread)
fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
LIST_INIT(&nconf->iface_list);
LIST_INIT(&nconf->tnbr_list);
LIST_INIT(&nconf->nbrp_list);
LIST_INIT(&nconf->l2vpn_list);
RB_INIT(&nconf->iface_tree);
RB_INIT(&nconf->tnbr_tree);
RB_INIT(&nconf->nbrp_tree);
RB_INIT(&nconf->l2vpn_tree);
break;
case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL)
@ -482,37 +484,37 @@ lde_dispatch_parent(struct thread *thread)
memcpy(niface, imsg.data, sizeof(struct iface));
LIST_INIT(&niface->addr_list);
LIST_INIT(&niface->ipv4.adj_list);
LIST_INIT(&niface->ipv6.adj_list);
RB_INIT(&niface->ipv4.adj_tree);
RB_INIT(&niface->ipv6.adj_tree);
niface->ipv4.iface = niface;
niface->ipv6.iface = niface;
LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
RB_INSERT(iface_head, &nconf->iface_tree, niface);
break;
case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
fatal(NULL);
memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
break;
case IMSG_RECONF_NBRP:
if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
fatal(NULL);
memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
break;
case IMSG_RECONF_L2VPN:
if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
LIST_INIT(&nl2vpn->if_list);
LIST_INIT(&nl2vpn->pw_list);
LIST_INIT(&nl2vpn->pw_inactive_list);
RB_INIT(&nl2vpn->if_tree);
RB_INIT(&nl2vpn->pw_tree);
RB_INIT(&nl2vpn->pw_inactive_tree);
LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
break;
case IMSG_RECONF_L2VPN_IF:
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
@ -520,7 +522,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
nlif->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
break;
case IMSG_RECONF_L2VPN_PW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -528,7 +530,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
break;
case IMSG_RECONF_L2VPN_IPW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -536,7 +538,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_inactive_list, npw, entry);
RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
break;
case IMSG_RECONF_END:
merge_config(ldeconf, nconf);
@ -1141,6 +1143,13 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
}
}
static __inline int
lde_map_compare(struct lde_map *a, struct lde_map *b)
{
return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
(union ldpd_addr *)&b->nexthop->id));
}
struct lde_map *
lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
{
@ -1154,13 +1163,15 @@ lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
me->nexthop = ln;
if (sent) {
LIST_INSERT_HEAD(&fn->upstream, me, entry);
RB_INSERT(lde_map_head, &fn->upstream, me);
me->head = &fn->upstream;
if (fec_insert(&ln->sent_map, &me->fec))
log_warnx("failed to add %s to sent map",
log_fec(&me->fec));
/* XXX on failure more cleanup is needed */
} else {
LIST_INSERT_HEAD(&fn->downstream, me, entry);
RB_INSERT(lde_map_head, &fn->downstream, me);
me->head = &fn->downstream;
if (fec_insert(&ln->recv_map, &me->fec))
log_warnx("failed to add %s to recv map",
log_fec(&me->fec));
@ -1185,7 +1196,7 @@ lde_map_free(void *ptr)
{
struct lde_map *map = ptr;
LIST_REMOVE(map, entry);
RB_REMOVE(lde_map_head, map->head, map);
free(map);
}

View File

@ -62,10 +62,13 @@ struct lde_req {
/* mapping entries */
struct lde_map {
struct fec fec;
LIST_ENTRY(lde_map) entry;
struct lde_map_head *head; /* fec_node's upstream/downstream */
RB_ENTRY(lde_map) entry;
struct lde_nbr *nexthop;
struct map map;
};
RB_HEAD(lde_map_head, lde_map);
RB_PROTOTYPE(lde_map_head, lde_map, entry, lde_map_cmp);
/* withdraw entries */
struct lde_wdraw {
@ -112,8 +115,8 @@ struct fec_node {
struct fec fec;
LIST_HEAD(, fec_nh) nexthops; /* fib nexthops */
LIST_HEAD(, lde_map) downstream; /* recv mappings */
LIST_HEAD(, lde_map) upstream; /* sent mappings */
struct lde_map_head downstream; /* recv mappings */
struct lde_map_head upstream; /* sent mappings */
uint32_t local_label;
void *data; /* fec specific data */

View File

@ -159,7 +159,7 @@ rt_dump(pid_t pid)
RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL &&
LIST_EMPTY(&fn->downstream))
RB_EMPTY(&fn->downstream))
continue;
rtctl.first = 1;
@ -179,7 +179,7 @@ rt_dump(pid_t pid)
}
rtctl.local_label = fn->local_label;
LIST_FOREACH(me, &fn->downstream, entry) {
RB_FOREACH(me, lde_map_head, &fn->downstream) {
rtctl.in_use = lde_nbr_is_nexthop(fn, me->nexthop);
rtctl.nexthop = me->nexthop->id;
rtctl.remote_label = me->map.label;
@ -188,7 +188,7 @@ rt_dump(pid_t pid)
&rtctl, sizeof(rtctl));
rtctl.first = 0;
}
if (LIST_EMPTY(&fn->downstream)) {
if (RB_EMPTY(&fn->downstream)) {
rtctl.in_use = 0;
rtctl.nexthop.s_addr = INADDR_ANY;
rtctl.remote_label = NO_LABEL;
@ -224,10 +224,10 @@ fec_free(void *arg)
while ((fnh = LIST_FIRST(&fn->nexthops)))
fec_nh_del(fnh);
if (!LIST_EMPTY(&fn->downstream))
if (!RB_EMPTY(&fn->downstream))
log_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec));
if (!LIST_EMPTY(&fn->upstream))
if (!RB_EMPTY(&fn->upstream))
log_warnx("%s: fec %s upstream list not empty", __func__,
log_fec(&fn->fec));
@ -251,8 +251,8 @@ fec_add(struct fec *fec)
fn->fec = *fec;
fn->local_label = NO_LABEL;
LIST_INIT(&fn->upstream);
LIST_INIT(&fn->downstream);
RB_INIT(&fn->upstream);
RB_INIT(&fn->downstream);
LIST_INIT(&fn->nexthops);
if (fec_insert(&ft, &fn->fec))
@ -774,8 +774,8 @@ lde_gc_timer(struct thread *thread)
fn = (struct fec_node *) fec;
if (!LIST_EMPTY(&fn->nexthops) ||
!LIST_EMPTY(&fn->downstream) ||
!LIST_EMPTY(&fn->upstream))
!RB_EMPTY(&fn->downstream) ||
!RB_EMPTY(&fn->upstream))
continue;
fec_remove(&ft, &fn->fec);

View File

@ -74,7 +74,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
DEBUG_OFF(event, EVENT);
else
DEBUG_ON(event, EVENT);
} else if (strcmp(type_str, "messages") == 0) {
} else if (strcmp(type_str, "messages") == 0) {
all = (vty_get_arg_value(args, "all")) ? 1 : 0;
dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL)
@ -99,7 +99,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
DEBUG_ON(msg, MSG_SEND_ALL);
}
}
} else if (strcmp(type_str, "zebra") == 0) {
} else if (strcmp(type_str, "zebra") == 0) {
if (disable)
DEBUG_OFF(zebra, ZEBRA);
else

File diff suppressed because it is too large Load Diff

View File

@ -142,7 +142,7 @@ ldp_af_iface_config_write(struct vty *vty, int af)
struct iface *iface;
struct iface_af *ia;
LIST_FOREACH(iface, &ldpd_conf->iface_list, entry) {
RB_FOREACH(iface, iface_head, &ldpd_conf->iface_tree) {
ia = iface_af_get(iface, af);
if (!ia->enabled)
continue;
@ -213,7 +213,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
vty_out(vty, " session holdtime %u%s", af_conf->keepalive,
VTY_NEWLINE);
LIST_FOREACH(tnbr, &ldpd_conf->tnbr_list, entry) {
RB_FOREACH(tnbr, tnbr_head, &ldpd_conf->tnbr_tree) {
if (tnbr->af == af) {
vty_out(vty, " !%s", VTY_NEWLINE);
vty_out(vty, " neighbor %s targeted%s",
@ -265,7 +265,7 @@ ldp_config_write(struct vty *vty)
if (ldpd_conf->flags & F_LDPD_DS_CISCO_INTEROP)
vty_out(vty, " dual-stack cisco-interop%s", VTY_NEWLINE);
LIST_FOREACH(nbrp, &ldpd_conf->nbrp_list, entry) {
RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
if (nbrp->flags & F_NBRP_KEEPALIVE)
vty_out(vty, " neighbor %s session holdtime %u%s",
inet_ntoa(nbrp->lsr_id), nbrp->keepalive,
@ -341,7 +341,7 @@ ldp_l2vpn_config_write(struct vty *vty)
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
LIST_FOREACH(l2vpn, &ldpd_conf->l2vpn_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &ldpd_conf->l2vpn_tree) {
vty_out(vty, "l2vpn %s type vpls%s", l2vpn->name, VTY_NEWLINE);
if (l2vpn->pw_type != DEFAULT_PW_TYPE)
@ -354,13 +354,13 @@ ldp_l2vpn_config_write(struct vty *vty)
vty_out(vty, " bridge %s%s", l2vpn->br_ifname,
VTY_NEWLINE);
LIST_FOREACH(lif, &l2vpn->if_list, entry)
RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
vty_out(vty, " member interface %s%s", lif->ifname,
VTY_NEWLINE);
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldp_l2vpn_pw_config_write(vty, pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
ldp_l2vpn_pw_config_write(vty, pw);
vty_out(vty, " !%s", VTY_NEWLINE);
@ -393,7 +393,7 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
if (if_lookup_name(xconf, ifname))
return (1);
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
if (l2vpn_if_find_name(l2vpn, ifname))
return (1);
if (l2vpn_pw_find_name(l2vpn, ifname))
@ -740,7 +740,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
} else {
if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} else if (nbrp->keepalive == secs)
goto cancel;
@ -857,7 +857,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
ia = iface_af_get(iface, af);
ia->enabled = 1;
LIST_INSERT_HEAD(&vty_conf->iface_list, iface, entry);
RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
ldp_reload_ref(vty_conf, (void **)&iface);
} else {
memset(&kif, 0, sizeof(kif));
@ -955,7 +955,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
if (tnbr == NULL)
goto cancel;
LIST_REMOVE(tnbr, entry);
RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
free(tnbr);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
@ -966,7 +966,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
tnbr = tnbr_new(af, &addr);
tnbr->flags |= F_TNBR_CONFIGURED;
LIST_INSERT_HEAD(&vty_conf->tnbr_list, tnbr, entry);
RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
ldp_reload(vty_conf);
@ -1129,7 +1129,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
} else {
if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} else if (nbrp->auth.method == AUTH_MD5SIG &&
strcmp(nbrp->auth.md5key, password_str) == 0)
goto cancel;
@ -1195,7 +1195,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
} else {
if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
}
nbrp->flags |= F_NBRP_GTSM;
@ -1235,7 +1235,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
if (l2vpn == NULL)
goto cancel;
LIST_REMOVE(l2vpn, entry);
RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
l2vpn_del(l2vpn);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
@ -1248,9 +1248,9 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
l2vpn = l2vpn_new(name_str);
l2vpn->type = L2VPN_TYPE_VPLS;
LIST_INSERT_HEAD(&vty_conf->l2vpn_list, l2vpn, entry);
RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
ldp_reload(vty_conf);
ldp_reload_ref(vty_conf, (void **)&l2vpn);
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
return (CMD_SUCCESS);
@ -1369,7 +1369,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
if (lif == NULL)
goto cancel;
LIST_REMOVE(lif, entry);
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
@ -1392,7 +1392,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
}
lif = l2vpn_if_new(l2vpn, &kif);
LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
ldp_reload_ref(vty_conf, (void **)&l2vpn);
@ -1425,14 +1425,14 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
if (pw == NULL)
goto cancel;
LIST_REMOVE(pw, entry);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
ldp_reload(vty_conf);
return (CMD_SUCCESS);
}
if (pw) {
VTY_PUSH_CONTEXT(LDP_PSEUDOWIRE_NODE, pw);
VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
goto cancel;
}
@ -1451,10 +1451,10 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
pw = l2vpn_pw_new(l2vpn, &kif);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
ldp_reload_ref(vty_conf, (void **)&pw);
VTY_PUSH_CONTEXT(LDP_PSEUDOWIRE_NODE, pw);
VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
return (CMD_SUCCESS);
@ -1474,7 +1474,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
preference_str = vty_get_arg_value(args, "preference");
pw = VTY_GET_CONTEXT(l2vpn_pw);
pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@ -1510,7 +1510,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
}
pw = VTY_GET_CONTEXT(l2vpn_pw);
pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable) {
@ -1546,7 +1546,7 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
}
pw = VTY_GET_CONTEXT(l2vpn_pw);
pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@ -1578,7 +1578,7 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING);
}
pw = VTY_GET_CONTEXT(l2vpn_pw);
pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@ -1600,7 +1600,7 @@ ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
pw = VTY_GET_CONTEXT(l2vpn_pw);
pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
vty_conf = ldp_dup_config_ref(ldpd_conf, (void **)&pw);
if (disable)
@ -1641,14 +1641,14 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
}
iface = if_new(&kif);
LIST_INSERT_HEAD(&conf->iface_list, iface, entry);
RB_INSERT(iface_head, &conf->iface_tree, iface);
return (iface);
}
void
iface_del_api(struct iface *iface)
iface_del_api(struct ldpd_conf *conf, struct iface *iface)
{
LIST_REMOVE(iface, entry);
RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface);
}
@ -1665,14 +1665,14 @@ tnbr_new_api(struct ldpd_conf *conf, int af, union ldpd_addr *addr)
tnbr = tnbr_new(af, addr);
tnbr->flags |= F_TNBR_CONFIGURED;
LIST_INSERT_HEAD(&conf->tnbr_list, tnbr, entry);
RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
return (tnbr);
}
void
tnbr_del_api(struct tnbr *tnbr)
tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr)
{
LIST_REMOVE(tnbr, entry);
RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
}
@ -1685,14 +1685,14 @@ nbrp_new_api(struct ldpd_conf *conf, struct in_addr lsr_id)
return (NULL);
nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&conf->nbrp_list, nbrp, entry);
RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
return (nbrp);
}
void
nbrp_del_api(struct nbr_params *nbrp)
nbrp_del_api(struct ldpd_conf *conf, struct nbr_params *nbrp)
{
LIST_REMOVE(nbrp, entry);
RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp);
}
@ -1706,29 +1706,29 @@ l2vpn_new_api(struct ldpd_conf *conf, const char *name)
l2vpn = l2vpn_new(name);
l2vpn->type = L2VPN_TYPE_VPLS;
LIST_INSERT_HEAD(&conf->l2vpn_list, l2vpn, entry);
RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
return (l2vpn);
}
void
l2vpn_del_api(struct l2vpn *l2vpn)
l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn)
{
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) {
LIST_REMOVE(lif, entry);
while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) {
LIST_REMOVE(pw, entry);
while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw);
}
while ((pw = LIST_FIRST(&l2vpn->pw_inactive_list)) != NULL) {
LIST_REMOVE(pw, entry);
while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
}
LIST_REMOVE(l2vpn, entry);
RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
free(l2vpn);
}
@ -1752,14 +1752,14 @@ l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
}
lif = l2vpn_if_new(l2vpn, &kif);
LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
return (lif);
}
void
l2vpn_if_del_api(struct l2vpn_if *lif)
l2vpn_if_del_api(struct l2vpn *l2vpn, struct l2vpn_if *lif)
{
LIST_REMOVE(lif, entry);
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
@ -1784,13 +1784,13 @@ l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
pw = l2vpn_pw_new(l2vpn, &kif);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
return (pw);
}
void
l2vpn_pw_del_api(struct l2vpn_pw *pw)
l2vpn_pw_del_api(struct l2vpn *l2vpn, struct l2vpn_pw *pw)
{
LIST_REMOVE(pw, entry);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw);
}

View File

@ -850,40 +850,40 @@ main_imsg_send_config(struct ldpd_conf *xconf)
sizeof(*xconf)) == -1)
return (-1);
LIST_FOREACH(iface, &xconf->iface_list, entry) {
RB_FOREACH(iface, iface_head, &xconf->iface_tree) {
if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface,
sizeof(*iface)) == -1)
return (-1);
}
LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
RB_FOREACH(tnbr, tnbr_head, &xconf->tnbr_tree) {
if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr,
sizeof(*tnbr)) == -1)
return (-1);
}
LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) {
RB_FOREACH(nbrp, nbrp_head, &xconf->nbrp_tree) {
if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp,
sizeof(*nbrp)) == -1)
return (-1);
}
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn,
sizeof(*l2vpn)) == -1)
return (-1);
LIST_FOREACH(lif, &l2vpn->if_list, entry) {
RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif,
sizeof(*lif)) == -1)
return (-1);
}
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw,
sizeof(*pw)) == -1)
return (-1);
}
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IPW, pw,
sizeof(*pw)) == -1)
return (-1);
@ -930,15 +930,15 @@ ldp_config_normalize(struct ldpd_conf *xconf, void **ref)
ldp_config_reset_af(xconf, AF_INET6, ref);
}
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (pw->flags & F_PW_STATIC_NBR_ADDR)
continue;
pw->af = AF_INET;
pw->addr.v4 = pw->lsr_id;
}
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
if (pw->flags & F_PW_STATIC_NBR_ADDR)
continue;
@ -954,17 +954,17 @@ ldp_config_reset_main(struct ldpd_conf *conf, void **ref)
struct iface *iface;
struct nbr_params *nbrp;
while ((iface = LIST_FIRST(&conf->iface_list)) != NULL) {
while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) {
if (ref && *ref == iface)
*ref = NULL;
LIST_REMOVE(iface, entry);
RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface);
}
while ((nbrp = LIST_FIRST(&conf->nbrp_list)) != NULL) {
while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) {
if (ref && *ref == nbrp)
*ref = NULL;
LIST_REMOVE(nbrp, entry);
RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp);
}
@ -987,18 +987,18 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref)
struct iface_af *ia;
struct tnbr *tnbr, *ttmp;
LIST_FOREACH(iface, &conf->iface_list, entry) {
RB_FOREACH(iface, iface_head, &conf->iface_tree) {
ia = iface_af_get(iface, af);
ia->enabled = 0;
}
LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
RB_FOREACH_SAFE(tnbr, tnbr_head, &conf->tnbr_tree, ttmp) {
if (tnbr->af != af)
continue;
if (ref && *ref == tnbr)
*ref = NULL;
LIST_REMOVE(tnbr, entry);
RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
}
@ -1032,46 +1032,46 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
} while (0)
COPY(xconf, conf);
LIST_INIT(&xconf->iface_list);
LIST_INIT(&xconf->tnbr_list);
LIST_INIT(&xconf->nbrp_list);
LIST_INIT(&xconf->l2vpn_list);
RB_INIT(&xconf->iface_tree);
RB_INIT(&xconf->tnbr_tree);
RB_INIT(&xconf->nbrp_tree);
RB_INIT(&xconf->l2vpn_tree);
LIST_FOREACH(iface, &conf->iface_list, entry) {
RB_FOREACH(iface, iface_head, &conf->iface_tree) {
COPY(xi, iface);
xi->ipv4.iface = xi;
xi->ipv6.iface = xi;
LIST_INSERT_HEAD(&xconf->iface_list, xi, entry);
RB_INSERT(iface_head, &xconf->iface_tree, xi);
}
LIST_FOREACH(tnbr, &conf->tnbr_list, entry) {
RB_FOREACH(tnbr, tnbr_head, &conf->tnbr_tree) {
COPY(xt, tnbr);
LIST_INSERT_HEAD(&xconf->tnbr_list, xt, entry);
RB_INSERT(tnbr_head, &xconf->tnbr_tree, xt);
}
LIST_FOREACH(nbrp, &conf->nbrp_list, entry) {
RB_FOREACH(nbrp, nbrp_head, &conf->nbrp_tree) {
COPY(xn, nbrp);
LIST_INSERT_HEAD(&xconf->nbrp_list, xn, entry);
RB_INSERT(nbrp_head, &xconf->nbrp_tree, xn);
}
LIST_FOREACH(l2vpn, &conf->l2vpn_list, entry) {
RB_FOREACH(l2vpn, l2vpn_head, &conf->l2vpn_tree) {
COPY(xl, l2vpn);
LIST_INIT(&xl->if_list);
LIST_INIT(&xl->pw_list);
LIST_INIT(&xl->pw_inactive_list);
LIST_INSERT_HEAD(&xconf->l2vpn_list, xl, entry);
RB_INIT(&xl->if_tree);
RB_INIT(&xl->pw_tree);
RB_INIT(&xl->pw_inactive_tree);
RB_INSERT(l2vpn_head, &xconf->l2vpn_tree, xl);
LIST_FOREACH(lif, &l2vpn->if_list, entry) {
RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
COPY(xf, lif);
xf->l2vpn = xl;
LIST_INSERT_HEAD(&xl->if_list, xf, entry);
RB_INSERT(l2vpn_if_head, &xl->if_tree, xf);
}
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
COPY(xp, pw);
xp->l2vpn = xl;
LIST_INSERT_HEAD(&xl->pw_list, xp, entry);
RB_INSERT(l2vpn_pw_head, &xl->pw_tree, xp);
}
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
COPY(xp, pw);
xp->l2vpn = xl;
LIST_INSERT_HEAD(&xl->pw_inactive_list, xp, entry);
RB_INSERT(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
}
}
#undef COPY
@ -1093,20 +1093,20 @@ ldp_clear_config(struct ldpd_conf *xconf)
struct nbr_params *nbrp;
struct l2vpn *l2vpn;
while ((iface = LIST_FIRST(&xconf->iface_list)) != NULL) {
LIST_REMOVE(iface, entry);
while ((iface = RB_ROOT(&xconf->iface_tree)) != NULL) {
RB_REMOVE(iface_head, &xconf->iface_tree, iface);
free(iface);
}
while ((tnbr = LIST_FIRST(&xconf->tnbr_list)) != NULL) {
LIST_REMOVE(tnbr, entry);
while ((tnbr = RB_ROOT(&xconf->tnbr_tree)) != NULL) {
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr);
}
while ((nbrp = LIST_FIRST(&xconf->nbrp_list)) != NULL) {
LIST_REMOVE(nbrp, entry);
while ((nbrp = RB_ROOT(&xconf->nbrp_tree)) != NULL) {
RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp);
free(nbrp);
}
while ((l2vpn = LIST_FIRST(&xconf->l2vpn_list)) != NULL) {
LIST_REMOVE(l2vpn, entry);
while ((l2vpn = RB_ROOT(&xconf->l2vpn_tree)) != NULL) {
RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn);
l2vpn_del(l2vpn);
}
@ -1236,10 +1236,10 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
{
struct iface *iface, *itmp, *xi;
LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) {
RB_FOREACH_SAFE(iface, iface_head, &conf->iface_tree, itmp) {
/* find deleted interfaces */
if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
LIST_REMOVE(iface, entry);
RB_REMOVE(iface_head, &conf->iface_tree, iface);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@ -1254,11 +1254,11 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
free(iface);
}
}
LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
RB_FOREACH_SAFE(xi, iface_head, &xconf->iface_tree, itmp) {
/* find new interfaces */
if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
LIST_REMOVE(xi, entry);
LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
RB_REMOVE(iface_head, &xconf->iface_tree, xi);
RB_INSERT(iface_head, &conf->iface_tree, xi);
if (ldpd_process == PROC_MAIN) {
QOBJ_REG (xi, iface);
@ -1271,7 +1271,7 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing interfaces */
merge_iface_af(&iface->ipv4, &xi->ipv4);
merge_iface_af(&iface->ipv6, &xi->ipv6);
LIST_REMOVE(xi, entry);
RB_REMOVE(iface_head, &xconf->iface_tree, xi);
if (ref && *ref == xi)
*ref = iface;
free(xi);
@ -1295,7 +1295,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
{
struct tnbr *tnbr, *ttmp, *xt;
LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
RB_FOREACH_SAFE(tnbr, tnbr_head, &conf->tnbr_tree, ttmp) {
if (!(tnbr->flags & F_TNBR_CONFIGURED))
continue;
@ -1303,26 +1303,26 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
switch (ldpd_process) {
case PROC_LDE_ENGINE:
LIST_REMOVE(tnbr, entry);
RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
break;
case PROC_LDP_ENGINE:
tnbr->flags &= ~F_TNBR_CONFIGURED;
tnbr_check(tnbr);
tnbr_check(conf, tnbr);
break;
case PROC_MAIN:
LIST_REMOVE(tnbr, entry);
RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
QOBJ_UNREG (tnbr);
free(tnbr);
break;
}
}
}
LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) {
RB_FOREACH_SAFE(xt, tnbr_head, &xconf->tnbr_tree, ttmp) {
/* find new tnbrs */
if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
LIST_REMOVE(xt, entry);
LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
RB_INSERT(tnbr_head, &conf->tnbr_tree, xt);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@ -1340,7 +1340,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing tnbrs */
if (!(tnbr->flags & F_TNBR_CONFIGURED))
tnbr->flags |= F_TNBR_CONFIGURED;
LIST_REMOVE(xt, entry);
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
if (ref && *ref == xt)
*ref = tnbr;
free(xt);
@ -1354,7 +1354,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
struct nbr *nbr;
int nbrp_changed;
LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
RB_FOREACH_SAFE(nbrp, nbrp_head, &conf->nbrp_tree, ntmp) {
/* find deleted nbrps */
if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) {
switch (ldpd_process) {
@ -1380,15 +1380,15 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
QOBJ_UNREG (nbrp);
break;
}
LIST_REMOVE(nbrp, entry);
RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp);
}
}
LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) {
RB_FOREACH_SAFE(xn, nbrp_head, &xconf->nbrp_tree, ntmp) {
/* find new nbrps */
if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) {
LIST_REMOVE(xn, entry);
LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry);
RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
RB_INSERT(nbrp_head, &conf->nbrp_tree, xn);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@ -1455,7 +1455,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
nbr_establish_connection(nbr);
}
}
LIST_REMOVE(xn, entry);
RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
if (ref && *ref == xn)
*ref = nbrp;
free(xn);
@ -1469,10 +1469,10 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
struct l2vpn_if *lif;
struct l2vpn_pw *pw;
LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
RB_FOREACH_SAFE(l2vpn, l2vpn_head, &conf->l2vpn_tree, ltmp) {
/* find deleted l2vpns */
if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
LIST_REMOVE(l2vpn, entry);
RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@ -1482,11 +1482,11 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
ldpe_l2vpn_exit(l2vpn);
break;
case PROC_MAIN:
LIST_FOREACH(lif, &l2vpn->if_list, entry)
RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
QOBJ_UNREG (lif);
LIST_FOREACH(pw, &l2vpn->pw_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
QOBJ_UNREG (pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
QOBJ_UNREG (pw);
QOBJ_UNREG (l2vpn);
break;
@ -1494,11 +1494,11 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
l2vpn_del(l2vpn);
}
}
LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
RB_FOREACH_SAFE(xl, l2vpn_head, &xconf->l2vpn_tree, ltmp) {
/* find new l2vpns */
if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
LIST_REMOVE(xl, entry);
LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
RB_INSERT(l2vpn_head, &conf->l2vpn_tree, xl);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@ -1516,7 +1516,7 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing l2vpns */
merge_l2vpn(conf, l2vpn, xl, ref);
LIST_REMOVE(xl, entry);
RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
if (ref && *ref == xl)
*ref = l2vpn;
free(xl);
@ -1530,42 +1530,42 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
struct l2vpn_pw *pw, *ptmp, *xp;
struct nbr *nbr;
int reset_nbr, reinstall_pwfec, reinstall_tnbr;
LIST_HEAD(, l2vpn_pw) pw_aux_list;
struct l2vpn_pw_head pw_aux_list;
int previous_pw_type, previous_mtu;
previous_pw_type = l2vpn->pw_type;
previous_mtu = l2vpn->mtu;
/* merge intefaces */
LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
RB_FOREACH_SAFE(lif, l2vpn_if_head, &l2vpn->if_tree, ftmp) {
/* find deleted interfaces */
if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) {
if (ldpd_process == PROC_MAIN)
QOBJ_UNREG (lif);
LIST_REMOVE(lif, entry);
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif);
}
}
LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
RB_FOREACH_SAFE(xf, l2vpn_if_head, &xl->if_tree, ftmp) {
/* find new interfaces */
if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) {
LIST_REMOVE(xf, entry);
LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, xf);
xf->l2vpn = l2vpn;
if (ldpd_process == PROC_MAIN)
QOBJ_REG (xf, l2vpn_if);
continue;
}
LIST_REMOVE(xf, entry);
RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
if (ref && *ref == xf)
*ref = lif;
free(xf);
}
/* merge active pseudowires */
LIST_INIT(&pw_aux_list);
LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
RB_INIT(&pw_aux_list);
RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_tree, ptmp) {
/* find deleted active pseudowires */
if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
switch (ldpd_process) {
@ -1580,15 +1580,15 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
break;
}
LIST_REMOVE(pw, entry);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw);
}
}
LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_tree, ptmp) {
/* find new active pseudowires */
if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
LIST_REMOVE(xp, entry);
LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, xp);
xp->l2vpn = l2vpn;
switch (ldpd_process) {
@ -1644,8 +1644,8 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
}
/* remove from active list */
LIST_REMOVE(pw, entry);
LIST_INSERT_HEAD(&pw_aux_list, pw, entry);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
RB_INSERT(l2vpn_pw_head, &pw_aux_list, pw);
}
if (ldpd_process == PROC_LDP_ENGINE) {
@ -1689,27 +1689,27 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
l2vpn->mtu = previous_mtu;
}
LIST_REMOVE(xp, entry);
RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
if (ref && *ref == xp)
*ref = pw;
free(xp);
}
/* merge inactive pseudowires */
LIST_FOREACH_SAFE(pw, &l2vpn->pw_inactive_list, entry, ptmp) {
RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree, ptmp) {
/* find deleted inactive pseudowires */
if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
LIST_REMOVE(pw, entry);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
if (ldpd_process == PROC_MAIN)
QOBJ_UNREG (pw);
free(pw);
}
}
LIST_FOREACH_SAFE(xp, &xl->pw_inactive_list, entry, ptmp) {
RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_inactive_tree, ptmp) {
/* find new inactive pseudowires */
if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
LIST_REMOVE(xp, entry);
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, xp, entry);
RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, xp);
xp->l2vpn = l2vpn;
if (ldpd_process == PROC_MAIN)
QOBJ_REG (xp, l2vpn_pw);
@ -1728,8 +1728,8 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
/* check if the pseudowire should be activated */
if (pw->lsr_id.s_addr != INADDR_ANY && pw->pwid != 0) {
/* remove from inactive list */
LIST_REMOVE(pw, entry);
LIST_INSERT_HEAD(&l2vpn->pw_list, pw, entry);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, pw);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
@ -1743,16 +1743,16 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
}
}
LIST_REMOVE(xp, entry);
RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
if (ref && *ref == xp)
*ref = pw;
free(xp);
}
/* insert pseudowires that were disabled in the inactive list */
LIST_FOREACH_SAFE(pw, &pw_aux_list, entry, ptmp) {
LIST_REMOVE(pw, entry);
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
RB_FOREACH_SAFE(pw, l2vpn_pw_head, &pw_aux_list, ptmp) {
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
}
l2vpn->pw_type = xl->pw_type;
@ -1770,10 +1770,10 @@ config_new_empty(void)
if (xconf == NULL)
fatal(NULL);
LIST_INIT(&xconf->iface_list);
LIST_INIT(&xconf->tnbr_list);
LIST_INIT(&xconf->nbrp_list);
LIST_INIT(&xconf->l2vpn_list);
RB_INIT(&xconf->iface_tree);
RB_INIT(&xconf->tnbr_tree);
RB_INIT(&xconf->nbrp_tree);
RB_INIT(&xconf->l2vpn_tree);
return (xconf);
}

View File

@ -196,7 +196,10 @@ enum nbr_action {
NBR_ACT_CLOSE_SESSION
};
TAILQ_HEAD(mapping_head, mapping_entry);
/* forward declarations */
RB_HEAD(global_adj_head, adj);
RB_HEAD(nbr_adj_head, adj);
RB_HEAD(ia_adj_head, adj);
struct map {
uint8_t type;
@ -256,7 +259,7 @@ struct iface_af {
int af;
int enabled;
int state;
LIST_HEAD(, adj) adj_list;
struct ia_adj_head adj_tree;
time_t uptime;
struct thread *hello_timer;
uint16_t hello_holdtime;
@ -264,7 +267,7 @@ struct iface_af {
};
struct iface {
LIST_ENTRY(iface) entry;
RB_ENTRY(iface) entry;
char name[IF_NAMESIZE];
unsigned int ifindex;
struct if_addr_head addr_list;
@ -275,11 +278,13 @@ struct iface {
struct iface_af ipv6;
QOBJ_FIELDS
};
RB_HEAD(iface_head, iface);
RB_PROTOTYPE(iface_head, iface, entry, iface_compare);
DECLARE_QOBJ_TYPE(iface)
/* source of targeted hellos */
struct tnbr {
LIST_ENTRY(tnbr) entry;
RB_ENTRY(tnbr) entry;
struct thread *hello_timer;
struct adj *adj;
int af;
@ -289,6 +294,8 @@ struct tnbr {
uint8_t flags;
QOBJ_FIELDS
};
RB_HEAD(tnbr_head, tnbr);
RB_PROTOTYPE(tnbr_head, tnbr, entry, tnbr_compare);
DECLARE_QOBJ_TYPE(tnbr)
#define F_TNBR_CONFIGURED 0x01
#define F_TNBR_DYNAMIC 0x02
@ -300,7 +307,7 @@ enum auth_method {
/* neighbor specific parameters */
struct nbr_params {
LIST_ENTRY(nbr_params) entry;
RB_ENTRY(nbr_params) entry;
struct in_addr lsr_id;
uint16_t keepalive;
int gtsm_enabled;
@ -313,23 +320,27 @@ struct nbr_params {
uint8_t flags;
QOBJ_FIELDS
};
RB_HEAD(nbrp_head, nbr_params);
RB_PROTOTYPE(nbrp_head, nbr_params, entry, nbr_params_compare);
DECLARE_QOBJ_TYPE(nbr_params)
#define F_NBRP_KEEPALIVE 0x01
#define F_NBRP_GTSM 0x02
#define F_NBRP_GTSM_HOPS 0x04
struct l2vpn_if {
LIST_ENTRY(l2vpn_if) entry;
RB_ENTRY(l2vpn_if) entry;
struct l2vpn *l2vpn;
char ifname[IF_NAMESIZE];
unsigned int ifindex;
uint16_t flags;
QOBJ_FIELDS
};
RB_HEAD(l2vpn_if_head, l2vpn_if);
RB_PROTOTYPE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare);
DECLARE_QOBJ_TYPE(l2vpn_if)
struct l2vpn_pw {
LIST_ENTRY(l2vpn_pw) entry;
RB_ENTRY(l2vpn_pw) entry;
struct l2vpn *l2vpn;
struct in_addr lsr_id;
int af;
@ -343,6 +354,8 @@ struct l2vpn_pw {
uint8_t flags;
QOBJ_FIELDS
};
RB_HEAD(l2vpn_pw_head, l2vpn_pw);
RB_PROTOTYPE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare);
DECLARE_QOBJ_TYPE(l2vpn_pw)
#define F_PW_STATUSTLV_CONF 0x01 /* status tlv configured */
#define F_PW_STATUSTLV 0x02 /* status tlv negotiated */
@ -352,18 +365,20 @@ DECLARE_QOBJ_TYPE(l2vpn_pw)
#define F_PW_STATIC_NBR_ADDR 0x20 /* static neighbor address configured */
struct l2vpn {
LIST_ENTRY(l2vpn) entry;
RB_ENTRY(l2vpn) entry;
char name[L2VPN_NAME_LEN];
int type;
int pw_type;
int mtu;
char br_ifname[IF_NAMESIZE];
unsigned int br_ifindex;
LIST_HEAD(, l2vpn_if) if_list;
LIST_HEAD(, l2vpn_pw) pw_list;
LIST_HEAD(, l2vpn_pw) pw_inactive_list;
struct l2vpn_if_head if_tree;
struct l2vpn_pw_head pw_tree;
struct l2vpn_pw_head pw_inactive_tree;
QOBJ_FIELDS
};
RB_HEAD(l2vpn_head, l2vpn);
RB_PROTOTYPE(l2vpn_head, l2vpn, entry, l2vpn_compare);
DECLARE_QOBJ_TYPE(l2vpn)
#define L2VPN_TYPE_VPWS 1
#define L2VPN_TYPE_VPLS 2
@ -404,10 +419,10 @@ struct ldpd_conf {
struct in_addr rtr_id;
struct ldpd_af_conf ipv4;
struct ldpd_af_conf ipv6;
LIST_HEAD(, iface) iface_list;
LIST_HEAD(, tnbr) tnbr_list;
LIST_HEAD(, nbr_params) nbrp_list;
LIST_HEAD(, l2vpn) l2vpn_list;
struct iface_head iface_tree;
struct tnbr_head tnbr_tree;
struct nbrp_head nbrp_tree;
struct l2vpn_head l2vpn_tree;
uint16_t lhello_holdtime;
uint16_t lhello_interval;
uint16_t thello_holdtime;
@ -438,7 +453,7 @@ struct ldpd_global {
uint32_t conf_seqnum;
int pfkeysock;
struct if_addr_head addr_list;
LIST_HEAD(, adj) adj_list;
struct global_adj_head adj_tree;
struct in_addr mcast_addr_v4;
struct in6_addr mcast_addr_v6;
TAILQ_HEAD(, pending_conn) pending_conns;
@ -627,23 +642,28 @@ void config_clear(struct ldpd_conf *);
/* ldp_vty_conf.c */
/* NOTE: the parameters' names should be preserved because of codegen */
struct iface *iface_new_api(struct ldpd_conf *cfg,
struct iface *iface_new_api(struct ldpd_conf *conf,
const char *name);
void iface_del_api(struct iface *iface);
struct tnbr *tnbr_new_api(struct ldpd_conf *cfg, int af,
void iface_del_api(struct ldpd_conf *conf,
struct iface *iface);
struct tnbr *tnbr_new_api(struct ldpd_conf *conf, int af,
union ldpd_addr *addr);
void tnbr_del_api(struct tnbr *tnbr);
struct nbr_params *nbrp_new_api(struct ldpd_conf *cfg,
void tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr);
struct nbr_params *nbrp_new_api(struct ldpd_conf *conf,
struct in_addr lsr_id);
void nbrp_del_api(struct nbr_params *nbrp);
struct l2vpn *l2vpn_new_api(struct ldpd_conf *cfg, const char *name);
void l2vpn_del_api(struct l2vpn *l2vpn);
void nbrp_del_api(struct ldpd_conf *conf,
struct nbr_params *nbrp);
struct l2vpn *l2vpn_new_api(struct ldpd_conf *conf, const char *name);
void l2vpn_del_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn);
struct l2vpn_if *l2vpn_if_new_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn, const char *ifname);
void l2vpn_if_del_api(struct l2vpn_if *lif);
void l2vpn_if_del_api(struct l2vpn *l2vpn,
struct l2vpn_if *lif);
struct l2vpn_pw *l2vpn_pw_new_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn, const char *ifname);
void l2vpn_pw_del_api(struct l2vpn_pw *pw);
void l2vpn_pw_del_api(struct l2vpn *l2vpn,
struct l2vpn_pw *pw);
/* socket.c */
int ldp_create_socket(int, enum socket_type);

View File

@ -111,7 +111,7 @@ ldpe(const char *user, const char *group)
ldpd_process = PROC_LDP_ENGINE;
LIST_INIT(&global.addr_list);
LIST_INIT(&global.adj_list);
RB_INIT(&global.adj_tree);
TAILQ_INIT(&global.pending_conns);
if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
fatal("inet_pton");
@ -209,7 +209,7 @@ ldpe_shutdown(void)
LIST_REMOVE(if_addr, entry);
free(if_addr);
}
while ((adj = LIST_FIRST(&global.adj_list)) != NULL)
while ((adj = RB_ROOT(&global.adj_tree)) != NULL)
adj_del(adj, S_SHUTDOWN);
/* clean up */
@ -414,10 +414,10 @@ ldpe_dispatch_main(struct thread *thread)
fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
LIST_INIT(&nconf->iface_list);
LIST_INIT(&nconf->tnbr_list);
LIST_INIT(&nconf->nbrp_list);
LIST_INIT(&nconf->l2vpn_list);
RB_INIT(&nconf->iface_tree);
RB_INIT(&nconf->tnbr_tree);
RB_INIT(&nconf->nbrp_tree);
RB_INIT(&nconf->l2vpn_tree);
break;
case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL)
@ -425,37 +425,37 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(niface, imsg.data, sizeof(struct iface));
LIST_INIT(&niface->addr_list);
LIST_INIT(&niface->ipv4.adj_list);
LIST_INIT(&niface->ipv6.adj_list);
RB_INIT(&niface->ipv4.adj_tree);
RB_INIT(&niface->ipv6.adj_tree);
niface->ipv4.iface = niface;
niface->ipv6.iface = niface;
LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
RB_INSERT(iface_head, &nconf->iface_tree, niface);
break;
case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
fatal(NULL);
memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
break;
case IMSG_RECONF_NBRP:
if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
fatal(NULL);
memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
break;
case IMSG_RECONF_L2VPN:
if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
LIST_INIT(&nl2vpn->if_list);
LIST_INIT(&nl2vpn->pw_list);
LIST_INIT(&nl2vpn->pw_inactive_list);
RB_INIT(&nl2vpn->if_tree);
RB_INIT(&nl2vpn->pw_tree);
RB_INIT(&nl2vpn->pw_inactive_tree);
LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
break;
case IMSG_RECONF_L2VPN_IF:
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
@ -463,7 +463,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
nlif->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
break;
case IMSG_RECONF_L2VPN_PW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -471,7 +471,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
break;
case IMSG_RECONF_L2VPN_IPW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -479,7 +479,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_inactive_list, npw, entry);
RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
break;
case IMSG_RECONF_END:
merge_config(leconf, nconf);
@ -743,12 +743,12 @@ ldpe_remove_dynamic_tnbrs(int af)
{
struct tnbr *tnbr, *safe;
LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) {
RB_FOREACH_SAFE(tnbr, tnbr_head, &leconf->tnbr_tree, safe) {
if (tnbr->af != af)
continue;
tnbr->flags &= ~F_TNBR_DYNAMIC;
tnbr_check(tnbr);
tnbr_check(leconf, tnbr);
}
}
@ -772,7 +772,7 @@ ldpe_iface_af_ctl(struct ctl_conn *c, int af, unsigned int idx)
struct iface_af *ia;
struct ctl_iface *ictl;
LIST_FOREACH(iface, &leconf->iface_list, entry) {
RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
if (idx == 0 || idx == iface->ifindex) {
ia = iface_af_get(iface, af);
if (!ia->enabled)
@ -805,7 +805,7 @@ ldpe_adj_ctl(struct ctl_conn *c)
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
LIST_FOREACH(iface, &leconf->iface_list, entry) {
RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
memset(&ictl, 0, sizeof(ictl));
ictl.active_v4 = (iface->ipv4.state == IF_STA_ACTIVE);
ictl.active_v6 = (iface->ipv6.state == IF_STA_ACTIVE);
@ -814,25 +814,25 @@ ldpe_adj_ctl(struct ctl_conn *c)
continue;
strlcpy(ictl.name, iface->name, sizeof(ictl.name));
if (LIST_EMPTY(&iface->ipv4.adj_list) &&
LIST_EMPTY(&iface->ipv6.adj_list))
if (RB_EMPTY(&iface->ipv4.adj_tree) &&
RB_EMPTY(&iface->ipv6.adj_tree))
ictl.no_adj = 1;
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0,
-1, &ictl, sizeof(ictl));
LIST_FOREACH(adj, &iface->ipv4.adj_list, ia_entry) {
RB_FOREACH(adj, ia_adj_head, &iface->ipv4.adj_tree) {
actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
0, 0, -1, actl, sizeof(struct ctl_adj));
}
LIST_FOREACH(adj, &iface->ipv6.adj_list, ia_entry) {
RB_FOREACH(adj, ia_adj_head, &iface->ipv6.adj_tree) {
actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
0, 0, -1, actl, sizeof(struct ctl_adj));
}
}
LIST_FOREACH(tnbr, &leconf->tnbr_list, entry) {
RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree) {
memset(&tctl, 0, sizeof(tctl));
tctl.af = tnbr->af;
tctl.addr = tnbr->addr;
@ -869,7 +869,7 @@ ldpe_nbr_ctl(struct ctl_conn *c)
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
sizeof(struct ctl_nbr));
LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) {
RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree) {
actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR_DISC,
0, 0, -1, actl, sizeof(struct ctl_adj));

View File

@ -32,6 +32,9 @@
#define min(x,y) ((x) <= (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
/* forward declarations */
TAILQ_HEAD(mapping_head, mapping_entry);
struct hello_source {
enum hello_type type;
struct {
@ -42,9 +45,7 @@ struct hello_source {
};
struct adj {
LIST_ENTRY(adj) global_entry;
LIST_ENTRY(adj) nbr_entry;
LIST_ENTRY(adj) ia_entry;
RB_ENTRY(adj) global_entry, nbr_entry, ia_entry;
struct in_addr lsr_id;
struct nbr *nbr;
int ds_tlv;
@ -53,6 +54,9 @@ struct adj {
uint16_t holdtime;
union ldpd_addr trans_addr;
};
RB_PROTOTYPE(global_adj_head, adj, global_entry, adj_compare)
RB_PROTOTYPE(nbr_adj_head, adj, nbr_entry, adj_compare)
RB_PROTOTYPE(ia_adj_head, adj, ia_entry, adj_compare)
struct tcp_conn {
struct nbr *nbr;
@ -67,7 +71,7 @@ struct tcp_conn {
struct nbr {
RB_ENTRY(nbr) id_tree, addr_tree, pid_tree;
struct tcp_conn *tcp;
LIST_HEAD(, adj) adj_list; /* adjacencies */
struct nbr_adj_head adj_tree; /* adjacencies */
struct thread *ev_connect;
struct thread *keepalive_timer;
struct thread *keepalive_timeout;
@ -225,7 +229,7 @@ void adj_start_itimer(struct adj *);
void adj_stop_itimer(struct adj *);
struct tnbr *tnbr_new(int, union ldpd_addr *);
struct tnbr *tnbr_find(struct ldpd_conf *, int, union ldpd_addr *);
struct tnbr *tnbr_check(struct tnbr *);
struct tnbr *tnbr_check(struct ldpd_conf *, struct tnbr *);
void tnbr_update(struct tnbr *);
void tnbr_update_all(int);
uint16_t tnbr_get_hello_holdtime(struct tnbr *);

View File

@ -39,10 +39,13 @@ static void nbr_start_itimeout(struct nbr *);
static int nbr_idtimer(struct thread *);
static int nbr_act_session_operational(struct nbr *);
static void nbr_send_labelmappings(struct nbr *);
static __inline int nbr_params_compare(struct nbr_params *,
struct nbr_params *);
RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare)
RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare)
RB_GENERATE(nbr_pid_head, nbr, pid_tree, nbr_pid_compare)
RB_GENERATE(nbrp_head, nbr_params, entry, nbr_params_compare)
struct {
int state;
@ -226,7 +229,7 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
fatal(__func__);
LIST_INIT(&nbr->adj_list);
RB_INIT(&nbr->adj_tree);
nbr->state = NBR_STA_PRESENT;
nbr->peerid = 0;
nbr->af = af;
@ -241,10 +244,10 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
nbr->raddr_scope = scope_id;
nbr->conf_seqnum = 0;
LIST_FOREACH(adj, &global.adj_list, global_entry) {
RB_FOREACH(adj, global_adj_head, &global.adj_tree) {
if (adj->lsr_id.s_addr == nbr->id.s_addr) {
adj->nbr = nbr;
LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
}
}
@ -363,7 +366,7 @@ nbr_adj_count(struct nbr *nbr, int af)
struct adj *adj;
int total = 0;
LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
if (adj_get_af(adj) == af)
total++;
@ -621,7 +624,7 @@ nbr_establish_connection(struct nbr *nbr)
* Send an extra hello to guarantee that the remote peer has formed
* an adjacency as well.
*/
LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
send_hello(adj->source.type, adj->source.link.ia,
adj->source.target);
@ -752,6 +755,12 @@ nbr_send_labelmappings(struct nbr *nbr)
NULL, 0);
}
static __inline int
nbr_params_compare(struct nbr_params *a, struct nbr_params *b)
{
return (ntohl(a->lsr_id.s_addr) - ntohl(b->lsr_id.s_addr));
}
struct nbr_params *
nbr_params_new(struct in_addr lsr_id)
{
@ -769,13 +778,9 @@ nbr_params_new(struct in_addr lsr_id)
struct nbr_params *
nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id)
{
struct nbr_params *nbrp;
LIST_FOREACH(nbrp, &xconf->nbrp_list, entry)
if (nbrp->lsr_id.s_addr == lsr_id.s_addr)
return (nbrp);
return (NULL);
struct nbr_params nbrp;
nbrp.lsr_id = lsr_id;
return (RB_FIND(nbrp_head, &xconf->nbrp_tree, &nbrp));
}
uint16_t

View File

@ -85,6 +85,8 @@ ldp_create_socket(int af, enum socket_type type)
if (ldpd_privs.change(ZPRIVS_RAISE))
log_warn("%s: could not raise privs", __func__);
if (sock_set_reuse(fd, 1) == -1) {
if (ldpd_privs.change(ZPRIVS_LOWER))
log_warn("%s: could not lower privs", __func__);
close(fd);
return (-1);
}

View File

@ -381,7 +381,7 @@ vrf_bitmap_set (vrf_bitmap_t bmap, vrf_id_t vrf_id)
u_char group = VRF_BITMAP_GROUP (vrf_id);
u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
if (bmap == VRF_BITMAP_NULL)
if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN)
return;
if (bm->groups[group] == NULL)
@ -399,7 +399,8 @@ vrf_bitmap_unset (vrf_bitmap_t bmap, vrf_id_t vrf_id)
u_char group = VRF_BITMAP_GROUP (vrf_id);
u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN ||
bm->groups[group] == NULL)
return;
UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
@ -413,7 +414,8 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
u_char group = VRF_BITMAP_GROUP (vrf_id);
u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
if (bmap == VRF_BITMAP_NULL || vrf_id == VRF_UNKNOWN ||
bm->groups[group] == NULL)
return 0;
return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],

View File

@ -508,18 +508,6 @@ vty_write (struct vty *vty, const char *buf, size_t nbytes)
buffer_put (vty->obuf, buf, nbytes);
}
/* Ensure length of input buffer. Is buffer is short, double it. */
static void
vty_ensure (struct vty *vty, int length)
{
if (vty->max <= length)
{
vty->max *= 2;
vty->buf = XREALLOC (MTYPE_VTY, vty->buf, vty->max);
vty->error_buf = XREALLOC (MTYPE_VTY, vty->error_buf, vty->max);
}
}
/* Basic function to insert character into vty. */
static void
vty_self_insert (struct vty *vty, char c)
@ -527,7 +515,9 @@ vty_self_insert (struct vty *vty, char c)
int i;
int length;
vty_ensure (vty, vty->length + 1);
if (vty->length + 1 > VTY_BUFSIZ)
return;
length = vty->length - vty->cp;
memmove (&vty->buf[vty->cp + 1], &vty->buf[vty->cp], length);
vty->buf[vty->cp] = c;
@ -544,26 +534,29 @@ vty_self_insert (struct vty *vty, char c)
static void
vty_self_insert_overwrite (struct vty *vty, char c)
{
vty_ensure (vty, vty->length + 1);
if (vty->cp == vty->length)
{
vty_self_insert (vty, c);
return;
}
vty->buf[vty->cp++] = c;
if (vty->cp > vty->length)
vty->length++;
if ((vty->node == AUTH_NODE) || (vty->node == AUTH_ENABLE_NODE))
return;
vty_write (vty, &c, 1);
}
/* Insert a word into vty interface with overwrite mode. */
/**
* Insert a string into vty->buf at the current cursor position.
*
* If the resultant string would be larger than VTY_BUFSIZ it is
* truncated to fit.
*/
static void
vty_insert_word_overwrite (struct vty *vty, char *str)
{
int len = strlen (str);
vty_write (vty, str, len);
strcpy (&vty->buf[vty->cp], str);
vty->cp += len;
size_t nwrite = MIN ((int) strlen (str), VTY_BUFSIZ - vty->cp);
vty_write (vty, str, nwrite);
strncpy (&vty->buf[vty->cp], str, nwrite);
vty->cp += nwrite;
vty->length = vty->cp;
}
@ -2148,36 +2141,45 @@ vtysh_read (struct thread *thread)
printf ("line: %.*s\n", nbytes, buf);
#endif /* VTYSH_DEBUG */
for (p = buf; p < buf+nbytes; p++)
if (vty->length + nbytes > VTY_BUFSIZ)
{
vty_ensure(vty, vty->length+1);
vty->buf[vty->length++] = *p;
if (*p == '\0')
/* Clear command line buffer. */
vty->cp = vty->length = 0;
vty_clear_buf (vty);
vty_out (vty, "%% Command is too long.%s", VTY_NEWLINE);
}
else
{
for (p = buf; p < buf+nbytes; p++)
{
/* Pass this line to parser. */
ret = vty_execute (vty);
/* Note that vty_execute clears the command buffer and resets
vty->length to 0. */
vty->buf[vty->length++] = *p;
if (*p == '\0')
{
/* Pass this line to parser. */
ret = vty_execute (vty);
/* Note that vty_execute clears the command buffer and resets
vty->length to 0. */
/* Return result. */
/* Return result. */
#ifdef VTYSH_DEBUG
printf ("result: %d\n", ret);
printf ("vtysh node: %d\n", vty->node);
printf ("result: %d\n", ret);
printf ("vtysh node: %d\n", vty->node);
#endif /* VTYSH_DEBUG */
/* hack for asynchronous "write integrated"
* - other commands in "buf" will be ditched
* - input during pending config-write is "unsupported" */
if (ret == CMD_SUSPEND)
break;
/* hack for asynchronous "write integrated"
* - other commands in "buf" will be ditched
* - input during pending config-write is "unsupported" */
if (ret == CMD_SUSPEND)
break;
/* warning: watchfrr hardcodes this result write */
header[3] = ret;
buffer_put(vty->obuf, header, 4);
/* warning: watchquagga hardcodes this result write */
header[3] = ret;
buffer_put(vty->obuf, header, 4);
if (!vty->t_write && (vtysh_flush(vty) < 0))
/* Try to flush results; exit if a write error occurs. */
return 0;
if (!vty->t_write && (vtysh_flush(vty) < 0))
/* Try to flush results; exit if a write error occurs. */
return 0;
}
}
}

View File

@ -26,7 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "sockunion.h"
#include "qobj.h"
#define VTY_BUFSIZ 512
#define VTY_BUFSIZ 4096
#define VTY_MAXHIST 20
/* VTY struct. */

View File

@ -473,9 +473,28 @@ typedef enum {
#define SAFI_MULTICAST 2
#define SAFI_MPLS_VPN 3
#define SAFI_RESERVED_4 4
#define SAFI_ENCAP 7 /* per IANA */
#define SAFI_ENCAP 5
#define SAFI_RESERVED_5 5
#define SAFI_MAX 8
#define SAFI_MAX 6
/*
* The above AFI and SAFI definitions are for internal use. The protocol
* definitions (IANA values) as for example used in BGP protocol packets
* are defined below and these will get mapped to/from the internal values
* in the appropriate places.
* The rationale is that the protocol (IANA) values may be sparse and are
* not optimal for use in data-structure sizing.
* Note: Only useful (i.e., supported) values are defined below.
*/
#define IANA_AFI_RESERVED 0
#define IANA_AFI_IPV4 1
#define IANA_AFI_IPV6 2
#define IANA_SAFI_RESERVED 0
#define IANA_SAFI_UNICAST 1
#define IANA_SAFI_MULTICAST 2
#define IANA_SAFI_ENCAP 7
#define IANA_SAFI_MPLS_VPN 128
/* Default Administrative Distance of each protocol. */
#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
@ -509,4 +528,48 @@ typedef uint32_t route_tag_t;
#define ROUTE_TAG_MAX UINT32_MAX
#define ROUTE_TAG_PRI PRIu32
static inline afi_t afi_iana2int (afi_t afi)
{
if (afi == IANA_AFI_IPV4)
return AFI_IP;
if (afi == IANA_AFI_IPV6)
return AFI_IP6;
return AFI_MAX;
}
static inline afi_t afi_int2iana (afi_t afi)
{
if (afi == AFI_IP)
return IANA_AFI_IPV4;
if (afi == AFI_IP6)
return IANA_AFI_IPV6;
return IANA_AFI_RESERVED;
}
static inline safi_t safi_iana2int (safi_t safi)
{
if (safi == IANA_SAFI_UNICAST)
return SAFI_UNICAST;
if (safi == IANA_SAFI_MULTICAST)
return SAFI_MULTICAST;
if (safi == IANA_SAFI_MPLS_VPN)
return SAFI_MPLS_VPN;
if (safi == IANA_SAFI_ENCAP)
return SAFI_ENCAP;
return SAFI_MAX;
}
static inline safi_t safi_int2iana (safi_t safi)
{
if (safi == SAFI_UNICAST)
return IANA_SAFI_UNICAST;
if (safi == SAFI_MULTICAST)
return IANA_SAFI_MULTICAST;
if (safi == SAFI_MPLS_VPN)
return IANA_SAFI_MPLS_VPN;
if (safi == SAFI_ENCAP)
return IANA_SAFI_ENCAP;
return IANA_SAFI_RESERVED;
}
#endif /* _ZEBRA_H */

View File

@ -0,0 +1,77 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_prog_perl_modules.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_PERL_MODULES([MODULES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# Checks to see if the given perl modules are available. If true the shell
# commands in ACTION-IF-TRUE are executed. If not the shell commands in
# ACTION-IF-FALSE are run. Note if $PERL is not set (for example by
# calling AC_CHECK_PROG, or AC_PATH_PROG), AC_CHECK_PROG(PERL, perl, perl)
# will be run.
#
# MODULES is a space separated list of module names. To check for a
# minimum version of a module, append the version number to the module
# name, separated by an equals sign.
#
# Example:
#
# AX_PROG_PERL_MODULES( Text::Wrap Net::LDAP=1.0.3, ,
# AC_MSG_WARN(Need some Perl modules)
#
# LICENSE
#
# Copyright (c) 2009 Dean Povey <povey@wedgetail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 7
AU_ALIAS([AC_PROG_PERL_MODULES], [AX_PROG_PERL_MODULES])
AC_DEFUN([AX_PROG_PERL_MODULES],[dnl
m4_define([ax_perl_modules])
m4_foreach([ax_perl_module], m4_split(m4_normalize([$1])),
[
m4_append([ax_perl_modules],
[']m4_bpatsubst(ax_perl_module,=,[ ])[' ])
])
# Make sure we have perl
if test -z "$PERL"; then
AC_CHECK_PROG(PERL,perl,perl)
fi
if test "x$PERL" != x; then
ax_perl_modules_failed=0
for ax_perl_module in ax_perl_modules; do
AC_MSG_CHECKING(for perl module $ax_perl_module)
# Would be nice to log result here, but can't rely on autoconf internals
$PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1
if test $? -ne 0; then
AC_MSG_RESULT(no);
ax_perl_modules_failed=1
else
AC_MSG_RESULT(ok);
fi
done
# Run optional shell commands
if test "$ax_perl_modules_failed" = 0; then
:
$2
else
:
$3
fi
else
AC_MSG_WARN(could not find perl)
fi])dnl

View File

@ -424,12 +424,9 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
else
{
summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
if (route->type == OSPF6_DEST_TYPE_RANGE)
summary->path.origin.id = route->linkstate_id;
else
summary->path.origin.id =
ospf6_new_ls_id (summary->path.origin.type,
summary->path.origin.adv_router, area->lsdb);
summary->path.origin.id =
ospf6_new_ls_id (summary->path.origin.type,
summary->path.origin.adv_router, area->lsdb);
}
summary = ospf6_route_add (summary, summary_table);
}

View File

@ -472,8 +472,6 @@ DEFUN (area_range,
range->prefix = prefix;
range->path.area_id = oa->area_id;
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
range->linkstate_id =
(u_int32_t) htonl(ospf6_new_range_ls_id (oa->range_table));
}
if (argc > idx_type)
@ -559,8 +557,6 @@ DEFUN (no_area_range,
/* purge the old aggregated summary LSA */
ospf6_abr_originate_summary(range);
}
ospf6_release_range_ls_id(oa->range_table,
(u_int32_t) ntohl(range->linkstate_id));
ospf6_route_remove (range, oa->range_table);
return CMD_SUCCESS;

View File

@ -547,24 +547,6 @@ ospf6_lsdb_show (struct vty *vty, enum ospf_lsdb_show_level level,
}
}
/* Decide new Link State ID to originate for the range. */
u_int32_t
ospf6_new_range_ls_id (struct ospf6_route_table *range_table)
{
u_int32_t id;
bf_assign_index(range_table->idspace, id);
return (id);
}
/* Release the LS ID back to the ID pool */
void
ospf6_release_range_ls_id (struct ospf6_route_table *range_table,
u_int32_t id)
{
bf_release_index(range_table->idspace, id);
}
u_int32_t
ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
struct ospf6_lsdb *lsdb)

View File

@ -81,9 +81,6 @@ extern void ospf6_lsdb_show (struct vty *vty,
extern u_int32_t ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
struct ospf6_lsdb *lsdb);
extern u_int32_t ospf6_new_range_ls_id (struct ospf6_route_table *range_table);
extern void ospf6_release_range_ls_id (struct ospf6_route_table *range_table,
u_int32_t id);
extern u_int32_t ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id,
u_int32_t adv_router,
struct ospf6_lsdb *lsdb);

View File

@ -682,7 +682,7 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
"I/F", "State", VNL);
*/
vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
vty_out (vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]%s",
router_id, on->priority, deadtime,
ospf6_neighbor_state_str[on->state], nstate, duration,
on->ospf6_if->interface->name,
@ -711,7 +711,7 @@ ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
timersub (&now, &on->last_changed, &res);
timerstring (&res, duration, sizeof (duration));
vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
vty_out (vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]%s",
router_id, ospf6_neighbor_state_str[on->state],
duration, drouter, bdrouter, on->ospf6_if->interface->name,
ospf6_interface_state_str[on->ospf6_if->state],
@ -856,11 +856,11 @@ DEFUN (show_ipv6_ospf6_neighbor,
}
if (showfunc == ospf6_neighbor_show)
vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
vty_out (vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]%s",
"Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
"I/F", "State", VNL);
else if (showfunc == ospf6_neighbor_show_drchoice)
vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
vty_out (vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]%s",
"RouterID", "State", "Duration", "DR", "BDR", "I/F",
"State", VNL);

View File

@ -1266,10 +1266,15 @@ DEFUN (no_ospf_area_vlink,
/* message-digest-key */
/* Delete one key */
i++;
vl_config.crypto_key_id = strtol (argv[i]->arg, NULL, 10);
if (vl_config.crypto_key_id < 0)
if (i < argc)
{
vl_config.crypto_key_id = strtol (argv[i]->arg, NULL, 10);
if (vl_config.crypto_key_id < 0)
return CMD_WARNING;
vl_config.md5_key = NULL;
}
else
return CMD_WARNING;
vl_config.md5_key = NULL;
break;
}

View File

@ -124,21 +124,21 @@ static struct test_segment mp_segments[] =
"MP IP6/MPLS-labeled VPN",
{ CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
6, SHOULD_PARSE, 0,
1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN, VALID_AFI,
1, AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
/* 10 */
{ "MP8",
@ -585,22 +585,26 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
if (!ret && t->validate_afi)
{
safi_t safi = t->safi;
afi_t afi;
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]);
/* 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[t->afi][safi])
if (!peer->afc_recv[afi][safi])
failed++;
if (!peer->afc_nego[t->afi][safi])
if (!peer->afc_nego[afi][safi])
failed++;
}
}

View File

@ -317,7 +317,7 @@ static struct test_segment {
{ "IPv4-VPNv4",
"IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -338,12 +338,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_PARSE,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* nexthop bytes */ 12,
/* RD */ 0, 0, 1, 2,
0, 0xff, 3, 4,
@ -355,12 +355,12 @@ static struct test_segment {
},
(3 + 1 + 3*4 + 1 + 3 + 4 + 1),
SHOULD_ERR,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -381,12 +381,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_ERR,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -407,12 +407,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_ERR,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -434,12 +434,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
SHOULD_ERR,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -460,12 +460,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_ERR,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -486,12 +486,12 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
SHOULD_PARSE,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
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, SAFI_MPLS_LABELED_VPN,
/* 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,
@ -513,7 +513,7 @@ static struct test_segment {
},
(4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
SHOULD_ERR,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
/* From bug #385 */
@ -625,7 +625,7 @@ static struct test_segment mp_unreach_segments [] =
{ "IPv4-unreach-VPNv4",
"IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs",
{
/* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
/* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
/* NLRI tuples */ 88 + 16,
0, 1, 2, /* tag */
/* rd, 8 octets */
@ -641,7 +641,7 @@ static struct test_segment mp_unreach_segments [] =
},
(3 + (1+3+8+2) + (1+3+8+3)),
SHOULD_PARSE,
AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
},
{ NULL, NULL, {0}, 0, 0}
};
@ -656,19 +656,6 @@ handle_result (struct peer *peer, struct test_segment *t,
{
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");
@ -720,9 +707,20 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
else
parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri);
if (parse_ret == 0 && t->afi_valid == VALID_AFI)
assert (nlri.afi == t->afi && nlri.safi == t->safi);
if (!parse_ret)
{
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)
{
@ -731,7 +729,7 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
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);
}

View File

@ -3,7 +3,7 @@ set testprefix "aspathtest "
set aborted 0
set color 1
spawn "./aspathtest"
spawn sh -c "exec ./aspathtest 2>/dev/null"
# proc onetest { test_name note start } {
# proc headerline { line } {

View File

@ -3,7 +3,7 @@ set testprefix "ecommtest "
set aborted 0
set color 0
spawn "./ecommtest"
spawn sh -c "exec ./ecommtest 2>/dev/null"
# proc simpletest { start } {

View File

@ -3,7 +3,7 @@ set testprefix "testbgpcap "
set aborted 0
set color 1
spawn "./testbgpcap"
spawn sh -c "exec ./testbgpcap 2>/dev/null"
# proc simpletest { start } {

View File

@ -3,7 +3,7 @@ set testprefix "testbgpmpath "
set aborted 0
set color 1
spawn "./testbgpmpath"
spawn sh -c "exec ./testbgpmpath 2>/dev/null"
# proc simpletest { start } {

View File

@ -3,7 +3,7 @@ set testprefix "testbgpmpattr "
set aborted 0
set color 1
spawn "./testbgpmpattr"
spawn sh -c "exec ./testbgpmpattr 2>/dev/null"
# proc simpletest { start } {

View File

@ -2,7 +2,7 @@ set timeout 10
set testprefix "tabletest "
set aborted 0
spawn "./tabletest"
spawn sh -c "exec ./tabletest 2>/dev/null"
for {set i 0} {$i < 6} {incr i 1} { onesimple "cmp $i" "Verifying cmp"; }
for {set i 0} {$i < 11} {incr i 1} { onesimple "succ $i" "Verifying successor"; }

View File

@ -2,6 +2,6 @@ set timeout 10
set testprefix "test-timer-correctness"
set aborted 0
spawn "./test-timer-correctness"
spawn sh -c "exec ./test-timer-correctness 2>/dev/null"
onesimple "" "Expected output and actual output match."

View File

@ -2,7 +2,7 @@ set timeout 10
set testprefix "testnexthopiter "
set aborted 0
spawn "./testnexthopiter"
spawn sh -c "exec ./testnexthopiter 2>/dev/null"
onesimple "simple" "Simple test passed."
onesimple "prng" "PRNG test passed."

View File

@ -1,5 +1,5 @@
set timeout 10
spawn "./teststream"
spawn sh -c "exec ./teststream 2>/dev/null"
expect {
"endp: 15, readable: 15, writeable: 1009" { }

View File

@ -141,6 +141,8 @@ sub generate_arguments {
# argument is the name of the node
if ($node{'input'} or $node{'type'} eq "select") {
$arg_value = "argv[" . $argc . "]->arg";
} elsif ($node{'optional'}) {
$arg_value = "(argc > " . $argc . " ? argv[" . $argc. "]->arg : NULL)";
} else {
$arg_value = '"' . $node{'name'} . '"';
}
@ -196,7 +198,11 @@ sub generate_code {
$helpstr .= $::options{$options_name}{'help'};
} else {
$funcname .= $node{'name'} . " ";
$cmdstr .= $node{'name'} . " ";
if ($node{'optional'}) {
$cmdstr .= "[" . $node{'name'} . "] ";
} else {
$cmdstr .= $node{'name'} . " ";
}
$helpstr .= "\n \"" . $node{'help'} . "\\n\"";
}
@ -279,6 +285,7 @@ sub parse_tree {
$node{'help'} = $xml_node->findvalue('./@help');
$node{'function'} = $xml_node->findvalue('./@function');
$node{'ifdef'} = $xml_node->findvalue('./@ifdef');
$node{'optional'} = $xml_node->findvalue('./@optional');
# push node to stack
push (@nodes, \%node);

File diff suppressed because it is too large Load Diff

View File

@ -26,4 +26,4 @@ extern void watchfrr_vty_init(void);
extern pid_t integrated_write_pid;
extern void integrated_write_sigchld(int status);
#endif /* FRR_WATCHFRR_H */
#endif /* FRR_WATCHFRR_H */

View File

@ -31,18 +31,18 @@
pid_t integrated_write_pid;
static int integrated_result_fd;
DEFUN (config_write_integrated,
config_write_integrated_cmd,
"write integrated",
"Write running configuration to memory, network, or terminal\n"
"Write integrated all-daemon Frr.conf file\n")
DEFUN(config_write_integrated,
config_write_integrated_cmd,
"write integrated",
"Write running configuration to memory, network, or terminal\n"
"Write integrated all-daemon Frr.conf file\n")
{
pid_t child;
sigset_t oldmask, sigmask;
if (integrated_write_pid != -1) {
vty_out(vty, "%% configuration write already in progress.%s",
VTY_NEWLINE);
VTY_NEWLINE);
return CMD_WARNING;
}
@ -61,20 +61,20 @@ DEFUN (config_write_integrated,
child = fork();
if (child == -1) {
vty_out(vty, "%% configuration write fork() failed: %s.%s",
safe_strerror(errno), VTY_NEWLINE);
safe_strerror(errno), VTY_NEWLINE);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return CMD_WARNING;
}
if (child != 0) {
/* note: the VTY won't write a command return value to vtysh; the
* session temporarily enters an intentional "hang" state. This is
* to make sure latency in vtysh doing the config write (several
* seconds is not rare to see) does not interfere with watchfrr's
* supervisor job.
*
* The fd is duplicated here so we don't need to hold a vty pointer
* (which could become invalid in the meantime).
*/
/* note: the VTY won't write a command return value to vtysh; the
* session temporarily enters an intentional "hang" state. This is
* to make sure latency in vtysh doing the config write (several
* seconds is not rare to see) does not interfere with watchfrr's
* supervisor job.
*
* The fd is duplicated here so we don't need to hold a vty pointer
* (which could become invalid in the meantime).
*/
integrated_write_pid = child;
integrated_result_fd = dup(vty->wfd);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
@ -93,7 +93,7 @@ DEFUN (config_write_integrated,
/* unbuffered write; we just messed with stdout... */
char msg[512];
snprintf(msg, sizeof(msg), "error executing %s: %s\n",
VTYSH_BIN_PATH, safe_strerror(errno));
VTYSH_BIN_PATH, safe_strerror(errno));
write(1, msg, strlen(msg));
exit(1);
}
@ -104,11 +104,11 @@ void integrated_write_sigchld(int status)
if (WIFEXITED(status)) {
zlog_info("configuration write completed with exit code %d",
WEXITSTATUS(status));
WEXITSTATUS(status));
reply[3] = WEXITSTATUS(status);
} else if (WIFSIGNALED(status)) {
zlog_warn("configuration write terminated by signal %d",
WTERMSIG(status));
WTERMSIG(status));
} else {
zlog_warn("configuration write terminated");
}

View File

@ -104,7 +104,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
/* tag */
if (tag_str)
tag = atol(tag_str);
VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
/* VRF id */
zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
@ -1340,12 +1340,12 @@ DEFUN (show_ip_route_tag,
if (strmatch(argv[idx_vrf]->text, "vrf"))
{
VRF_GET_ID (vrf_id, argv[idx_name]->arg);
tag = atol(argv[idx_tag]->arg);
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
}
else
{
idx_tag -= 2;
tag = atol(argv[idx_tag]->arg);
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
}
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
@ -1918,7 +1918,7 @@ DEFUN (show_ip_route_vrf_all_tag,
route_tag_t tag = 0;
if (argv[idx_number]->arg)
tag = atol(argv[idx_number]->arg);
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{
@ -2356,7 +2356,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
/* tag */
if (tag_str)
tag = atol(tag_str);
VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295);
/* When gateway is valid IPv6 addrees, then gate is treated as
nexthop address other case gate is treated as interface name. */
@ -2866,12 +2866,12 @@ DEFUN (show_ipv6_route_tag,
if (strmatch(argv[idx_vrf]->text, "vrf"))
{
VRF_GET_ID (vrf_id, argv[idx_name]->arg);
tag = atol(argv[idx_tag]->arg);
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
}
else
{
idx_tag -= 2;
tag = atol(argv[idx_tag]->arg);
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295);
}
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
@ -3252,7 +3252,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
route_tag_t tag = 0;
if (argv[idx_number]->arg)
tag = atol(argv[idx_number]->arg);
VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
{