summaryrefslogtreecommitdiff
path: root/bgpd/bgp_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_packet.c')
-rw-r--r--bgpd/bgp_packet.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 0e251dced8..7137c1a784 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -587,7 +587,7 @@ void bgp_open_send(struct peer *peer)
* @param peer
* @return 0
*/
-static int bgp_write_notify(struct peer *peer)
+static void bgp_write_notify(struct peer *peer)
{
int ret, val;
uint8_t type;
@@ -597,7 +597,7 @@ static int bgp_write_notify(struct peer *peer)
s = stream_fifo_pop(peer->obuf);
if (!s)
- return 0;
+ return;
assert(stream_get_endp(s) >= BGP_HEADER_SIZE);
@@ -617,7 +617,7 @@ static int bgp_write_notify(struct peer *peer)
if (ret <= 0) {
stream_free(s);
BGP_EVENT_ADD(peer, TCP_fatal_error);
- return 0;
+ return;
}
/* Disable Nagle, make NOTIFY packet go out right away */
@@ -649,8 +649,6 @@ static int bgp_write_notify(struct peer *peer)
BGP_EVENT_ADD(peer, BGP_Stop);
stream_free(s);
-
- return 0;
}
/*
@@ -976,14 +974,21 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id)
return -1;
} else if ((peer->status == OpenConfirm)
|| (peer->status == OpenSent)) {
- /* 1. The BGP Identifier of the local system is compared
- to
- the BGP Identifier of the remote system (as specified
- in
- the OPEN message). */
-
+ /* 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 the BGP Identifiers of the peers
+ * involved in the connection collision
+ * are identical, then the connection
+ * initiated by the BGP speaker with the
+ * larger AS number is preserved.
+ */
if (ntohl(peer->local_id.s_addr)
- < ntohl(remote_id.s_addr))
+ < ntohl(remote_id.s_addr)
+ || (ntohl(peer->local_id.s_addr)
+ == ntohl(remote_id.s_addr)
+ && peer->local_as < peer->as))
if (!CHECK_FLAG(peer->sflags,
PEER_STATUS_ACCEPT_PEER)) {
/* 2. If the value of the local BGP
@@ -1007,10 +1012,13 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id)
return -1;
}
else {
- if (ntohl(peer->local_id.s_addr) ==
- ntohl(remote_id.s_addr))
- flog_err(EC_BGP_ROUTER_ID_SAME, "Peer's router-id %s is the same as ours",
- inet_ntoa(remote_id));
+ if (ntohl(peer->local_id.s_addr)
+ == ntohl(remote_id.s_addr)
+ && peer->local_as == peer->as)
+ flog_err(
+ EC_BGP_ROUTER_ID_SAME,
+ "Peer's router-id %s is the same as ours",
+ inet_ntoa(remote_id));
/* 3. Otherwise, the local system closes newly
created
@@ -1142,6 +1150,15 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
return BGP_Stop;
}
+ /* Codification of AS 0 Processing */
+ if (remote_as == BGP_AS_ZERO) {
+ flog_err(EC_BGP_PKT_OPEN, "%s bad OPEN, got AS set to 0",
+ peer->host);
+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+ BGP_NOTIFY_OPEN_BAD_PEER_AS);
+ return BGP_Stop;
+ }
+
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
@@ -1190,10 +1207,17 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
}
}
- /* remote router-id check. */
+ /* rfc6286:
+ * If the BGP Identifier field of the OPEN message
+ * is zero, or if it is the same as the BGP Identifier
+ * of the local BGP speaker and the message is from an
+ * internal peer, then the Error Subcode is set to
+ * "Bad BGP Identifier".
+ */
if (remote_id.s_addr == INADDR_ANY
|| IPV4_CLASS_DE(ntohl(remote_id.s_addr))
- || ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)) {
+ || (peer->sort == BGP_PEER_IBGP
+ && ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr))) {
if (bgp_debug_neighbor_events(peer))
zlog_debug("%s bad OPEN, wrong router identifier %s",
peer->host, inet_ntoa(remote_id));
@@ -1338,8 +1362,9 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
peer->afc[AFI_IP6][SAFI_FLOWSPEC];
}
- /* When collision is detected and this peer is closed. Retrun
- immidiately. */
+ /* When collision is detected and this peer is closed.
+ * Return immediately.
+ */
ret = bgp_collision_detect(peer, remote_id);
if (ret < 0)
return BGP_Stop;
@@ -1447,7 +1472,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
- BGP_NOTIFY_SUBCODE_UNSPECIFIC);
+ bgp_fsm_error_subcode(peer->status));
return BGP_Stop;
}
@@ -1859,7 +1884,7 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
- BGP_NOTIFY_SUBCODE_UNSPECIFIC);
+ bgp_fsm_error_subcode(peer->status));
return BGP_Stop;
}
@@ -2251,7 +2276,7 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size)
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
- BGP_NOTIFY_SUBCODE_UNSPECIFIC);
+ bgp_fsm_error_subcode(peer->status));
return BGP_Stop;
}
@@ -2328,7 +2353,7 @@ int bgp_process_packet(struct thread *thread)
flog_err(
EC_BGP_PKT_OPEN,
"%s: BGP OPEN receipt failed for peer: %s",
- __FUNCTION__, peer->host);
+ __func__, peer->host);
break;
case BGP_MSG_UPDATE:
atomic_fetch_add_explicit(&peer->update_in, 1,
@@ -2339,7 +2364,7 @@ int bgp_process_packet(struct thread *thread)
flog_err(
EC_BGP_UPDATE_RCV,
"%s: BGP UPDATE receipt failed for peer: %s",
- __FUNCTION__, peer->host);
+ __func__, peer->host);
break;
case BGP_MSG_NOTIFY:
atomic_fetch_add_explicit(&peer->notify_in, 1,
@@ -2349,7 +2374,7 @@ int bgp_process_packet(struct thread *thread)
flog_err(
EC_BGP_NOTIFY_RCV,
"%s: BGP NOTIFY receipt failed for peer: %s",
- __FUNCTION__, peer->host);
+ __func__, peer->host);
break;
case BGP_MSG_KEEPALIVE:
peer->readtime = monotime(NULL);
@@ -2360,7 +2385,7 @@ int bgp_process_packet(struct thread *thread)
flog_err(
EC_BGP_KEEP_RCV,
"%s: BGP KEEPALIVE receipt failed for peer: %s",
- __FUNCTION__, peer->host);
+ __func__, peer->host);
break;
case BGP_MSG_ROUTE_REFRESH_NEW:
case BGP_MSG_ROUTE_REFRESH_OLD:
@@ -2371,7 +2396,7 @@ int bgp_process_packet(struct thread *thread)
flog_err(
EC_BGP_RFSH_RCV,
"%s: BGP ROUTEREFRESH receipt failed for peer: %s",
- __FUNCTION__, peer->host);
+ __func__, peer->host);
break;
case BGP_MSG_CAPABILITY:
atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1,
@@ -2381,7 +2406,7 @@ int bgp_process_packet(struct thread *thread)
flog_err(
EC_BGP_CAP_RCV,
"%s: BGP CAPABILITY receipt failed for peer: %s",
- __FUNCTION__, peer->host);
+ __func__, peer->host);
break;
default:
/* Suppress uninitialized variable warning */