]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_packet.c
tools: Convert type int functions to bool where possible
[mirror_frr.git] / bgpd / bgp_packet.c
CommitLineData
718e3744 1/* BGP packet management routine.
56257a44
QY
2 * Contains utility functions for constructing and consuming BGP messages.
3 * Copyright (C) 2017 Cumulus Networks
896014f4
DL
4 * Copyright (C) 1999 Kunihiro Ishiguro
5 *
6 * This file is part of GNU Zebra.
7 *
8 * GNU Zebra is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * GNU Zebra is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
718e3744 22
23#include <zebra.h>
d3ecc69e 24#include <sys/time.h>
718e3744 25
26#include "thread.h"
27#include "stream.h"
28#include "network.h"
29#include "prefix.h"
30#include "command.h"
31#include "log.h"
32#include "memory.h"
d62a17ae 33#include "sockunion.h" /* for inet_ntop () */
baa376fc 34#include "sockopt.h"
718e3744 35#include "linklist.h"
36#include "plist.h"
3f9c7369 37#include "queue.h"
039f3a34 38#include "filter.h"
02705213 39#include "lib_errors.h"
718e3744 40
41#include "bgpd/bgpd.h"
42#include "bgpd/bgp_table.h"
43#include "bgpd/bgp_dump.h"
6c29258c 44#include "bgpd/bgp_bmp.h"
718e3744 45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_debug.h"
14454c9f 47#include "bgpd/bgp_errors.h"
718e3744 48#include "bgpd/bgp_fsm.h"
49#include "bgpd/bgp_route.h"
50#include "bgpd/bgp_packet.h"
51#include "bgpd/bgp_open.h"
52#include "bgpd/bgp_aspath.h"
53#include "bgpd/bgp_community.h"
54#include "bgpd/bgp_ecommunity.h"
57d187bc 55#include "bgpd/bgp_lcommunity.h"
718e3744 56#include "bgpd/bgp_network.h"
57#include "bgpd/bgp_mplsvpn.h"
7ef5a232 58#include "bgpd/bgp_evpn.h"
718e3744 59#include "bgpd/bgp_advertise.h"
93406d87 60#include "bgpd/bgp_vty.h"
3f9c7369 61#include "bgpd/bgp_updgrp.h"
cd1964ff 62#include "bgpd/bgp_label.h"
56257a44 63#include "bgpd/bgp_io.h"
934af458 64#include "bgpd/bgp_keepalives.h"
7c40bf39 65#include "bgpd/bgp_flowspec.h"
718e3744 66
584470fb
DL
67DEFINE_HOOK(bgp_packet_dump,
68 (struct peer *peer, uint8_t type, bgp_size_t size,
69 struct stream *s),
70 (peer, type, size, s))
71
6fd04594
DL
72DEFINE_HOOK(bgp_packet_send,
73 (struct peer *peer, uint8_t type, bgp_size_t size,
74 struct stream *s),
75 (peer, type, size, s))
76
d8151687
QY
77/**
78 * Sets marker and type fields for a BGP message.
79 *
80 * @param s the stream containing the packet
81 * @param type the packet type
82 * @return the size of the stream
83 */
d7c0a89a 84int bgp_packet_set_marker(struct stream *s, uint8_t type)
718e3744 85{
d62a17ae 86 int i;
718e3744 87
d62a17ae 88 /* Fill in marker. */
89 for (i = 0; i < BGP_MARKER_SIZE; i++)
90 stream_putc(s, 0xff);
718e3744 91
d62a17ae 92 /* Dummy total length. This field is should be filled in later on. */
93 stream_putw(s, 0);
718e3744 94
d62a17ae 95 /* BGP packet type. */
96 stream_putc(s, type);
718e3744 97
d62a17ae 98 /* Return current stream size. */
99 return stream_get_endp(s);
718e3744 100}
101
d8151687
QY
102/**
103 * Sets size field for a BGP message.
104 *
105 * Size field is set to the size of the stream passed.
106 *
107 * @param s the stream containing the packet
108 * @return the size of the stream
109 */
d62a17ae 110int bgp_packet_set_size(struct stream *s)
718e3744 111{
d62a17ae 112 int cp;
718e3744 113
d62a17ae 114 /* Preserve current pointer. */
115 cp = stream_get_endp(s);
116 stream_putw_at(s, BGP_MARKER_SIZE, cp);
718e3744 117
d62a17ae 118 return cp;
718e3744 119}
120
d3ecc69e
QY
121/*
122 * Push a packet onto the beginning of the peer's output queue.
123 * This function acquires the peer's write mutex before proceeding.
124 */
125static void bgp_packet_add(struct peer *peer, struct stream *s)
126{
00dffa8c
DL
127 frr_with_mutex(&peer->io_mtx) {
128 stream_fifo_push(peer->obuf, s);
129 }
718e3744 130}
131
d62a17ae 132static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
133 safi_t safi)
93406d87 134{
d62a17ae 135 struct stream *s;
136 iana_afi_t pkt_afi;
5c525538 137 iana_safi_t pkt_safi;
d62a17ae 138
139 if (DISABLE_BGP_ANNOUNCE)
140 return NULL;
141
142 if (bgp_debug_neighbor_events(peer))
143 zlog_debug("send End-of-RIB for %s to %s",
5cb5f4d0 144 get_afi_safi_str(afi, safi, false), peer->host);
d62a17ae 145
146 s = stream_new(BGP_MAX_PACKET_SIZE);
147
148 /* Make BGP update packet. */
149 bgp_packet_set_marker(s, BGP_MSG_UPDATE);
150
151 /* Unfeasible Routes Length */
152 stream_putw(s, 0);
153
154 if (afi == AFI_IP && safi == SAFI_UNICAST) {
155 /* Total Path Attribute Length */
156 stream_putw(s, 0);
157 } else {
158 /* Convert AFI, SAFI to values for packet. */
159 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
160
161 /* Total Path Attribute Length */
162 stream_putw(s, 6);
163 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
164 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
165 stream_putc(s, 3);
166 stream_putw(s, pkt_afi);
167 stream_putc(s, pkt_safi);
168 }
169
170 bgp_packet_set_size(s);
d62a17ae 171 return s;
718e3744 172}
173
d8151687
QY
174/* Called when there is a change in the EOR(implicit or explicit) status of a
175 * peer. Ends the update-delay if all expected peers are done with EORs. */
176void bgp_check_update_delay(struct bgp *bgp)
177{
178 struct listnode *node, *nnode;
179 struct peer *peer = NULL;
180
181 if (bgp_debug_neighbor_events(peer))
182 zlog_debug("Checking update delay, T: %d R: %d I:%d E: %d",
183 bgp->established, bgp->restarted_peers,
184 bgp->implicit_eors, bgp->explicit_eors);
185
186 if (bgp->established
187 <= bgp->restarted_peers + bgp->implicit_eors + bgp->explicit_eors) {
becedef6
QY
188 /*
189 * This is an extra sanity check to make sure we wait for all
190 * the eligible configured peers. This check is performed if
191 * establish wait timer is on, or establish wait option is not
192 * given with the update-delay command
193 */
d8151687
QY
194 if (bgp->t_establish_wait
195 || (bgp->v_establish_wait == bgp->v_update_delay))
196 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
197 if (CHECK_FLAG(peer->flags,
198 PEER_FLAG_CONFIG_NODE)
199 && !CHECK_FLAG(peer->flags,
200 PEER_FLAG_SHUTDOWN)
201 && !peer->update_delay_over) {
202 if (bgp_debug_neighbor_events(peer))
203 zlog_debug(
204 " Peer %s pending, continuing read-only mode",
205 peer->host);
206 return;
207 }
208 }
209
210 zlog_info(
211 "Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d",
212 bgp->restarted_peers, bgp->implicit_eors,
213 bgp->explicit_eors);
214 bgp_update_delay_end(bgp);
215 }
216}
217
becedef6
QY
218/*
219 * Called if peer is known to have restarted. The restart-state bit in
220 * Graceful-Restart capability is used for that
221 */
d8151687
QY
222void bgp_update_restarted_peers(struct peer *peer)
223{
224 if (!bgp_update_delay_active(peer->bgp))
225 return; /* BGP update delay has ended */
226 if (peer->update_delay_over)
227 return; /* This peer has already been considered */
228
229 if (bgp_debug_neighbor_events(peer))
230 zlog_debug("Peer %s: Checking restarted", peer->host);
231
232 if (peer->status == Established) {
233 peer->update_delay_over = 1;
234 peer->bgp->restarted_peers++;
235 bgp_check_update_delay(peer->bgp);
236 }
237}
238
becedef6
QY
239/*
240 * Called as peer receives a keep-alive. Determines if this occurence can be
241 * taken as an implicit EOR for this peer.
242 * NOTE: The very first keep-alive after the Established state of a peer is
243 * considered implicit EOR for the update-delay purposes
244 */
d8151687
QY
245void bgp_update_implicit_eors(struct peer *peer)
246{
247 if (!bgp_update_delay_active(peer->bgp))
248 return; /* BGP update delay has ended */
249 if (peer->update_delay_over)
250 return; /* This peer has already been considered */
251
252 if (bgp_debug_neighbor_events(peer))
253 zlog_debug("Peer %s: Checking implicit EORs", peer->host);
254
255 if (peer->status == Established) {
256 peer->update_delay_over = 1;
257 peer->bgp->implicit_eors++;
258 bgp_check_update_delay(peer->bgp);
259 }
260}
261
becedef6
QY
262/*
263 * Should be called only when there is a change in the EOR_RECEIVED status
264 * for any afi/safi on a peer.
265 */
d8151687
QY
266static void bgp_update_explicit_eors(struct peer *peer)
267{
268 afi_t afi;
269 safi_t safi;
270
271 if (!bgp_update_delay_active(peer->bgp))
272 return; /* BGP update delay has ended */
273 if (peer->update_delay_over)
274 return; /* This peer has already been considered */
275
276 if (bgp_debug_neighbor_events(peer))
277 zlog_debug("Peer %s: Checking explicit EORs", peer->host);
278
279 for (afi = AFI_IP; afi < AFI_MAX; afi++)
280 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
281 if (peer->afc_nego[afi][safi]
282 && !CHECK_FLAG(peer->af_sflags[afi][safi],
283 PEER_STATUS_EOR_RECEIVED)) {
284 if (bgp_debug_neighbor_events(peer))
285 zlog_debug(
0437e105 286 " afi %d safi %d didn't receive EOR",
d8151687
QY
287 afi, safi);
288 return;
289 }
290 }
291
292 peer->update_delay_over = 1;
293 peer->bgp->explicit_eors++;
294 bgp_check_update_delay(peer->bgp);
295}
296
297/**
298 * Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers.
299 *
300 * mp_withdraw, if set, is used to nullify attr structure on most of the
301 * calling safi function and for evpn, passed as parameter
302 */
303int bgp_nlri_parse(struct peer *peer, struct attr *attr,
304 struct bgp_nlri *packet, int mp_withdraw)
305{
306 switch (packet->safi) {
307 case SAFI_UNICAST:
308 case SAFI_MULTICAST:
309 return bgp_nlri_parse_ip(peer, mp_withdraw ? NULL : attr,
310 packet);
311 case SAFI_LABELED_UNICAST:
312 return bgp_nlri_parse_label(peer, mp_withdraw ? NULL : attr,
313 packet);
314 case SAFI_MPLS_VPN:
315 return bgp_nlri_parse_vpn(peer, mp_withdraw ? NULL : attr,
316 packet);
317 case SAFI_EVPN:
318 return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
7c40bf39 319 case SAFI_FLOWSPEC:
320 return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
d8151687 321 }
513386b5 322 return BGP_NLRI_PARSE_ERROR;
d8151687
QY
323}
324
6ec98a2f
QY
325/*
326 * Checks a variety of conditions to determine whether the peer needs to be
327 * rescheduled for packet generation again, and does so if necessary.
328 *
329 * @param peer to check for rescheduling
330 */
af1e1dc6
QY
331static void bgp_write_proceed_actions(struct peer *peer)
332{
333 afi_t afi;
334 safi_t safi;
335 struct peer_af *paf;
336 struct bpacket *next_pkt;
337 struct update_subgroup *subgrp;
338
c58b0f46
QY
339 FOREACH_AFI_SAFI (afi, safi) {
340 paf = peer_af_find(peer, afi, safi);
341 if (!paf)
342 continue;
343 subgrp = paf->subgroup;
344 if (!subgrp)
345 continue;
346
347 next_pkt = paf->next_pkt_to_send;
348 if (next_pkt && next_pkt->buffer) {
349 BGP_TIMER_ON(peer->t_generate_updgrp_packets,
350 bgp_generate_updgrp_packets, 0);
351 return;
352 }
af1e1dc6 353
c58b0f46
QY
354 /* No packets readily available for AFI/SAFI, are there
355 * subgroup packets
356 * that need to be generated? */
357 if (bpacket_queue_is_full(SUBGRP_INST(subgrp),
358 SUBGRP_PKTQ(subgrp))
359 || subgroup_packets_to_build(subgrp)) {
360 BGP_TIMER_ON(peer->t_generate_updgrp_packets,
361 bgp_generate_updgrp_packets, 0);
362 return;
363 }
af1e1dc6 364
c58b0f46
QY
365 /* No packets to send, see if EOR is pending */
366 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
367 if (!subgrp->t_coalesce && peer->afc_nego[afi][safi]
368 && peer->synctime
369 && !CHECK_FLAG(peer->af_sflags[afi][safi],
370 PEER_STATUS_EOR_SEND)
371 && safi != SAFI_MPLS_VPN) {
af1e1dc6
QY
372 BGP_TIMER_ON(peer->t_generate_updgrp_packets,
373 bgp_generate_updgrp_packets, 0);
374 return;
375 }
af1e1dc6 376 }
c58b0f46 377 }
af1e1dc6
QY
378}
379
6ec98a2f
QY
380/*
381 * Generate advertisement information (withdraws, updates, EOR) from each
382 * update group a peer belongs to, encode this information into packets, and
383 * enqueue the packets onto the peer's output buffer.
56257a44
QY
384 */
385int bgp_generate_updgrp_packets(struct thread *thread)
718e3744 386{
56257a44 387 struct peer *peer = THREAD_ARG(thread);
56257a44
QY
388
389 struct stream *s;
d62a17ae 390 struct peer_af *paf;
391 struct bpacket *next_pkt;
d0ad6d8e
QY
392 uint32_t wpq;
393 uint32_t generated = 0;
d62a17ae 394 afi_t afi;
395 safi_t safi;
396
d0ad6d8e
QY
397 wpq = atomic_load_explicit(&peer->bgp->wpkt_quanta,
398 memory_order_relaxed);
399
d62a17ae 400 /*
401 * The code beyond this part deals with update packets, proceed only
402 * if peer is Established and updates are not on hold (as part of
403 * update-delay post processing).
3f9c7369 404 */
d62a17ae 405 if (peer->status != Established)
56257a44 406 return 0;
d62a17ae 407
5410015a 408 if (peer->bgp->main_peers_update_hold)
56257a44 409 return 0;
d62a17ae 410
56257a44
QY
411 do {
412 s = NULL;
c58b0f46
QY
413 FOREACH_AFI_SAFI (afi, safi) {
414 paf = peer_af_find(peer, afi, safi);
415 if (!paf || !PAF_SUBGRP(paf))
416 continue;
417 next_pkt = paf->next_pkt_to_send;
80bd61c4 418
c58b0f46
QY
419 /*
420 * Try to generate a packet for the peer if we are at
421 * the end of the list. Always try to push out
422 * WITHDRAWs first.
423 */
424 if (!next_pkt || !next_pkt->buffer) {
425 next_pkt = subgroup_withdraw_packet(
426 PAF_SUBGRP(paf));
427 if (!next_pkt || !next_pkt->buffer)
428 subgroup_update_packet(PAF_SUBGRP(paf));
429 next_pkt = paf->next_pkt_to_send;
430 }
80bd61c4 431
c58b0f46
QY
432 /*
433 * If we still don't have a packet to send to the peer,
434 * then try to find out out if we have to send eor or
435 * if not, skip to the next AFI, SAFI. Don't send the
436 * EOR prematurely; if the subgroup's coalesce timer is
437 * running, the adjacency-out structure is not created
438 * yet.
439 */
440 if (!next_pkt || !next_pkt->buffer) {
441 if (CHECK_FLAG(peer->cap,
36235319 442 PEER_CAP_RESTART_RCV)) {
c58b0f46 443 if (!(PAF_SUBGRP(paf))->t_coalesce
36235319
QY
444 && peer->afc_nego[afi][safi]
445 && peer->synctime
446 && !CHECK_FLAG(
447 peer->af_sflags[afi][safi],
448 PEER_STATUS_EOR_SEND)) {
d6e3c15b 449 /* If EOR is disabled,
450 * the message is not sent
451 */
36235319
QY
452 if (BGP_SEND_EOR(peer->bgp, afi,
453 safi)) {
d6e3c15b 454 SET_FLAG(
36235319
QY
455 peer->af_sflags
456 [afi]
457 [safi],
458 PEER_STATUS_EOR_SEND);
d6e3c15b 459
9e3b51a7 460 /* Update EOR
461 * send time
462 */
36235319
QY
463 peer->eor_stime[afi]
464 [safi] =
465 monotime(NULL);
9e3b51a7 466
d6e3c15b 467 BGP_UPDATE_EOR_PKT(
36235319
QY
468 peer, afi, safi,
469 s);
56257a44 470 }
80bd61c4 471 }
d62a17ae 472 }
c58b0f46
QY
473 continue;
474 }
9e3b51a7 475
476 /* Update packet send time */
477 peer->pkt_stime[afi][safi] = monotime(NULL);
478
c58b0f46
QY
479 /* Found a packet template to send, overwrite
480 * packet with appropriate attributes from peer
481 * and advance peer */
482 s = bpacket_reformat_for_peer(next_pkt, paf);
483 bgp_packet_add(peer, s);
c58b0f46
QY
484 bpacket_queue_advance_peer(paf);
485 }
d0ad6d8e 486 } while (s && (++generated < wpq));
80bd61c4 487
6ec98a2f
QY
488 if (generated)
489 bgp_writes_on(peer);
490
af1e1dc6
QY
491 bgp_write_proceed_actions(peer);
492
80bd61c4
QY
493 return 0;
494}
495
d3ecc69e
QY
496/*
497 * Creates a BGP Keepalive packet and appends it to the peer's output queue.
498 */
d62a17ae 499void bgp_keepalive_send(struct peer *peer)
718e3744 500{
d62a17ae 501 struct stream *s;
502
503 s = stream_new(BGP_MAX_PACKET_SIZE);
718e3744 504
d62a17ae 505 /* Make keepalive packet. */
506 bgp_packet_set_marker(s, BGP_MSG_KEEPALIVE);
718e3744 507
d62a17ae 508 /* Set packet size. */
509 (void)bgp_packet_set_size(s);
718e3744 510
d62a17ae 511 /* Dump packet if debug option is set. */
512 /* bgp_packet_dump (s); */
718e3744 513
d62a17ae 514 if (bgp_debug_keepalive(peer))
515 zlog_debug("%s sending KEEPALIVE", peer->host);
718e3744 516
d62a17ae 517 /* Add packet to the peer. */
518 bgp_packet_add(peer, s);
424ab01d
QY
519
520 bgp_writes_on(peer);
718e3744 521}
522
d3ecc69e
QY
523/*
524 * Creates a BGP Open packet and appends it to the peer's output queue.
525 * Sets capabilities as necessary.
526 */
d62a17ae 527void bgp_open_send(struct peer *peer)
718e3744 528{
d62a17ae 529 struct stream *s;
d7c0a89a 530 uint16_t send_holdtime;
d62a17ae 531 as_t local_as;
718e3744 532
b90a8e13 533 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
d62a17ae 534 send_holdtime = peer->holdtime;
535 else
536 send_holdtime = peer->bgp->default_holdtime;
718e3744 537
d62a17ae 538 /* local-as Change */
539 if (peer->change_local_as)
540 local_as = peer->change_local_as;
541 else
542 local_as = peer->local_as;
718e3744 543
d62a17ae 544 s = stream_new(BGP_MAX_PACKET_SIZE);
718e3744 545
d62a17ae 546 /* Make open packet. */
547 bgp_packet_set_marker(s, BGP_MSG_OPEN);
718e3744 548
d62a17ae 549 /* Set open packet values. */
550 stream_putc(s, BGP_VERSION_4); /* BGP version */
d7c0a89a
QY
551 stream_putw(s, (local_as <= BGP_AS_MAX) ? (uint16_t)local_as
552 : BGP_AS_TRANS);
d62a17ae 553 stream_putw(s, send_holdtime); /* Hold Time */
554 stream_put_in_addr(s, &peer->local_id); /* BGP Identifier */
718e3744 555
d62a17ae 556 /* Set capability code. */
557 bgp_open_capability(s, peer);
718e3744 558
d62a17ae 559 /* Set BGP packet length. */
560 (void)bgp_packet_set_size(s);
718e3744 561
d62a17ae 562 if (bgp_debug_neighbor_events(peer))
563 zlog_debug(
564 "%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
565 peer->host, BGP_VERSION_4, local_as, send_holdtime,
566 inet_ntoa(peer->local_id));
718e3744 567
d62a17ae 568 /* Dump packet if debug option is set. */
569 /* bgp_packet_dump (s); */
6fd04594 570 hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s);
718e3744 571
d62a17ae 572 /* Add packet to the peer. */
573 bgp_packet_add(peer, s);
424ab01d
QY
574
575 bgp_writes_on(peer);
576}
577
a127f33b
QY
578/*
579 * Writes NOTIFICATION message directly to a peer socket without waiting for
580 * the I/O thread.
581 *
582 * There must be exactly one stream on the peer->obuf FIFO, and the data within
583 * this stream must match the format of a BGP NOTIFICATION message.
584 * Transmission is best-effort.
585 *
586 * @requires peer->io_mtx
587 * @param peer
588 * @return 0
589 */
424ab01d
QY
590static int bgp_write_notify(struct peer *peer)
591{
592 int ret, val;
d7c0a89a 593 uint8_t type;
424ab01d
QY
594 struct stream *s;
595
a127f33b
QY
596 /* There should be at least one packet. */
597 s = stream_fifo_pop(peer->obuf);
424ab01d 598
8ec586b0
QY
599 if (!s)
600 return 0;
601
602 assert(stream_get_endp(s) >= BGP_HEADER_SIZE);
603
424ab01d
QY
604 /* Stop collecting data within the socket */
605 sockopt_cork(peer->fd, 0);
606
becedef6
QY
607 /*
608 * socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
609 * we only care about getting a clean shutdown at this point.
610 */
424ab01d
QY
611 ret = write(peer->fd, STREAM_DATA(s), stream_get_endp(s));
612
becedef6
QY
613 /*
614 * only connection reset/close gets counted as TCP_fatal_error, failure
615 * to write the entire NOTIFY doesn't get different FSM treatment
616 */
424ab01d 617 if (ret <= 0) {
3735936b 618 stream_free(s);
424ab01d
QY
619 BGP_EVENT_ADD(peer, TCP_fatal_error);
620 return 0;
621 }
622
623 /* Disable Nagle, make NOTIFY packet go out right away */
624 val = 1;
625 (void)setsockopt(peer->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val,
626 sizeof(val));
627
628 /* Retrieve BGP packet type. */
629 stream_set_getp(s, BGP_MARKER_SIZE + 2);
630 type = stream_getc(s);
631
632 assert(type == BGP_MSG_NOTIFY);
633
634 /* Type should be notify. */
0112e9e0 635 atomic_fetch_add_explicit(&peer->notify_out, 1, memory_order_relaxed);
424ab01d
QY
636 peer->notify_out++;
637
638 /* Double start timer. */
639 peer->v_start *= 2;
640
641 /* Overflow check. */
642 if (peer->v_start >= (60 * 2))
643 peer->v_start = (60 * 2);
644
becedef6
QY
645 /*
646 * Handle Graceful Restart case where the state changes to
647 * Connect instead of Idle
648 */
424ab01d
QY
649 BGP_EVENT_ADD(peer, BGP_Stop);
650
3735936b
QY
651 stream_free(s);
652
424ab01d 653 return 0;
718e3744 654}
655
d3ecc69e
QY
656/*
657 * Creates a BGP Notify and appends it to the peer's output queue.
658 *
becedef6
QY
659 * This function attempts to write the packet from the thread it is called
660 * from, to ensure the packet gets out ASAP.
d3ecc69e 661 *
a127f33b
QY
662 * This function may be called from multiple threads. Since the function
663 * modifies I/O buffer(s) in the peer, these are locked for the duration of the
664 * call to prevent tampering from other threads.
665 *
666 * Delivery of the NOTIFICATION is attempted once and is best-effort. After
667 * return, the peer structure *must* be reset; no assumptions about session
668 * state are valid.
669 *
d3ecc69e
QY
670 * @param peer
671 * @param code BGP error code
672 * @param sub_code BGP error subcode
673 * @param data Data portion
674 * @param datalen length of data portion
675 */
d7c0a89a
QY
676void bgp_notify_send_with_data(struct peer *peer, uint8_t code,
677 uint8_t sub_code, uint8_t *data, size_t datalen)
718e3744 678{
d62a17ae 679 struct stream *s;
d62a17ae 680
a127f33b 681 /* Lock I/O mutex to prevent other threads from pushing packets */
00dffa8c 682 frr_mutex_lock_autounlock(&peer->io_mtx);
a127f33b
QY
683 /* ============================================== */
684
d62a17ae 685 /* Allocate new stream. */
686 s = stream_new(BGP_MAX_PACKET_SIZE);
687
d3ecc69e 688 /* Make notify packet. */
d62a17ae 689 bgp_packet_set_marker(s, BGP_MSG_NOTIFY);
690
691 /* Set notify packet values. */
692 stream_putc(s, code); /* BGP notify code */
693 stream_putc(s, sub_code); /* BGP notify sub_code */
694
695 /* If notify data is present. */
696 if (data)
697 stream_write(s, data, datalen);
698
699 /* Set BGP packet length. */
bd6b2706 700 bgp_packet_set_size(s);
d62a17ae 701
424ab01d 702 /* wipe output buffer */
a127f33b 703 stream_fifo_clean(peer->obuf);
d62a17ae 704
becedef6
QY
705 /*
706 * If possible, store last packet for debugging purposes. This check is
707 * in place because we are sometimes called with a doppelganger peer,
708 * who tends to have a plethora of fields nulled out.
709 */
1a1f4534 710 if (peer->curr) {
d8151687 711 size_t packetsize = stream_get_endp(peer->curr);
1a1f4534 712 assert(packetsize <= sizeof(peer->last_reset_cause));
d8151687
QY
713 memcpy(peer->last_reset_cause, peer->curr->data, packetsize);
714 peer->last_reset_cause_size = packetsize;
715 }
716
d62a17ae 717 /* For debug */
718 {
719 struct bgp_notify bgp_notify;
720 int first = 0;
721 int i;
722 char c[4];
723
724 bgp_notify.code = code;
725 bgp_notify.subcode = sub_code;
726 bgp_notify.data = NULL;
e0981960 727 bgp_notify.length = datalen;
d62a17ae 728 bgp_notify.raw_data = data;
729
730 peer->notify.code = bgp_notify.code;
731 peer->notify.subcode = bgp_notify.subcode;
732
e0981960 733 if (bgp_notify.length && data) {
d62a17ae 734 bgp_notify.data =
735 XMALLOC(MTYPE_TMP, bgp_notify.length * 3);
736 for (i = 0; i < bgp_notify.length; i++)
737 if (first) {
552d6491
QY
738 snprintf(c, sizeof(c), " %02x",
739 data[i]);
f009ff26 740
552d6491 741 strlcat(bgp_notify.data, c,
2ba1fe69 742 bgp_notify.length);
f009ff26 743
d62a17ae 744 } else {
745 first = 1;
552d6491 746 snprintf(c, sizeof(c), "%02x", data[i]);
f009ff26 747
552d6491 748 strlcpy(bgp_notify.data, c,
2ba1fe69 749 bgp_notify.length);
d62a17ae 750 }
751 }
752 bgp_notify_print(peer, &bgp_notify, "sending");
753
754 if (bgp_notify.data) {
755 XFREE(MTYPE_TMP, bgp_notify.data);
d62a17ae 756 bgp_notify.length = 0;
757 }
758 }
759
760 /* peer reset cause */
761 if (code == BGP_NOTIFY_CEASE) {
762 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
763 peer->last_reset = PEER_DOWN_USER_RESET;
764 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
765 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
766 else
767 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
768 } else
769 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
770
d3ecc69e 771 /* Add packet to peer's output queue */
a127f33b 772 stream_fifo_push(peer->obuf, s);
424ab01d 773
5cce3f05 774 bgp_peer_gr_flags_update(peer);
36235319
QY
775 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
776 peer->bgp->peer);
5cce3f05 777
424ab01d 778 bgp_write_notify(peer);
718e3744 779}
780
d3ecc69e
QY
781/*
782 * Creates a BGP Notify and appends it to the peer's output queue.
783 *
becedef6
QY
784 * This function attempts to write the packet from the thread it is called
785 * from, to ensure the packet gets out ASAP.
d3ecc69e
QY
786 *
787 * @param peer
788 * @param code BGP error code
789 * @param sub_code BGP error subcode
790 */
d7c0a89a 791void bgp_notify_send(struct peer *peer, uint8_t code, uint8_t sub_code)
718e3744 792{
d62a17ae 793 bgp_notify_send_with_data(peer, code, sub_code, NULL, 0);
718e3744 794}
795
d3ecc69e
QY
796/*
797 * Creates BGP Route Refresh packet and appends it to the peer's output queue.
798 *
799 * @param peer
800 * @param afi Address Family Identifier
801 * @param safi Subsequent Address Family Identifier
802 * @param orf_type Outbound Route Filtering type
803 * @param when_to_refresh Whether to refresh immediately or defer
804 * @param remove Whether to remove ORF for specified AFI/SAFI
805 */
d62a17ae 806void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
807 uint8_t orf_type, uint8_t when_to_refresh,
808 int remove)
718e3744 809{
d62a17ae 810 struct stream *s;
811 struct bgp_filter *filter;
812 int orf_refresh = 0;
813 iana_afi_t pkt_afi;
5c525538 814 iana_safi_t pkt_safi;
d62a17ae 815
816 if (DISABLE_BGP_ANNOUNCE)
817 return;
818
819 filter = &peer->filter[afi][safi];
820
821 /* Convert AFI, SAFI to values for packet. */
822 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
823
824 s = stream_new(BGP_MAX_PACKET_SIZE);
825
826 /* Make BGP update packet. */
827 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
828 bgp_packet_set_marker(s, BGP_MSG_ROUTE_REFRESH_NEW);
718e3744 829 else
d62a17ae 830 bgp_packet_set_marker(s, BGP_MSG_ROUTE_REFRESH_OLD);
831
832 /* Encode Route Refresh message. */
833 stream_putw(s, pkt_afi);
834 stream_putc(s, 0);
835 stream_putc(s, pkt_safi);
836
837 if (orf_type == ORF_TYPE_PREFIX || orf_type == ORF_TYPE_PREFIX_OLD)
838 if (remove || filter->plist[FILTER_IN].plist) {
d7c0a89a 839 uint16_t orf_len;
d62a17ae 840 unsigned long orfp;
841
842 orf_refresh = 1;
843 stream_putc(s, when_to_refresh);
844 stream_putc(s, orf_type);
845 orfp = stream_get_endp(s);
846 stream_putw(s, 0);
847
848 if (remove) {
849 UNSET_FLAG(peer->af_sflags[afi][safi],
850 PEER_STATUS_ORF_PREFIX_SEND);
851 stream_putc(s, ORF_COMMON_PART_REMOVE_ALL);
852 if (bgp_debug_neighbor_events(peer))
853 zlog_debug(
748a041f 854 "%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s",
d62a17ae 855 peer->host, orf_type,
856 (when_to_refresh == REFRESH_DEFER
857 ? "defer"
858 : "immediate"),
748a041f
DS
859 iana_afi2str(pkt_afi),
860 iana_safi2str(pkt_safi));
d62a17ae 861 } else {
862 SET_FLAG(peer->af_sflags[afi][safi],
863 PEER_STATUS_ORF_PREFIX_SEND);
864 prefix_bgp_orf_entry(
865 s, filter->plist[FILTER_IN].plist,
866 ORF_COMMON_PART_ADD,
867 ORF_COMMON_PART_PERMIT,
868 ORF_COMMON_PART_DENY);
869 if (bgp_debug_neighbor_events(peer))
870 zlog_debug(
748a041f 871 "%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s",
d62a17ae 872 peer->host, orf_type,
873 (when_to_refresh == REFRESH_DEFER
874 ? "defer"
875 : "immediate"),
748a041f
DS
876 iana_afi2str(pkt_afi),
877 iana_safi2str(pkt_safi));
d62a17ae 878 }
879
880 /* Total ORF Entry Len. */
881 orf_len = stream_get_endp(s) - orfp - 2;
882 stream_putw_at(s, orfp, orf_len);
883 }
884
885 /* Set packet size. */
886 (void)bgp_packet_set_size(s);
887
888 if (bgp_debug_neighbor_events(peer)) {
889 if (!orf_refresh)
748a041f
DS
890 zlog_debug("%s sending REFRESH_REQ for afi/safi: %s/%s",
891 peer->host, iana_afi2str(pkt_afi),
892 iana_safi2str(pkt_safi));
d62a17ae 893 }
894
895 /* Add packet to the peer. */
896 bgp_packet_add(peer, s);
424ab01d
QY
897
898 bgp_writes_on(peer);
718e3744 899}
900
d3ecc69e
QY
901/*
902 * Create a BGP Capability packet and append it to the peer's output queue.
903 *
904 * @param peer
905 * @param afi Address Family Identifier
906 * @param safi Subsequent Address Family Identifier
907 * @param capability_code BGP Capability Code
908 * @param action Set or Remove capability
909 */
d62a17ae 910void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
911 int capability_code, int action)
718e3744 912{
d62a17ae 913 struct stream *s;
914 iana_afi_t pkt_afi;
5c525538 915 iana_safi_t pkt_safi;
d62a17ae 916
917 /* Convert AFI, SAFI to values for packet. */
918 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
919
920 s = stream_new(BGP_MAX_PACKET_SIZE);
921
922 /* Make BGP update packet. */
923 bgp_packet_set_marker(s, BGP_MSG_CAPABILITY);
924
925 /* Encode MP_EXT capability. */
926 if (capability_code == CAPABILITY_CODE_MP) {
927 stream_putc(s, action);
928 stream_putc(s, CAPABILITY_CODE_MP);
929 stream_putc(s, CAPABILITY_CODE_MP_LEN);
930 stream_putw(s, pkt_afi);
931 stream_putc(s, 0);
932 stream_putc(s, pkt_safi);
933
934 if (bgp_debug_neighbor_events(peer))
935 zlog_debug(
748a041f 936 "%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s",
d62a17ae 937 peer->host,
938 action == CAPABILITY_ACTION_SET ? "Advertising"
939 : "Removing",
748a041f 940 iana_afi2str(pkt_afi), iana_safi2str(pkt_safi));
d62a17ae 941 }
942
943 /* Set packet size. */
944 (void)bgp_packet_set_size(s);
718e3744 945
d62a17ae 946 /* Add packet to the peer. */
947 bgp_packet_add(peer, s);
424ab01d
QY
948
949 bgp_writes_on(peer);
d62a17ae 950}
718e3744 951
d62a17ae 952/* RFC1771 6.8 Connection collision detection. */
953static int bgp_collision_detect(struct peer *new, struct in_addr remote_id)
954{
955 struct peer *peer;
956
957 /* Upon receipt of an OPEN message, the local system must examine
958 all of its connections that are in the OpenConfirm state. A BGP
959 speaker may also examine connections in an OpenSent state if it
960 knows the BGP Identifier of the peer by means outside of the
961 protocol. If among these connections there is a connection to a
962 remote BGP speaker whose BGP Identifier equals the one in the
963 OPEN message, then the local system performs the following
964 collision resolution procedure: */
965
966 if ((peer = new->doppelganger) != NULL) {
967 /* Do not accept the new connection in Established or Clearing
968 * states.
969 * Note that a peer GR is handled by closing the existing
970 * connection
971 * upon receipt of new one.
972 */
973 if (peer->status == Established || peer->status == Clearing) {
974 bgp_notify_send(new, BGP_NOTIFY_CEASE,
975 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
95f7965d 976 return -1;
d62a17ae 977 } else if ((peer->status == OpenConfirm)
978 || (peer->status == OpenSent)) {
979 /* 1. The BGP Identifier of the local system is compared
980 to
981 the BGP Identifier of the remote system (as specified
982 in
983 the OPEN message). */
984
985 if (ntohl(peer->local_id.s_addr)
986 < ntohl(remote_id.s_addr))
987 if (!CHECK_FLAG(peer->sflags,
988 PEER_STATUS_ACCEPT_PEER)) {
989 /* 2. If the value of the local BGP
990 Identifier is less
991 than the remote one, the local system
992 closes BGP
993 connection that already exists (the
994 one that is
995 already in the OpenConfirm state),
996 and accepts BGP
997 connection initiated by the remote
998 system. */
999 bgp_notify_send(
1000 peer, BGP_NOTIFY_CEASE,
1001 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1002 return 1;
1003 } else {
1004 bgp_notify_send(
1005 new, BGP_NOTIFY_CEASE,
1006 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1007 return -1;
1008 }
1009 else {
3dbe2b60
DS
1010 if (ntohl(peer->local_id.s_addr) ==
1011 ntohl(remote_id.s_addr))
1012 flog_err(EC_BGP_ROUTER_ID_SAME, "Peer's router-id %s is the same as ours",
1013 inet_ntoa(remote_id));
1014
d62a17ae 1015 /* 3. Otherwise, the local system closes newly
1016 created
1017 BGP connection (the one associated with the
1018 newly
1019 received OPEN message), and continues to use
1020 the
1021 existing one (the one that is already in the
1022 OpenConfirm state). */
1023 if (CHECK_FLAG(peer->sflags,
1024 PEER_STATUS_ACCEPT_PEER)) {
1025 bgp_notify_send(
1026 peer, BGP_NOTIFY_CEASE,
1027 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1028 return 1;
1029 } else {
1030 bgp_notify_send(
1031 new, BGP_NOTIFY_CEASE,
1032 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1033 return -1;
1034 }
1035 }
1036 }
1037 }
1038 return 0;
1039}
718e3744 1040
d8151687
QY
1041/* Packet processing routines ---------------------------------------------- */
1042/*
1043 * This is a family of functions designed to be called from
1044 * bgp_process_packet(). These functions all share similar behavior and should
1045 * adhere to the following invariants and restrictions:
1046 *
1047 * Return codes
1048 * ------------
1049 * The return code of any one of those functions should be one of the FSM event
1050 * codes specified in bgpd.h. If a NOTIFY was sent, this event code MUST be
1051 * BGP_Stop. Otherwise, the code SHOULD correspond to the function's expected
1052 * packet type. For example, bgp_open_receive() should return BGP_Stop upon
1053 * error and Receive_OPEN_message otherwise.
1054 *
1055 * If no action is necessary, the correct return code is BGP_PACKET_NOOP as
1056 * defined below.
1057 *
1058 * Side effects
1059 * ------------
1060 * - May send NOTIFY messages
1061 * - May not modify peer->status
1062 * - May not call bgp_event_update()
1063 */
1064
1065#define BGP_PACKET_NOOP 0
1066
1067/**
1068 * Process BGP OPEN message for peer.
1069 *
1070 * If any errors are encountered in the OPEN message, immediately sends NOTIFY
1071 * and returns BGP_Stop.
1072 *
1073 * @param peer
1074 * @param size size of the packet
1075 * @return as in summary
1076 */
d62a17ae 1077static int bgp_open_receive(struct peer *peer, bgp_size_t size)
1078{
1079 int ret;
d7c0a89a
QY
1080 uint8_t version;
1081 uint8_t optlen;
1082 uint16_t holdtime;
1083 uint16_t send_holdtime;
d62a17ae 1084 as_t remote_as;
6dcef54c 1085 as_t as4 = 0, as4_be;
d62a17ae 1086 struct in_addr remote_id;
1087 int mp_capability;
d7c0a89a
QY
1088 uint8_t notify_data_remote_as[2];
1089 uint8_t notify_data_remote_as4[4];
1090 uint8_t notify_data_remote_id[4];
1091 uint16_t *holdtime_ptr;
d62a17ae 1092
1093 /* Parse open packet. */
424ab01d
QY
1094 version = stream_getc(peer->curr);
1095 memcpy(notify_data_remote_as, stream_pnt(peer->curr), 2);
1096 remote_as = stream_getw(peer->curr);
d7c0a89a 1097 holdtime_ptr = (uint16_t *)stream_pnt(peer->curr);
424ab01d
QY
1098 holdtime = stream_getw(peer->curr);
1099 memcpy(notify_data_remote_id, stream_pnt(peer->curr), 4);
1100 remote_id.s_addr = stream_get_ipv4(peer->curr);
d62a17ae 1101
1102 /* Receive OPEN message log */
1103 if (bgp_debug_neighbor_events(peer))
1104 zlog_debug(
1105 "%s rcv OPEN, version %d, remote-as (in open) %u,"
1106 " holdtime %d, id %s",
1107 peer->host, version, remote_as, holdtime,
1108 inet_ntoa(remote_id));
1109
1110 /* BEGIN to read the capability here, but dont do it yet */
1111 mp_capability = 0;
424ab01d 1112 optlen = stream_getc(peer->curr);
d62a17ae 1113
1114 if (optlen != 0) {
1115 /* If not enough bytes, it is an error. */
424ab01d 1116 if (STREAM_READABLE(peer->curr) < optlen) {
d62a17ae 1117 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1118 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
d8151687 1119 return BGP_Stop;
d62a17ae 1120 }
718e3744 1121
d62a17ae 1122 /* We need the as4 capability value *right now* because
1123 * if it is there, we have not got the remote_as yet, and
1124 * without
1125 * that we do not know which peer is connecting to us now.
1126 */
1127 as4 = peek_for_as4_capability(peer, optlen);
d62a17ae 1128 }
718e3744 1129
6dcef54c
DL
1130 as4_be = htonl(as4);
1131 memcpy(notify_data_remote_as4, &as4_be, 4);
1132
d62a17ae 1133 /* Just in case we have a silly peer who sends AS4 capability set to 0
1134 */
1135 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && !as4) {
e50f7cfd 1136 flog_err(EC_BGP_PKT_OPEN,
1c50c1c0
QY
1137 "%s bad OPEN, got AS4 capability, but AS4 set to 0",
1138 peer->host);
d62a17ae 1139 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1140 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1141 notify_data_remote_as4, 4);
d8151687 1142 return BGP_Stop;
d62a17ae 1143 }
718e3744 1144
33d022bc
DA
1145 /* Codification of AS 0 Processing */
1146 if (remote_as == BGP_AS_ZERO) {
1147 flog_err(EC_BGP_PKT_OPEN, "%s bad OPEN, got AS set to 0",
1148 peer->host);
1149 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1150 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1151 return BGP_Stop;
1152 }
1153
d62a17ae 1154 if (remote_as == BGP_AS_TRANS) {
1155 /* Take the AS4 from the capability. We must have received the
1156 * capability now! Otherwise we have a asn16 peer who uses
1157 * BGP_AS_TRANS, for some unknown reason.
1158 */
1159 if (as4 == BGP_AS_TRANS) {
af4c2728 1160 flog_err(
e50f7cfd 1161 EC_BGP_PKT_OPEN,
d62a17ae 1162 "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1163 peer->host);
1164 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1165 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1166 notify_data_remote_as4, 4);
d8151687 1167 return BGP_Stop;
d62a17ae 1168 }
718e3744 1169
d62a17ae 1170 if (!as4 && BGP_DEBUG(as4, AS4))
1171 zlog_debug(
1172 "%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1173 " Odd, but proceeding.",
1174 peer->host);
1175 else if (as4 < BGP_AS_MAX && BGP_DEBUG(as4, AS4))
1176 zlog_debug(
1177 "%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
1178 "in 2-bytes, very odd peer.",
1179 peer->host, as4);
1180 if (as4)
1181 remote_as = as4;
1182 } else {
1183 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX
1184 */
1185 /* If we have got the capability, peer->as4cap must match
1186 * remote_as */
1187 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1188 && as4 != remote_as) {
1189 /* raise error, log this, close session */
af4c2728 1190 flog_err(
e50f7cfd 1191 EC_BGP_PKT_OPEN,
d62a17ae 1192 "%s bad OPEN, got AS4 capability, but remote_as %u"
1193 " mismatch with 16bit 'myasn' %u in open",
1194 peer->host, as4, remote_as);
1195 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1196 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1197 notify_data_remote_as4, 4);
d8151687 1198 return BGP_Stop;
d62a17ae 1199 }
1200 }
6b0655a2 1201
d62a17ae 1202 /* remote router-id check. */
975a328e
DA
1203 if (remote_id.s_addr == INADDR_ANY
1204 || IPV4_CLASS_DE(ntohl(remote_id.s_addr))
d62a17ae 1205 || ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)) {
1206 if (bgp_debug_neighbor_events(peer))
1207 zlog_debug("%s bad OPEN, wrong router identifier %s",
1208 peer->host, inet_ntoa(remote_id));
1209 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1210 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1211 notify_data_remote_id, 4);
d8151687 1212 return BGP_Stop;
d62a17ae 1213 }
1214
1215 /* Set remote router-id */
1216 peer->remote_id = remote_id;
1217
1218 /* Peer BGP version check. */
1219 if (version != BGP_VERSION_4) {
d7c0a89a 1220 uint16_t maxver = htons(BGP_VERSION_4);
d62a17ae 1221 /* XXX this reply may not be correct if version < 4 XXX */
1222 if (bgp_debug_neighbor_events(peer))
1223 zlog_debug(
1224 "%s bad protocol version, remote requested %d, local request %d",
1225 peer->host, version, BGP_VERSION_4);
1226 /* Data must be in network byte order here */
1227 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1228 BGP_NOTIFY_OPEN_UNSUP_VERSION,
d7c0a89a 1229 (uint8_t *)&maxver, 2);
d8151687 1230 return BGP_Stop;
d62a17ae 1231 }
1232
1233 /* Check neighbor as number. */
1234 if (peer->as_type == AS_UNSPECIFIED) {
1235 if (bgp_debug_neighbor_events(peer))
1236 zlog_debug(
1237 "%s bad OPEN, remote AS is unspecified currently",
1238 peer->host);
1239 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1240 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1241 notify_data_remote_as, 2);
d8151687 1242 return BGP_Stop;
d62a17ae 1243 } else if (peer->as_type == AS_INTERNAL) {
1244 if (remote_as != peer->bgp->as) {
1245 if (bgp_debug_neighbor_events(peer))
1246 zlog_debug(
1247 "%s bad OPEN, remote AS is %u, internal specified",
1248 peer->host, remote_as);
1249 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1250 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1251 notify_data_remote_as, 2);
d8151687 1252 return BGP_Stop;
1ff9a340 1253 }
d62a17ae 1254 peer->as = peer->local_as;
1255 } else if (peer->as_type == AS_EXTERNAL) {
1256 if (remote_as == peer->bgp->as) {
1257 if (bgp_debug_neighbor_events(peer))
1258 zlog_debug(
1259 "%s bad OPEN, remote AS is %u, external specified",
1260 peer->host, remote_as);
1261 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1262 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1263 notify_data_remote_as, 2);
d8151687 1264 return BGP_Stop;
1ff9a340 1265 }
d62a17ae 1266 peer->as = remote_as;
1267 } else if ((peer->as_type == AS_SPECIFIED) && (remote_as != peer->as)) {
1268 if (bgp_debug_neighbor_events(peer))
1269 zlog_debug("%s bad OPEN, remote AS is %u, expected %u",
1270 peer->host, remote_as, peer->as);
1271 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1272 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1273 notify_data_remote_as, 2);
d8151687 1274 return BGP_Stop;
eb821189 1275 }
718e3744 1276
d62a17ae 1277 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1278 calculate the value of the Hold Timer by using the smaller of its
1279 configured Hold Time and the Hold Time received in the OPEN message.
1280 The Hold Time MUST be either zero or at least three seconds. An
1281 implementation may reject connections on the basis of the Hold Time.
0b2aa3a0 1282 */
d62a17ae 1283
1284 if (holdtime < 3 && holdtime != 0) {
1285 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1286 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
d7c0a89a 1287 (uint8_t *)holdtime_ptr, 2);
d8151687 1288 return BGP_Stop;
0b2aa3a0 1289 }
d62a17ae 1290
1291 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1292 would be one third of the Hold Time interval. KEEPALIVE messages
1293 MUST NOT be sent more frequently than one per second. An
1294 implementation MAY adjust the rate at which it sends KEEPALIVE
1295 messages as a function of the Hold Time interval. */
1296
b90a8e13 1297 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
d62a17ae 1298 send_holdtime = peer->holdtime;
1299 else
1300 send_holdtime = peer->bgp->default_holdtime;
1301
1302 if (holdtime < send_holdtime)
1303 peer->v_holdtime = holdtime;
1304 else
1305 peer->v_holdtime = send_holdtime;
1306
b90a8e13 1307 if ((CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
d25e4efc 1308 && (peer->keepalive < peer->v_holdtime / 3))
d62a17ae 1309 peer->v_keepalive = peer->keepalive;
1310 else
1311 peer->v_keepalive = peer->v_holdtime / 3;
1312
1313 /* Open option part parse. */
1314 if (optlen != 0) {
1bb379bf 1315 if (bgp_open_option_parse(peer, optlen, &mp_capability) < 0)
d8151687 1316 return BGP_Stop;
d62a17ae 1317 } else {
1318 if (bgp_debug_neighbor_events(peer))
1319 zlog_debug("%s rcvd OPEN w/ OPTION parameter len: 0",
1320 peer->host);
0299c004 1321 }
d62a17ae 1322
1323 /*
1324 * Assume that the peer supports the locally configured set of
1325 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1326 * capabilities, or if 'override-capability' is configured.
1327 */
1328 if (!mp_capability
1329 || CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1330 peer->afc_nego[AFI_IP][SAFI_UNICAST] =
1331 peer->afc[AFI_IP][SAFI_UNICAST];
1332 peer->afc_nego[AFI_IP][SAFI_MULTICAST] =
1333 peer->afc[AFI_IP][SAFI_MULTICAST];
1334 peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] =
1335 peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
7c40bf39 1336 peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] =
1337 peer->afc[AFI_IP][SAFI_FLOWSPEC];
d62a17ae 1338 peer->afc_nego[AFI_IP6][SAFI_UNICAST] =
1339 peer->afc[AFI_IP6][SAFI_UNICAST];
1340 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] =
1341 peer->afc[AFI_IP6][SAFI_MULTICAST];
1342 peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] =
1343 peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
1344 peer->afc_nego[AFI_L2VPN][SAFI_EVPN] =
1345 peer->afc[AFI_L2VPN][SAFI_EVPN];
7c40bf39 1346 peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] =
1347 peer->afc[AFI_IP6][SAFI_FLOWSPEC];
0299c004 1348 }
d62a17ae 1349
1350 /* When collision is detected and this peer is closed. Retrun
1351 immidiately. */
1352 ret = bgp_collision_detect(peer, remote_id);
1353 if (ret < 0)
d8151687 1354 return BGP_Stop;
d62a17ae 1355
1356 /* Get sockname. */
1bb379bf 1357 if (bgp_getsockname(peer) < 0) {
450971aa 1358 flog_err_sys(EC_LIB_SOCKET,
09c866e3 1359 "%s: bgp_getsockname() failed for peer: %s",
15569c58 1360 __func__, peer->host);
d8151687 1361 return BGP_Stop;
d62a17ae 1362 }
1363
1364 /* Verify valid local address present based on negotiated
1365 * address-families. */
1366 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
e5f22b30 1367 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
d62a17ae 1368 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1369 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1370 || peer->afc_nego[AFI_IP][SAFI_ENCAP]) {
975a328e 1371 if (peer->nexthop.v4.s_addr == INADDR_ANY) {
d62a17ae 1372#if defined(HAVE_CUMULUS)
af4c2728 1373 flog_err(
e50f7cfd 1374 EC_BGP_SND_FAIL,
d62a17ae 1375 "%s: No local IPv4 addr resetting connection, fd %d",
1376 peer->host, peer->fd);
1377 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1378 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1379 return BGP_Stop;
1d808091 1380#endif
d62a17ae 1381 }
1382 }
1383 if (peer->afc_nego[AFI_IP6][SAFI_UNICAST]
e5f22b30 1384 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
d62a17ae 1385 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1386 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1387 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) {
1388 if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) {
1389#if defined(HAVE_CUMULUS)
af4c2728 1390 flog_err(
e50f7cfd 1391 EC_BGP_SND_FAIL,
d62a17ae 1392 "%s: No local IPv6 addr resetting connection, fd %d",
1393 peer->host, peer->fd);
1394 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1395 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1396 return BGP_Stop;
1d808091 1397#endif
d62a17ae 1398 }
1399 }
1400 peer->rtt = sockopt_tcp_rtt(peer->fd);
1401
d8151687 1402 return Receive_OPEN_message;
718e3744 1403}
1404
d8151687
QY
1405/**
1406 * Process BGP KEEPALIVE message for peer.
1407 *
1408 * @param peer
1409 * @param size size of the packet
1410 * @return as in summary
1411 */
1412static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size)
f188f2c4 1413{
d8151687
QY
1414 if (bgp_debug_keepalive(peer))
1415 zlog_debug("%s KEEPALIVE rcvd", peer->host);
d62a17ae 1416
d8151687 1417 bgp_update_implicit_eors(peer);
d62a17ae 1418
d8151687 1419 return Receive_KEEPALIVE_message;
f188f2c4
DS
1420}
1421
d62a17ae 1422
d8151687
QY
1423/**
1424 * Process BGP UPDATE message for peer.
1425 *
1426 * Parses UPDATE and creates attribute object.
1427 *
1428 * @param peer
1429 * @param size size of the packet
1430 * @return as in summary
7ef5a232 1431 */
d62a17ae 1432static int bgp_update_receive(struct peer *peer, bgp_size_t size)
718e3744 1433{
d62a17ae 1434 int ret, nlri_ret;
d7c0a89a 1435 uint8_t *end;
d62a17ae 1436 struct stream *s;
1437 struct attr attr;
1438 bgp_size_t attribute_len;
1439 bgp_size_t update_len;
1440 bgp_size_t withdraw_len;
f009ff26 1441 bool restart = false;
d62a17ae 1442
1443 enum NLRI_TYPES {
1444 NLRI_UPDATE,
1445 NLRI_WITHDRAW,
1446 NLRI_MP_UPDATE,
1447 NLRI_MP_WITHDRAW,
1448 NLRI_TYPE_MAX
1449 };
1450 struct bgp_nlri nlris[NLRI_TYPE_MAX];
1451
1452 /* Status must be Established. */
1453 if (peer->status != Established) {
e50f7cfd 1454 flog_err(EC_BGP_INVALID_STATUS,
1c50c1c0
QY
1455 "%s [FSM] Update packet received under status %s",
1456 peer->host,
1457 lookup_msg(bgp_status_msg, peer->status, NULL));
0e35025e 1458 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
3893aeee 1459 bgp_fsm_error_subcode(peer->status));
d8151687 1460 return BGP_Stop;
d62a17ae 1461 }
1462
1463 /* Set initial values. */
1464 memset(&attr, 0, sizeof(struct attr));
1465 attr.label_index = BGP_INVALID_LABEL_INDEX;
1466 attr.label = MPLS_INVALID_LABEL;
1467 memset(&nlris, 0, sizeof(nlris));
1468 memset(peer->rcvd_attr_str, 0, BUFSIZ);
1469 peer->rcvd_attr_printed = 0;
1470
424ab01d 1471 s = peer->curr;
d62a17ae 1472 end = stream_pnt(s) + size;
1473
1474 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1475 Length is too large (i.e., if Unfeasible Routes Length + Total
1476 Attribute Length + 23 exceeds the message Length), then the Error
1477 Subcode is set to Malformed Attribute List. */
1478 if (stream_pnt(s) + 2 > end) {
e50f7cfd 1479 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0
QY
1480 "%s [Error] Update packet error"
1481 " (packet length is short for unfeasible length)",
1482 peer->host);
d62a17ae 1483 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
1484 BGP_NOTIFY_UPDATE_MAL_ATTR);
d8151687 1485 return BGP_Stop;
d62a17ae 1486 }
1487
1488 /* Unfeasible Route Length. */
1489 withdraw_len = stream_getw(s);
1490
1491 /* Unfeasible Route Length check. */
1492 if (stream_pnt(s) + withdraw_len > end) {
e50f7cfd 1493 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0
QY
1494 "%s [Error] Update packet error"
1495 " (packet unfeasible length overflow %d)",
1496 peer->host, withdraw_len);
d62a17ae 1497 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
1498 BGP_NOTIFY_UPDATE_MAL_ATTR);
d8151687 1499 return BGP_Stop;
d62a17ae 1500 }
1501
1502 /* Unfeasible Route packet format check. */
1503 if (withdraw_len > 0) {
1504 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1505 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1506 nlris[NLRI_WITHDRAW].nlri = stream_pnt(s);
1507 nlris[NLRI_WITHDRAW].length = withdraw_len;
1508 stream_forward_getp(s, withdraw_len);
1509 }
1510
1511 /* Attribute total length check. */
1512 if (stream_pnt(s) + 2 > end) {
ade6974d 1513 flog_warn(
e50f7cfd 1514 EC_BGP_UPDATE_PACKET_SHORT,
ade6974d
QY
1515 "%s [Error] Packet Error (update packet is short for attribute length)",
1516 peer->host);
d62a17ae 1517 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
1518 BGP_NOTIFY_UPDATE_MAL_ATTR);
d8151687 1519 return BGP_Stop;
d62a17ae 1520 }
1521
1522 /* Fetch attribute total length. */
1523 attribute_len = stream_getw(s);
1524
1525 /* Attribute length check. */
1526 if (stream_pnt(s) + attribute_len > end) {
ade6974d 1527 flog_warn(
e50f7cfd 1528 EC_BGP_UPDATE_PACKET_LONG,
ade6974d
QY
1529 "%s [Error] Packet Error (update packet attribute length overflow %d)",
1530 peer->host, attribute_len);
d62a17ae 1531 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
1532 BGP_NOTIFY_UPDATE_MAL_ATTR);
d8151687 1533 return BGP_Stop;
d62a17ae 1534 }
1535
1536 /* Certain attribute parsing errors should not be considered bad enough
1537 * to reset the session for, most particularly any partial/optional
1538 * attributes that have 'tunneled' over speakers that don't understand
1539 * them. Instead we withdraw only the prefix concerned.
1540 *
1541 * Complicates the flow a little though..
1542 */
1543 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1544/* This define morphs the update case into a withdraw when lower levels
1545 * have signalled an error condition where this is best.
1546 */
b881c707 1547#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
718e3744 1548
d62a17ae 1549 /* Parse attribute when it exists. */
1550 if (attribute_len) {
1551 attr_parse_ret = bgp_attr_parse(peer, &attr, attribute_len,
1552 &nlris[NLRI_MP_UPDATE],
1553 &nlris[NLRI_MP_WITHDRAW]);
1554 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR) {
1555 bgp_attr_unintern_sub(&attr);
d8151687 1556 return BGP_Stop;
d62a17ae 1557 }
1558 }
1559
1560 /* Logging the attribute. */
1561 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1562 || BGP_DEBUG(update, UPDATE_IN)
1563 || BGP_DEBUG(update, UPDATE_PREFIX)) {
1564 ret = bgp_dump_attr(&attr, peer->rcvd_attr_str, BUFSIZ);
1565
b4d46cc9
DL
1566 peer->stat_upd_7606++;
1567
d62a17ae 1568 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
af4c2728 1569 flog_err(
e50f7cfd 1570 EC_BGP_UPDATE_RCV,
d62a17ae 1571 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1572 peer->host);
1573
1574 if (ret && bgp_debug_update(peer, NULL, NULL, 1)) {
1575 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
1576 peer->rcvd_attr_str);
1577 peer->rcvd_attr_printed = 1;
1578 }
1579 }
1580
1581 /* Network Layer Reachability Information. */
1582 update_len = end - stream_pnt(s);
1583
1584 if (update_len) {
1585 /* Set NLRI portion to structure. */
1586 nlris[NLRI_UPDATE].afi = AFI_IP;
1587 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1588 nlris[NLRI_UPDATE].nlri = stream_pnt(s);
1589 nlris[NLRI_UPDATE].length = update_len;
1590 stream_forward_getp(s, update_len);
9738e9aa 1591
1592 if (CHECK_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
1593 /*
1594 * We skipped nexthop attribute validation earlier so
1595 * validate the nexthop now.
1596 */
1597 if (bgp_attr_nexthop_valid(peer, &attr) < 0) {
1598 bgp_attr_unintern_sub(&attr);
1599 return BGP_Stop;
1600 }
1601 }
d62a17ae 1602 }
1603
1604 if (BGP_DEBUG(update, UPDATE_IN))
1605 zlog_debug("%s rcvd UPDATE wlen %d attrlen %d alen %d",
1606 peer->host, withdraw_len, attribute_len, update_len);
1607
1608 /* Parse any given NLRIs */
1609 for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) {
1610 if (!nlris[i].nlri)
1611 continue;
1612
1613 /* NLRI is processed iff the peer if configured for the specific
1614 * afi/safi */
1615 if (!peer->afc[nlris[i].afi][nlris[i].safi]) {
1616 zlog_info(
1617 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1618 peer->host, nlris[i].afi, nlris[i].safi);
1619 continue;
1620 }
1621
1622 /* EoR handled later */
1623 if (nlris[i].length == 0)
1624 continue;
1625
1626 switch (i) {
1627 case NLRI_UPDATE:
1628 case NLRI_MP_UPDATE:
1629 nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG,
1630 &nlris[i], 0);
1631 break;
1632 case NLRI_WITHDRAW:
1633 case NLRI_MP_WITHDRAW:
1634 nlri_ret = bgp_nlri_parse(peer, &attr, &nlris[i], 1);
1635 break;
1636 default:
513386b5 1637 nlri_ret = BGP_NLRI_PARSE_ERROR;
d62a17ae 1638 }
1639
513386b5
DA
1640 if (nlri_ret < BGP_NLRI_PARSE_OK
1641 && nlri_ret != BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW) {
e50f7cfd 1642 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0 1643 "%s [Error] Error parsing NLRI", peer->host);
d62a17ae 1644 if (peer->status == Established)
1645 bgp_notify_send(
1646 peer, BGP_NOTIFY_UPDATE_ERR,
1647 i <= NLRI_WITHDRAW
1648 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1649 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1650 bgp_attr_unintern_sub(&attr);
d8151687 1651 return BGP_Stop;
d62a17ae 1652 }
1653 }
1654
1655 /* EoR checks
1656 *
1657 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1658 * and MP EoR should have only an empty MP_UNREACH
1659 */
996c9314
LB
1660 if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0)
1661 || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
d62a17ae 1662 afi_t afi = 0;
1663 safi_t safi;
f009ff26 1664 struct graceful_restart_info *gr_info;
1665
1666 /* Restarting router */
36235319
QY
1667 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
1668 && BGP_PEER_RESTARTING_MODE(peer))
f009ff26 1669 restart = true;
d62a17ae 1670
1671 /* Non-MP IPv4/Unicast is a completely emtpy UPDATE - already
1672 * checked
1673 * update and withdraw NLRI lengths are 0.
1674 */
1675 if (!attribute_len) {
1676 afi = AFI_IP;
1677 safi = SAFI_UNICAST;
1678 } else if (attr.flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI)
1679 && nlris[NLRI_MP_WITHDRAW].length == 0) {
1680 afi = nlris[NLRI_MP_WITHDRAW].afi;
1681 safi = nlris[NLRI_MP_WITHDRAW].safi;
9b9df989
DS
1682 } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) {
1683 afi = nlris[NLRI_MP_UPDATE].afi;
1684 safi = nlris[NLRI_MP_UPDATE].safi;
d62a17ae 1685 }
1686
1687 if (afi && peer->afc[afi][safi]) {
e82d19a3
DS
1688 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
1689
d62a17ae 1690 /* End-of-RIB received */
1691 if (!CHECK_FLAG(peer->af_sflags[afi][safi],
1692 PEER_STATUS_EOR_RECEIVED)) {
1693 SET_FLAG(peer->af_sflags[afi][safi],
1694 PEER_STATUS_EOR_RECEIVED);
1695 bgp_update_explicit_eors(peer);
f009ff26 1696 /* Update graceful restart information */
1697 gr_info = &(peer->bgp->gr_info[afi][safi]);
1698 if (restart)
1699 gr_info->eor_received++;
1700 /* If EOR received from all peers and selection
1701 * deferral timer is running, cancel the timer
1702 * and invoke the best path calculation
1703 */
36235319
QY
1704 if (gr_info->eor_required
1705 == gr_info->eor_received) {
1706 if (bgp_debug_neighbor_events(peer))
1707 zlog_debug(
1708 "%s %d, %s %d",
f009ff26 1709 "EOR REQ",
1710 gr_info->eor_required,
1711 "EOR RCV",
1712 gr_info->eor_received);
1713 BGP_TIMER_OFF(
1714 gr_info->t_select_deferral);
1715 gr_info->eor_required = 0;
1716 gr_info->eor_received = 0;
1717 /* Best path selection */
1718 if (bgp_best_path_select_defer(
36235319
QY
1719 peer->bgp, afi, safi)
1720 < 0)
f009ff26 1721 return BGP_Stop;
1722 }
d62a17ae 1723 }
1724
1725 /* NSF delete stale route */
1726 if (peer->nsf[afi][safi])
1727 bgp_clear_stale_route(peer, afi, safi);
1728
a0e89d54
TA
1729 zlog_info(
1730 "%s: rcvd End-of-RIB for %s from %s in vrf %s",
1731 __func__, get_afi_safi_str(afi, safi, false),
1732 peer->host, vrf ? vrf->name : VRF_DEFAULT_NAME);
1733 }
f80f838b 1734 }
d62a17ae 1735
1736 /* Everything is done. We unintern temporary structures which
1737 interned in bgp_attr_parse(). */
1738 bgp_attr_unintern_sub(&attr);
1739
d62a17ae 1740 peer->update_time = bgp_clock();
1741
1742 /* Rearm holdtime timer */
1743 BGP_TIMER_OFF(peer->t_holdtime);
1744 bgp_timer_set(peer);
1745
d8151687 1746 return Receive_UPDATE_message;
718e3744 1747}
1748
d8151687
QY
1749/**
1750 * Process BGP NOTIFY message for peer.
1751 *
1752 * @param peer
1753 * @param size size of the packet
1754 * @return as in summary
1755 */
1756static int bgp_notify_receive(struct peer *peer, bgp_size_t size)
718e3744 1757{
d62a17ae 1758 struct bgp_notify bgp_notify;
1759
1760 if (peer->notify.data) {
1761 XFREE(MTYPE_TMP, peer->notify.data);
d62a17ae 1762 peer->notify.length = 0;
1763 }
1764
424ab01d
QY
1765 bgp_notify.code = stream_getc(peer->curr);
1766 bgp_notify.subcode = stream_getc(peer->curr);
d62a17ae 1767 bgp_notify.length = size - 2;
1768 bgp_notify.data = NULL;
1769
1770 /* Preserv notify code and sub code. */
1771 peer->notify.code = bgp_notify.code;
1772 peer->notify.subcode = bgp_notify.subcode;
1773 /* For further diagnostic record returned Data. */
1774 if (bgp_notify.length) {
1775 peer->notify.length = size - 2;
1776 peer->notify.data = XMALLOC(MTYPE_TMP, size - 2);
424ab01d 1777 memcpy(peer->notify.data, stream_pnt(peer->curr), size - 2);
d62a17ae 1778 }
1779
1780 /* For debug */
1781 {
1782 int i;
1783 int first = 0;
1784 char c[4];
1785
1786 if (bgp_notify.length) {
1787 bgp_notify.data =
1788 XMALLOC(MTYPE_TMP, bgp_notify.length * 3);
1789 for (i = 0; i < bgp_notify.length; i++)
1790 if (first) {
552d6491 1791 snprintf(c, sizeof(c), " %02x",
424ab01d 1792 stream_getc(peer->curr));
f009ff26 1793
552d6491 1794 strlcat(bgp_notify.data, c,
f009ff26 1795 bgp_notify.length * 3);
1796
d62a17ae 1797 } else {
1798 first = 1;
552d6491
QY
1799 snprintf(c, sizeof(c), "%02x",
1800 stream_getc(peer->curr));
f009ff26 1801
552d6491 1802 strlcpy(bgp_notify.data, c,
f009ff26 1803 bgp_notify.length * 3);
d62a17ae 1804 }
d7c0a89a 1805 bgp_notify.raw_data = (uint8_t *)peer->notify.data;
d62a17ae 1806 }
1807
1808 bgp_notify_print(peer, &bgp_notify, "received");
1809 if (bgp_notify.data) {
1810 XFREE(MTYPE_TMP, bgp_notify.data);
d62a17ae 1811 bgp_notify.length = 0;
1812 }
1813 }
1814
1815 /* peer count update */
0112e9e0 1816 atomic_fetch_add_explicit(&peer->notify_in, 1, memory_order_relaxed);
d62a17ae 1817
1818 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1819
1820 /* We have to check for Notify with Unsupported Optional Parameter.
1821 in that case we fallback to open without the capability option.
1822 But this done in bgp_stop. We just mark it here to avoid changing
1823 the fsm tables. */
1824 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR
1825 && bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM)
1826 UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1827
5cce3f05 1828 bgp_peer_gr_flags_update(peer);
36235319
QY
1829 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
1830 peer->bgp->peer);
5cce3f05 1831
d8151687 1832 return Receive_NOTIFICATION_message;
718e3744 1833}
1834
d8151687
QY
1835/**
1836 * Process BGP ROUTEREFRESH message for peer.
1837 *
1838 * @param peer
1839 * @param size size of the packet
1840 * @return as in summary
1841 */
1842static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
718e3744 1843{
d62a17ae 1844 iana_afi_t pkt_afi;
1845 afi_t afi;
5c525538
RW
1846 iana_safi_t pkt_safi;
1847 safi_t safi;
d62a17ae 1848 struct stream *s;
1849 struct peer_af *paf;
1850 struct update_group *updgrp;
1851 struct peer *updgrp_peer;
1852
1853 /* If peer does not have the capability, send notification. */
1854 if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) {
e50f7cfd 1855 flog_err(EC_BGP_NO_CAP,
1c50c1c0
QY
1856 "%s [Error] BGP route refresh is not enabled",
1857 peer->host);
d62a17ae 1858 bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
1859 BGP_NOTIFY_HEADER_BAD_MESTYPE);
d8151687 1860 return BGP_Stop;
d62a17ae 1861 }
1862
1863 /* Status must be Established. */
1864 if (peer->status != Established) {
af4c2728 1865 flog_err(
e50f7cfd 1866 EC_BGP_INVALID_STATUS,
d62a17ae 1867 "%s [Error] Route refresh packet received under status %s",
1868 peer->host,
1869 lookup_msg(bgp_status_msg, peer->status, NULL));
0e35025e 1870 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
3893aeee 1871 bgp_fsm_error_subcode(peer->status));
d8151687 1872 return BGP_Stop;
d62a17ae 1873 }
1874
424ab01d 1875 s = peer->curr;
d62a17ae 1876
1877 /* Parse packet. */
1878 pkt_afi = stream_getw(s);
1879 (void)stream_getc(s);
1880 pkt_safi = stream_getc(s);
1881
1882 if (bgp_debug_update(peer, NULL, NULL, 0))
748a041f
DS
1883 zlog_debug("%s rcvd REFRESH_REQ for afi/safi: %s/%s",
1884 peer->host, iana_afi2str(pkt_afi),
1885 iana_safi2str(pkt_safi));
d62a17ae 1886
1887 /* Convert AFI, SAFI to internal values and check. */
1888 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
1889 zlog_info(
748a041f
DS
1890 "%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored",
1891 peer->host, iana_afi2str(pkt_afi),
1892 iana_safi2str(pkt_safi));
d8151687 1893 return BGP_PACKET_NOOP;
d62a17ae 1894 }
1895
1896 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) {
d7c0a89a
QY
1897 uint8_t *end;
1898 uint8_t when_to_refresh;
1899 uint8_t orf_type;
1900 uint16_t orf_len;
d62a17ae 1901
1902 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1903 < 5) {
1904 zlog_info("%s ORF route refresh length error",
1905 peer->host);
0e35025e
DA
1906 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1907 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1908 return BGP_Stop;
718e3744 1909 }
1910
d62a17ae 1911 when_to_refresh = stream_getc(s);
1912 end = stream_pnt(s) + (size - 5);
1913
1914 while ((stream_pnt(s) + 2) < end) {
1915 orf_type = stream_getc(s);
1916 orf_len = stream_getw(s);
1917
1918 /* orf_len in bounds? */
1919 if ((stream_pnt(s) + orf_len) > end)
1920 break; /* XXX: Notify instead?? */
1921 if (orf_type == ORF_TYPE_PREFIX
1922 || orf_type == ORF_TYPE_PREFIX_OLD) {
1923 uint8_t *p_pnt = stream_pnt(s);
1924 uint8_t *p_end = stream_pnt(s) + orf_len;
1925 struct orf_prefix orfp;
d7c0a89a
QY
1926 uint8_t common = 0;
1927 uint32_t seq;
d62a17ae 1928 int psize;
1929 char name[BUFSIZ];
1930 int ret = CMD_SUCCESS;
1931
1932 if (bgp_debug_neighbor_events(peer)) {
1933 zlog_debug(
1934 "%s rcvd Prefixlist ORF(%d) length %d",
1935 peer->host, orf_type, orf_len);
1936 }
1937
1938 /* we're going to read at least 1 byte of common
1939 * ORF header,
1940 * and 7 bytes of ORF Address-filter entry from
1941 * the stream
1942 */
1943 if (orf_len < 7)
1944 break;
1945
1946 /* ORF prefix-list name */
1947 sprintf(name, "%s.%d.%d", peer->host, afi,
1948 safi);
1949
1950 while (p_pnt < p_end) {
1951 /* If the ORF entry is malformed, want
1952 * to read as much of it
1953 * as possible without going beyond the
1954 * bounds of the entry,
1955 * to maximise debug information.
1956 */
1957 int ok;
1958 memset(&orfp, 0,
1959 sizeof(struct orf_prefix));
1960 common = *p_pnt++;
1961 /* after ++: p_pnt <= p_end */
1962 if (common
1963 & ORF_COMMON_PART_REMOVE_ALL) {
1964 if (bgp_debug_neighbor_events(
1965 peer))
1966 zlog_debug(
1967 "%s rcvd Remove-All pfxlist ORF request",
1968 peer->host);
1969 prefix_bgp_orf_remove_all(afi,
1970 name);
1971 break;
1972 }
d7c0a89a
QY
1973 ok = ((uint32_t)(p_end - p_pnt)
1974 >= sizeof(uint32_t));
d62a17ae 1975 if (ok) {
1976 memcpy(&seq, p_pnt,
d7c0a89a
QY
1977 sizeof(uint32_t));
1978 p_pnt += sizeof(uint32_t);
d62a17ae 1979 orfp.seq = ntohl(seq);
1980 } else
1981 p_pnt = p_end;
1982
5ca840a3 1983 /* val checked in prefix_bgp_orf_set */
1bb379bf 1984 if (p_pnt < p_end)
5ca840a3
DS
1985 orfp.ge = *p_pnt++;
1986
1987 /* val checked in prefix_bgp_orf_set */
1bb379bf 1988 if (p_pnt < p_end)
5ca840a3
DS
1989 orfp.le = *p_pnt++;
1990
d62a17ae 1991 if ((ok = (p_pnt < p_end)))
1992 orfp.p.prefixlen = *p_pnt++;
5ca840a3
DS
1993
1994 /* afi checked already */
1995 orfp.p.family = afi2family(afi);
1996
1997 /* 0 if not ok */
1998 psize = PSIZE(orfp.p.prefixlen);
1999 /* valid for family ? */
2000 if (psize > prefix_blen(&orfp.p)) {
d62a17ae 2001 ok = 0;
2002 psize = prefix_blen(&orfp.p);
2003 }
5ca840a3
DS
2004 /* valid for packet ? */
2005 if (psize > (p_end - p_pnt)) {
d62a17ae 2006 ok = 0;
2007 psize = p_end - p_pnt;
2008 }
2009
2010 if (psize > 0)
2011 memcpy(&orfp.p.u.prefix, p_pnt,
2012 psize);
2013 p_pnt += psize;
2014
2015 if (bgp_debug_neighbor_events(peer)) {
2016 char buf[INET6_BUFSIZ];
2017
2018 zlog_debug(
2019 "%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2020 peer->host,
2021 (common & ORF_COMMON_PART_REMOVE
2022 ? "Remove"
2023 : "Add"),
2024 (common & ORF_COMMON_PART_DENY
2025 ? "deny"
2026 : "permit"),
2027 orfp.seq,
2028 inet_ntop(
2029 orfp.p.family,
2030 &orfp.p.u.prefix,
2031 buf,
2032 INET6_BUFSIZ),
2033 orfp.p.prefixlen,
2034 orfp.ge, orfp.le,
2035 ok ? "" : " MALFORMED");
2036 }
2037
2038 if (ok)
2039 ret = prefix_bgp_orf_set(
2040 name, afi, &orfp,
2041 (common & ORF_COMMON_PART_DENY
2042 ? 0
2043 : 1),
2044 (common & ORF_COMMON_PART_REMOVE
2045 ? 0
2046 : 1));
2047
2048 if (!ok || (ok && ret != CMD_SUCCESS)) {
2049 zlog_info(
2050 "%s Received misformatted prefixlist ORF."
2051 " Remove All pfxlist",
2052 peer->host);
2053 prefix_bgp_orf_remove_all(afi,
2054 name);
2055 break;
2056 }
2057 }
2058
2059 peer->orf_plist[afi][safi] =
2060 prefix_bgp_orf_lookup(afi, name);
2061 }
2062 stream_forward_getp(s, orf_len);
718e3744 2063 }
d62a17ae 2064 if (bgp_debug_neighbor_events(peer))
2065 zlog_debug("%s rcvd Refresh %s ORF request", peer->host,
2066 when_to_refresh == REFRESH_DEFER
2067 ? "Defer"
2068 : "Immediate");
2069 if (when_to_refresh == REFRESH_DEFER)
d8151687 2070 return BGP_PACKET_NOOP;
d62a17ae 2071 }
40d2700d 2072
d62a17ae 2073 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2074 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2075 PEER_STATUS_ORF_WAIT_REFRESH))
2076 UNSET_FLAG(peer->af_sflags[afi][safi],
2077 PEER_STATUS_ORF_WAIT_REFRESH);
2078
2079 paf = peer_af_find(peer, afi, safi);
2080 if (paf && paf->subgroup) {
2081 if (peer->orf_plist[afi][safi]) {
2082 updgrp = PAF_UPDGRP(paf);
2083 updgrp_peer = UPDGRP_PEER(updgrp);
2084 updgrp_peer->orf_plist[afi][safi] =
2085 peer->orf_plist[afi][safi];
2086 }
2087
2088 /* If the peer is configured for default-originate clear the
2089 * SUBGRP_STATUS_DEFAULT_ORIGINATE flag so that we will
2090 * re-advertise the
2091 * default
2092 */
2093 if (CHECK_FLAG(paf->subgroup->sflags,
2094 SUBGRP_STATUS_DEFAULT_ORIGINATE))
2095 UNSET_FLAG(paf->subgroup->sflags,
2096 SUBGRP_STATUS_DEFAULT_ORIGINATE);
718e3744 2097 }
d62a17ae 2098
2099 /* Perform route refreshment to the peer */
2100 bgp_announce_route(peer, afi, safi);
d8151687
QY
2101
2102 /* No FSM action necessary */
2103 return BGP_PACKET_NOOP;
718e3744 2104}
2105
d8151687
QY
2106/**
2107 * Parse BGP CAPABILITY message for peer.
2108 *
2109 * @param peer
2110 * @param size size of the packet
2111 * @return as in summary
2112 */
d7c0a89a 2113static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
d62a17ae 2114 bgp_size_t length)
718e3744 2115{
d7c0a89a 2116 uint8_t *end;
d62a17ae 2117 struct capability_mp_data mpc;
2118 struct capability_header *hdr;
d7c0a89a 2119 uint8_t action;
d62a17ae 2120 iana_afi_t pkt_afi;
2121 afi_t afi;
5c525538
RW
2122 iana_safi_t pkt_safi;
2123 safi_t safi;
d62a17ae 2124
2125 end = pnt + length;
2126
2127 while (pnt < end) {
2128 /* We need at least action, capability code and capability
2129 * length. */
2130 if (pnt + 3 > end) {
2131 zlog_info("%s Capability length error", peer->host);
0e35025e
DA
2132 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2133 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2134 return BGP_Stop;
d62a17ae 2135 }
2136 action = *pnt;
2137 hdr = (struct capability_header *)(pnt + 1);
2138
2139 /* Action value check. */
2140 if (action != CAPABILITY_ACTION_SET
2141 && action != CAPABILITY_ACTION_UNSET) {
2142 zlog_info("%s Capability Action Value error %d",
2143 peer->host, action);
0e35025e
DA
2144 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2145 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2146 return BGP_Stop;
d62a17ae 2147 }
2148
2149 if (bgp_debug_neighbor_events(peer))
2150 zlog_debug(
2151 "%s CAPABILITY has action: %d, code: %u, length %u",
2152 peer->host, action, hdr->code, hdr->length);
2153
2154 /* Capability length check. */
2155 if ((pnt + hdr->length + 3) > end) {
2156 zlog_info("%s Capability length error", peer->host);
0e35025e
DA
2157 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2158 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2159 return BGP_Stop;
d62a17ae 2160 }
2161
2162 /* Fetch structure to the byte stream. */
2163 memcpy(&mpc, pnt + 3, sizeof(struct capability_mp_data));
d2b6417b 2164 pnt += hdr->length + 3;
d62a17ae 2165
2166 /* We know MP Capability Code. */
2167 if (hdr->code == CAPABILITY_CODE_MP) {
2168 pkt_afi = ntohs(mpc.afi);
2169 pkt_safi = mpc.safi;
2170
2171 /* Ignore capability when override-capability is set. */
2172 if (CHECK_FLAG(peer->flags,
2173 PEER_FLAG_OVERRIDE_CAPABILITY))
2174 continue;
2175
2176 /* Convert AFI, SAFI to internal values. */
2177 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
2178 &safi)) {
2179 if (bgp_debug_neighbor_events(peer))
2180 zlog_debug(
2181 "%s Dynamic Capability MP_EXT afi/safi invalid "
748a041f
DS
2182 "(%s/%s)",
2183 peer->host,
2184 iana_afi2str(pkt_afi),
2185 iana_safi2str(pkt_safi));
d62a17ae 2186 continue;
2187 }
2188
2189 /* Address family check. */
2190 if (bgp_debug_neighbor_events(peer))
2191 zlog_debug(
2192 "%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2193 peer->host,
2194 action == CAPABILITY_ACTION_SET
2195 ? "Advertising"
2196 : "Removing",
2197 pkt_afi, pkt_safi);
2198
2199 if (action == CAPABILITY_ACTION_SET) {
2200 peer->afc_recv[afi][safi] = 1;
2201 if (peer->afc[afi][safi]) {
2202 peer->afc_nego[afi][safi] = 1;
2203 bgp_announce_route(peer, afi, safi);
2204 }
2205 } else {
2206 peer->afc_recv[afi][safi] = 0;
2207 peer->afc_nego[afi][safi] = 0;
2208
2209 if (peer_active_nego(peer))
2210 bgp_clear_route(peer, afi, safi);
2211 else
d8151687 2212 return BGP_Stop;
d62a17ae 2213 }
2214 } else {
ade6974d 2215 flog_warn(
e50f7cfd 2216 EC_BGP_UNRECOGNIZED_CAPABILITY,
ade6974d
QY
2217 "%s unrecognized capability code: %d - ignored",
2218 peer->host, hdr->code);
d62a17ae 2219 }
d62a17ae 2220 }
d8151687
QY
2221
2222 /* No FSM action necessary */
2223 return BGP_PACKET_NOOP;
718e3744 2224}
2225
d8151687
QY
2226/**
2227 * Parse BGP CAPABILITY message for peer.
01b7ce2d 2228 *
d8151687
QY
2229 * Exported for unit testing.
2230 *
2231 * @param peer
2232 * @param size size of the packet
2233 * @return as in summary
01b7ce2d 2234 */
d62a17ae 2235int bgp_capability_receive(struct peer *peer, bgp_size_t size)
718e3744 2236{
d7c0a89a 2237 uint8_t *pnt;
d62a17ae 2238
2239 /* Fetch pointer. */
424ab01d 2240 pnt = stream_pnt(peer->curr);
d62a17ae 2241
2242 if (bgp_debug_neighbor_events(peer))
2243 zlog_debug("%s rcv CAPABILITY", peer->host);
2244
2245 /* If peer does not have the capability, send notification. */
2246 if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) {
e50f7cfd 2247 flog_err(EC_BGP_NO_CAP,
1c50c1c0
QY
2248 "%s [Error] BGP dynamic capability is not enabled",
2249 peer->host);
d62a17ae 2250 bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
2251 BGP_NOTIFY_HEADER_BAD_MESTYPE);
d8151687 2252 return BGP_Stop;
d62a17ae 2253 }
2254
2255 /* Status must be Established. */
2256 if (peer->status != Established) {
af4c2728 2257 flog_err(
e50f7cfd 2258 EC_BGP_NO_CAP,
d62a17ae 2259 "%s [Error] Dynamic capability packet received under status %s",
2260 peer->host,
2261 lookup_msg(bgp_status_msg, peer->status, NULL));
0e35025e 2262 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
3893aeee 2263 bgp_fsm_error_subcode(peer->status));
d8151687 2264 return BGP_Stop;
d62a17ae 2265 }
2266
2267 /* Parse packet. */
2268 return bgp_capability_msg_parse(peer, pnt, size);
718e3744 2269}
6b0655a2 2270
d8151687
QY
2271/**
2272 * Processes a peer's input buffer.
2273 *
2274 * This function sidesteps the event loop and directly calls bgp_event_update()
2275 * after processing each BGP message. This is necessary to ensure proper
2276 * ordering of FSM events and unifies the behavior that was present previously,
2277 * whereby some of the packet handling functions would update the FSM and some
2278 * would not, making event flow difficult to understand. Please think twice
2279 * before hacking this.
2280 *
2281 * Thread type: THREAD_EVENT
2282 * @param thread
2283 * @return 0
2284 */
424ab01d 2285int bgp_process_packet(struct thread *thread)
718e3744 2286{
424ab01d 2287 /* Yes first of all get peer pointer. */
d8151687
QY
2288 struct peer *peer; // peer
2289 uint32_t rpkt_quanta_old; // how many packets to read
2290 int fsm_update_result; // return code of bgp_event_update()
2291 int mprc; // message processing return code
555e09d4 2292
424ab01d 2293 peer = THREAD_ARG(thread);
555e09d4
QY
2294 rpkt_quanta_old = atomic_load_explicit(&peer->bgp->rpkt_quanta,
2295 memory_order_relaxed);
e3c7270d 2296 fsm_update_result = 0;
555e09d4 2297
424ab01d 2298 /* Guard against scheduled events that occur after peer deletion. */
9eb217ff 2299 if (peer->status == Deleted || peer->status == Clearing)
d62a17ae 2300 return 0;
718e3744 2301
555e09d4 2302 unsigned int processed = 0;
d62a17ae 2303
555e09d4 2304 while (processed < rpkt_quanta_old) {
d7c0a89a 2305 uint8_t type = 0;
9eb217ff
QY
2306 bgp_size_t size;
2307 char notify_data_length[2];
d62a17ae 2308
00dffa8c 2309 frr_with_mutex(&peer->io_mtx) {
9eb217ff
QY
2310 peer->curr = stream_fifo_pop(peer->ibuf);
2311 }
d62a17ae 2312
9eb217ff
QY
2313 if (peer->curr == NULL) // no packets to process, hmm...
2314 return 0;
d62a17ae 2315
9eb217ff
QY
2316 /* skip the marker and copy the packet length */
2317 stream_forward_getp(peer->curr, BGP_MARKER_SIZE);
2318 memcpy(notify_data_length, stream_pnt(peer->curr), 2);
2319
2320 /* read in the packet length and type */
2321 size = stream_getw(peer->curr);
2322 type = stream_getc(peer->curr);
2323
584470fb 2324 hook_call(bgp_packet_dump, peer, type, size, peer->curr);
9eb217ff
QY
2325
2326 /* adjust size to exclude the marker + length + type */
2327 size -= BGP_HEADER_SIZE;
2328
2329 /* Read rest of the packet and call each sort of packet routine
2330 */
2331 switch (type) {
2332 case BGP_MSG_OPEN:
0112e9e0
QY
2333 atomic_fetch_add_explicit(&peer->open_in, 1,
2334 memory_order_relaxed);
d8151687
QY
2335 mprc = bgp_open_receive(peer, size);
2336 if (mprc == BGP_Stop)
af4c2728 2337 flog_err(
e50f7cfd 2338 EC_BGP_PKT_OPEN,
d8151687 2339 "%s: BGP OPEN receipt failed for peer: %s",
0767b4f3 2340 __func__, peer->host);
9eb217ff
QY
2341 break;
2342 case BGP_MSG_UPDATE:
0112e9e0
QY
2343 atomic_fetch_add_explicit(&peer->update_in, 1,
2344 memory_order_relaxed);
9eb217ff 2345 peer->readtime = monotime(NULL);
d8151687
QY
2346 mprc = bgp_update_receive(peer, size);
2347 if (mprc == BGP_Stop)
af4c2728 2348 flog_err(
e50f7cfd 2349 EC_BGP_UPDATE_RCV,
d8151687 2350 "%s: BGP UPDATE receipt failed for peer: %s",
0767b4f3 2351 __func__, peer->host);
9eb217ff
QY
2352 break;
2353 case BGP_MSG_NOTIFY:
0112e9e0
QY
2354 atomic_fetch_add_explicit(&peer->notify_in, 1,
2355 memory_order_relaxed);
d8151687
QY
2356 mprc = bgp_notify_receive(peer, size);
2357 if (mprc == BGP_Stop)
af4c2728 2358 flog_err(
e50f7cfd 2359 EC_BGP_NOTIFY_RCV,
d8151687 2360 "%s: BGP NOTIFY receipt failed for peer: %s",
0767b4f3 2361 __func__, peer->host);
9eb217ff
QY
2362 break;
2363 case BGP_MSG_KEEPALIVE:
2364 peer->readtime = monotime(NULL);
0112e9e0
QY
2365 atomic_fetch_add_explicit(&peer->keepalive_in, 1,
2366 memory_order_relaxed);
d8151687
QY
2367 mprc = bgp_keepalive_receive(peer, size);
2368 if (mprc == BGP_Stop)
af4c2728 2369 flog_err(
e50f7cfd 2370 EC_BGP_KEEP_RCV,
d8151687 2371 "%s: BGP KEEPALIVE receipt failed for peer: %s",
0767b4f3 2372 __func__, peer->host);
9eb217ff
QY
2373 break;
2374 case BGP_MSG_ROUTE_REFRESH_NEW:
2375 case BGP_MSG_ROUTE_REFRESH_OLD:
0112e9e0
QY
2376 atomic_fetch_add_explicit(&peer->refresh_in, 1,
2377 memory_order_relaxed);
d8151687
QY
2378 mprc = bgp_route_refresh_receive(peer, size);
2379 if (mprc == BGP_Stop)
af4c2728 2380 flog_err(
e50f7cfd 2381 EC_BGP_RFSH_RCV,
d8151687 2382 "%s: BGP ROUTEREFRESH receipt failed for peer: %s",
0767b4f3 2383 __func__, peer->host);
9eb217ff
QY
2384 break;
2385 case BGP_MSG_CAPABILITY:
0112e9e0
QY
2386 atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1,
2387 memory_order_relaxed);
d8151687
QY
2388 mprc = bgp_capability_receive(peer, size);
2389 if (mprc == BGP_Stop)
af4c2728 2390 flog_err(
e50f7cfd 2391 EC_BGP_CAP_RCV,
d8151687 2392 "%s: BGP CAPABILITY receipt failed for peer: %s",
0767b4f3 2393 __func__, peer->host);
9eb217ff 2394 break;
e3c7270d 2395 default:
db878db0
QY
2396 /* Suppress uninitialized variable warning */
2397 mprc = 0;
5041dc4f 2398 (void)mprc;
becedef6
QY
2399 /*
2400 * The message type should have been sanitized before
2401 * we ever got here. Receipt of a message with an
2402 * invalid header at this point is indicative of a
2403 * security issue.
2404 */
e3c7270d 2405 assert (!"Message of invalid type received during input processing");
9eb217ff
QY
2406 }
2407
d8151687
QY
2408 /* delete processed packet */
2409 stream_free(peer->curr);
2410 peer->curr = NULL;
2411 processed++;
9eb217ff 2412
d8151687
QY
2413 /* Update FSM */
2414 if (mprc != BGP_PACKET_NOOP)
2415 fsm_update_result = bgp_event_update(peer, mprc);
e3c7270d
QY
2416 else
2417 continue;
d8151687 2418
becedef6
QY
2419 /*
2420 * If peer was deleted, do not process any more packets. This
2421 * is usually due to executing BGP_Stop or a stub deletion.
2422 */
d8151687
QY
2423 if (fsm_update_result == FSM_PEER_TRANSFERRED
2424 || fsm_update_result == FSM_PEER_STOPPED)
2425 break;
d62a17ae 2426 }
2427
d8151687
QY
2428 if (fsm_update_result != FSM_PEER_TRANSFERRED
2429 && fsm_update_result != FSM_PEER_STOPPED) {
00dffa8c 2430 frr_with_mutex(&peer->io_mtx) {
becedef6
QY
2431 // more work to do, come back later
2432 if (peer->ibuf->count > 0)
4af76660
QY
2433 thread_add_timer_msec(
2434 bm->master, bgp_process_packet, peer, 0,
2435 &peer->t_process_packet);
d8151687 2436 }
718e3744 2437 }
2438
d62a17ae 2439 return 0;
718e3744 2440}
9e3b51a7 2441
2442/* Send EOR when routes are processed by selection deferral timer */
2443void bgp_send_delayed_eor(struct bgp *bgp)
2444{
2445 struct peer *peer;
2446 struct listnode *node, *nnode;
2447
2448 /* EOR message sent in bgp_write_proceed_actions */
2449 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
2450 bgp_write_proceed_actions(peer);
2451}