#include "plist.h"
#include "queue.h"
#include "filter.h"
+#include "lib_errors.h"
#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_errors.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_label.h"
#include "bgpd/bgp_io.h"
#include "bgpd/bgp_keepalives.h"
+#include "bgpd/bgp_flowspec.h"
/**
* Sets marker and type fields for a BGP message.
* @param type the packet type
* @return the size of the stream
*/
-int bgp_packet_set_marker(struct stream *s, u_char type)
+int bgp_packet_set_marker(struct stream *s, uint8_t type)
{
int i;
PEER_STATUS_EOR_RECEIVED)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- " afi %d safi %d didnt receive EOR",
+ " afi %d safi %d didn't receive EOR",
afi, safi);
return;
}
packet);
case SAFI_EVPN:
return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
+ case SAFI_FLOWSPEC:
+ return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
}
return -1;
}
void bgp_open_send(struct peer *peer)
{
struct stream *s;
- u_int16_t send_holdtime;
+ uint16_t send_holdtime;
as_t local_as;
- if (PEER_OR_GROUP_TIMER_SET(peer))
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
send_holdtime = peer->holdtime;
else
send_holdtime = peer->bgp->default_holdtime;
/* Set open packet values. */
stream_putc(s, BGP_VERSION_4); /* BGP version */
- stream_putw(s,
- (local_as <= BGP_AS_MAX) ? (u_int16_t)local_as
- : BGP_AS_TRANS);
+ stream_putw(s, (local_as <= BGP_AS_MAX) ? (uint16_t)local_as
+ : BGP_AS_TRANS);
stream_putw(s, send_holdtime); /* Hold Time */
stream_put_in_addr(s, &peer->local_id); /* BGP Identifier */
static int bgp_write_notify(struct peer *peer)
{
int ret, val;
- u_char type;
+ uint8_t type;
struct stream *s;
/* There should be at least one packet. */
* @param data Data portion
* @param datalen length of data portion
*/
-void bgp_notify_send_with_data(struct peer *peer, u_char code, u_char sub_code,
- u_char *data, size_t datalen)
+void bgp_notify_send_with_data(struct peer *peer, uint8_t code,
+ uint8_t sub_code, uint8_t *data, size_t datalen)
{
struct stream *s;
- int length;
/* Lock I/O mutex to prevent other threads from pushing packets */
pthread_mutex_lock(&peer->io_mtx);
stream_write(s, data, datalen);
/* Set BGP packet length. */
- length = bgp_packet_set_size(s);
+ bgp_packet_set_size(s);
/* wipe output buffer */
stream_fifo_clean(peer->obuf);
bgp_notify.code = code;
bgp_notify.subcode = sub_code;
bgp_notify.data = NULL;
- bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
+ bgp_notify.length = datalen;
bgp_notify.raw_data = data;
peer->notify.code = bgp_notify.code;
peer->notify.subcode = bgp_notify.subcode;
- if (bgp_notify.length) {
+ if (bgp_notify.length && data) {
bgp_notify.data =
XMALLOC(MTYPE_TMP, bgp_notify.length * 3);
for (i = 0; i < bgp_notify.length; i++)
* @param code BGP error code
* @param sub_code BGP error subcode
*/
-void bgp_notify_send(struct peer *peer, u_char code, u_char sub_code)
+void bgp_notify_send(struct peer *peer, uint8_t code, uint8_t sub_code)
{
bgp_notify_send_with_data(peer, code, sub_code, NULL, 0);
}
* @param remove Whether to remove ORF for specified AFI/SAFI
*/
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)
+ uint8_t orf_type, uint8_t when_to_refresh,
+ int remove)
{
struct stream *s;
struct bgp_filter *filter;
if (orf_type == ORF_TYPE_PREFIX || orf_type == ORF_TYPE_PREFIX_OLD)
if (remove || filter->plist[FILTER_IN].plist) {
- u_int16_t orf_len;
+ uint16_t orf_len;
unsigned long orfp;
orf_refresh = 1;
static int 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;
+ uint8_t version;
+ uint8_t optlen;
+ uint16_t holdtime;
+ uint16_t send_holdtime;
as_t remote_as;
as_t as4 = 0;
struct in_addr remote_id;
int mp_capability;
- u_int8_t notify_data_remote_as[2];
- u_int8_t notify_data_remote_as4[4];
- u_int8_t notify_data_remote_id[4];
- u_int16_t *holdtime_ptr;
+ uint8_t notify_data_remote_as[2];
+ uint8_t notify_data_remote_as4[4];
+ uint8_t notify_data_remote_id[4];
+ uint16_t *holdtime_ptr;
/* Parse open packet. */
version = stream_getc(peer->curr);
memcpy(notify_data_remote_as, stream_pnt(peer->curr), 2);
remote_as = stream_getw(peer->curr);
- holdtime_ptr = (u_int16_t *)stream_pnt(peer->curr);
+ holdtime_ptr = (uint16_t *)stream_pnt(peer->curr);
holdtime = stream_getw(peer->curr);
memcpy(notify_data_remote_id, stream_pnt(peer->curr), 4);
remote_id.s_addr = stream_get_ipv4(peer->curr);
/* 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",
+ flog_err(EC_BGP_PKT_OPEN,
+ "%s bad OPEN, got AS4 capability, but AS4 set to 0",
peer->host);
bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_BAD_PEER_AS,
* BGP_AS_TRANS, for some unknown reason.
*/
if (as4 == BGP_AS_TRANS) {
- zlog_err(
+ flog_err(
+ EC_BGP_PKT_OPEN,
"%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
peer->host);
bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
&& as4 != remote_as) {
/* raise error, log this, close session */
- zlog_err(
+ flog_err(
+ EC_BGP_PKT_OPEN,
"%s bad OPEN, got AS4 capability, but remote_as %u"
" mismatch with 16bit 'myasn' %u in open",
peer->host, as4, remote_as);
/* Peer BGP version check. */
if (version != BGP_VERSION_4) {
- u_int16_t maxver = htons(BGP_VERSION_4);
+ uint16_t maxver = htons(BGP_VERSION_4);
/* XXX this reply may not be correct if version < 4 XXX */
if (bgp_debug_neighbor_events(peer))
zlog_debug(
/* Data must be in network byte order here */
bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNSUP_VERSION,
- (u_int8_t *)&maxver, 2);
+ (uint8_t *)&maxver, 2);
return BGP_Stop;
}
if (holdtime < 3 && holdtime != 0) {
bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
- (u_char *)holdtime_ptr, 2);
+ (uint8_t *)holdtime_ptr, 2);
return BGP_Stop;
}
implementation MAY adjust the rate at which it sends KEEPALIVE
messages as a function of the Hold Time interval. */
- if (PEER_OR_GROUP_TIMER_SET(peer))
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
send_holdtime = peer->holdtime;
else
send_holdtime = peer->bgp->default_holdtime;
else
peer->v_holdtime = send_holdtime;
- if ((PEER_OR_GROUP_TIMER_SET(peer))
+ if ((CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
&& (peer->keepalive < peer->v_holdtime / 3))
peer->v_keepalive = peer->keepalive;
else
peer->afc[AFI_IP][SAFI_MULTICAST];
peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] =
peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
+ peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] =
+ peer->afc[AFI_IP][SAFI_FLOWSPEC];
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_LABELED_UNICAST];
peer->afc_nego[AFI_L2VPN][SAFI_EVPN] =
peer->afc[AFI_L2VPN][SAFI_EVPN];
+ peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] =
+ peer->afc[AFI_IP6][SAFI_FLOWSPEC];
}
/* When collision is detected and this peer is closed. Retrun
/* Get sockname. */
if ((ret = bgp_getsockname(peer)) < 0) {
- zlog_err("%s: bgp_getsockname() failed for peer: %s",
- __FUNCTION__, peer->host);
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s: bgp_getsockname() failed for peer: %s",
+ __FUNCTION__, peer->host);
return BGP_Stop;
}
|| peer->afc_nego[AFI_IP][SAFI_ENCAP]) {
if (!peer->nexthop.v4.s_addr) {
#if defined(HAVE_CUMULUS)
- zlog_err(
+ flog_err(
+ EC_BGP_SND_FAIL,
"%s: No local IPv4 addr resetting connection, fd %d",
peer->host, peer->fd);
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
|| peer->afc_nego[AFI_IP6][SAFI_ENCAP]) {
if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) {
#if defined(HAVE_CUMULUS)
- zlog_err(
+ flog_err(
+ EC_BGP_SND_FAIL,
"%s: No local IPv6 addr resetting connection, fd %d",
peer->host, peer->fd);
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
static int bgp_update_receive(struct peer *peer, bgp_size_t size)
{
int ret, nlri_ret;
- u_char *end;
+ uint8_t *end;
struct stream *s;
struct attr attr;
bgp_size_t attribute_len;
/* Status must be Established. */
if (peer->status != Established) {
- zlog_err("%s [FSM] Update packet received under status %s",
+ flog_err(EC_BGP_INVALID_STATUS,
+ "%s [FSM] Update packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
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);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%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 BGP_Stop;
/* 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);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%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 BGP_Stop;
/* Attribute total length check. */
if (stream_pnt(s) + 2 > end) {
- zlog_warn(
- "%s [Error] Packet Error"
- " (update packet is short for attribute length)",
+ flog_warn(
+ EC_BGP_UPDATE_PACKET_SHORT,
+ "%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);
/* Attribute length check. */
if (stream_pnt(s) + attribute_len > end) {
- zlog_warn(
- "%s [Error] Packet Error"
- " (update packet attribute length overflow %d)",
+ flog_warn(
+ EC_BGP_UPDATE_PACKET_LONG,
+ "%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);
ret = bgp_dump_attr(&attr, peer->rcvd_attr_str, BUFSIZ);
if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
- zlog_err(
+ flog_err(
+ EC_BGP_UPDATE_RCV,
"%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
peer->host);
}
if (nlri_ret < 0) {
- zlog_err("%s [Error] Error parsing NLRI", peer->host);
+ flog_err(EC_BGP_UPDATE_RCV,
+ "%s [Error] Error parsing NLRI", peer->host);
if (peer->status == Established)
bgp_notify_send(
peer, BGP_NOTIFY_UPDATE_ERR,
stream_getc(peer->curr));
strcpy(bgp_notify.data, c);
}
- bgp_notify.raw_data = (u_char *)peer->notify.data;
+ bgp_notify.raw_data = (uint8_t *)peer->notify.data;
}
bgp_notify_print(peer, &bgp_notify, "received");
/* If peer does not have the capability, send notification. */
if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) {
- zlog_err("%s [Error] BGP route refresh is not enabled",
+ flog_err(EC_BGP_NO_CAP,
+ "%s [Error] BGP route refresh is not enabled",
peer->host);
bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
BGP_NOTIFY_HEADER_BAD_MESTYPE);
/* Status must be Established. */
if (peer->status != Established) {
- zlog_err(
+ flog_err(
+ EC_BGP_INVALID_STATUS,
"%s [Error] Route refresh packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
}
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;
+ uint8_t *end;
+ uint8_t when_to_refresh;
+ uint8_t orf_type;
+ uint16_t orf_len;
if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
< 5) {
uint8_t *p_pnt = stream_pnt(s);
uint8_t *p_end = stream_pnt(s) + orf_len;
struct orf_prefix orfp;
- u_char common = 0;
- u_int32_t seq;
+ uint8_t common = 0;
+ uint32_t seq;
int psize;
char name[BUFSIZ];
int ret = CMD_SUCCESS;
name);
break;
}
- ok = ((u_int32_t)(p_end - p_pnt)
- >= sizeof(u_int32_t));
+ ok = ((uint32_t)(p_end - p_pnt)
+ >= sizeof(uint32_t));
if (ok) {
memcpy(&seq, p_pnt,
- sizeof(u_int32_t));
- p_pnt += sizeof(u_int32_t);
+ sizeof(uint32_t));
+ p_pnt += sizeof(uint32_t);
orfp.seq = ntohl(seq);
} else
p_pnt = p_end;
* @param size size of the packet
* @return as in summary
*/
-static int bgp_capability_msg_parse(struct peer *peer, u_char *pnt,
+static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
bgp_size_t length)
{
- u_char *end;
+ uint8_t *end;
struct capability_mp_data mpc;
struct capability_header *hdr;
- u_char action;
+ uint8_t action;
iana_afi_t pkt_afi;
afi_t afi;
iana_safi_t pkt_safi;
return BGP_Stop;
}
} else {
- zlog_warn(
+ flog_warn(
+ EC_BGP_UNRECOGNIZED_CAPABILITY,
"%s unrecognized capability code: %d - ignored",
peer->host, hdr->code);
}
*/
int bgp_capability_receive(struct peer *peer, bgp_size_t size)
{
- u_char *pnt;
+ uint8_t *pnt;
/* Fetch pointer. */
pnt = stream_pnt(peer->curr);
/* If peer does not have the capability, send notification. */
if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) {
- zlog_err("%s [Error] BGP dynamic capability is not enabled",
+ flog_err(EC_BGP_NO_CAP,
+ "%s [Error] BGP dynamic capability is not enabled",
peer->host);
bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
BGP_NOTIFY_HEADER_BAD_MESTYPE);
/* Status must be Established. */
if (peer->status != Established) {
- zlog_err(
+ flog_err(
+ EC_BGP_NO_CAP,
"%s [Error] Dynamic capability packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
unsigned int processed = 0;
while (processed < rpkt_quanta_old) {
- u_char type = 0;
+ uint8_t type = 0;
bgp_size_t size;
char notify_data_length[2];
memory_order_relaxed);
mprc = bgp_open_receive(peer, size);
if (mprc == BGP_Stop)
- zlog_err(
+ flog_err(
+ EC_BGP_PKT_OPEN,
"%s: BGP OPEN receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
peer->readtime = monotime(NULL);
mprc = bgp_update_receive(peer, size);
if (mprc == BGP_Stop)
- zlog_err(
+ flog_err(
+ EC_BGP_UPDATE_RCV,
"%s: BGP UPDATE receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
memory_order_relaxed);
mprc = bgp_notify_receive(peer, size);
if (mprc == BGP_Stop)
- zlog_err(
+ flog_err(
+ EC_BGP_NOTIFY_RCV,
"%s: BGP NOTIFY receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
memory_order_relaxed);
mprc = bgp_keepalive_receive(peer, size);
if (mprc == BGP_Stop)
- zlog_err(
+ flog_err(
+ EC_BGP_KEEP_RCV,
"%s: BGP KEEPALIVE receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
memory_order_relaxed);
mprc = bgp_route_refresh_receive(peer, size);
if (mprc == BGP_Stop)
- zlog_err(
+ flog_err(
+ EC_BGP_RFSH_RCV,
"%s: BGP ROUTEREFRESH receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;
memory_order_relaxed);
mprc = bgp_capability_receive(peer, size);
if (mprc == BGP_Stop)
- zlog_err(
+ flog_err(
+ EC_BGP_CAP_RCV,
"%s: BGP CAPABILITY receipt failed for peer: %s",
__FUNCTION__, peer->host);
break;