diff options
Diffstat (limited to 'bgpd/bgp_packet.c')
| -rw-r--r-- | bgpd/bgp_packet.c | 83 |
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 */ |
