2002-12-13 21:15:29 +01:00
|
|
|
/* BGP packet management routine.
|
|
|
|
Copyright (C) 1999 Kunihiro Ishiguro
|
|
|
|
|
|
|
|
This file is part of GNU Zebra.
|
|
|
|
|
|
|
|
GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
later version.
|
|
|
|
|
|
|
|
GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with GNU Zebra; see the file COPYING. If not, write to the Free
|
|
|
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
02111-1307, USA. */
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "thread.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "sockunion.h" /* for inet_ntop () */
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "plist.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "queue.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "bgpd/bgpd.h"
|
|
|
|
#include "bgpd/bgp_table.h"
|
|
|
|
#include "bgpd/bgp_dump.h"
|
|
|
|
#include "bgpd/bgp_attr.h"
|
|
|
|
#include "bgpd/bgp_debug.h"
|
|
|
|
#include "bgpd/bgp_fsm.h"
|
|
|
|
#include "bgpd/bgp_route.h"
|
|
|
|
#include "bgpd/bgp_packet.h"
|
|
|
|
#include "bgpd/bgp_open.h"
|
|
|
|
#include "bgpd/bgp_aspath.h"
|
|
|
|
#include "bgpd/bgp_community.h"
|
|
|
|
#include "bgpd/bgp_ecommunity.h"
|
|
|
|
#include "bgpd/bgp_network.h"
|
|
|
|
#include "bgpd/bgp_mplsvpn.h"
|
|
|
|
#include "bgpd/bgp_advertise.h"
|
2005-02-02 15:40:33 +01:00
|
|
|
#include "bgpd/bgp_vty.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "bgpd/bgp_updgrp.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
int stream_put_prefix (struct stream *, struct prefix *);
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set up BGP packet marker and packet type. */
|
2015-05-20 03:03:47 +02:00
|
|
|
int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_packet_set_marker (struct stream *s, u_char type)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Fill in marker. */
|
|
|
|
for (i = 0; i < BGP_MARKER_SIZE; i++)
|
|
|
|
stream_putc (s, 0xff);
|
|
|
|
|
|
|
|
/* Dummy total length. This field is should be filled in later on. */
|
|
|
|
stream_putw (s, 0);
|
|
|
|
|
|
|
|
/* BGP packet type. */
|
|
|
|
stream_putc (s, type);
|
|
|
|
|
|
|
|
/* Return current stream size. */
|
2005-02-09 16:51:56 +01:00
|
|
|
return stream_get_endp (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set BGP packet header size entry. If size is zero then use current
|
|
|
|
stream size. */
|
2015-05-20 03:03:47 +02:00
|
|
|
int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_packet_set_size (struct stream *s)
|
|
|
|
{
|
|
|
|
int cp;
|
|
|
|
|
|
|
|
/* Preserve current pointer. */
|
2005-02-09 16:51:56 +01:00
|
|
|
cp = stream_get_endp (s);
|
|
|
|
stream_putw_at (s, BGP_MARKER_SIZE, cp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return cp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add new packet to the peer. */
|
2015-05-20 03:03:47 +02:00
|
|
|
void
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_packet_add (struct peer *peer, struct stream *s)
|
|
|
|
{
|
|
|
|
/* Add packet to the end of list. */
|
|
|
|
stream_fifo_push (peer->obuf, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free first packet. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_packet_delete (struct peer *peer)
|
|
|
|
{
|
|
|
|
stream_free (stream_fifo_pop (peer->obuf));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check file descriptor whether connect is established. */
|
2015-05-20 02:47:21 +02:00
|
|
|
int
|
|
|
|
bgp_connect_check (struct peer *peer, int change_state)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int status;
|
2004-06-04 19:58:18 +02:00
|
|
|
socklen_t slen;
|
2002-12-13 21:15:29 +01:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Anyway I have to reset read and write thread. */
|
|
|
|
BGP_READ_OFF (peer->t_read);
|
|
|
|
BGP_WRITE_OFF (peer->t_write);
|
|
|
|
|
|
|
|
/* Check file descriptor. */
|
|
|
|
slen = sizeof (status);
|
2004-05-01 10:44:08 +02:00
|
|
|
ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If getsockopt is fail, this is fatal error. */
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_info ("can't get sockopt for nonblocking connect");
|
2002-12-13 21:15:29 +01:00
|
|
|
BGP_EVENT_ADD (peer, TCP_fatal_error);
|
2015-05-20 02:47:21 +02:00
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* When status is 0 then TCP connection is established. */
|
|
|
|
if (status == 0)
|
|
|
|
{
|
|
|
|
BGP_EVENT_ADD (peer, TCP_connection_open);
|
2015-05-20 02:47:21 +02:00
|
|
|
return 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("%s [Event] Connect failed (%s)",
|
|
|
|
peer->host, safe_strerror (errno));
|
2015-05-20 02:47:21 +02:00
|
|
|
if (change_state)
|
|
|
|
BGP_EVENT_ADD (peer, TCP_connection_open_failed);
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-28 14:44:16 +02:00
|
|
|
static struct stream *
|
2005-02-02 15:40:33 +01:00
|
|
|
bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct stream *packet;
|
|
|
|
|
2008-07-22 23:11:48 +02:00
|
|
|
if (DISABLE_BGP_ANNOUNCE)
|
|
|
|
return NULL;
|
2005-02-02 15:40:33 +01:00
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2005-02-02 15:40:33 +01:00
|
|
|
zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
|
|
|
|
|
|
|
|
s = stream_new (BGP_MAX_PACKET_SIZE);
|
|
|
|
|
|
|
|
/* Make BGP update packet. */
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_UPDATE);
|
|
|
|
|
|
|
|
/* Unfeasible Routes Length */
|
|
|
|
stream_putw (s, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
if (afi == AFI_IP && safi == SAFI_UNICAST)
|
|
|
|
{
|
|
|
|
/* Total Path Attribute Length */
|
|
|
|
stream_putw (s, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
bgp_packet_set_size (s);
|
2005-05-19 04:12:25 +02:00
|
|
|
packet = stream_dup (s);
|
2005-02-02 15:40:33 +01:00
|
|
|
bgp_packet_add (peer, packet);
|
|
|
|
stream_free (s);
|
|
|
|
return packet;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get next packet to be written. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static struct stream *
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_write_packet (struct peer *peer)
|
|
|
|
{
|
2015-05-20 03:03:47 +02:00
|
|
|
struct stream *s = NULL;
|
|
|
|
struct peer_af *paf;
|
|
|
|
struct bpacket *next_pkt;
|
2002-12-13 21:15:29 +01:00
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
|
|
|
|
|
|
|
s = stream_fifo_head (peer->obuf);
|
|
|
|
if (s)
|
|
|
|
return s;
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/*
|
|
|
|
* The code beyond this part deals with update packets, proceed only
|
|
|
|
* if peer is Established and updates are not on hold (as part of
|
|
|
|
* update-delay post processing).
|
|
|
|
*/
|
|
|
|
if (peer->status != Established)
|
|
|
|
return NULL;
|
|
|
|
|
2015-05-20 02:40:42 +02:00
|
|
|
if (peer->bgp && (peer->bgp->main_peers_update_hold ||
|
|
|
|
peer->bgp->rsclient_peers_update_hold))
|
|
|
|
return NULL;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
|
|
|
{
|
2015-05-20 03:03:47 +02:00
|
|
|
paf = peer_af_find (peer, afi, safi);
|
|
|
|
if (!paf || !PAF_SUBGRP(paf))
|
|
|
|
continue;
|
|
|
|
next_pkt = paf->next_pkt_to_send;
|
|
|
|
|
|
|
|
/* Try to generate a packet for the peer if we are at the end of
|
|
|
|
* the list. Always try to push out WITHDRAWs first. */
|
|
|
|
if (!next_pkt || !next_pkt->buffer)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-20 03:03:47 +02:00
|
|
|
next_pkt = subgroup_withdraw_packet(PAF_SUBGRP(paf));
|
|
|
|
if (!next_pkt || !next_pkt->buffer)
|
|
|
|
subgroup_update_packet (PAF_SUBGRP(paf));
|
|
|
|
next_pkt = paf->next_pkt_to_send;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
|
|
|
|
/* If we still don't have a packet to send to the peer, then
|
|
|
|
* try to find out out if we have to send eor or if not, skip to
|
|
|
|
* the next AFI, SAFI.
|
|
|
|
* Don't send the EOR prematurely... if the subgroup's coalesce
|
|
|
|
* timer is running, the adjacency-out structure is not created
|
|
|
|
* yet.
|
|
|
|
*/
|
|
|
|
if (!next_pkt || !next_pkt->buffer)
|
|
|
|
{
|
|
|
|
if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
|
2005-02-02 15:40:33 +01:00
|
|
|
{
|
2015-05-20 03:03:47 +02:00
|
|
|
if (!(PAF_SUBGRP(paf))->t_coalesce &&
|
|
|
|
peer->afc_nego[afi][safi] && peer->synctime
|
|
|
|
&& ! CHECK_FLAG (peer->af_sflags[afi][safi],
|
|
|
|
PEER_STATUS_EOR_SEND)
|
2005-02-02 15:40:33 +01:00
|
|
|
&& safi != SAFI_MPLS_VPN)
|
|
|
|
{
|
2015-05-20 03:03:47 +02:00
|
|
|
SET_FLAG (peer->af_sflags[afi][safi],
|
|
|
|
PEER_STATUS_EOR_SEND);
|
|
|
|
return bgp_update_packet_eor (peer, afi, safi);
|
2005-02-02 15:40:33 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
continue;
|
2005-02-02 15:40:33 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/*
|
|
|
|
* Found a packet template to send, overwrite packet with appropriate
|
|
|
|
* attributes from peer and advance peer
|
|
|
|
*/
|
|
|
|
s = bpacket_reformat_for_peer (next_pkt, paf);
|
|
|
|
bpacket_queue_advance_peer (paf);
|
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 0))
|
|
|
|
zlog_debug ("u%llu:s%llu %s send UPDATE len %d ",
|
|
|
|
PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
|
|
|
|
peer->host, (stream_get_endp(s) - stream_get_getp(s)));
|
|
|
|
return s;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
return NULL;
|
2015-05-20 02:58:12 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* The next action for the peer from a write perspective */
|
|
|
|
static void
|
|
|
|
bgp_write_proceed_actions (struct peer *peer)
|
2015-05-20 02:58:12 +02:00
|
|
|
{
|
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
2015-05-20 03:03:47 +02:00
|
|
|
struct peer_af *paf;
|
|
|
|
struct bpacket *next_pkt;
|
|
|
|
int fullq_found = 0;
|
2015-05-20 03:03:55 +02:00
|
|
|
struct update_subgroup *subgrp;
|
2015-05-20 02:58:12 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (stream_fifo_head (peer->obuf))
|
2015-05-20 02:58:12 +02:00
|
|
|
{
|
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
2015-05-20 03:03:47 +02:00
|
|
|
return;
|
2015-05-20 02:58:12 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
|
|
|
{
|
|
|
|
paf = peer_af_find (peer, afi, safi);
|
|
|
|
if (!paf)
|
|
|
|
continue;
|
2015-05-20 03:03:55 +02:00
|
|
|
subgrp = paf->subgroup;
|
|
|
|
if (!subgrp)
|
|
|
|
continue;
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
next_pkt = paf->next_pkt_to_send;
|
|
|
|
if (next_pkt && next_pkt->buffer)
|
|
|
|
{
|
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
|
|
|
return;
|
|
|
|
}
|
2015-05-20 03:03:55 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* No packets readily available for AFI/SAFI, are there subgroup packets
|
|
|
|
* that need to be generated? */
|
2015-05-20 03:03:55 +02:00
|
|
|
if (bpacket_queue_is_full(SUBGRP_INST(subgrp),
|
|
|
|
SUBGRP_PKTQ(subgrp)))
|
2015-05-20 03:03:47 +02:00
|
|
|
fullq_found = 1;
|
2015-05-20 03:03:55 +02:00
|
|
|
else if (subgroup_packets_to_build (subgrp))
|
2015-05-20 03:03:47 +02:00
|
|
|
{
|
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
|
|
|
return;
|
|
|
|
}
|
2015-05-20 03:03:55 +02:00
|
|
|
|
|
|
|
/* No packets to send, see if EOR is pending */
|
|
|
|
if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
|
|
|
|
{
|
|
|
|
if (!subgrp->t_coalesce &&
|
|
|
|
peer->afc_nego[afi][safi] &&
|
|
|
|
peer->synctime &&
|
|
|
|
!CHECK_FLAG(peer->af_sflags[afi][safi],
|
|
|
|
PEER_STATUS_EOR_SEND) &&
|
|
|
|
safi != SAFI_MPLS_VPN)
|
|
|
|
{
|
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2015-05-20 03:03:47 +02:00
|
|
|
}
|
|
|
|
if (fullq_found)
|
2015-05-20 02:58:12 +02:00
|
|
|
{
|
2015-05-20 03:03:47 +02:00
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
|
|
|
return;
|
2015-05-20 02:58:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Write packet to the peer. */
|
|
|
|
int
|
|
|
|
bgp_write (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct peer *peer;
|
|
|
|
u_char type;
|
2015-05-20 03:03:47 +02:00
|
|
|
struct stream *s;
|
2002-12-13 21:15:29 +01:00
|
|
|
int num;
|
2004-10-13 07:06:08 +02:00
|
|
|
unsigned int count = 0;
|
bgpd: bgpd-mrai.patch
BGP: Event-driven route announcement taking into account min route advertisement interval
ISSUE
BGP starts the routeadv timer (peer->t_routeadv) to expire in 1 sec
when a peer is established. From then on, the timer expires
periodically based on the configured MRAI value (default: 30sec for
EBGP, 5sec for IBGP). At the expiry, the write thread is triggered
that takes the routes from peer's sync FIFO (adj-rib-out) and sends
UPDATEs. This has a few drawbacks:
(1) Delay in new route announcement: Even when the last UPDATE message
was sent a while back, the next route change will necessarily have
to wait for routeadv expiry
(2) CPU usage: The timer is always armed. If the operator chooses to
configure a lower value of MRAI (zero second is a preferred choice
in many deployments) for better convergence, it leads to high CPU
usage for BGP process, even at the times of no network churn.
PATCH
Make the route advertisement event-driven - When routes are added to
peer's sync FIFO, check if the routeadv timer needs to be adjusted (or
started). Conversely, do not arm the routeadv timer unconditionally.
The patch also addresses route announcements during read-only mode
(update-delay). During read-only mode operation, the routeadv timer
is not started. When BGP comes out of read-only mode and all the
routes are processed, the timer is started for all peers with zero
expiry, so that the UPDATEs can be sent all at once. This leads to
(near-)optimal UPDATE packing.
Finally, the patch makes the "max # packets to write to peer socket at
a time" configurable. Currently it is hard-coded to 10. The command is
at the top router-bgp mode and is called "write-quanta <number>". It
is a useful convergence parameter to tweak.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
2015-05-20 02:40:37 +02:00
|
|
|
int oc = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Yes first of all get peer pointer. */
|
|
|
|
peer = THREAD_ARG (thread);
|
|
|
|
peer->t_write = NULL;
|
|
|
|
|
|
|
|
/* For non-blocking IO check. */
|
|
|
|
if (peer->status == Connect)
|
|
|
|
{
|
2015-05-20 02:47:21 +02:00
|
|
|
bgp_connect_check (peer, 1);
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-08-05 19:26:25 +02:00
|
|
|
s = bgp_write_packet (peer);
|
|
|
|
if (!s)
|
2015-05-20 03:03:47 +02:00
|
|
|
{
|
|
|
|
bgp_write_proceed_actions (peer);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-08-05 19:26:25 +02:00
|
|
|
|
|
|
|
sockopt_cork (peer->fd, 1);
|
|
|
|
|
bgpd: bgpd-mrai.patch
BGP: Event-driven route announcement taking into account min route advertisement interval
ISSUE
BGP starts the routeadv timer (peer->t_routeadv) to expire in 1 sec
when a peer is established. From then on, the timer expires
periodically based on the configured MRAI value (default: 30sec for
EBGP, 5sec for IBGP). At the expiry, the write thread is triggered
that takes the routes from peer's sync FIFO (adj-rib-out) and sends
UPDATEs. This has a few drawbacks:
(1) Delay in new route announcement: Even when the last UPDATE message
was sent a while back, the next route change will necessarily have
to wait for routeadv expiry
(2) CPU usage: The timer is always armed. If the operator chooses to
configure a lower value of MRAI (zero second is a preferred choice
in many deployments) for better convergence, it leads to high CPU
usage for BGP process, even at the times of no network churn.
PATCH
Make the route advertisement event-driven - When routes are added to
peer's sync FIFO, check if the routeadv timer needs to be adjusted (or
started). Conversely, do not arm the routeadv timer unconditionally.
The patch also addresses route announcements during read-only mode
(update-delay). During read-only mode operation, the routeadv timer
is not started. When BGP comes out of read-only mode and all the
routes are processed, the timer is started for all peers with zero
expiry, so that the UPDATEs can be sent all at once. This leads to
(near-)optimal UPDATE packing.
Finally, the patch makes the "max # packets to write to peer socket at
a time" configurable. Currently it is hard-coded to 10. The command is
at the top router-bgp mode and is called "write-quanta <number>". It
is a useful convergence parameter to tweak.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
2015-05-20 02:40:37 +02:00
|
|
|
oc = peer->update_out;
|
|
|
|
|
2010-08-05 19:26:25 +02:00
|
|
|
/* Nonblocking write until TCP output buffer is full. */
|
|
|
|
do
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int writenum;
|
|
|
|
|
|
|
|
/* Number of bytes to be sent. */
|
|
|
|
writenum = stream_get_endp (s) - stream_get_getp (s);
|
|
|
|
|
|
|
|
/* Call write() system call. */
|
2004-05-01 10:44:08 +02:00
|
|
|
num = write (peer->fd, STREAM_PNT (s), writenum);
|
2010-08-05 19:26:23 +02:00
|
|
|
if (num < 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2010-08-05 19:26:25 +02:00
|
|
|
/* write failed either retry needed or error */
|
|
|
|
if (ERRNO_IO_RETRY(errno))
|
|
|
|
break;
|
|
|
|
|
|
|
|
BGP_EVENT_ADD (peer, TCP_fatal_error);
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2010-08-05 19:26:23 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (num != writenum)
|
|
|
|
{
|
2010-08-05 19:26:23 +02:00
|
|
|
/* Partial write */
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_getp (s, num);
|
2010-08-05 19:26:25 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Retrieve BGP packet type. */
|
|
|
|
stream_set_getp (s, BGP_MARKER_SIZE + 2);
|
|
|
|
type = stream_getc (s);
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case BGP_MSG_OPEN:
|
|
|
|
peer->open_out++;
|
|
|
|
break;
|
|
|
|
case BGP_MSG_UPDATE:
|
|
|
|
peer->update_out++;
|
|
|
|
break;
|
|
|
|
case BGP_MSG_NOTIFY:
|
|
|
|
peer->notify_out++;
|
|
|
|
/* Double start timer. */
|
|
|
|
peer->v_start *= 2;
|
|
|
|
|
|
|
|
/* Overflow check. */
|
|
|
|
if (peer->v_start >= (60 * 2))
|
|
|
|
peer->v_start = (60 * 2);
|
|
|
|
|
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states
2006-09-14 Paul Jakma <paul.jakma@sun.com>
* (general) Fix some niggly issues around 'shutdown' and clearing
by adding a Clearing FSM wait-state and a hidden 'Deleted'
FSM state, to allow deleted peers to 'cool off' and hit 0
references. This introduces a slow memory leak of struct peer,
however that's more a testament to the fragility of the
reference counting than a bug in this patch, cleanup of
reference counting to fix this is to follow.
* bgpd.h: Add Clearing, Deleted states and Clearing_Completed
and event.
* bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and
Deleted.
* bgp_fsm.h: Don't allow timer/event threads to set anything
for Deleted peers.
* bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted
needs to stop everything.
(bgp_stop) Remove explicit fsm_change_status call, the
general framework handles the transition.
(bgp_start) Log a warning if a start is attempted on a peer
that should stay down, trying to start a peer.
(struct .. FSM) Add Clearing_Completed
events, has little influence except when in state
Clearing to signal wait-state can end.
Add Clearing and Deleted states, former is a wait-state,
latter is a placeholder state to allow peers to disappear
quietly once refcounts settle.
(bgp_event) Try reduce verbosity of FSM state-change debug,
changes to same state are not interesting (Established->Established)
Allow NULL action functions in FSM.
* bgp_packet.c: (bgp_write) Use FSM events, rather than trying
to twiddle directly with FSM state behind the back of FSM.
(bgp_write_notify) ditto.
(bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else
this patch crashes, now it leaks instead.
* bgp_route.c: (bgp_clear_node_complete) Clearing_Completed
event, to end clearing.
(bgp_clear_route) See extensive comments.
* bgpd.c: (peer_free) should only be called while in Deleted,
peer refcounting controls when peer_free is called.
bgp_sync_delete should be here, not in peer_delete.
(peer_delete) Initiate delete.
Transition to Deleted state manually.
When removing peer from indices that provide visibility of it,
take great care to be idempotent wrt the reference counting
of struct peer through those indices.
Use bgp_timer_set, rather than replicating.
Call to bgp_sync_delete isn't appropriate here, sync can be
referenced while shutting down and finishing deletion.
(peer_group_bind) Take care to be idempotent wrt list references
indexing peers.
2006-09-14 04:58:49 +02:00
|
|
|
/* Flush any existing events */
|
2006-10-16 01:39:59 +02:00
|
|
|
BGP_EVENT_ADD (peer, BGP_Stop);
|
2013-01-11 19:27:23 +01:00
|
|
|
goto done;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
case BGP_MSG_KEEPALIVE:
|
|
|
|
peer->keepalive_out++;
|
|
|
|
break;
|
|
|
|
case BGP_MSG_ROUTE_REFRESH_NEW:
|
|
|
|
case BGP_MSG_ROUTE_REFRESH_OLD:
|
|
|
|
peer->refresh_out++;
|
|
|
|
break;
|
|
|
|
case BGP_MSG_CAPABILITY:
|
|
|
|
peer->dynamic_cap_out++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* OK we send packet so delete it. */
|
|
|
|
bgp_packet_delete (peer);
|
|
|
|
}
|
bgpd: bgpd-mrai.patch
BGP: Event-driven route announcement taking into account min route advertisement interval
ISSUE
BGP starts the routeadv timer (peer->t_routeadv) to expire in 1 sec
when a peer is established. From then on, the timer expires
periodically based on the configured MRAI value (default: 30sec for
EBGP, 5sec for IBGP). At the expiry, the write thread is triggered
that takes the routes from peer's sync FIFO (adj-rib-out) and sends
UPDATEs. This has a few drawbacks:
(1) Delay in new route announcement: Even when the last UPDATE message
was sent a while back, the next route change will necessarily have
to wait for routeadv expiry
(2) CPU usage: The timer is always armed. If the operator chooses to
configure a lower value of MRAI (zero second is a preferred choice
in many deployments) for better convergence, it leads to high CPU
usage for BGP process, even at the times of no network churn.
PATCH
Make the route advertisement event-driven - When routes are added to
peer's sync FIFO, check if the routeadv timer needs to be adjusted (or
started). Conversely, do not arm the routeadv timer unconditionally.
The patch also addresses route announcements during read-only mode
(update-delay). During read-only mode operation, the routeadv timer
is not started. When BGP comes out of read-only mode and all the
routes are processed, the timer is started for all peers with zero
expiry, so that the UPDATEs can be sent all at once. This leads to
(near-)optimal UPDATE packing.
Finally, the patch makes the "max # packets to write to peer socket at
a time" configurable. Currently it is hard-coded to 10. The command is
at the top router-bgp mode and is called "write-quanta <number>". It
is a useful convergence parameter to tweak.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
2015-05-20 02:40:37 +02:00
|
|
|
while (++count < peer->bgp->wpkt_quanta &&
|
2010-08-05 19:26:25 +02:00
|
|
|
(s = bgp_write_packet (peer)) != NULL);
|
bgpd: bgpd-mrai.patch
BGP: Event-driven route announcement taking into account min route advertisement interval
ISSUE
BGP starts the routeadv timer (peer->t_routeadv) to expire in 1 sec
when a peer is established. From then on, the timer expires
periodically based on the configured MRAI value (default: 30sec for
EBGP, 5sec for IBGP). At the expiry, the write thread is triggered
that takes the routes from peer's sync FIFO (adj-rib-out) and sends
UPDATEs. This has a few drawbacks:
(1) Delay in new route announcement: Even when the last UPDATE message
was sent a while back, the next route change will necessarily have
to wait for routeadv expiry
(2) CPU usage: The timer is always armed. If the operator chooses to
configure a lower value of MRAI (zero second is a preferred choice
in many deployments) for better convergence, it leads to high CPU
usage for BGP process, even at the times of no network churn.
PATCH
Make the route advertisement event-driven - When routes are added to
peer's sync FIFO, check if the routeadv timer needs to be adjusted (or
started). Conversely, do not arm the routeadv timer unconditionally.
The patch also addresses route announcements during read-only mode
(update-delay). During read-only mode operation, the routeadv timer
is not started. When BGP comes out of read-only mode and all the
routes are processed, the timer is started for all peers with zero
expiry, so that the UPDATEs can be sent all at once. This leads to
(near-)optimal UPDATE packing.
Finally, the patch makes the "max # packets to write to peer socket at
a time" configurable. Currently it is hard-coded to 10. The command is
at the top router-bgp mode and is called "write-quanta <number>". It
is a useful convergence parameter to tweak.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
2015-05-20 02:40:37 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_write_proceed_actions (peer);
|
2013-01-11 19:27:23 +01:00
|
|
|
|
|
|
|
done:
|
bgpd: bgpd-mrai.patch
BGP: Event-driven route announcement taking into account min route advertisement interval
ISSUE
BGP starts the routeadv timer (peer->t_routeadv) to expire in 1 sec
when a peer is established. From then on, the timer expires
periodically based on the configured MRAI value (default: 30sec for
EBGP, 5sec for IBGP). At the expiry, the write thread is triggered
that takes the routes from peer's sync FIFO (adj-rib-out) and sends
UPDATEs. This has a few drawbacks:
(1) Delay in new route announcement: Even when the last UPDATE message
was sent a while back, the next route change will necessarily have
to wait for routeadv expiry
(2) CPU usage: The timer is always armed. If the operator chooses to
configure a lower value of MRAI (zero second is a preferred choice
in many deployments) for better convergence, it leads to high CPU
usage for BGP process, even at the times of no network churn.
PATCH
Make the route advertisement event-driven - When routes are added to
peer's sync FIFO, check if the routeadv timer needs to be adjusted (or
started). Conversely, do not arm the routeadv timer unconditionally.
The patch also addresses route announcements during read-only mode
(update-delay). During read-only mode operation, the routeadv timer
is not started. When BGP comes out of read-only mode and all the
routes are processed, the timer is started for all peers with zero
expiry, so that the UPDATEs can be sent all at once. This leads to
(near-)optimal UPDATE packing.
Finally, the patch makes the "max # packets to write to peer socket at
a time" configurable. Currently it is hard-coded to 10. The command is
at the top router-bgp mode and is called "write-quanta <number>". It
is a useful convergence parameter to tweak.
Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
2015-05-20 02:40:37 +02:00
|
|
|
/* Update the last write if some updates were written. */
|
|
|
|
if (peer->update_out > oc)
|
|
|
|
peer->last_write = bgp_clock ();
|
|
|
|
|
2013-01-11 19:27:23 +01:00
|
|
|
sockopt_cork (peer->fd, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is only for sending NOTIFICATION message to neighbor. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_write_notify (struct peer *peer)
|
|
|
|
{
|
2010-08-05 19:26:23 +02:00
|
|
|
int ret, val;
|
2002-12-13 21:15:29 +01:00
|
|
|
u_char type;
|
2015-05-20 03:03:47 +02:00
|
|
|
struct stream *s;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* There should be at least one packet. */
|
|
|
|
s = stream_fifo_head (peer->obuf);
|
|
|
|
if (!s)
|
|
|
|
return 0;
|
|
|
|
assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
|
|
|
|
|
2012-12-14 20:12:17 +01:00
|
|
|
/* Stop collecting data within the socket */
|
|
|
|
sockopt_cork (peer->fd, 0);
|
|
|
|
|
2013-07-31 14:39:41 +02:00
|
|
|
/* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
|
|
|
|
* we only care about getting a clean shutdown at this point. */
|
2012-12-14 20:12:17 +01:00
|
|
|
ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
|
2013-07-31 14:39:41 +02:00
|
|
|
|
|
|
|
/* only connection reset/close gets counted as TCP_fatal_error, failure
|
|
|
|
* to write the entire NOTIFY doesn't get different FSM treatment */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2006-10-16 01:39:59 +02:00
|
|
|
BGP_EVENT_ADD (peer, TCP_fatal_error);
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-14 20:12:17 +01:00
|
|
|
/* Disable Nagle, make NOTIFY packet go out right away */
|
|
|
|
val = 1;
|
|
|
|
(void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
|
|
|
|
(char *) &val, sizeof (val));
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Retrieve BGP packet type. */
|
|
|
|
stream_set_getp (s, BGP_MARKER_SIZE + 2);
|
|
|
|
type = stream_getc (s);
|
|
|
|
|
|
|
|
assert (type == BGP_MSG_NOTIFY);
|
|
|
|
|
|
|
|
/* Type should be notify. */
|
|
|
|
peer->notify_out++;
|
|
|
|
|
|
|
|
/* Double start timer. */
|
|
|
|
peer->v_start *= 2;
|
|
|
|
|
|
|
|
/* Overflow check. */
|
|
|
|
if (peer->v_start >= (60 * 2))
|
|
|
|
peer->v_start = (60 * 2);
|
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
/* Handle Graceful Restart case where the state changes to
|
|
|
|
Connect instead of Idle */
|
2006-10-16 01:39:59 +02:00
|
|
|
BGP_EVENT_ADD (peer, BGP_Stop);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make keepalive packet and send it to the peer. */
|
|
|
|
void
|
|
|
|
bgp_keepalive_send (struct peer *peer)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
s = stream_new (BGP_MAX_PACKET_SIZE);
|
|
|
|
|
|
|
|
/* Make keepalive packet. */
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
|
|
|
|
|
|
|
|
/* Set packet size. */
|
|
|
|
length = bgp_packet_set_size (s);
|
|
|
|
|
|
|
|
/* Dump packet if debug option is set. */
|
|
|
|
/* bgp_packet_dump (s); */
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_keepalive(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s sending KEEPALIVE", peer->host);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Add packet to the peer. */
|
|
|
|
bgp_packet_add (peer, s);
|
|
|
|
|
2004-05-01 10:44:08 +02:00
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Make open packet and send it to the peer. */
|
|
|
|
void
|
|
|
|
bgp_open_send (struct peer *peer)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
int length;
|
|
|
|
u_int16_t send_holdtime;
|
|
|
|
as_t local_as;
|
|
|
|
|
|
|
|
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
|
|
|
|
send_holdtime = peer->holdtime;
|
|
|
|
else
|
|
|
|
send_holdtime = peer->bgp->default_holdtime;
|
|
|
|
|
|
|
|
/* local-as Change */
|
|
|
|
if (peer->change_local_as)
|
|
|
|
local_as = peer->change_local_as;
|
|
|
|
else
|
|
|
|
local_as = peer->local_as;
|
|
|
|
|
|
|
|
s = stream_new (BGP_MAX_PACKET_SIZE);
|
|
|
|
|
|
|
|
/* Make open packet. */
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_OPEN);
|
|
|
|
|
|
|
|
/* Set open packet values. */
|
|
|
|
stream_putc (s, BGP_VERSION_4); /* BGP version */
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
|
|
|
|
: BGP_AS_TRANS);
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_putw (s, send_holdtime); /* Hold Time */
|
|
|
|
stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
|
|
|
|
|
|
|
|
/* Set capability code. */
|
|
|
|
bgp_open_capability (s, peer);
|
|
|
|
|
|
|
|
/* Set BGP packet length. */
|
|
|
|
length = bgp_packet_set_size (s);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2009-04-30 15:16:22 +02:00
|
|
|
zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, BGP_VERSION_4, local_as,
|
|
|
|
send_holdtime, inet_ntoa (peer->local_id));
|
|
|
|
|
|
|
|
/* Dump packet if debug option is set. */
|
|
|
|
/* bgp_packet_dump (s); */
|
|
|
|
|
|
|
|
/* Add packet to the peer. */
|
|
|
|
bgp_packet_add (peer, s);
|
|
|
|
|
2004-05-01 10:44:08 +02:00
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Send BGP notify packet with data potion. */
|
|
|
|
void
|
|
|
|
bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
|
|
|
|
u_char *data, size_t datalen)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
/* Allocate new stream. */
|
|
|
|
s = stream_new (BGP_MAX_PACKET_SIZE);
|
|
|
|
|
|
|
|
/* Make nitify packet. */
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
|
|
|
|
|
|
|
|
/* Set notify packet values. */
|
|
|
|
stream_putc (s, code); /* BGP notify code */
|
|
|
|
stream_putc (s, sub_code); /* BGP notify sub_code */
|
|
|
|
|
|
|
|
/* If notify data is present. */
|
|
|
|
if (data)
|
|
|
|
stream_write (s, data, datalen);
|
|
|
|
|
|
|
|
/* Set BGP packet length. */
|
|
|
|
length = bgp_packet_set_size (s);
|
|
|
|
|
|
|
|
/* Add packet to the peer. */
|
|
|
|
stream_fifo_clean (peer->obuf);
|
|
|
|
bgp_packet_add (peer, s);
|
|
|
|
|
|
|
|
/* For debug */
|
|
|
|
{
|
|
|
|
struct bgp_notify bgp_notify;
|
|
|
|
int first = 0;
|
|
|
|
int i;
|
|
|
|
char c[4];
|
|
|
|
|
|
|
|
bgp_notify.code = code;
|
|
|
|
bgp_notify.subcode = sub_code;
|
|
|
|
bgp_notify.data = NULL;
|
|
|
|
bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
|
|
|
|
|
|
|
|
if (bgp_notify.length)
|
|
|
|
{
|
|
|
|
bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
|
|
|
|
for (i = 0; i < bgp_notify.length; i++)
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
sprintf (c, " %02x", data[i]);
|
|
|
|
strcat (bgp_notify.data, c);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
first = 1;
|
|
|
|
sprintf (c, "%02x", data[i]);
|
|
|
|
strcpy (bgp_notify.data, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bgp_notify_print (peer, &bgp_notify, "sending");
|
|
|
|
if (bgp_notify.data)
|
|
|
|
XFREE (MTYPE_TMP, bgp_notify.data);
|
|
|
|
}
|
|
|
|
|
2004-05-20 11:19:34 +02:00
|
|
|
/* peer reset cause */
|
|
|
|
if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
|
|
|
|
{
|
|
|
|
if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
|
2011-09-12 11:27:52 +02:00
|
|
|
peer->last_reset = PEER_DOWN_USER_RESET;
|
2004-05-20 11:19:34 +02:00
|
|
|
else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
|
2011-09-12 11:27:52 +02:00
|
|
|
peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
|
2004-05-20 11:19:34 +02:00
|
|
|
else
|
2011-09-12 11:27:52 +02:00
|
|
|
peer->last_reset = PEER_DOWN_NOTIFY_SEND;
|
2004-05-20 11:19:34 +02:00
|
|
|
}
|
|
|
|
|
2011-09-10 14:53:30 +02:00
|
|
|
/* Call immediately. */
|
2002-12-13 21:15:29 +01:00
|
|
|
BGP_WRITE_OFF (peer->t_write);
|
|
|
|
|
|
|
|
bgp_write_notify (peer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send BGP notify packet. */
|
|
|
|
void
|
|
|
|
bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
|
|
|
|
{
|
|
|
|
bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send route refresh message to the peer. */
|
|
|
|
void
|
|
|
|
bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
|
|
|
|
u_char orf_type, u_char when_to_refresh, int remove)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct stream *packet;
|
|
|
|
int length;
|
|
|
|
struct bgp_filter *filter;
|
|
|
|
int orf_refresh = 0;
|
|
|
|
|
2008-07-22 23:11:48 +02:00
|
|
|
if (DISABLE_BGP_ANNOUNCE)
|
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
filter = &peer->filter[afi][safi];
|
|
|
|
|
|
|
|
/* Adjust safi code. */
|
|
|
|
if (safi == SAFI_MPLS_VPN)
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
safi = SAFI_MPLS_LABELED_VPN;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
s = stream_new (BGP_MAX_PACKET_SIZE);
|
|
|
|
|
|
|
|
/* Make BGP update packet. */
|
|
|
|
if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
|
|
|
|
else
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
|
|
|
|
|
|
|
|
/* Encode Route Refresh message. */
|
|
|
|
stream_putw (s, afi);
|
|
|
|
stream_putc (s, 0);
|
|
|
|
stream_putc (s, safi);
|
|
|
|
|
|
|
|
if (orf_type == ORF_TYPE_PREFIX
|
|
|
|
|| orf_type == ORF_TYPE_PREFIX_OLD)
|
|
|
|
if (remove || filter->plist[FILTER_IN].plist)
|
|
|
|
{
|
|
|
|
u_int16_t orf_len;
|
|
|
|
unsigned long orfp;
|
|
|
|
|
|
|
|
orf_refresh = 1;
|
|
|
|
stream_putc (s, when_to_refresh);
|
|
|
|
stream_putc (s, orf_type);
|
2005-02-09 16:51:56 +01:00
|
|
|
orfp = stream_get_endp (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_putw (s, 0);
|
|
|
|
|
|
|
|
if (remove)
|
|
|
|
{
|
|
|
|
UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
|
|
|
|
stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, orf_type,
|
|
|
|
(when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
|
|
|
|
afi, safi);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
|
|
|
|
prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
|
|
|
|
ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
|
|
|
|
ORF_COMMON_PART_DENY);
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, orf_type,
|
|
|
|
(when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
|
|
|
|
afi, safi);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Total ORF Entry Len. */
|
2005-02-09 16:51:56 +01:00
|
|
|
orf_len = stream_get_endp (s) - orfp - 2;
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_putw_at (s, orfp, orf_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set packet size. */
|
|
|
|
length = bgp_packet_set_size (s);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (! orf_refresh)
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, afi, safi);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make real packet. */
|
2005-05-19 04:12:25 +02:00
|
|
|
packet = stream_dup (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_free (s);
|
|
|
|
|
|
|
|
/* Add packet to the peer. */
|
|
|
|
bgp_packet_add (peer, packet);
|
|
|
|
|
2004-05-01 10:44:08 +02:00
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Send capability message to the peer. */
|
|
|
|
void
|
|
|
|
bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
|
|
|
|
int capability_code, int action)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct stream *packet;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
/* Adjust safi code. */
|
|
|
|
if (safi == SAFI_MPLS_VPN)
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
safi = SAFI_MPLS_LABELED_VPN;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
s = stream_new (BGP_MAX_PACKET_SIZE);
|
|
|
|
|
|
|
|
/* Make BGP update packet. */
|
|
|
|
bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
|
|
|
|
|
|
|
|
/* Encode MP_EXT capability. */
|
|
|
|
if (capability_code == CAPABILITY_CODE_MP)
|
|
|
|
{
|
|
|
|
stream_putc (s, action);
|
|
|
|
stream_putc (s, CAPABILITY_CODE_MP);
|
|
|
|
stream_putc (s, CAPABILITY_CODE_MP_LEN);
|
|
|
|
stream_putw (s, afi);
|
|
|
|
stream_putc (s, 0);
|
|
|
|
stream_putc (s, safi);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, action == CAPABILITY_ACTION_SET ?
|
|
|
|
"Advertising" : "Removing", afi, safi);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set packet size. */
|
|
|
|
length = bgp_packet_set_size (s);
|
|
|
|
|
|
|
|
/* Make real packet. */
|
2005-05-19 04:12:25 +02:00
|
|
|
packet = stream_dup (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_free (s);
|
|
|
|
|
|
|
|
/* Add packet to the peer. */
|
|
|
|
bgp_packet_add (peer, packet);
|
|
|
|
|
2004-05-01 10:44:08 +02:00
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* RFC1771 6.8 Connection collision detection. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2004-05-01 10:44:08 +02:00
|
|
|
bgp_collision_detect (struct peer *new, struct in_addr remote_id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-05-01 10:44:08 +02:00
|
|
|
struct peer *peer;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Upon receipt of an OPEN message, the local system must examine
|
|
|
|
all of its connections that are in the OpenConfirm state. A BGP
|
|
|
|
speaker may also examine connections in an OpenSent state if it
|
|
|
|
knows the BGP Identifier of the peer by means outside of the
|
|
|
|
protocol. If among these connections there is a connection to a
|
|
|
|
remote BGP speaker whose BGP Identifier equals the one in the
|
|
|
|
OPEN message, then the local system performs the following
|
|
|
|
collision resolution procedure: */
|
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
if ((peer = new->doppelganger) != NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-20 02:40:37 +02:00
|
|
|
/* Do not accept the new connection in Established or Clearing states.
|
|
|
|
* Note that a peer GR is handled by closing the existing connection
|
|
|
|
* upon receipt of new one.
|
|
|
|
*/
|
|
|
|
if (peer->status == Established || peer->status == Clearing)
|
|
|
|
{
|
|
|
|
bgp_notify_send (new, BGP_NOTIFY_CEASE,
|
|
|
|
BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
else if ((peer->status == OpenConfirm) || (peer->status == OpenSent))
|
2004-05-01 10:44:08 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
/* 1. The BGP Identifier of the local system is compared to
|
|
|
|
the BGP Identifier of the remote system (as specified in
|
|
|
|
the OPEN message). */
|
|
|
|
|
|
|
|
if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
|
2015-05-20 02:40:37 +02:00
|
|
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
|
|
|
|
{
|
|
|
|
/* 2. If the value of the local BGP Identifier is less
|
|
|
|
than the remote one, the local system closes BGP
|
|
|
|
connection that already exists (the one that is
|
|
|
|
already in the OpenConfirm state), and accepts BGP
|
|
|
|
connection initiated by the remote system. */
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
|
|
|
|
BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bgp_notify_send (new, BGP_NOTIFY_CEASE,
|
|
|
|
BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* 3. Otherwise, the local system closes newly created
|
|
|
|
BGP connection (the one associated with the newly
|
|
|
|
received OPEN message), and continues to use the
|
|
|
|
existing one (the one that is already in the
|
|
|
|
OpenConfirm state). */
|
2015-05-20 02:40:37 +02:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
|
|
|
|
{
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
|
|
|
|
BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bgp_notify_send (new, BGP_NOTIFY_CEASE,
|
|
|
|
BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2004-05-01 10:44:08 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_open_receive (struct peer *peer, bgp_size_t size)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u_char version;
|
|
|
|
u_char optlen;
|
|
|
|
u_int16_t holdtime;
|
|
|
|
u_int16_t send_holdtime;
|
|
|
|
as_t remote_as;
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
as_t as4 = 0;
|
2015-05-20 02:40:37 +02:00
|
|
|
struct peer *active_peer = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct in_addr remote_id;
|
2012-02-19 19:19:52 +01:00
|
|
|
int mp_capability;
|
2004-06-04 19:58:18 +02:00
|
|
|
u_int8_t notify_data_remote_as[2];
|
2015-05-20 03:03:52 +02:00
|
|
|
u_int8_t notify_data_remote_as4[4];
|
2004-06-04 19:58:18 +02:00
|
|
|
u_int8_t notify_data_remote_id[4];
|
2015-05-20 03:03:43 +02:00
|
|
|
u_int16_t *holdtime_ptr;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Parse open packet. */
|
|
|
|
version = stream_getc (peer->ibuf);
|
|
|
|
memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
|
|
|
|
remote_as = stream_getw (peer->ibuf);
|
2015-05-20 03:03:43 +02:00
|
|
|
holdtime_ptr = stream_pnt (peer->ibuf);
|
2002-12-13 21:15:29 +01:00
|
|
|
holdtime = stream_getw (peer->ibuf);
|
|
|
|
memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
|
|
|
|
remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
|
|
|
|
|
|
|
|
/* Receive OPEN message log */
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2009-04-30 15:16:22 +02:00
|
|
|
zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
" holdtime %d, id %s",
|
|
|
|
peer->host, version, remote_as, holdtime,
|
|
|
|
inet_ntoa (remote_id));
|
|
|
|
|
|
|
|
/* BEGIN to read the capability here, but dont do it yet */
|
2012-02-19 19:19:52 +01:00
|
|
|
mp_capability = 0;
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
optlen = stream_getc (peer->ibuf);
|
|
|
|
|
|
|
|
if (optlen != 0)
|
|
|
|
{
|
|
|
|
/* We need the as4 capability value *right now* because
|
|
|
|
* if it is there, we have not got the remote_as yet, and without
|
|
|
|
* that we do not know which peer is connecting to us now.
|
|
|
|
*/
|
|
|
|
as4 = peek_for_as4_capability (peer, optlen);
|
2015-05-20 03:03:52 +02:00
|
|
|
memcpy (notify_data_remote_as4, &as4, 4);
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Just in case we have a silly peer who sends AS4 capability set to 0 */
|
|
|
|
if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
|
|
|
|
{
|
|
|
|
zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
|
|
|
|
peer->host);
|
2015-05-20 03:03:52 +02:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_BAD_PEER_AS,
|
|
|
|
notify_data_remote_as4, 4);
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remote_as == BGP_AS_TRANS)
|
|
|
|
{
|
|
|
|
/* Take the AS4 from the capability. We must have received the
|
|
|
|
* capability now! Otherwise we have a asn16 peer who uses
|
|
|
|
* BGP_AS_TRANS, for some unknown reason.
|
|
|
|
*/
|
|
|
|
if (as4 == BGP_AS_TRANS)
|
|
|
|
{
|
|
|
|
zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
|
|
|
|
peer->host);
|
2015-05-20 03:03:52 +02:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_BAD_PEER_AS,
|
|
|
|
notify_data_remote_as4, 4);
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!as4 && BGP_DEBUG (as4, AS4))
|
|
|
|
zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
|
|
|
|
" Odd, but proceeding.", peer->host);
|
|
|
|
else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
|
[bgpd] TCP-MD5: password vty configuration and initial Linux support
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* bgp_packet.c: (bgp_open_receive) fix warning in a zlog call
* bgp_vty.c: (bgp_vty_return) add return code
* bgpd.c: (bgp_master_init) setup the socket list.
* bgp_network.c: Remove the dual IPv4/6 socket thing for now, which
was implemented by Michael, until such time as its clear its
required for Linux (see sockopt comments). IPv6 support, including
IPv4 sessions on AF_INET6 sockets, therefore is broken, and the
'-l 0.0.0.0' arguments would need to be given to bgpd to make
things work here.
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Tomohiko Kusuda <kusuda@inetcore.com>
Leigh Brown <leigh@solinno.co.uk>
* bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5
sockopt and bgpd.
(bgp_md5_set_socket) Helper for bgp_connect
(bgp_md5_set) setup TCP-MD5SIG for the given peer.
(bgp_connect) call out to bgp_md5_set_socket for the outgoing
connect socket.
(bgp_socket) save references to the listen sockets, needed if
TCP-MD5SIG is applied later or changed.
* bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password'
commands.
* bgpd.c: (peer_{new,delete) manage TCP-MD5 password
(peer_group2peer_config_copy) inherit TCP-MD5 password
(peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5
passwords: applying checks, stopping peers, and trying to return
errors to UI, etc.
(bgp_config_write_peer) save password.
Fix missing newline in writeout of neighbor ... port.
2008-07-21 Paul Jakma <paul.jakma@sun.com>
* sockunion.c: ifdef out various places that converted
v4mapped sockets to pure v4. Doesn't seem necessary at all,
presumably a workaround for now historical inet_ntop bugs (?)
2008-07-21 Michael H. Warfield <mhw@wittsend.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
|
|
|
zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
"in 2-bytes, very odd peer.", peer->host, as4);
|
|
|
|
if (as4)
|
|
|
|
remote_as = as4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
|
|
|
|
/* If we have got the capability, peer->as4cap must match remote_as */
|
|
|
|
if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
|
|
|
|
&& as4 != remote_as)
|
|
|
|
{
|
|
|
|
/* raise error, log this, close session */
|
|
|
|
zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
|
|
|
|
" mismatch with 16bit 'myasn' %u in open",
|
|
|
|
peer->host, as4, remote_as);
|
2015-05-20 03:03:52 +02:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_BAD_PEER_AS,
|
|
|
|
notify_data_remote_as4, 4);
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* remote router-id check. */
|
2015-05-20 03:03:56 +02:00
|
|
|
if (remote_id.s_addr == 0
|
|
|
|
|| IPV4_CLASS_DE (ntohl (remote_id.s_addr))
|
|
|
|
|| ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s bad OPEN, wrong router identifier %s",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, inet_ntoa (remote_id));
|
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
|
|
|
|
notify_data_remote_id, 4);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set remote router-id */
|
|
|
|
peer->remote_id = remote_id;
|
|
|
|
|
|
|
|
/* Peer BGP version check. */
|
|
|
|
if (version != BGP_VERSION_4)
|
|
|
|
{
|
2012-12-07 22:25:00 +01:00
|
|
|
u_int16_t maxver = htons(BGP_VERSION_4);
|
|
|
|
/* XXX this reply may not be correct if version < 4 XXX */
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, version, BGP_VERSION_4);
|
2012-12-07 22:25:00 +01:00
|
|
|
/* Data must be in network byte order here */
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_UNSUP_VERSION,
|
2012-12-07 22:25:00 +01:00
|
|
|
(u_int8_t *) &maxver, 2);
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check neighbor as number. */
|
|
|
|
if (remote_as != peer->as)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2009-04-30 15:16:22 +02:00
|
|
|
zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, remote_as, peer->as);
|
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_BAD_PEER_AS,
|
|
|
|
notify_data_remote_as, 2);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
|
|
|
|
calculate the value of the Hold Timer by using the smaller of its
|
|
|
|
configured Hold Time and the Hold Time received in the OPEN message.
|
|
|
|
The Hold Time MUST be either zero or at least three seconds. An
|
|
|
|
implementation may reject connections on the basis of the Hold Time. */
|
|
|
|
|
|
|
|
if (holdtime < 3 && holdtime != 0)
|
|
|
|
{
|
2015-05-20 03:03:43 +02:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
|
|
|
|
holdtime_ptr, 2);
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* From the rfc: A reasonable maximum time between KEEPALIVE messages
|
|
|
|
would be one third of the Hold Time interval. KEEPALIVE messages
|
|
|
|
MUST NOT be sent more frequently than one per second. An
|
|
|
|
implementation MAY adjust the rate at which it sends KEEPALIVE
|
|
|
|
messages as a function of the Hold Time interval. */
|
|
|
|
|
|
|
|
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
|
|
|
|
send_holdtime = peer->holdtime;
|
|
|
|
else
|
|
|
|
send_holdtime = peer->bgp->default_holdtime;
|
|
|
|
|
|
|
|
if (holdtime < send_holdtime)
|
|
|
|
peer->v_holdtime = holdtime;
|
|
|
|
else
|
|
|
|
peer->v_holdtime = send_holdtime;
|
|
|
|
|
|
|
|
peer->v_keepalive = peer->v_holdtime / 3;
|
|
|
|
|
|
|
|
/* Open option part parse. */
|
|
|
|
if (optlen != 0)
|
|
|
|
{
|
2012-02-19 19:19:52 +01:00
|
|
|
if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
|
2012-01-09 21:59:26 +01:00
|
|
|
{
|
|
|
|
bgp_notify_send (peer,
|
|
|
|
BGP_NOTIFY_OPEN_ERR,
|
|
|
|
BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
|
|
|
|
return ret;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host);
|
|
|
|
}
|
|
|
|
|
2012-02-19 19:19:52 +01:00
|
|
|
/*
|
|
|
|
* Assume that the peer supports the locally configured set of
|
|
|
|
* AFI/SAFIs if the peer did not send us any Mulitiprotocol
|
|
|
|
* capabilities, or if 'override-capability' is configured.
|
|
|
|
*/
|
|
|
|
if (! mp_capability ||
|
|
|
|
CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
|
|
|
|
peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
|
|
|
|
peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
|
|
|
|
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
/* When collision is detected and this peer is closed. Retrun
|
|
|
|
immidiately. */
|
|
|
|
ret = bgp_collision_detect (peer, remote_id);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Get sockname. */
|
2015-05-20 02:40:37 +02:00
|
|
|
if ((ret = bgp_getsockname (peer)) < 0)
|
|
|
|
{
|
|
|
|
zlog_err("%s: bgp_getsockname() failed for peer: %s", __FUNCTION__,
|
|
|
|
peer->host);
|
|
|
|
return (ret);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:40:37 +02:00
|
|
|
if ((ret = bgp_event_update(peer, Receive_OPEN_message)) < 0)
|
|
|
|
{
|
|
|
|
zlog_err("%s: BGP event update failed for peer: %s", __FUNCTION__,
|
|
|
|
peer->host);
|
|
|
|
/* DD: bgp send notify and reset state */
|
|
|
|
return (ret);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
peer->packet_size = 0;
|
|
|
|
if (peer->ibuf)
|
|
|
|
stream_reset (peer->ibuf);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
/* Called when there is a change in the EOR(implicit or explicit) status of a peer.
|
|
|
|
Ends the update-delay if all expected peers are done with EORs. */
|
|
|
|
void
|
|
|
|
bgp_check_update_delay(struct bgp *bgp)
|
|
|
|
{
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct peer *peer;
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
zlog_debug ("Checking update delay, T: %d R: %d I:%d E: %d", bgp->established,
|
|
|
|
bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors);
|
|
|
|
|
|
|
|
if (bgp->established <=
|
|
|
|
bgp->restarted_peers + bgp->implicit_eors + bgp->explicit_eors)
|
|
|
|
{
|
|
|
|
/* This is an extra sanity check to make sure we wait for all the
|
|
|
|
eligible configured peers. This check is performed if establish wait
|
|
|
|
timer is on, or establish wait option is not given with the
|
|
|
|
update-delay command */
|
|
|
|
if (bgp->t_establish_wait ||
|
|
|
|
(bgp->v_establish_wait == bgp->v_update_delay))
|
|
|
|
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
|
|
|
{
|
2015-05-20 02:40:37 +02:00
|
|
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
|
|
|
|
&& !CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
&& !peer->update_delay_over)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
zlog_debug (" Peer %s pending, continuing read-only mode",
|
|
|
|
peer->host);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
zlog_info ("Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d",
|
|
|
|
bgp->restarted_peers, bgp->implicit_eors, bgp->explicit_eors);
|
|
|
|
bgp_update_delay_end(bgp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called if peer is known to have restarted. The restart-state bit in
|
|
|
|
Graceful-Restart capability is used for that */
|
|
|
|
void
|
|
|
|
bgp_update_restarted_peers (struct peer *peer)
|
|
|
|
{
|
|
|
|
if (!bgp_update_delay_active(peer->bgp)) return; /* BGP update delay has ended */
|
|
|
|
if (peer->update_delay_over) return; /* This peer has already been considered */
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
zlog_debug ("Peer %s: Checking restarted", peer->host);
|
|
|
|
|
|
|
|
if (peer->status == Established)
|
|
|
|
{
|
|
|
|
peer->update_delay_over = 1;
|
|
|
|
peer->bgp->restarted_peers++;
|
|
|
|
bgp_check_update_delay(peer->bgp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called as peer receives a keep-alive. Determines if this occurence can be
|
|
|
|
taken as an implicit EOR for this peer.
|
|
|
|
NOTE: The very first keep-alive after the Established state of a peer is
|
|
|
|
considered implicit EOR for the update-delay purposes */
|
|
|
|
void
|
|
|
|
bgp_update_implicit_eors (struct peer *peer)
|
|
|
|
{
|
|
|
|
if (!bgp_update_delay_active(peer->bgp)) return; /* BGP update delay has ended */
|
|
|
|
if (peer->update_delay_over) return; /* This peer has already been considered */
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
zlog_debug ("Peer %s: Checking implicit EORs", peer->host);
|
|
|
|
|
|
|
|
if (peer->status == Established)
|
|
|
|
{
|
|
|
|
peer->update_delay_over = 1;
|
|
|
|
peer->bgp->implicit_eors++;
|
|
|
|
bgp_check_update_delay(peer->bgp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Should be called only when there is a change in the EOR_RECEIVED status
|
|
|
|
for any afi/safi on a peer */
|
|
|
|
static void
|
|
|
|
bgp_update_explicit_eors (struct peer *peer)
|
|
|
|
{
|
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
|
|
|
|
|
|
|
if (!bgp_update_delay_active(peer->bgp)) return; /* BGP update delay has ended */
|
|
|
|
if (peer->update_delay_over) return; /* This peer has already been considered */
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
zlog_debug ("Peer %s: Checking explicit EORs", peer->host);
|
|
|
|
|
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
|
|
|
{
|
|
|
|
if (peer->afc_nego[afi][safi] &&
|
|
|
|
!CHECK_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED))
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
zlog_debug (" afi %d safi %d didnt receive EOR", afi, safi);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
peer->update_delay_over = 1;
|
|
|
|
peer->bgp->explicit_eors++;
|
|
|
|
bgp_check_update_delay(peer->bgp);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Parse BGP Update packet and make attribute object. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_update_receive (struct peer *peer, bgp_size_t size)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u_char *end;
|
|
|
|
struct stream *s;
|
|
|
|
struct attr attr;
|
2012-05-07 18:53:03 +02:00
|
|
|
struct attr_extra extra;
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_size_t attribute_len;
|
|
|
|
bgp_size_t update_len;
|
|
|
|
bgp_size_t withdraw_len;
|
|
|
|
struct bgp_nlri update;
|
|
|
|
struct bgp_nlri withdraw;
|
|
|
|
struct bgp_nlri mp_update;
|
|
|
|
struct bgp_nlri mp_withdraw;
|
2015-05-20 02:58:12 +02:00
|
|
|
int num_pfx_adv, num_pfx_wd;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Status must be Established. */
|
|
|
|
if (peer->status != Established)
|
|
|
|
{
|
|
|
|
zlog_err ("%s [FSM] Update packet received under status %s",
|
|
|
|
peer->host, LOOKUP (bgp_status_msg, peer->status));
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set initial values. */
|
|
|
|
memset (&attr, 0, sizeof (struct attr));
|
2012-05-07 18:53:03 +02:00
|
|
|
memset (&extra, 0, sizeof (struct attr_extra));
|
2002-12-13 21:15:29 +01:00
|
|
|
memset (&update, 0, sizeof (struct bgp_nlri));
|
|
|
|
memset (&withdraw, 0, sizeof (struct bgp_nlri));
|
|
|
|
memset (&mp_update, 0, sizeof (struct bgp_nlri));
|
|
|
|
memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
|
2012-05-07 18:53:03 +02:00
|
|
|
attr.extra = &extra;
|
2015-05-20 02:58:12 +02:00
|
|
|
num_pfx_adv = num_pfx_wd = 0;
|
2015-05-20 02:58:12 +02:00
|
|
|
memset (peer->rcvd_attr_str, 0, BUFSIZ);
|
|
|
|
peer->rcvd_attr_printed = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
s = peer->ibuf;
|
|
|
|
end = stream_pnt (s) + size;
|
|
|
|
|
|
|
|
/* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
|
|
|
|
Length is too large (i.e., if Unfeasible Routes Length + Total
|
|
|
|
Attribute Length + 23 exceeds the message Length), then the Error
|
|
|
|
Subcode is set to Malformed Attribute List. */
|
|
|
|
if (stream_pnt (s) + 2 > end)
|
|
|
|
{
|
|
|
|
zlog_err ("%s [Error] Update packet error"
|
|
|
|
" (packet length is short for unfeasible length)",
|
|
|
|
peer->host);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
|
|
|
|
BGP_NOTIFY_UPDATE_MAL_ATTR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unfeasible Route Length. */
|
|
|
|
withdraw_len = stream_getw (s);
|
|
|
|
|
|
|
|
/* Unfeasible Route Length check. */
|
|
|
|
if (stream_pnt (s) + withdraw_len > end)
|
|
|
|
{
|
|
|
|
zlog_err ("%s [Error] Update packet error"
|
|
|
|
" (packet unfeasible length overflow %d)",
|
|
|
|
peer->host, withdraw_len);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
|
|
|
|
BGP_NOTIFY_UPDATE_MAL_ATTR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unfeasible Route packet format check. */
|
|
|
|
if (withdraw_len > 0)
|
|
|
|
{
|
2015-05-20 03:03:45 +02:00
|
|
|
ret = bgp_nlri_sanity_check (peer, AFI_IP, SAFI_UNICAST, stream_pnt (s),
|
|
|
|
withdraw_len, &num_pfx_wd);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
withdraw.afi = AFI_IP;
|
|
|
|
withdraw.safi = SAFI_UNICAST;
|
|
|
|
withdraw.nlri = stream_pnt (s);
|
|
|
|
withdraw.length = withdraw_len;
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_getp (s, withdraw_len);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Attribute total length check. */
|
|
|
|
if (stream_pnt (s) + 2 > end)
|
|
|
|
{
|
|
|
|
zlog_warn ("%s [Error] Packet Error"
|
|
|
|
" (update packet is short for attribute length)",
|
|
|
|
peer->host);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
|
|
|
|
BGP_NOTIFY_UPDATE_MAL_ATTR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fetch attribute total length. */
|
|
|
|
attribute_len = stream_getw (s);
|
|
|
|
|
|
|
|
/* Attribute length check. */
|
|
|
|
if (stream_pnt (s) + attribute_len > end)
|
|
|
|
{
|
|
|
|
zlog_warn ("%s [Error] Packet Error"
|
|
|
|
" (update packet attribute length overflow %d)",
|
|
|
|
peer->host, attribute_len);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
|
|
|
|
BGP_NOTIFY_UPDATE_MAL_ATTR);
|
|
|
|
return -1;
|
|
|
|
}
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
|
|
|
|
/* Certain attribute parsing errors should not be considered bad enough
|
|
|
|
* to reset the session for, most particularly any partial/optional
|
|
|
|
* attributes that have 'tunneled' over speakers that don't understand
|
|
|
|
* them. Instead we withdraw only the prefix concerned.
|
|
|
|
*
|
|
|
|
* Complicates the flow a little though..
|
|
|
|
*/
|
|
|
|
bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
|
|
|
|
/* This define morphs the update case into a withdraw when lower levels
|
|
|
|
* have signalled an error condition where this is best.
|
|
|
|
*/
|
|
|
|
#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Parse attribute when it exists. */
|
|
|
|
if (attribute_len)
|
|
|
|
{
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
|
2002-12-13 21:15:29 +01:00
|
|
|
&mp_update, &mp_withdraw);
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
|
2014-06-04 01:00:51 +02:00
|
|
|
{
|
|
|
|
bgp_attr_unintern_sub (&attr);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Logging the attribute. */
|
2015-05-20 02:58:12 +02:00
|
|
|
if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW ||
|
|
|
|
BGP_DEBUG (update, UPDATE_IN) ||
|
|
|
|
BGP_DEBUG (update, UPDATE_PREFIX))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
ret = bgp_dump_attr (peer, &attr, peer->rcvd_attr_str, BUFSIZ);
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
|
|
|
|
if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_err ("%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
|
|
|
|
peer->host);
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (ret && bgp_debug_update(peer, NULL, NULL, 1))
|
2015-05-20 02:58:12 +02:00
|
|
|
{
|
|
|
|
zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
|
|
|
|
peer->rcvd_attr_printed = 1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Network Layer Reachability Information. */
|
|
|
|
update_len = end - stream_pnt (s);
|
|
|
|
|
|
|
|
if (update_len)
|
|
|
|
{
|
|
|
|
/* Check NLRI packet format and prefix length. */
|
2015-05-20 03:03:45 +02:00
|
|
|
ret = bgp_nlri_sanity_check (peer, AFI_IP, SAFI_UNICAST, stream_pnt (s),
|
|
|
|
update_len, &num_pfx_adv);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
{
|
|
|
|
bgp_attr_unintern_sub (&attr);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set NLRI portion to structure. */
|
|
|
|
update.afi = AFI_IP;
|
|
|
|
update.safi = SAFI_UNICAST;
|
|
|
|
update.nlri = stream_pnt (s);
|
|
|
|
update.length = update_len;
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_getp (s, update_len);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (BGP_DEBUG (update, UPDATE_IN))
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_debug("%s rcvd UPDATE wlen %d wpfx %d attrlen %d alen %d apfx %d",
|
|
|
|
peer->host, withdraw_len, num_pfx_wd, attribute_len,
|
|
|
|
update_len, num_pfx_adv);
|
2015-05-20 02:58:12 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* NLRI is processed only when the peer is configured specific
|
|
|
|
Address Family and Subsequent Address Family. */
|
|
|
|
if (peer->afc[AFI_IP][SAFI_UNICAST])
|
|
|
|
{
|
|
|
|
if (withdraw.length)
|
|
|
|
bgp_nlri_parse (peer, NULL, &withdraw);
|
|
|
|
|
|
|
|
if (update.length)
|
|
|
|
{
|
|
|
|
/* We check well-known attribute only for IPv4 unicast
|
|
|
|
update. */
|
|
|
|
ret = bgp_attr_check (peer, &attr);
|
|
|
|
if (ret < 0)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
{
|
|
|
|
bgp_attr_unintern_sub (&attr);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-01 21:13:16 +01:00
|
|
|
if (mp_update.length
|
|
|
|
&& mp_update.afi == AFI_IP
|
|
|
|
&& mp_update.safi == SAFI_UNICAST)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
|
2005-02-01 21:13:16 +01:00
|
|
|
|
|
|
|
if (mp_withdraw.length
|
|
|
|
&& mp_withdraw.afi == AFI_IP
|
|
|
|
&& mp_withdraw.safi == SAFI_UNICAST)
|
|
|
|
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
|
|
|
|
2004-07-09 19:48:53 +02:00
|
|
|
if (! attribute_len && ! withdraw_len)
|
|
|
|
{
|
|
|
|
/* End-of-RIB received */
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
if (!CHECK_FLAG(peer->af_sflags[AFI_IP][SAFI_UNICAST],
|
|
|
|
PEER_STATUS_EOR_RECEIVED))
|
|
|
|
{
|
|
|
|
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
|
|
|
|
PEER_STATUS_EOR_RECEIVED);
|
|
|
|
bgp_update_explicit_eors(peer);
|
|
|
|
}
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
/* NSF delete stale route */
|
|
|
|
if (peer->nsf[AFI_IP][SAFI_UNICAST])
|
|
|
|
bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("rcvd End-of-RIB for IPv4 Unicast from %s", peer->host);
|
2004-07-09 19:48:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
if (peer->afc[AFI_IP][SAFI_MULTICAST])
|
|
|
|
{
|
|
|
|
if (mp_update.length
|
|
|
|
&& mp_update.afi == AFI_IP
|
|
|
|
&& mp_update.safi == SAFI_MULTICAST)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (mp_withdraw.length
|
|
|
|
&& mp_withdraw.afi == AFI_IP
|
|
|
|
&& mp_withdraw.safi == SAFI_MULTICAST)
|
|
|
|
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
if (! withdraw_len
|
2004-07-09 19:48:53 +02:00
|
|
|
&& mp_withdraw.afi == AFI_IP
|
|
|
|
&& mp_withdraw.safi == SAFI_MULTICAST
|
|
|
|
&& mp_withdraw.length == 0)
|
|
|
|
{
|
|
|
|
/* End-of-RIB received */
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
if (!CHECK_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
|
|
|
|
PEER_STATUS_EOR_RECEIVED))
|
|
|
|
{
|
|
|
|
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
|
|
|
|
PEER_STATUS_EOR_RECEIVED);
|
|
|
|
bgp_update_explicit_eors(peer);
|
|
|
|
}
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
/* NSF delete stale route */
|
|
|
|
if (peer->nsf[AFI_IP][SAFI_MULTICAST])
|
|
|
|
bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("rcvd End-of-RIB for IPv4 Multicast from %s", peer->host);
|
2004-07-09 19:48:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
if (peer->afc[AFI_IP6][SAFI_UNICAST])
|
|
|
|
{
|
|
|
|
if (mp_update.length
|
|
|
|
&& mp_update.afi == AFI_IP6
|
|
|
|
&& mp_update.safi == SAFI_UNICAST)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (mp_withdraw.length
|
|
|
|
&& mp_withdraw.afi == AFI_IP6
|
|
|
|
&& mp_withdraw.safi == SAFI_UNICAST)
|
|
|
|
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
if (! withdraw_len
|
2004-07-09 19:48:53 +02:00
|
|
|
&& mp_withdraw.afi == AFI_IP6
|
|
|
|
&& mp_withdraw.safi == SAFI_UNICAST
|
|
|
|
&& mp_withdraw.length == 0)
|
|
|
|
{
|
|
|
|
/* End-of-RIB received */
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST],
|
|
|
|
PEER_STATUS_EOR_RECEIVED))
|
|
|
|
{
|
|
|
|
SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
|
|
|
|
bgp_update_explicit_eors(peer);
|
|
|
|
}
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
/* NSF delete stale route */
|
|
|
|
if (peer->nsf[AFI_IP6][SAFI_UNICAST])
|
|
|
|
bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("rcvd End-of-RIB for IPv6 Unicast from %s", peer->host);
|
2004-07-09 19:48:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
if (peer->afc[AFI_IP6][SAFI_MULTICAST])
|
|
|
|
{
|
|
|
|
if (mp_update.length
|
|
|
|
&& mp_update.afi == AFI_IP6
|
|
|
|
&& mp_update.safi == SAFI_MULTICAST)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (mp_withdraw.length
|
|
|
|
&& mp_withdraw.afi == AFI_IP6
|
|
|
|
&& mp_withdraw.safi == SAFI_MULTICAST)
|
|
|
|
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
if (! withdraw_len
|
2004-07-09 19:48:53 +02:00
|
|
|
&& mp_withdraw.afi == AFI_IP6
|
|
|
|
&& mp_withdraw.safi == SAFI_MULTICAST
|
|
|
|
&& mp_withdraw.length == 0)
|
|
|
|
{
|
|
|
|
/* End-of-RIB received */
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_MULTICAST],
|
|
|
|
PEER_STATUS_EOR_RECEIVED))
|
|
|
|
{
|
|
|
|
SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_MULTICAST], PEER_STATUS_EOR_RECEIVED);
|
|
|
|
bgp_update_explicit_eors(peer);
|
|
|
|
}
|
|
|
|
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
/* NSF delete stale route */
|
|
|
|
if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
|
|
|
|
bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
|
|
|
|
|
2015-05-20 03:04:06 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_debug ("rcvd End-of-RIB for IPv6 Multicast from %s", peer->host);
|
2004-07-09 19:48:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
|
|
|
|
{
|
|
|
|
if (mp_update.length
|
|
|
|
&& mp_update.afi == AFI_IP
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
&& mp_update.safi == SAFI_MPLS_LABELED_VPN)
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (mp_withdraw.length
|
|
|
|
&& mp_withdraw.afi == AFI_IP
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
&& mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2005-02-02 15:40:33 +01:00
|
|
|
if (! withdraw_len
|
2004-07-09 19:48:53 +02:00
|
|
|
&& mp_withdraw.afi == AFI_IP
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
&& mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
|
2004-07-09 19:48:53 +02:00
|
|
|
&& mp_withdraw.length == 0)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
|
|
|
|
/* End-of-RIB received */
|
|
|
|
if (!CHECK_FLAG (peer->af_sflags[AFI_IP][SAFI_MPLS_VPN],
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
PEER_STATUS_EOR_RECEIVED))
|
2015-05-20 02:58:12 +02:00
|
|
|
{
|
bgpd: bgpd-update-delay.patch
COMMAND:
'update-delay <max-delay in seconds> [<establish-wait in seconds>]'
DESCRIPTION:
This feature is used to enable read-only mode on BGP process restart or when
BGP process is cleared using 'clear ip bgp *'. When applicable, read-only mode
would begin as soon as the first peer reaches Established state and a timer
for <max-delay> seconds is started.
During this mode BGP doesn't run any best-path or generate any updates to its
peers. This mode continues until:
1. All the configured peers, except the shutdown peers, have sent explicit EOR
(End-Of-RIB) or an implicit-EOR. The first keep-alive after BGP has reached
Established is considered an implicit-EOR.
If the <establish-wait> optional value is given, then BGP will wait for
peers to reach establish from the begining of the update-delay till the
establish-wait period is over, i.e. the minimum set of established peers for
which EOR is expected would be peers established during the establish-wait
window, not necessarily all the configured neighbors.
2. max-delay period is over.
On hitting any of the above two conditions, BGP resumes the decision process
and generates updates to its peers.
Default <max-delay> is 0, i.e. the feature is off by default.
This feature can be useful in reducing CPU/network used as BGP restarts/clears.
Particularly useful in the topologies where BGP learns a prefix from many peers.
Intermediate bestpaths are possible for the same prefix as peers get established
and start receiving updates at different times. This feature should offer a
value-add if the network has a high number of such prefixes.
IMPLEMENTATION OBJECTIVES:
Given this is an optional feature, minimized the code-churn. Used existing
constructs wherever possible (existing queue-plug/unplug were used to achieve
delay and resume of best-paths/update-generation). As a result, no new
data-structure(s) had to be defined and allocated. When the feature is disabled,
the new node is not exercised for the most part.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
Dinesh Dutt <ddutt@cumulusnetworks.com>
2015-05-20 02:40:33 +02:00
|
|
|
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MPLS_VPN], PEER_STATUS_EOR_RECEIVED);
|
2015-05-20 02:58:12 +02:00
|
|
|
bgp_update_explicit_eors(peer);
|
|
|
|
}
|
2004-07-09 19:48:53 +02:00
|
|
|
|
2015-05-20 03:04:06 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_debug ("rcvd End-of-RIB for VPNv4 Unicast from %s", peer->host);
|
2004-07-09 19:48:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Everything is done. We unintern temporary structures which
|
|
|
|
interned in bgp_attr_parse(). */
|
bgpd: Implement revised error handling for partial optional/trans. attributes
* BGP error handling generally boils down to "reset session". This was fine
when all BGP speakers pretty much understood all BGP messages. However
the increasing deployment of new attribute types has shown this approach
to cause problems, in particular where a new attribute type is "tunneled"
over some speakers which do not understand it, and then arrives at a speaker
which does but considers it malformed (e.g. corruption along the way, or
because of early implementation bugs/interop issues).
To mitigate this drafts before the IDR (likely to be adopted) propose to
treat errors in partial (i.e. not understood by neighbour), optional
transitive attributes, when received from eBGP peers, as withdrawing only
the NLRIs in the affected UPDATE, rather than causing the entire session
to be reset. See:
http://tools.ietf.org/html/draft-scudder-idr-optional-transitive
* bgp_aspath.c: (assegments_parse) Replace the "NULL means valid, 0-length
OR an error" return value with an error code - instead taking
pointer to result structure as arg.
(aspath_parse) adjust to suit previous change, but here NULL really
does mean error in the external interface.
* bgp_attr.h (bgp_attr_parse) use an explictly typed and enumerated
value to indicate return result.
(bgp_attr_unintern_sub) cleans up just the members of an attr, but not the
attr itself, for benefit of those who use a stack-local attr.
* bgp_attr.c: (bgp_attr_unintern_sub) split out from bgp_attr_unintern
(bgp_attr_unintern) as previous.
(bgp_attr_malformed) helper function to centralise decisions on how to
handle errors in attributes.
(bgp_attr_{aspathlimit,origin,etc..}) Use bgp_attr_malformed.
(bgp_attr_aspathlimit) Subcode for error specifc to this attr should be
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR.
(bgp_attr_as4_path) be more rigorous about checks, ala bgp_attr_as_path.
(bgp_attr_parse) Adjust to deal with the additional error level that
bgp_attr_ parsers can raise, and also similarly return appropriate
error back up to (bgp_update_receive). Try to avoid leaking as4_path.
* bgp_packet.c: (bgp_update_receive) Adjust to deal with BGP_ATTR_PARSE_WITHDRAW
error level from bgp_attr_parse, which should lead to a withdraw, by
making the attribute parameter in call to (bgp_nlri_parse) conditional
on the error, so the update case morphs also into a withdraw.
Use bgp_attr_unintern_sub from above, instead of doing this itself.
Fix error case returns which were not calling bgp_attr_unintern_sub
and probably leaking memory.
* tests/aspath_test.c: Fix to work for null return with bad segments
2010-11-23 17:35:42 +01:00
|
|
|
bgp_attr_unintern_sub (&attr);
|
2012-05-07 18:53:03 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If peering is stopped due to some reason, do not generate BGP
|
|
|
|
event. */
|
|
|
|
if (peer->status != Established)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Increment packet counter. */
|
|
|
|
peer->update_in++;
|
2010-01-15 14:22:10 +01:00
|
|
|
peer->update_time = bgp_clock ();
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2012-06-20 17:45:50 +02:00
|
|
|
/* Rearm holdtime timer */
|
2012-05-07 18:53:07 +02:00
|
|
|
BGP_TIMER_OFF (peer->t_holdtime);
|
2012-06-20 17:45:50 +02:00
|
|
|
bgp_timer_set (peer);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Notify message treatment function. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_notify_receive (struct peer *peer, bgp_size_t size)
|
|
|
|
{
|
|
|
|
struct bgp_notify bgp_notify;
|
|
|
|
|
|
|
|
if (peer->notify.data)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_TMP, peer->notify.data);
|
|
|
|
peer->notify.data = NULL;
|
|
|
|
peer->notify.length = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bgp_notify.code = stream_getc (peer->ibuf);
|
|
|
|
bgp_notify.subcode = stream_getc (peer->ibuf);
|
|
|
|
bgp_notify.length = size - 2;
|
|
|
|
bgp_notify.data = NULL;
|
|
|
|
|
|
|
|
/* Preserv notify code and sub code. */
|
|
|
|
peer->notify.code = bgp_notify.code;
|
|
|
|
peer->notify.subcode = bgp_notify.subcode;
|
|
|
|
/* For further diagnostic record returned Data. */
|
|
|
|
if (bgp_notify.length)
|
|
|
|
{
|
|
|
|
peer->notify.length = size - 2;
|
|
|
|
peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
|
|
|
|
memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For debug */
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int first = 0;
|
|
|
|
char c[4];
|
|
|
|
|
|
|
|
if (bgp_notify.length)
|
|
|
|
{
|
|
|
|
bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
|
|
|
|
for (i = 0; i < bgp_notify.length; i++)
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
sprintf (c, " %02x", stream_getc (peer->ibuf));
|
|
|
|
strcat (bgp_notify.data, c);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
first = 1;
|
|
|
|
sprintf (c, "%02x", stream_getc (peer->ibuf));
|
|
|
|
strcpy (bgp_notify.data, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bgp_notify_print(peer, &bgp_notify, "received");
|
|
|
|
if (bgp_notify.data)
|
|
|
|
XFREE (MTYPE_TMP, bgp_notify.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* peer count update */
|
|
|
|
peer->notify_in++;
|
|
|
|
|
2004-05-20 11:19:34 +02:00
|
|
|
if (peer->status == Established)
|
|
|
|
peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* We have to check for Notify with Unsupported Optional Parameter.
|
|
|
|
in that case we fallback to open without the capability option.
|
|
|
|
But this done in bgp_stop. We just mark it here to avoid changing
|
|
|
|
the fsm tables. */
|
|
|
|
if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
|
|
|
|
bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
|
|
|
|
UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
|
|
|
|
|
|
|
|
BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Keepalive treatment function -- get keepalive send keepalive */
|
2005-06-28 14:44:16 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_keepalive(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s KEEPALIVE rcvd", peer->host);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route refresh message is received. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
|
|
|
|
{
|
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
|
|
|
u_char reserved;
|
|
|
|
struct stream *s;
|
2015-05-20 03:04:05 +02:00
|
|
|
struct peer_af *paf;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If peer does not have the capability, send notification. */
|
|
|
|
if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_err ("%s [Error] BGP route refresh is not enabled",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host);
|
|
|
|
bgp_notify_send (peer,
|
|
|
|
BGP_NOTIFY_HEADER_ERR,
|
|
|
|
BGP_NOTIFY_HEADER_BAD_MESTYPE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Status must be Established. */
|
|
|
|
if (peer->status != Established)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_err ("%s [Error] Route refresh packet received under status %s",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, LOOKUP (bgp_status_msg, peer->status));
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = peer->ibuf;
|
|
|
|
|
|
|
|
/* Parse packet. */
|
|
|
|
afi = stream_getw (s);
|
|
|
|
reserved = stream_getc (s);
|
|
|
|
safi = stream_getc (s);
|
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 0))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, afi, safi);
|
|
|
|
|
|
|
|
/* Check AFI and SAFI. */
|
|
|
|
if ((afi != AFI_IP && afi != AFI_IP6)
|
|
|
|
|| (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
&& safi != SAFI_MPLS_LABELED_VPN))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_info ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
|
|
|
|
peer->host, afi, safi);
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adjust safi code. */
|
bgpd: more SAFI fixes
(with resolved conflict in bgpd/bgp_packet.c)
Two macros resolving to the same integer constant broke a case block and
a more thorough merge of BGP_SAFI_VPNV4 and BGP_SAFI_VPNV6 was
performed.
* bgpd.h: MPLS-labeled VPN SAFI is AFI-independent, switch to single
* macro
* bgp_capability_test.c: update test data
* bgp_mp_attr_test.c: idem
* bgp_route.c: (bgp_maximum_prefix_overflow, bgp_table_stats_vty) update
macro and check conditions (where appropriate)
* bgp_packet.c: (bgp_route_refresh_send, bgp_capability_send,
bgp_update_receive, bgp_route_refresh_receive): idem
* bgp_open.c: (bgp_capability_vty_out, bgp_afi_safi_valid_indices,
bgp_open_capability_orf, bgp_open_capability): idem
* bgp_attr.c: (bgp_mp_reach_parse, bgp_packet_attribute,
bgp_packet_withdraw): idem
2011-07-14 10:36:19 +02:00
|
|
|
if (safi == SAFI_MPLS_LABELED_VPN)
|
2002-12-13 21:15:29 +01:00
|
|
|
safi = SAFI_MPLS_VPN;
|
|
|
|
|
|
|
|
if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
|
|
|
|
{
|
|
|
|
u_char *end;
|
|
|
|
u_char when_to_refresh;
|
|
|
|
u_char orf_type;
|
|
|
|
u_int16_t orf_len;
|
|
|
|
|
|
|
|
if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
|
|
|
|
{
|
|
|
|
zlog_info ("%s ORF route refresh length error", peer->host);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
when_to_refresh = stream_getc (s);
|
|
|
|
end = stream_pnt (s) + (size - 5);
|
|
|
|
|
2007-12-22 17:49:52 +01:00
|
|
|
while ((stream_pnt (s) + 2) < end)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
orf_type = stream_getc (s);
|
|
|
|
orf_len = stream_getw (s);
|
2007-12-22 17:49:52 +01:00
|
|
|
|
|
|
|
/* orf_len in bounds? */
|
|
|
|
if ((stream_pnt (s) + orf_len) > end)
|
|
|
|
break; /* XXX: Notify instead?? */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (orf_type == ORF_TYPE_PREFIX
|
|
|
|
|| orf_type == ORF_TYPE_PREFIX_OLD)
|
|
|
|
{
|
|
|
|
u_char *p_pnt = stream_pnt (s);
|
|
|
|
u_char *p_end = stream_pnt (s) + orf_len;
|
|
|
|
struct orf_prefix orfp;
|
|
|
|
u_char common = 0;
|
|
|
|
u_int32_t seq;
|
|
|
|
int psize;
|
|
|
|
char name[BUFSIZ];
|
|
|
|
int ret;
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host, orf_type, orf_len);
|
|
|
|
}
|
|
|
|
|
2007-12-22 17:49:52 +01:00
|
|
|
/* we're going to read at least 1 byte of common ORF header,
|
|
|
|
* and 7 bytes of ORF Address-filter entry from the stream
|
|
|
|
*/
|
|
|
|
if (orf_len < 7)
|
|
|
|
break;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* ORF prefix-list name */
|
|
|
|
sprintf (name, "%s.%d.%d", peer->host, afi, safi);
|
|
|
|
|
|
|
|
while (p_pnt < p_end)
|
|
|
|
{
|
2010-05-14 14:38:39 +02:00
|
|
|
/* If the ORF entry is malformed, want to read as much of it
|
|
|
|
* as possible without going beyond the bounds of the entry,
|
|
|
|
* to maximise debug information.
|
|
|
|
*/
|
2011-04-11 17:31:43 +02:00
|
|
|
int ok;
|
2002-12-13 21:15:29 +01:00
|
|
|
memset (&orfp, 0, sizeof (struct orf_prefix));
|
|
|
|
common = *p_pnt++;
|
2010-05-14 14:38:39 +02:00
|
|
|
/* after ++: p_pnt <= p_end */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (common & ORF_COMMON_PART_REMOVE_ALL)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_bgp_orf_remove_all (name);
|
|
|
|
break;
|
|
|
|
}
|
2010-05-14 14:38:39 +02:00
|
|
|
ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
|
2011-12-13 18:11:39 +01:00
|
|
|
if (ok)
|
2010-05-14 14:38:39 +02:00
|
|
|
{
|
2011-04-11 17:31:43 +02:00
|
|
|
memcpy (&seq, p_pnt, sizeof (u_int32_t));
|
|
|
|
p_pnt += sizeof (u_int32_t);
|
|
|
|
orfp.seq = ntohl (seq);
|
2010-05-14 14:38:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
p_pnt = p_end ;
|
|
|
|
|
|
|
|
if ((ok = (p_pnt < p_end)))
|
|
|
|
orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
|
|
|
|
if ((ok = (p_pnt < p_end)))
|
|
|
|
orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
|
|
|
|
if ((ok = (p_pnt < p_end)))
|
|
|
|
orfp.p.prefixlen = *p_pnt++ ;
|
|
|
|
orfp.p.family = afi2family (afi); /* afi checked already */
|
|
|
|
|
|
|
|
psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
|
|
|
|
if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
|
|
|
|
{
|
|
|
|
ok = 0 ;
|
|
|
|
psize = prefix_blen(&orfp.p) ;
|
|
|
|
}
|
|
|
|
if (psize > (p_end - p_pnt)) /* valid for packet ? */
|
|
|
|
{
|
|
|
|
ok = 0 ;
|
|
|
|
psize = p_end - p_pnt ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (psize > 0)
|
|
|
|
memcpy (&orfp.p.u.prefix, p_pnt, psize);
|
2002-12-13 21:15:29 +01:00
|
|
|
p_pnt += psize;
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2012-05-07 18:52:53 +02:00
|
|
|
{
|
|
|
|
char buf[INET6_BUFSIZ];
|
|
|
|
|
|
|
|
zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
|
|
|
|
peer->host,
|
|
|
|
(common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
|
|
|
|
(common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
|
|
|
|
orfp.seq,
|
|
|
|
inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
|
|
|
|
orfp.p.prefixlen, orfp.ge, orfp.le,
|
|
|
|
ok ? "" : " MALFORMED");
|
|
|
|
}
|
|
|
|
|
2010-05-14 14:38:39 +02:00
|
|
|
if (ok)
|
2011-04-11 17:31:43 +02:00
|
|
|
ret = prefix_bgp_orf_set (name, afi, &orfp,
|
|
|
|
(common & ORF_COMMON_PART_DENY ? 0 : 1 ),
|
|
|
|
(common & ORF_COMMON_PART_REMOVE ? 0 : 1));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2010-05-14 14:38:39 +02:00
|
|
|
if (!ok || (ret != CMD_SUCCESS))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_info ("%s Received misformatted prefixlist ORF."
|
|
|
|
" Remove All pfxlist", peer->host);
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_bgp_orf_remove_all (name);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
peer->orf_plist[afi][safi] =
|
|
|
|
prefix_list_lookup (AFI_ORF_PREFIX, name);
|
|
|
|
}
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_getp (s, orf_len);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
|
2002-12-13 21:15:29 +01:00
|
|
|
when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
|
|
|
|
if (when_to_refresh == REFRESH_DEFER)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* First update is deferred until ORF or ROUTE-REFRESH is received */
|
|
|
|
if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
|
|
|
|
UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
|
|
|
|
|
2015-05-20 03:04:05 +02:00
|
|
|
/* If the peer is configured for default-originate clear the
|
|
|
|
* SUBGRP_STATUS_DEFAULT_ORIGINATE flag so that we will re-advertise the
|
|
|
|
* default
|
|
|
|
*/
|
|
|
|
paf = peer_af_find (peer, afi, safi);
|
|
|
|
if (paf && paf->subgroup &&
|
|
|
|
CHECK_FLAG (paf->subgroup->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
|
|
|
|
UNSET_FLAG (paf->subgroup->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Perform route refreshment to the peer */
|
|
|
|
bgp_announce_route (peer, afi, safi);
|
|
|
|
}
|
|
|
|
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
|
|
|
|
{
|
|
|
|
u_char *end;
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
struct capability_mp_data mpc;
|
|
|
|
struct capability_header *hdr;
|
2002-12-13 21:15:29 +01:00
|
|
|
u_char action;
|
|
|
|
struct bgp *bgp;
|
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
|
|
|
|
|
|
|
bgp = peer->bgp;
|
|
|
|
end = pnt + length;
|
|
|
|
|
|
|
|
while (pnt < end)
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
/* We need at least action, capability code and capability length. */
|
|
|
|
if (pnt + 3 > end)
|
|
|
|
{
|
|
|
|
zlog_info ("%s Capability length error", peer->host);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
action = *pnt;
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
hdr = (struct capability_header *)(pnt + 1);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Action value check. */
|
|
|
|
if (action != CAPABILITY_ACTION_SET
|
|
|
|
&& action != CAPABILITY_ACTION_UNSET)
|
|
|
|
{
|
|
|
|
zlog_info ("%s Capability Action Value error %d",
|
|
|
|
peer->host, action);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
peer->host, action, hdr->code, hdr->length);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Capability length check. */
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
if ((pnt + hdr->length + 3) > end)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
zlog_info ("%s Capability length error", peer->host);
|
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
/* Fetch structure to the byte stream. */
|
|
|
|
memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* We know MP Capability Code. */
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
if (hdr->code == CAPABILITY_CODE_MP)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
afi = ntohs (mpc.afi);
|
|
|
|
safi = mpc.safi;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Ignore capability when override-capability is set. */
|
|
|
|
if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
|
|
|
|
continue;
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
|
|
|
|
if (!bgp_afi_safi_valid_indices (afi, &safi))
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
|
|
|
|
"(%u/%u)", peer->host, afi, safi);
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Address family check. */
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
|
|
|
|
peer->host,
|
|
|
|
action == CAPABILITY_ACTION_SET
|
|
|
|
? "Advertising" : "Removing",
|
|
|
|
ntohs(mpc.afi) , mpc.safi);
|
|
|
|
|
|
|
|
if (action == CAPABILITY_ACTION_SET)
|
|
|
|
{
|
|
|
|
peer->afc_recv[afi][safi] = 1;
|
|
|
|
if (peer->afc[afi][safi])
|
|
|
|
{
|
|
|
|
peer->afc_nego[afi][safi] = 1;
|
|
|
|
bgp_announce_route (peer, afi, safi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
peer->afc_recv[afi][safi] = 0;
|
|
|
|
peer->afc_nego[afi][safi] = 0;
|
|
|
|
|
|
|
|
if (peer_active_nego (peer))
|
[bgpd] Stability fixes including bugs 397, 492
I've spent the last several weeks working on stability fixes to bgpd.
These patches fix all of the numerous crashes, assertion failures, memory
leaks and memory stomping I could find. Valgrind was used extensively.
Added new function bgp_exit() to help catch problems. If "debug bgp" is
configured and bgpd exits with status of 0, statistics on remaining
lib/memory.c allocations are printed to stderr. It is my hope that other
developers will use this to stay on top of memory issues.
Example questionable exit:
bgpd: memstats: Current memory utilization in module LIB:
bgpd: memstats: Link List : 6
bgpd: memstats: Link Node : 5
bgpd: memstats: Hash : 8
bgpd: memstats: Hash Bucket : 2
bgpd: memstats: Hash Index : 8
bgpd: memstats: Work queue : 3
bgpd: memstats: Work queue item : 2
bgpd: memstats: Work queue name string : 3
bgpd: memstats: Current memory utilization in module BGP:
bgpd: memstats: BGP instance : 1
bgpd: memstats: BGP peer : 1
bgpd: memstats: BGP peer hostname : 1
bgpd: memstats: BGP attribute : 1
bgpd: memstats: BGP extra attributes : 1
bgpd: memstats: BGP aspath : 1
bgpd: memstats: BGP aspath str : 1
bgpd: memstats: BGP table : 24
bgpd: memstats: BGP node : 1
bgpd: memstats: BGP route : 1
bgpd: memstats: BGP synchronise : 8
bgpd: memstats: BGP Process queue : 1
bgpd: memstats: BGP node clear queue : 1
bgpd: memstats: NOTE: If configuration exists, utilization may be expected.
Example clean exit:
bgpd: memstats: No remaining tracked memory utilization.
This patch fixes bug #397: "Invalid free in bgp_announce_check()".
This patch fixes bug #492: "SIGBUS in bgpd/bgp_route.c:
bgp_clear_route_node()".
My apologies for not separating out these changes into individual patches.
The complexity of doing so boggled what is left of my brain. I hope this
is all still useful to the community.
This code has been production tested, in non-route-server-client mode, on
a linux 32-bit box and a 64-bit box.
Release/reset functions, used by bgp_exit(), added to:
bgpd/bgp_attr.c,h
bgpd/bgp_community.c,h
bgpd/bgp_dump.c,h
bgpd/bgp_ecommunity.c,h
bgpd/bgp_filter.c,h
bgpd/bgp_nexthop.c,h
bgpd/bgp_route.c,h
lib/routemap.c,h
File by file analysis:
* bgpd/bgp_aspath.c: Prevent re-use of ashash after it is released.
* bgpd/bgp_attr.c: #if removed uncalled cluster_dup().
* bgpd/bgp_clist.c,h: Allow community_list_terminate() to be called from
bgp_exit().
* bgpd/bgp_filter.c: Fix aslist->name use without allocation check, and
also fix memory leak.
* bgpd/bgp_main.c: Created bgp_exit() exit routine. This function frees
allocations made as part of bgpd initialization and, to some extent,
configuration. If "debug bgp" is configured, memory stats are printed
as described above.
* bgpd/bgp_nexthop.c: zclient_new() already allocates stream for
ibuf/obuf, so bgp_scan_init() shouldn't do it too. Also, made it so
zlookup is global so bgp_exit() can use it.
* bgpd/bgp_packet.c: bgp_capability_msg_parse() call to bgp_clear_route()
adjusted to use new BGP_CLEAR_ROUTE_NORMAL flag.
* bgpd/bgp_route.h: Correct reference counter "lock" to be signed.
bgp_clear_route() now accepts a bgp_clear_route_type of either
BGP_CLEAR_ROUTE_NORMAL or BGP_CLEAR_ROUTE_MY_RSCLIENT.
* bgpd/bgp_route.c:
- bgp_process_rsclient(): attr was being zero'ed and then
bgp_attr_extra_free() was being called with it, even though it was
never filled with valid data.
- bgp_process_rsclient(): Make sure rsclient->group is not NULL before
use.
- bgp_processq_del(): Add call to bgp_table_unlock().
- bgp_process(): Add call to bgp_table_lock().
- bgp_update_rsclient(): memset clearing of new_attr not needed since
declarationw with "= { 0 }" does it. memset was already commented
out.
- bgp_update_rsclient(): Fix screwed up misleading indentation.
- bgp_withdraw_rsclient(): Fix screwed up misleading indentation.
- bgp_clear_route_node(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_node_queue_del(): Add call to bgp_table_unlock() and also
free struct bgp_clear_node_queue used for work item.
- bgp_clear_node_complete(): Do peer_unlock() after BGP_EVENT_ADD() in
case peer is released by peer_unlock() call.
- bgp_clear_route_table(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT. Use
struct bgp_clear_node_queue to supply data to worker. Add call to
bgp_table_lock().
- bgp_clear_route(): Add support for BGP_CLEAR_ROUTE_NORMAL or
BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_route_all(): Use BGP_CLEAR_ROUTE_NORMAL.
Bug 397 fixes:
- bgp_default_originate()
- bgp_announce_table()
* bgpd/bgp_table.h:
- struct bgp_table: Added reference count. Changed type of owner to be
"struct peer *" rather than "void *".
- struct bgp_node: Correct reference counter "lock" to be signed.
* bgpd/bgp_table.c:
- Added bgp_table reference counting.
- bgp_table_free(): Fixed cleanup code. Call peer_unlock() on owner if
set.
- bgp_unlock_node(): Added assertion.
- bgp_node_get(): Added call to bgp_lock_node() to code path that it was
missing from.
* bgpd/bgp_vty.c:
- peer_rsclient_set_vty(): Call peer_lock() as part of peer assignment
to owner. Handle failure gracefully.
- peer_rsclient_unset_vty(): Add call to bgp_clear_route() with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
* bgpd/bgp_zebra.c: Made it so zclient is global so bgp_exit() can use it.
* bgpd/bgpd.c:
- peer_lock(): Allow to be called when status is "Deleted".
- peer_deactivate(): Supply BGP_CLEAR_ROUTE_NORMAL purpose to
bgp_clear_route() call.
- peer_delete(): Common variable listnode pn. Fix bug in which rsclient
was only dealt with if not part of a peer group. Call
bgp_clear_route() for rsclient, if appropriate, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- peer_group_get(): Use XSTRDUP() instead of strdup() for conf->host.
- peer_group_bind(): Call bgp_clear_route() for rsclient, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- bgp_create(): Use XSTRDUP() instead of strdup() for peer_self->host.
- bgp_delete(): Delete peers before groups, rather than after. And then
rather than deleting rsclients, verify that there are none at this
point.
- bgp_unlock(): Add assertion.
- bgp_free(): Call bgp_table_finish() rather than doing XFREE() itself.
* lib/command.c,h: Compiler warning fixes. Add cmd_terminate(). Fixed
massive leak in install_element() in which cmd_make_descvec() was being
called more than once for the same cmd->strvec/string/doc.
* lib/log.c: Make closezlog() check fp before calling fclose().
* lib/memory.c: Catch when alloc count goes negative by using signed
counts. Correct #endif comment. Add log_memstats_stderr().
* lib/memory.h: Add log_memstats_stderr().
* lib/thread.c: thread->funcname was being accessed in thread_call() after
it had been freed. Rearranged things so that thread_call() frees
funcname. Also made it so thread_master_free() cleans up cpu_record.
* lib/vty.c,h: Use global command_cr. Add vty_terminate().
* lib/zclient.c,h: Re-enable zclient_free().
2009-07-18 07:44:03 +02:00
|
|
|
bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
else
|
|
|
|
BGP_EVENT_ADD (peer, BGP_Stop);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
zlog_warn ("%s unrecognized capability code: %d - ignored",
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
peer->host, hdr->code);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
pnt += hdr->length + 3;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-06-18 13:34:43 +02:00
|
|
|
/* Dynamic Capability is received.
|
|
|
|
*
|
|
|
|
* This is exported for unit-test purposes
|
|
|
|
*/
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_capability_receive (struct peer *peer, bgp_size_t size)
|
|
|
|
{
|
|
|
|
u_char *pnt;
|
|
|
|
|
|
|
|
/* Fetch pointer. */
|
|
|
|
pnt = stream_pnt (peer->ibuf);
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
2004-12-08 22:03:23 +01:00
|
|
|
zlog_debug ("%s rcv CAPABILITY", peer->host);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If peer does not have the capability, send notification. */
|
|
|
|
if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_err ("%s [Error] BGP dynamic capability is not enabled",
|
2002-12-13 21:15:29 +01:00
|
|
|
peer->host);
|
|
|
|
bgp_notify_send (peer,
|
|
|
|
BGP_NOTIFY_HEADER_ERR,
|
|
|
|
BGP_NOTIFY_HEADER_BAD_MESTYPE);
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Status must be Established. */
|
|
|
|
if (peer->status != Established)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_err ("%s [Error] Dynamic capability packet received under status %s",
|
|
|
|
peer->host, LOOKUP (bgp_status_msg, peer->status));
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse packet. */
|
[bgpd] cleanup, compact and consolidate capability parsing code
2007-07-26 Paul Jakma <paul.jakma@sun.com>
* (general) Clean up and compact capability parsing slightly.
Consolidate validation of length and logging of generic TLV, and
memcpy of capability data, thus removing such from cap specifc
code (not always present or correct).
* bgp_open.h: Add structures for the generic capability TLV header
and for the data formats of the various specific capabilities we
support. Hence remove the badly named, or else misdefined, struct
capability.
* bgp_open.c: (bgp_capability_vty_out) Use struct capability_mp_data.
Do the length checks *before* memcpy()'ing based on that length
(stored capability - should have been validated anyway on input,
but..).
(bgp_afi_safi_valid_indices) new function to validate (afi,safi)
which is about to be used as index into arrays, consolidates
several instances of same, at least one of which appeared to be
incomplete..
(bgp_capability_mp) Much condensed.
(bgp_capability_orf_entry) New, process one ORF entry
(bgp_capability_orf) Condensed. Fixed to process all ORF entries.
(bgp_capability_restart) Condensed, and fixed to use a
cap-specific type, rather than abusing capability_mp.
(struct message capcode_str) added to aid generic logging.
(size_t cap_minsizes[]) added to aid generic validation of
capability length field.
(bgp_capability_parse) Generic logging and validation of TLV
consolidated here. Code compacted as much as possible.
* bgp_packet.c: (bgp_open_receive) Capability parsers now use
streams, so no more need here to manually fudge the input stream
getp.
(bgp_capability_msg_parse) use struct capability_mp_data. Validate
lengths /before/ memcpy. Use bgp_afi_safi_valid_indices.
(bgp_capability_receive) Exported for use by test harness.
* bgp_vty.c: (bgp_show_summary) fix conversion warning
(bgp_show_peer) ditto
* bgp_debug.h: Fix storage 'extern' after type 'const'.
* lib/log.c: (mes_lookup) warning about code not being in
same-number array slot should be debug, not warning. E.g. BGP
has several discontigious number spaces, allocating from
different parts of a space is not uncommon (e.g. IANA
assigned versus vendor-assigned code points in some number
space).
2007-08-06 17:21:45 +02:00
|
|
|
return bgp_capability_msg_parse (peer, pnt, size);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* BGP read utility function. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_read_packet (struct peer *peer)
|
|
|
|
{
|
|
|
|
int nbytes;
|
|
|
|
int readsize;
|
|
|
|
|
2005-02-09 16:51:56 +01:00
|
|
|
readsize = peer->packet_size - stream_get_endp (peer->ibuf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If size is zero then return. */
|
|
|
|
if (! readsize)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Read packet from fd. */
|
2010-08-05 19:26:23 +02:00
|
|
|
nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If read byte is smaller than zero then error occured. */
|
|
|
|
if (nbytes < 0)
|
|
|
|
{
|
2010-08-05 19:26:23 +02:00
|
|
|
/* Transient error should retry */
|
|
|
|
if (nbytes == -2)
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
|
2015-05-20 02:58:12 +02:00
|
|
|
zlog_err ("%s [Error] bgp_read_packet error: %s",
|
|
|
|
peer->host, safe_strerror (errno));
|
2005-02-02 15:40:33 +01:00
|
|
|
|
|
|
|
if (peer->status == Established)
|
|
|
|
{
|
|
|
|
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
|
|
|
|
{
|
|
|
|
peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
|
|
|
|
SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
peer->last_reset = PEER_DOWN_CLOSE_SESSION;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
BGP_EVENT_ADD (peer, TCP_fatal_error);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* When read byte is zero : clear bgp peer and return */
|
|
|
|
if (nbytes == 0)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("%s [Event] BGP connection closed fd %d",
|
|
|
|
peer->host, peer->fd);
|
2004-05-20 11:19:34 +02:00
|
|
|
|
|
|
|
if (peer->status == Established)
|
2005-02-02 15:40:33 +01:00
|
|
|
{
|
|
|
|
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
|
|
|
|
{
|
|
|
|
peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
|
|
|
|
SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
peer->last_reset = PEER_DOWN_CLOSE_SESSION;
|
|
|
|
}
|
2004-05-20 11:19:34 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
BGP_EVENT_ADD (peer, TCP_connection_closed);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We read partial packet. */
|
2005-02-09 16:51:56 +01:00
|
|
|
if (stream_get_endp (peer->ibuf) != peer->packet_size)
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Marker check. */
|
2005-06-28 14:44:16 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_marker_all_one (struct stream *s, int length)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
if (s->data[i] != 0xff)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-01-04 23:29:23 +01:00
|
|
|
/* Recent thread time.
|
|
|
|
On same clock base as bgp_clock (MONOTONIC)
|
|
|
|
but can be time of last context switch to bgp_read thread. */
|
|
|
|
static time_t
|
|
|
|
bgp_recent_clock (void)
|
|
|
|
{
|
|
|
|
return recent_relative_time().tv_sec;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Starting point of packet process function. */
|
|
|
|
int
|
|
|
|
bgp_read (struct thread *thread)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u_char type = 0;
|
|
|
|
struct peer *peer;
|
|
|
|
bgp_size_t size;
|
|
|
|
char notify_data_length[2];
|
2015-05-20 02:40:39 +02:00
|
|
|
u_int32_t notify_out;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Yes first of all get peer pointer. */
|
|
|
|
peer = THREAD_ARG (thread);
|
|
|
|
peer->t_read = NULL;
|
|
|
|
|
2015-05-20 02:40:39 +02:00
|
|
|
/* Note notify_out so we can check later to see if we sent another one */
|
|
|
|
notify_out = peer->notify_out;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* For non-blocking IO check. */
|
|
|
|
if (peer->status == Connect)
|
|
|
|
{
|
2015-05-20 02:47:21 +02:00
|
|
|
bgp_connect_check (peer, 1);
|
2002-12-13 21:15:29 +01:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-05-01 10:44:08 +02:00
|
|
|
if (peer->fd < 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-05-01 10:44:08 +02:00
|
|
|
zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2004-05-01 10:44:08 +02:00
|
|
|
BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Read packet header to determine type of the packet */
|
|
|
|
if (peer->packet_size == 0)
|
|
|
|
peer->packet_size = BGP_HEADER_SIZE;
|
|
|
|
|
2005-02-09 16:51:56 +01:00
|
|
|
if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
ret = bgp_read_packet (peer);
|
|
|
|
|
|
|
|
/* Header read error or partial read packet. */
|
|
|
|
if (ret < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Get size and type. */
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
|
2002-12-13 21:15:29 +01:00
|
|
|
memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
|
|
|
|
size = stream_getw (peer->ibuf);
|
|
|
|
type = stream_getc (peer->ibuf);
|
|
|
|
|
|
|
|
/* Marker check */
|
2004-07-09 14:11:31 +02:00
|
|
|
if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
|
2002-12-13 21:15:29 +01:00
|
|
|
&& ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
|
|
|
|
{
|
|
|
|
bgp_notify_send (peer,
|
|
|
|
BGP_NOTIFY_HEADER_ERR,
|
|
|
|
BGP_NOTIFY_HEADER_NOT_SYNC);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BGP type check. */
|
|
|
|
if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
|
|
|
|
&& type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
|
|
|
|
&& type != BGP_MSG_ROUTE_REFRESH_NEW
|
|
|
|
&& type != BGP_MSG_ROUTE_REFRESH_OLD
|
|
|
|
&& type != BGP_MSG_CAPABILITY)
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("%s unknown message type 0x%02x",
|
|
|
|
peer->host, type);
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_HEADER_ERR,
|
|
|
|
BGP_NOTIFY_HEADER_BAD_MESTYPE,
|
|
|
|
&type, 1);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
/* Mimimum packet length check. */
|
|
|
|
if ((size < BGP_HEADER_SIZE)
|
|
|
|
|| (size > BGP_MAX_PACKET_SIZE)
|
|
|
|
|| (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
|
|
|
|
|| (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
|
|
|
|
|| (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
|
|
|
|
|| (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
|
|
|
|
|| (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
|
|
|
|
|| (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
|
|
|
|
|| (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
|
|
|
|
{
|
2015-05-20 02:58:12 +02:00
|
|
|
if (bgp_debug_neighbor_events(peer))
|
|
|
|
zlog_debug ("%s bad message length - %d for %s",
|
|
|
|
peer->host, size,
|
|
|
|
type == 128 ? "ROUTE-REFRESH" :
|
|
|
|
bgp_type_str[(int) type]);
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_notify_send_with_data (peer,
|
|
|
|
BGP_NOTIFY_HEADER_ERR,
|
|
|
|
BGP_NOTIFY_HEADER_BAD_MESLEN,
|
2004-09-26 18:09:34 +02:00
|
|
|
(u_char *) notify_data_length, 2);
|
2002-12-13 21:15:29 +01:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adjust size to message length. */
|
|
|
|
peer->packet_size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = bgp_read_packet (peer);
|
|
|
|
if (ret < 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
/* Get size and type again. */
|
|
|
|
size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
|
|
|
|
type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
|
|
|
|
|
|
|
|
/* BGP packet dump function. */
|
|
|
|
bgp_dump_packet (peer, type, peer->ibuf);
|
|
|
|
|
|
|
|
size = (peer->packet_size - BGP_HEADER_SIZE);
|
|
|
|
|
|
|
|
/* Read rest of the packet and call each sort of packet routine */
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case BGP_MSG_OPEN:
|
|
|
|
peer->open_in++;
|
2004-07-09 14:11:31 +02:00
|
|
|
bgp_open_receive (peer, size); /* XXX return value ignored! */
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case BGP_MSG_UPDATE:
|
2013-01-04 23:29:23 +01:00
|
|
|
peer->readtime = bgp_recent_clock ();
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_update_receive (peer, size);
|
|
|
|
break;
|
|
|
|
case BGP_MSG_NOTIFY:
|
|
|
|
bgp_notify_receive (peer, size);
|
|
|
|
break;
|
|
|
|
case BGP_MSG_KEEPALIVE:
|
2013-01-04 23:29:23 +01:00
|
|
|
peer->readtime = bgp_recent_clock ();
|
2002-12-13 21:15:29 +01:00
|
|
|
bgp_keepalive_receive (peer, size);
|
|
|
|
break;
|
|
|
|
case BGP_MSG_ROUTE_REFRESH_NEW:
|
|
|
|
case BGP_MSG_ROUTE_REFRESH_OLD:
|
|
|
|
peer->refresh_in++;
|
|
|
|
bgp_route_refresh_receive (peer, size);
|
|
|
|
break;
|
|
|
|
case BGP_MSG_CAPABILITY:
|
|
|
|
peer->dynamic_cap_in++;
|
|
|
|
bgp_capability_receive (peer, size);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:40:39 +02:00
|
|
|
/* If reading this packet caused us to send a NOTIFICATION then store a copy
|
|
|
|
* of the packet for troubleshooting purposes
|
|
|
|
*/
|
|
|
|
if (notify_out < peer->notify_out)
|
|
|
|
{
|
|
|
|
memcpy(peer->last_reset_cause, peer->ibuf->data, peer->packet_size);
|
|
|
|
peer->last_reset_cause_size = peer->packet_size;
|
|
|
|
notify_out = peer->notify_out;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Clear input buffer. */
|
|
|
|
peer->packet_size = 0;
|
|
|
|
if (peer->ibuf)
|
|
|
|
stream_reset (peer->ibuf);
|
|
|
|
|
|
|
|
done:
|
2015-05-20 02:40:39 +02:00
|
|
|
/* If reading this packet caused us to send a NOTIFICATION then store a copy
|
|
|
|
* of the packet for troubleshooting purposes
|
|
|
|
*/
|
|
|
|
if (notify_out < peer->notify_out)
|
|
|
|
{
|
|
|
|
memcpy(peer->last_reset_cause, peer->ibuf->data, peer->packet_size);
|
|
|
|
peer->last_reset_cause_size = peer->packet_size;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|