]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_packet.c
Merge pull request #5761 from qlyoung/fix-bgp-gr-cruft
[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);
976 return (-1);
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 {
1010 /* 3. Otherwise, the local system closes newly
1011 created
1012 BGP connection (the one associated with the
1013 newly
1014 received OPEN message), and continues to use
1015 the
1016 existing one (the one that is already in the
1017 OpenConfirm state). */
1018 if (CHECK_FLAG(peer->sflags,
1019 PEER_STATUS_ACCEPT_PEER)) {
1020 bgp_notify_send(
1021 peer, BGP_NOTIFY_CEASE,
1022 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1023 return 1;
1024 } else {
1025 bgp_notify_send(
1026 new, BGP_NOTIFY_CEASE,
1027 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1028 return -1;
1029 }
1030 }
1031 }
1032 }
1033 return 0;
1034}
718e3744 1035
d8151687
QY
1036/* Packet processing routines ---------------------------------------------- */
1037/*
1038 * This is a family of functions designed to be called from
1039 * bgp_process_packet(). These functions all share similar behavior and should
1040 * adhere to the following invariants and restrictions:
1041 *
1042 * Return codes
1043 * ------------
1044 * The return code of any one of those functions should be one of the FSM event
1045 * codes specified in bgpd.h. If a NOTIFY was sent, this event code MUST be
1046 * BGP_Stop. Otherwise, the code SHOULD correspond to the function's expected
1047 * packet type. For example, bgp_open_receive() should return BGP_Stop upon
1048 * error and Receive_OPEN_message otherwise.
1049 *
1050 * If no action is necessary, the correct return code is BGP_PACKET_NOOP as
1051 * defined below.
1052 *
1053 * Side effects
1054 * ------------
1055 * - May send NOTIFY messages
1056 * - May not modify peer->status
1057 * - May not call bgp_event_update()
1058 */
1059
1060#define BGP_PACKET_NOOP 0
1061
1062/**
1063 * Process BGP OPEN message for peer.
1064 *
1065 * If any errors are encountered in the OPEN message, immediately sends NOTIFY
1066 * and returns BGP_Stop.
1067 *
1068 * @param peer
1069 * @param size size of the packet
1070 * @return as in summary
1071 */
d62a17ae 1072static int bgp_open_receive(struct peer *peer, bgp_size_t size)
1073{
1074 int ret;
d7c0a89a
QY
1075 uint8_t version;
1076 uint8_t optlen;
1077 uint16_t holdtime;
1078 uint16_t send_holdtime;
d62a17ae 1079 as_t remote_as;
6dcef54c 1080 as_t as4 = 0, as4_be;
d62a17ae 1081 struct in_addr remote_id;
1082 int mp_capability;
d7c0a89a
QY
1083 uint8_t notify_data_remote_as[2];
1084 uint8_t notify_data_remote_as4[4];
1085 uint8_t notify_data_remote_id[4];
1086 uint16_t *holdtime_ptr;
d62a17ae 1087
1088 /* Parse open packet. */
424ab01d
QY
1089 version = stream_getc(peer->curr);
1090 memcpy(notify_data_remote_as, stream_pnt(peer->curr), 2);
1091 remote_as = stream_getw(peer->curr);
d7c0a89a 1092 holdtime_ptr = (uint16_t *)stream_pnt(peer->curr);
424ab01d
QY
1093 holdtime = stream_getw(peer->curr);
1094 memcpy(notify_data_remote_id, stream_pnt(peer->curr), 4);
1095 remote_id.s_addr = stream_get_ipv4(peer->curr);
d62a17ae 1096
1097 /* Receive OPEN message log */
1098 if (bgp_debug_neighbor_events(peer))
1099 zlog_debug(
1100 "%s rcv OPEN, version %d, remote-as (in open) %u,"
1101 " holdtime %d, id %s",
1102 peer->host, version, remote_as, holdtime,
1103 inet_ntoa(remote_id));
1104
1105 /* BEGIN to read the capability here, but dont do it yet */
1106 mp_capability = 0;
424ab01d 1107 optlen = stream_getc(peer->curr);
d62a17ae 1108
1109 if (optlen != 0) {
1110 /* If not enough bytes, it is an error. */
424ab01d 1111 if (STREAM_READABLE(peer->curr) < optlen) {
d62a17ae 1112 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1113 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
d8151687 1114 return BGP_Stop;
d62a17ae 1115 }
718e3744 1116
d62a17ae 1117 /* We need the as4 capability value *right now* because
1118 * if it is there, we have not got the remote_as yet, and
1119 * without
1120 * that we do not know which peer is connecting to us now.
1121 */
1122 as4 = peek_for_as4_capability(peer, optlen);
d62a17ae 1123 }
718e3744 1124
6dcef54c
DL
1125 as4_be = htonl(as4);
1126 memcpy(notify_data_remote_as4, &as4_be, 4);
1127
d62a17ae 1128 /* Just in case we have a silly peer who sends AS4 capability set to 0
1129 */
1130 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && !as4) {
e50f7cfd 1131 flog_err(EC_BGP_PKT_OPEN,
1c50c1c0
QY
1132 "%s bad OPEN, got AS4 capability, but AS4 set to 0",
1133 peer->host);
d62a17ae 1134 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1135 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1136 notify_data_remote_as4, 4);
d8151687 1137 return BGP_Stop;
d62a17ae 1138 }
718e3744 1139
d62a17ae 1140 if (remote_as == BGP_AS_TRANS) {
1141 /* Take the AS4 from the capability. We must have received the
1142 * capability now! Otherwise we have a asn16 peer who uses
1143 * BGP_AS_TRANS, for some unknown reason.
1144 */
1145 if (as4 == BGP_AS_TRANS) {
af4c2728 1146 flog_err(
e50f7cfd 1147 EC_BGP_PKT_OPEN,
d62a17ae 1148 "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1149 peer->host);
1150 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1151 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1152 notify_data_remote_as4, 4);
d8151687 1153 return BGP_Stop;
d62a17ae 1154 }
718e3744 1155
d62a17ae 1156 if (!as4 && BGP_DEBUG(as4, AS4))
1157 zlog_debug(
1158 "%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1159 " Odd, but proceeding.",
1160 peer->host);
1161 else if (as4 < BGP_AS_MAX && BGP_DEBUG(as4, AS4))
1162 zlog_debug(
1163 "%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
1164 "in 2-bytes, very odd peer.",
1165 peer->host, as4);
1166 if (as4)
1167 remote_as = as4;
1168 } else {
1169 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX
1170 */
1171 /* If we have got the capability, peer->as4cap must match
1172 * remote_as */
1173 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1174 && as4 != remote_as) {
1175 /* raise error, log this, close session */
af4c2728 1176 flog_err(
e50f7cfd 1177 EC_BGP_PKT_OPEN,
d62a17ae 1178 "%s bad OPEN, got AS4 capability, but remote_as %u"
1179 " mismatch with 16bit 'myasn' %u in open",
1180 peer->host, as4, remote_as);
1181 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1182 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1183 notify_data_remote_as4, 4);
d8151687 1184 return BGP_Stop;
d62a17ae 1185 }
1186 }
6b0655a2 1187
d62a17ae 1188 /* remote router-id check. */
1189 if (remote_id.s_addr == 0 || IPV4_CLASS_DE(ntohl(remote_id.s_addr))
1190 || ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)) {
1191 if (bgp_debug_neighbor_events(peer))
1192 zlog_debug("%s bad OPEN, wrong router identifier %s",
1193 peer->host, inet_ntoa(remote_id));
1194 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1195 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1196 notify_data_remote_id, 4);
d8151687 1197 return BGP_Stop;
d62a17ae 1198 }
1199
1200 /* Set remote router-id */
1201 peer->remote_id = remote_id;
1202
1203 /* Peer BGP version check. */
1204 if (version != BGP_VERSION_4) {
d7c0a89a 1205 uint16_t maxver = htons(BGP_VERSION_4);
d62a17ae 1206 /* XXX this reply may not be correct if version < 4 XXX */
1207 if (bgp_debug_neighbor_events(peer))
1208 zlog_debug(
1209 "%s bad protocol version, remote requested %d, local request %d",
1210 peer->host, version, BGP_VERSION_4);
1211 /* Data must be in network byte order here */
1212 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1213 BGP_NOTIFY_OPEN_UNSUP_VERSION,
d7c0a89a 1214 (uint8_t *)&maxver, 2);
d8151687 1215 return BGP_Stop;
d62a17ae 1216 }
1217
1218 /* Check neighbor as number. */
1219 if (peer->as_type == AS_UNSPECIFIED) {
1220 if (bgp_debug_neighbor_events(peer))
1221 zlog_debug(
1222 "%s bad OPEN, remote AS is unspecified currently",
1223 peer->host);
1224 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1225 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1226 notify_data_remote_as, 2);
d8151687 1227 return BGP_Stop;
d62a17ae 1228 } else if (peer->as_type == AS_INTERNAL) {
1229 if (remote_as != peer->bgp->as) {
1230 if (bgp_debug_neighbor_events(peer))
1231 zlog_debug(
1232 "%s bad OPEN, remote AS is %u, internal specified",
1233 peer->host, remote_as);
1234 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1235 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1236 notify_data_remote_as, 2);
d8151687 1237 return BGP_Stop;
1ff9a340 1238 }
d62a17ae 1239 peer->as = peer->local_as;
1240 } else if (peer->as_type == AS_EXTERNAL) {
1241 if (remote_as == peer->bgp->as) {
1242 if (bgp_debug_neighbor_events(peer))
1243 zlog_debug(
1244 "%s bad OPEN, remote AS is %u, external specified",
1245 peer->host, remote_as);
1246 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1247 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1248 notify_data_remote_as, 2);
d8151687 1249 return BGP_Stop;
1ff9a340 1250 }
d62a17ae 1251 peer->as = remote_as;
1252 } else if ((peer->as_type == AS_SPECIFIED) && (remote_as != peer->as)) {
1253 if (bgp_debug_neighbor_events(peer))
1254 zlog_debug("%s bad OPEN, remote AS is %u, expected %u",
1255 peer->host, remote_as, peer->as);
1256 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1257 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1258 notify_data_remote_as, 2);
d8151687 1259 return BGP_Stop;
eb821189 1260 }
718e3744 1261
d62a17ae 1262 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1263 calculate the value of the Hold Timer by using the smaller of its
1264 configured Hold Time and the Hold Time received in the OPEN message.
1265 The Hold Time MUST be either zero or at least three seconds. An
1266 implementation may reject connections on the basis of the Hold Time.
0b2aa3a0 1267 */
d62a17ae 1268
1269 if (holdtime < 3 && holdtime != 0) {
1270 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1271 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
d7c0a89a 1272 (uint8_t *)holdtime_ptr, 2);
d8151687 1273 return BGP_Stop;
0b2aa3a0 1274 }
d62a17ae 1275
1276 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1277 would be one third of the Hold Time interval. KEEPALIVE messages
1278 MUST NOT be sent more frequently than one per second. An
1279 implementation MAY adjust the rate at which it sends KEEPALIVE
1280 messages as a function of the Hold Time interval. */
1281
b90a8e13 1282 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
d62a17ae 1283 send_holdtime = peer->holdtime;
1284 else
1285 send_holdtime = peer->bgp->default_holdtime;
1286
1287 if (holdtime < send_holdtime)
1288 peer->v_holdtime = holdtime;
1289 else
1290 peer->v_holdtime = send_holdtime;
1291
b90a8e13 1292 if ((CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
d25e4efc 1293 && (peer->keepalive < peer->v_holdtime / 3))
d62a17ae 1294 peer->v_keepalive = peer->keepalive;
1295 else
1296 peer->v_keepalive = peer->v_holdtime / 3;
1297
1298 /* Open option part parse. */
1299 if (optlen != 0) {
1300 if ((ret = bgp_open_option_parse(peer, optlen, &mp_capability))
1301 < 0)
d8151687 1302 return BGP_Stop;
d62a17ae 1303 } else {
1304 if (bgp_debug_neighbor_events(peer))
1305 zlog_debug("%s rcvd OPEN w/ OPTION parameter len: 0",
1306 peer->host);
0299c004 1307 }
d62a17ae 1308
1309 /*
1310 * Assume that the peer supports the locally configured set of
1311 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1312 * capabilities, or if 'override-capability' is configured.
1313 */
1314 if (!mp_capability
1315 || CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1316 peer->afc_nego[AFI_IP][SAFI_UNICAST] =
1317 peer->afc[AFI_IP][SAFI_UNICAST];
1318 peer->afc_nego[AFI_IP][SAFI_MULTICAST] =
1319 peer->afc[AFI_IP][SAFI_MULTICAST];
1320 peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] =
1321 peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
7c40bf39 1322 peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] =
1323 peer->afc[AFI_IP][SAFI_FLOWSPEC];
d62a17ae 1324 peer->afc_nego[AFI_IP6][SAFI_UNICAST] =
1325 peer->afc[AFI_IP6][SAFI_UNICAST];
1326 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] =
1327 peer->afc[AFI_IP6][SAFI_MULTICAST];
1328 peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] =
1329 peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
1330 peer->afc_nego[AFI_L2VPN][SAFI_EVPN] =
1331 peer->afc[AFI_L2VPN][SAFI_EVPN];
7c40bf39 1332 peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] =
1333 peer->afc[AFI_IP6][SAFI_FLOWSPEC];
0299c004 1334 }
d62a17ae 1335
1336 /* When collision is detected and this peer is closed. Retrun
1337 immidiately. */
1338 ret = bgp_collision_detect(peer, remote_id);
1339 if (ret < 0)
d8151687 1340 return BGP_Stop;
d62a17ae 1341
1342 /* Get sockname. */
1343 if ((ret = bgp_getsockname(peer)) < 0) {
450971aa 1344 flog_err_sys(EC_LIB_SOCKET,
09c866e3
QY
1345 "%s: bgp_getsockname() failed for peer: %s",
1346 __FUNCTION__, peer->host);
d8151687 1347 return BGP_Stop;
d62a17ae 1348 }
1349
1350 /* Verify valid local address present based on negotiated
1351 * address-families. */
1352 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
e5f22b30 1353 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
d62a17ae 1354 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1355 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1356 || peer->afc_nego[AFI_IP][SAFI_ENCAP]) {
1357 if (!peer->nexthop.v4.s_addr) {
1358#if defined(HAVE_CUMULUS)
af4c2728 1359 flog_err(
e50f7cfd 1360 EC_BGP_SND_FAIL,
d62a17ae 1361 "%s: No local IPv4 addr resetting connection, fd %d",
1362 peer->host, peer->fd);
1363 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1364 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1365 return BGP_Stop;
1d808091 1366#endif
d62a17ae 1367 }
1368 }
1369 if (peer->afc_nego[AFI_IP6][SAFI_UNICAST]
e5f22b30 1370 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
d62a17ae 1371 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1372 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1373 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) {
1374 if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) {
1375#if defined(HAVE_CUMULUS)
af4c2728 1376 flog_err(
e50f7cfd 1377 EC_BGP_SND_FAIL,
d62a17ae 1378 "%s: No local IPv6 addr resetting connection, fd %d",
1379 peer->host, peer->fd);
1380 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1381 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1382 return BGP_Stop;
1d808091 1383#endif
d62a17ae 1384 }
1385 }
1386 peer->rtt = sockopt_tcp_rtt(peer->fd);
1387
d8151687 1388 return Receive_OPEN_message;
718e3744 1389}
1390
d8151687
QY
1391/**
1392 * Process BGP KEEPALIVE message for peer.
1393 *
1394 * @param peer
1395 * @param size size of the packet
1396 * @return as in summary
1397 */
1398static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size)
f188f2c4 1399{
d8151687
QY
1400 if (bgp_debug_keepalive(peer))
1401 zlog_debug("%s KEEPALIVE rcvd", peer->host);
d62a17ae 1402
d8151687 1403 bgp_update_implicit_eors(peer);
d62a17ae 1404
d8151687 1405 return Receive_KEEPALIVE_message;
f188f2c4
DS
1406}
1407
d62a17ae 1408
d8151687
QY
1409/**
1410 * Process BGP UPDATE message for peer.
1411 *
1412 * Parses UPDATE and creates attribute object.
1413 *
1414 * @param peer
1415 * @param size size of the packet
1416 * @return as in summary
7ef5a232 1417 */
d62a17ae 1418static int bgp_update_receive(struct peer *peer, bgp_size_t size)
718e3744 1419{
d62a17ae 1420 int ret, nlri_ret;
d7c0a89a 1421 uint8_t *end;
d62a17ae 1422 struct stream *s;
1423 struct attr attr;
1424 bgp_size_t attribute_len;
1425 bgp_size_t update_len;
1426 bgp_size_t withdraw_len;
f009ff26 1427 bool restart = false;
d62a17ae 1428
1429 enum NLRI_TYPES {
1430 NLRI_UPDATE,
1431 NLRI_WITHDRAW,
1432 NLRI_MP_UPDATE,
1433 NLRI_MP_WITHDRAW,
1434 NLRI_TYPE_MAX
1435 };
1436 struct bgp_nlri nlris[NLRI_TYPE_MAX];
1437
1438 /* Status must be Established. */
1439 if (peer->status != Established) {
e50f7cfd 1440 flog_err(EC_BGP_INVALID_STATUS,
1c50c1c0
QY
1441 "%s [FSM] Update packet received under status %s",
1442 peer->host,
1443 lookup_msg(bgp_status_msg, peer->status, NULL));
0e35025e
DA
1444 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1445 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1446 return BGP_Stop;
d62a17ae 1447 }
1448
1449 /* Set initial values. */
1450 memset(&attr, 0, sizeof(struct attr));
1451 attr.label_index = BGP_INVALID_LABEL_INDEX;
1452 attr.label = MPLS_INVALID_LABEL;
1453 memset(&nlris, 0, sizeof(nlris));
1454 memset(peer->rcvd_attr_str, 0, BUFSIZ);
1455 peer->rcvd_attr_printed = 0;
1456
424ab01d 1457 s = peer->curr;
d62a17ae 1458 end = stream_pnt(s) + size;
1459
1460 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1461 Length is too large (i.e., if Unfeasible Routes Length + Total
1462 Attribute Length + 23 exceeds the message Length), then the Error
1463 Subcode is set to Malformed Attribute List. */
1464 if (stream_pnt(s) + 2 > end) {
e50f7cfd 1465 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0
QY
1466 "%s [Error] Update packet error"
1467 " (packet length is short for unfeasible length)",
1468 peer->host);
d62a17ae 1469 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
1470 BGP_NOTIFY_UPDATE_MAL_ATTR);
d8151687 1471 return BGP_Stop;
d62a17ae 1472 }
1473
1474 /* Unfeasible Route Length. */
1475 withdraw_len = stream_getw(s);
1476
1477 /* Unfeasible Route Length check. */
1478 if (stream_pnt(s) + withdraw_len > end) {
e50f7cfd 1479 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0
QY
1480 "%s [Error] Update packet error"
1481 " (packet unfeasible length overflow %d)",
1482 peer->host, withdraw_len);
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 packet format check. */
1489 if (withdraw_len > 0) {
1490 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1491 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1492 nlris[NLRI_WITHDRAW].nlri = stream_pnt(s);
1493 nlris[NLRI_WITHDRAW].length = withdraw_len;
1494 stream_forward_getp(s, withdraw_len);
1495 }
1496
1497 /* Attribute total length check. */
1498 if (stream_pnt(s) + 2 > end) {
ade6974d 1499 flog_warn(
e50f7cfd 1500 EC_BGP_UPDATE_PACKET_SHORT,
ade6974d
QY
1501 "%s [Error] Packet Error (update packet is short for attribute length)",
1502 peer->host);
d62a17ae 1503 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
1504 BGP_NOTIFY_UPDATE_MAL_ATTR);
d8151687 1505 return BGP_Stop;
d62a17ae 1506 }
1507
1508 /* Fetch attribute total length. */
1509 attribute_len = stream_getw(s);
1510
1511 /* Attribute length check. */
1512 if (stream_pnt(s) + attribute_len > end) {
ade6974d 1513 flog_warn(
e50f7cfd 1514 EC_BGP_UPDATE_PACKET_LONG,
ade6974d
QY
1515 "%s [Error] Packet Error (update packet attribute length overflow %d)",
1516 peer->host, attribute_len);
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 /* Certain attribute parsing errors should not be considered bad enough
1523 * to reset the session for, most particularly any partial/optional
1524 * attributes that have 'tunneled' over speakers that don't understand
1525 * them. Instead we withdraw only the prefix concerned.
1526 *
1527 * Complicates the flow a little though..
1528 */
1529 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1530/* This define morphs the update case into a withdraw when lower levels
1531 * have signalled an error condition where this is best.
1532 */
b881c707 1533#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
718e3744 1534
d62a17ae 1535 /* Parse attribute when it exists. */
1536 if (attribute_len) {
1537 attr_parse_ret = bgp_attr_parse(peer, &attr, attribute_len,
1538 &nlris[NLRI_MP_UPDATE],
1539 &nlris[NLRI_MP_WITHDRAW]);
1540 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR) {
1541 bgp_attr_unintern_sub(&attr);
d8151687 1542 return BGP_Stop;
d62a17ae 1543 }
1544 }
1545
1546 /* Logging the attribute. */
1547 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1548 || BGP_DEBUG(update, UPDATE_IN)
1549 || BGP_DEBUG(update, UPDATE_PREFIX)) {
1550 ret = bgp_dump_attr(&attr, peer->rcvd_attr_str, BUFSIZ);
1551
b4d46cc9
DL
1552 peer->stat_upd_7606++;
1553
d62a17ae 1554 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
af4c2728 1555 flog_err(
e50f7cfd 1556 EC_BGP_UPDATE_RCV,
d62a17ae 1557 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1558 peer->host);
1559
1560 if (ret && bgp_debug_update(peer, NULL, NULL, 1)) {
1561 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
1562 peer->rcvd_attr_str);
1563 peer->rcvd_attr_printed = 1;
1564 }
1565 }
1566
1567 /* Network Layer Reachability Information. */
1568 update_len = end - stream_pnt(s);
1569
1570 if (update_len) {
1571 /* Set NLRI portion to structure. */
1572 nlris[NLRI_UPDATE].afi = AFI_IP;
1573 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1574 nlris[NLRI_UPDATE].nlri = stream_pnt(s);
1575 nlris[NLRI_UPDATE].length = update_len;
1576 stream_forward_getp(s, update_len);
9738e9aa 1577
1578 if (CHECK_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
1579 /*
1580 * We skipped nexthop attribute validation earlier so
1581 * validate the nexthop now.
1582 */
1583 if (bgp_attr_nexthop_valid(peer, &attr) < 0) {
1584 bgp_attr_unintern_sub(&attr);
1585 return BGP_Stop;
1586 }
1587 }
d62a17ae 1588 }
1589
1590 if (BGP_DEBUG(update, UPDATE_IN))
1591 zlog_debug("%s rcvd UPDATE wlen %d attrlen %d alen %d",
1592 peer->host, withdraw_len, attribute_len, update_len);
1593
1594 /* Parse any given NLRIs */
1595 for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) {
1596 if (!nlris[i].nlri)
1597 continue;
1598
1599 /* NLRI is processed iff the peer if configured for the specific
1600 * afi/safi */
1601 if (!peer->afc[nlris[i].afi][nlris[i].safi]) {
1602 zlog_info(
1603 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1604 peer->host, nlris[i].afi, nlris[i].safi);
1605 continue;
1606 }
1607
1608 /* EoR handled later */
1609 if (nlris[i].length == 0)
1610 continue;
1611
1612 switch (i) {
1613 case NLRI_UPDATE:
1614 case NLRI_MP_UPDATE:
1615 nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG,
1616 &nlris[i], 0);
1617 break;
1618 case NLRI_WITHDRAW:
1619 case NLRI_MP_WITHDRAW:
1620 nlri_ret = bgp_nlri_parse(peer, &attr, &nlris[i], 1);
1621 break;
1622 default:
513386b5 1623 nlri_ret = BGP_NLRI_PARSE_ERROR;
d62a17ae 1624 }
1625
513386b5
DA
1626 if (nlri_ret < BGP_NLRI_PARSE_OK
1627 && nlri_ret != BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW) {
e50f7cfd 1628 flog_err(EC_BGP_UPDATE_RCV,
1c50c1c0 1629 "%s [Error] Error parsing NLRI", peer->host);
d62a17ae 1630 if (peer->status == Established)
1631 bgp_notify_send(
1632 peer, BGP_NOTIFY_UPDATE_ERR,
1633 i <= NLRI_WITHDRAW
1634 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1635 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1636 bgp_attr_unintern_sub(&attr);
d8151687 1637 return BGP_Stop;
d62a17ae 1638 }
1639 }
1640
1641 /* EoR checks
1642 *
1643 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1644 * and MP EoR should have only an empty MP_UNREACH
1645 */
996c9314
LB
1646 if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0)
1647 || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
d62a17ae 1648 afi_t afi = 0;
1649 safi_t safi;
f009ff26 1650 struct graceful_restart_info *gr_info;
1651
1652 /* Restarting router */
36235319
QY
1653 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
1654 && BGP_PEER_RESTARTING_MODE(peer))
f009ff26 1655 restart = true;
d62a17ae 1656
1657 /* Non-MP IPv4/Unicast is a completely emtpy UPDATE - already
1658 * checked
1659 * update and withdraw NLRI lengths are 0.
1660 */
1661 if (!attribute_len) {
1662 afi = AFI_IP;
1663 safi = SAFI_UNICAST;
1664 } else if (attr.flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI)
1665 && nlris[NLRI_MP_WITHDRAW].length == 0) {
1666 afi = nlris[NLRI_MP_WITHDRAW].afi;
1667 safi = nlris[NLRI_MP_WITHDRAW].safi;
9b9df989
DS
1668 } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) {
1669 afi = nlris[NLRI_MP_UPDATE].afi;
1670 safi = nlris[NLRI_MP_UPDATE].safi;
d62a17ae 1671 }
1672
1673 if (afi && peer->afc[afi][safi]) {
e82d19a3
DS
1674 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
1675
d62a17ae 1676 /* End-of-RIB received */
1677 if (!CHECK_FLAG(peer->af_sflags[afi][safi],
1678 PEER_STATUS_EOR_RECEIVED)) {
1679 SET_FLAG(peer->af_sflags[afi][safi],
1680 PEER_STATUS_EOR_RECEIVED);
1681 bgp_update_explicit_eors(peer);
f009ff26 1682 /* Update graceful restart information */
1683 gr_info = &(peer->bgp->gr_info[afi][safi]);
1684 if (restart)
1685 gr_info->eor_received++;
1686 /* If EOR received from all peers and selection
1687 * deferral timer is running, cancel the timer
1688 * and invoke the best path calculation
1689 */
36235319
QY
1690 if (gr_info->eor_required
1691 == gr_info->eor_received) {
1692 if (bgp_debug_neighbor_events(peer))
1693 zlog_debug(
1694 "%s %d, %s %d",
f009ff26 1695 "EOR REQ",
1696 gr_info->eor_required,
1697 "EOR RCV",
1698 gr_info->eor_received);
1699 BGP_TIMER_OFF(
1700 gr_info->t_select_deferral);
1701 gr_info->eor_required = 0;
1702 gr_info->eor_received = 0;
1703 /* Best path selection */
1704 if (bgp_best_path_select_defer(
36235319
QY
1705 peer->bgp, afi, safi)
1706 < 0)
f009ff26 1707 return BGP_Stop;
1708 }
d62a17ae 1709 }
1710
1711 /* NSF delete stale route */
1712 if (peer->nsf[afi][safi])
1713 bgp_clear_stale_route(peer, afi, safi);
1714
a0e89d54
TA
1715 zlog_info(
1716 "%s: rcvd End-of-RIB for %s from %s in vrf %s",
1717 __func__, get_afi_safi_str(afi, safi, false),
1718 peer->host, vrf ? vrf->name : VRF_DEFAULT_NAME);
1719 }
f80f838b 1720 }
d62a17ae 1721
1722 /* Everything is done. We unintern temporary structures which
1723 interned in bgp_attr_parse(). */
1724 bgp_attr_unintern_sub(&attr);
1725
d62a17ae 1726 peer->update_time = bgp_clock();
1727
1728 /* Rearm holdtime timer */
1729 BGP_TIMER_OFF(peer->t_holdtime);
1730 bgp_timer_set(peer);
1731
d8151687 1732 return Receive_UPDATE_message;
718e3744 1733}
1734
d8151687
QY
1735/**
1736 * Process BGP NOTIFY message for peer.
1737 *
1738 * @param peer
1739 * @param size size of the packet
1740 * @return as in summary
1741 */
1742static int bgp_notify_receive(struct peer *peer, bgp_size_t size)
718e3744 1743{
d62a17ae 1744 struct bgp_notify bgp_notify;
1745
1746 if (peer->notify.data) {
1747 XFREE(MTYPE_TMP, peer->notify.data);
d62a17ae 1748 peer->notify.length = 0;
1749 }
1750
424ab01d
QY
1751 bgp_notify.code = stream_getc(peer->curr);
1752 bgp_notify.subcode = stream_getc(peer->curr);
d62a17ae 1753 bgp_notify.length = size - 2;
1754 bgp_notify.data = NULL;
1755
1756 /* Preserv notify code and sub code. */
1757 peer->notify.code = bgp_notify.code;
1758 peer->notify.subcode = bgp_notify.subcode;
1759 /* For further diagnostic record returned Data. */
1760 if (bgp_notify.length) {
1761 peer->notify.length = size - 2;
1762 peer->notify.data = XMALLOC(MTYPE_TMP, size - 2);
424ab01d 1763 memcpy(peer->notify.data, stream_pnt(peer->curr), size - 2);
d62a17ae 1764 }
1765
1766 /* For debug */
1767 {
1768 int i;
1769 int first = 0;
1770 char c[4];
1771
1772 if (bgp_notify.length) {
1773 bgp_notify.data =
1774 XMALLOC(MTYPE_TMP, bgp_notify.length * 3);
1775 for (i = 0; i < bgp_notify.length; i++)
1776 if (first) {
552d6491 1777 snprintf(c, sizeof(c), " %02x",
424ab01d 1778 stream_getc(peer->curr));
f009ff26 1779
552d6491 1780 strlcat(bgp_notify.data, c,
f009ff26 1781 bgp_notify.length * 3);
1782
d62a17ae 1783 } else {
1784 first = 1;
552d6491
QY
1785 snprintf(c, sizeof(c), "%02x",
1786 stream_getc(peer->curr));
f009ff26 1787
552d6491 1788 strlcpy(bgp_notify.data, c,
f009ff26 1789 bgp_notify.length * 3);
d62a17ae 1790 }
d7c0a89a 1791 bgp_notify.raw_data = (uint8_t *)peer->notify.data;
d62a17ae 1792 }
1793
1794 bgp_notify_print(peer, &bgp_notify, "received");
1795 if (bgp_notify.data) {
1796 XFREE(MTYPE_TMP, bgp_notify.data);
d62a17ae 1797 bgp_notify.length = 0;
1798 }
1799 }
1800
1801 /* peer count update */
0112e9e0 1802 atomic_fetch_add_explicit(&peer->notify_in, 1, memory_order_relaxed);
d62a17ae 1803
1804 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1805
1806 /* We have to check for Notify with Unsupported Optional Parameter.
1807 in that case we fallback to open without the capability option.
1808 But this done in bgp_stop. We just mark it here to avoid changing
1809 the fsm tables. */
1810 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR
1811 && bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM)
1812 UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1813
5cce3f05 1814 bgp_peer_gr_flags_update(peer);
36235319
QY
1815 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
1816 peer->bgp->peer);
5cce3f05 1817
d8151687 1818 return Receive_NOTIFICATION_message;
718e3744 1819}
1820
d8151687
QY
1821/**
1822 * Process BGP ROUTEREFRESH message for peer.
1823 *
1824 * @param peer
1825 * @param size size of the packet
1826 * @return as in summary
1827 */
1828static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
718e3744 1829{
d62a17ae 1830 iana_afi_t pkt_afi;
1831 afi_t afi;
5c525538
RW
1832 iana_safi_t pkt_safi;
1833 safi_t safi;
d62a17ae 1834 struct stream *s;
1835 struct peer_af *paf;
1836 struct update_group *updgrp;
1837 struct peer *updgrp_peer;
1838
1839 /* If peer does not have the capability, send notification. */
1840 if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) {
e50f7cfd 1841 flog_err(EC_BGP_NO_CAP,
1c50c1c0
QY
1842 "%s [Error] BGP route refresh is not enabled",
1843 peer->host);
d62a17ae 1844 bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
1845 BGP_NOTIFY_HEADER_BAD_MESTYPE);
d8151687 1846 return BGP_Stop;
d62a17ae 1847 }
1848
1849 /* Status must be Established. */
1850 if (peer->status != Established) {
af4c2728 1851 flog_err(
e50f7cfd 1852 EC_BGP_INVALID_STATUS,
d62a17ae 1853 "%s [Error] Route refresh packet received under status %s",
1854 peer->host,
1855 lookup_msg(bgp_status_msg, peer->status, NULL));
0e35025e
DA
1856 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1857 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1858 return BGP_Stop;
d62a17ae 1859 }
1860
424ab01d 1861 s = peer->curr;
d62a17ae 1862
1863 /* Parse packet. */
1864 pkt_afi = stream_getw(s);
1865 (void)stream_getc(s);
1866 pkt_safi = stream_getc(s);
1867
1868 if (bgp_debug_update(peer, NULL, NULL, 0))
748a041f
DS
1869 zlog_debug("%s rcvd REFRESH_REQ for afi/safi: %s/%s",
1870 peer->host, iana_afi2str(pkt_afi),
1871 iana_safi2str(pkt_safi));
d62a17ae 1872
1873 /* Convert AFI, SAFI to internal values and check. */
1874 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
1875 zlog_info(
748a041f
DS
1876 "%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored",
1877 peer->host, iana_afi2str(pkt_afi),
1878 iana_safi2str(pkt_safi));
d8151687 1879 return BGP_PACKET_NOOP;
d62a17ae 1880 }
1881
1882 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) {
d7c0a89a
QY
1883 uint8_t *end;
1884 uint8_t when_to_refresh;
1885 uint8_t orf_type;
1886 uint16_t orf_len;
d62a17ae 1887
1888 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1889 < 5) {
1890 zlog_info("%s ORF route refresh length error",
1891 peer->host);
0e35025e
DA
1892 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1893 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 1894 return BGP_Stop;
718e3744 1895 }
1896
d62a17ae 1897 when_to_refresh = stream_getc(s);
1898 end = stream_pnt(s) + (size - 5);
1899
1900 while ((stream_pnt(s) + 2) < end) {
1901 orf_type = stream_getc(s);
1902 orf_len = stream_getw(s);
1903
1904 /* orf_len in bounds? */
1905 if ((stream_pnt(s) + orf_len) > end)
1906 break; /* XXX: Notify instead?? */
1907 if (orf_type == ORF_TYPE_PREFIX
1908 || orf_type == ORF_TYPE_PREFIX_OLD) {
1909 uint8_t *p_pnt = stream_pnt(s);
1910 uint8_t *p_end = stream_pnt(s) + orf_len;
1911 struct orf_prefix orfp;
d7c0a89a
QY
1912 uint8_t common = 0;
1913 uint32_t seq;
d62a17ae 1914 int psize;
1915 char name[BUFSIZ];
1916 int ret = CMD_SUCCESS;
1917
1918 if (bgp_debug_neighbor_events(peer)) {
1919 zlog_debug(
1920 "%s rcvd Prefixlist ORF(%d) length %d",
1921 peer->host, orf_type, orf_len);
1922 }
1923
1924 /* we're going to read at least 1 byte of common
1925 * ORF header,
1926 * and 7 bytes of ORF Address-filter entry from
1927 * the stream
1928 */
1929 if (orf_len < 7)
1930 break;
1931
1932 /* ORF prefix-list name */
1933 sprintf(name, "%s.%d.%d", peer->host, afi,
1934 safi);
1935
1936 while (p_pnt < p_end) {
1937 /* If the ORF entry is malformed, want
1938 * to read as much of it
1939 * as possible without going beyond the
1940 * bounds of the entry,
1941 * to maximise debug information.
1942 */
1943 int ok;
1944 memset(&orfp, 0,
1945 sizeof(struct orf_prefix));
1946 common = *p_pnt++;
1947 /* after ++: p_pnt <= p_end */
1948 if (common
1949 & ORF_COMMON_PART_REMOVE_ALL) {
1950 if (bgp_debug_neighbor_events(
1951 peer))
1952 zlog_debug(
1953 "%s rcvd Remove-All pfxlist ORF request",
1954 peer->host);
1955 prefix_bgp_orf_remove_all(afi,
1956 name);
1957 break;
1958 }
d7c0a89a
QY
1959 ok = ((uint32_t)(p_end - p_pnt)
1960 >= sizeof(uint32_t));
d62a17ae 1961 if (ok) {
1962 memcpy(&seq, p_pnt,
d7c0a89a
QY
1963 sizeof(uint32_t));
1964 p_pnt += sizeof(uint32_t);
d62a17ae 1965 orfp.seq = ntohl(seq);
1966 } else
1967 p_pnt = p_end;
1968
1969 if ((ok = (p_pnt < p_end)))
1970 orfp.ge =
1971 *p_pnt++; /* value
1972 checked in
1973 prefix_bgp_orf_set()
1974 */
1975 if ((ok = (p_pnt < p_end)))
1976 orfp.le =
1977 *p_pnt++; /* value
1978 checked in
1979 prefix_bgp_orf_set()
1980 */
1981 if ((ok = (p_pnt < p_end)))
1982 orfp.p.prefixlen = *p_pnt++;
1983 orfp.p.family = afi2family(
1984 afi); /* afi checked already */
1985
1986 psize = PSIZE(
1987 orfp.p.prefixlen); /* 0 if not
1988 ok */
1989 if (psize
1990 > prefix_blen(
1991 &orfp.p)) /* valid for
1992 family ? */
1993 {
1994 ok = 0;
1995 psize = prefix_blen(&orfp.p);
1996 }
1997 if (psize
1998 > (p_end - p_pnt)) /* valid for
1999 packet ? */
2000 {
2001 ok = 0;
2002 psize = p_end - p_pnt;
2003 }
2004
2005 if (psize > 0)
2006 memcpy(&orfp.p.u.prefix, p_pnt,
2007 psize);
2008 p_pnt += psize;
2009
2010 if (bgp_debug_neighbor_events(peer)) {
2011 char buf[INET6_BUFSIZ];
2012
2013 zlog_debug(
2014 "%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2015 peer->host,
2016 (common & ORF_COMMON_PART_REMOVE
2017 ? "Remove"
2018 : "Add"),
2019 (common & ORF_COMMON_PART_DENY
2020 ? "deny"
2021 : "permit"),
2022 orfp.seq,
2023 inet_ntop(
2024 orfp.p.family,
2025 &orfp.p.u.prefix,
2026 buf,
2027 INET6_BUFSIZ),
2028 orfp.p.prefixlen,
2029 orfp.ge, orfp.le,
2030 ok ? "" : " MALFORMED");
2031 }
2032
2033 if (ok)
2034 ret = prefix_bgp_orf_set(
2035 name, afi, &orfp,
2036 (common & ORF_COMMON_PART_DENY
2037 ? 0
2038 : 1),
2039 (common & ORF_COMMON_PART_REMOVE
2040 ? 0
2041 : 1));
2042
2043 if (!ok || (ok && ret != CMD_SUCCESS)) {
2044 zlog_info(
2045 "%s Received misformatted prefixlist ORF."
2046 " Remove All pfxlist",
2047 peer->host);
2048 prefix_bgp_orf_remove_all(afi,
2049 name);
2050 break;
2051 }
2052 }
2053
2054 peer->orf_plist[afi][safi] =
2055 prefix_bgp_orf_lookup(afi, name);
2056 }
2057 stream_forward_getp(s, orf_len);
718e3744 2058 }
d62a17ae 2059 if (bgp_debug_neighbor_events(peer))
2060 zlog_debug("%s rcvd Refresh %s ORF request", peer->host,
2061 when_to_refresh == REFRESH_DEFER
2062 ? "Defer"
2063 : "Immediate");
2064 if (when_to_refresh == REFRESH_DEFER)
d8151687 2065 return BGP_PACKET_NOOP;
d62a17ae 2066 }
40d2700d 2067
d62a17ae 2068 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2069 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2070 PEER_STATUS_ORF_WAIT_REFRESH))
2071 UNSET_FLAG(peer->af_sflags[afi][safi],
2072 PEER_STATUS_ORF_WAIT_REFRESH);
2073
2074 paf = peer_af_find(peer, afi, safi);
2075 if (paf && paf->subgroup) {
2076 if (peer->orf_plist[afi][safi]) {
2077 updgrp = PAF_UPDGRP(paf);
2078 updgrp_peer = UPDGRP_PEER(updgrp);
2079 updgrp_peer->orf_plist[afi][safi] =
2080 peer->orf_plist[afi][safi];
2081 }
2082
2083 /* If the peer is configured for default-originate clear the
2084 * SUBGRP_STATUS_DEFAULT_ORIGINATE flag so that we will
2085 * re-advertise the
2086 * default
2087 */
2088 if (CHECK_FLAG(paf->subgroup->sflags,
2089 SUBGRP_STATUS_DEFAULT_ORIGINATE))
2090 UNSET_FLAG(paf->subgroup->sflags,
2091 SUBGRP_STATUS_DEFAULT_ORIGINATE);
718e3744 2092 }
d62a17ae 2093
2094 /* Perform route refreshment to the peer */
2095 bgp_announce_route(peer, afi, safi);
d8151687
QY
2096
2097 /* No FSM action necessary */
2098 return BGP_PACKET_NOOP;
718e3744 2099}
2100
d8151687
QY
2101/**
2102 * Parse BGP CAPABILITY message for peer.
2103 *
2104 * @param peer
2105 * @param size size of the packet
2106 * @return as in summary
2107 */
d7c0a89a 2108static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
d62a17ae 2109 bgp_size_t length)
718e3744 2110{
d7c0a89a 2111 uint8_t *end;
d62a17ae 2112 struct capability_mp_data mpc;
2113 struct capability_header *hdr;
d7c0a89a 2114 uint8_t action;
d62a17ae 2115 iana_afi_t pkt_afi;
2116 afi_t afi;
5c525538
RW
2117 iana_safi_t pkt_safi;
2118 safi_t safi;
d62a17ae 2119
2120 end = pnt + length;
2121
2122 while (pnt < end) {
2123 /* We need at least action, capability code and capability
2124 * length. */
2125 if (pnt + 3 > end) {
2126 zlog_info("%s Capability length error", peer->host);
0e35025e
DA
2127 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2128 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2129 return BGP_Stop;
d62a17ae 2130 }
2131 action = *pnt;
2132 hdr = (struct capability_header *)(pnt + 1);
2133
2134 /* Action value check. */
2135 if (action != CAPABILITY_ACTION_SET
2136 && action != CAPABILITY_ACTION_UNSET) {
2137 zlog_info("%s Capability Action Value error %d",
2138 peer->host, action);
0e35025e
DA
2139 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2140 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2141 return BGP_Stop;
d62a17ae 2142 }
2143
2144 if (bgp_debug_neighbor_events(peer))
2145 zlog_debug(
2146 "%s CAPABILITY has action: %d, code: %u, length %u",
2147 peer->host, action, hdr->code, hdr->length);
2148
2149 /* Capability length check. */
2150 if ((pnt + hdr->length + 3) > end) {
2151 zlog_info("%s Capability length error", peer->host);
0e35025e
DA
2152 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2153 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2154 return BGP_Stop;
d62a17ae 2155 }
2156
2157 /* Fetch structure to the byte stream. */
2158 memcpy(&mpc, pnt + 3, sizeof(struct capability_mp_data));
d2b6417b 2159 pnt += hdr->length + 3;
d62a17ae 2160
2161 /* We know MP Capability Code. */
2162 if (hdr->code == CAPABILITY_CODE_MP) {
2163 pkt_afi = ntohs(mpc.afi);
2164 pkt_safi = mpc.safi;
2165
2166 /* Ignore capability when override-capability is set. */
2167 if (CHECK_FLAG(peer->flags,
2168 PEER_FLAG_OVERRIDE_CAPABILITY))
2169 continue;
2170
2171 /* Convert AFI, SAFI to internal values. */
2172 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
2173 &safi)) {
2174 if (bgp_debug_neighbor_events(peer))
2175 zlog_debug(
2176 "%s Dynamic Capability MP_EXT afi/safi invalid "
748a041f
DS
2177 "(%s/%s)",
2178 peer->host,
2179 iana_afi2str(pkt_afi),
2180 iana_safi2str(pkt_safi));
d62a17ae 2181 continue;
2182 }
2183
2184 /* Address family check. */
2185 if (bgp_debug_neighbor_events(peer))
2186 zlog_debug(
2187 "%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2188 peer->host,
2189 action == CAPABILITY_ACTION_SET
2190 ? "Advertising"
2191 : "Removing",
2192 pkt_afi, pkt_safi);
2193
2194 if (action == CAPABILITY_ACTION_SET) {
2195 peer->afc_recv[afi][safi] = 1;
2196 if (peer->afc[afi][safi]) {
2197 peer->afc_nego[afi][safi] = 1;
2198 bgp_announce_route(peer, afi, safi);
2199 }
2200 } else {
2201 peer->afc_recv[afi][safi] = 0;
2202 peer->afc_nego[afi][safi] = 0;
2203
2204 if (peer_active_nego(peer))
2205 bgp_clear_route(peer, afi, safi);
2206 else
d8151687 2207 return BGP_Stop;
d62a17ae 2208 }
2209 } else {
ade6974d 2210 flog_warn(
e50f7cfd 2211 EC_BGP_UNRECOGNIZED_CAPABILITY,
ade6974d
QY
2212 "%s unrecognized capability code: %d - ignored",
2213 peer->host, hdr->code);
d62a17ae 2214 }
d62a17ae 2215 }
d8151687
QY
2216
2217 /* No FSM action necessary */
2218 return BGP_PACKET_NOOP;
718e3744 2219}
2220
d8151687
QY
2221/**
2222 * Parse BGP CAPABILITY message for peer.
01b7ce2d 2223 *
d8151687
QY
2224 * Exported for unit testing.
2225 *
2226 * @param peer
2227 * @param size size of the packet
2228 * @return as in summary
01b7ce2d 2229 */
d62a17ae 2230int bgp_capability_receive(struct peer *peer, bgp_size_t size)
718e3744 2231{
d7c0a89a 2232 uint8_t *pnt;
d62a17ae 2233
2234 /* Fetch pointer. */
424ab01d 2235 pnt = stream_pnt(peer->curr);
d62a17ae 2236
2237 if (bgp_debug_neighbor_events(peer))
2238 zlog_debug("%s rcv CAPABILITY", peer->host);
2239
2240 /* If peer does not have the capability, send notification. */
2241 if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) {
e50f7cfd 2242 flog_err(EC_BGP_NO_CAP,
1c50c1c0
QY
2243 "%s [Error] BGP dynamic capability is not enabled",
2244 peer->host);
d62a17ae 2245 bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
2246 BGP_NOTIFY_HEADER_BAD_MESTYPE);
d8151687 2247 return BGP_Stop;
d62a17ae 2248 }
2249
2250 /* Status must be Established. */
2251 if (peer->status != Established) {
af4c2728 2252 flog_err(
e50f7cfd 2253 EC_BGP_NO_CAP,
d62a17ae 2254 "%s [Error] Dynamic capability packet received under status %s",
2255 peer->host,
2256 lookup_msg(bgp_status_msg, peer->status, NULL));
0e35025e
DA
2257 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
2258 BGP_NOTIFY_SUBCODE_UNSPECIFIC);
d8151687 2259 return BGP_Stop;
d62a17ae 2260 }
2261
2262 /* Parse packet. */
2263 return bgp_capability_msg_parse(peer, pnt, size);
718e3744 2264}
6b0655a2 2265
d8151687
QY
2266/**
2267 * Processes a peer's input buffer.
2268 *
2269 * This function sidesteps the event loop and directly calls bgp_event_update()
2270 * after processing each BGP message. This is necessary to ensure proper
2271 * ordering of FSM events and unifies the behavior that was present previously,
2272 * whereby some of the packet handling functions would update the FSM and some
2273 * would not, making event flow difficult to understand. Please think twice
2274 * before hacking this.
2275 *
2276 * Thread type: THREAD_EVENT
2277 * @param thread
2278 * @return 0
2279 */
424ab01d 2280int bgp_process_packet(struct thread *thread)
718e3744 2281{
424ab01d 2282 /* Yes first of all get peer pointer. */
d8151687
QY
2283 struct peer *peer; // peer
2284 uint32_t rpkt_quanta_old; // how many packets to read
2285 int fsm_update_result; // return code of bgp_event_update()
2286 int mprc; // message processing return code
555e09d4 2287
424ab01d 2288 peer = THREAD_ARG(thread);
555e09d4
QY
2289 rpkt_quanta_old = atomic_load_explicit(&peer->bgp->rpkt_quanta,
2290 memory_order_relaxed);
e3c7270d 2291 fsm_update_result = 0;
555e09d4 2292
424ab01d 2293 /* Guard against scheduled events that occur after peer deletion. */
9eb217ff 2294 if (peer->status == Deleted || peer->status == Clearing)
d62a17ae 2295 return 0;
718e3744 2296
555e09d4 2297 unsigned int processed = 0;
d62a17ae 2298
555e09d4 2299 while (processed < rpkt_quanta_old) {
d7c0a89a 2300 uint8_t type = 0;
9eb217ff
QY
2301 bgp_size_t size;
2302 char notify_data_length[2];
d62a17ae 2303
00dffa8c 2304 frr_with_mutex(&peer->io_mtx) {
9eb217ff
QY
2305 peer->curr = stream_fifo_pop(peer->ibuf);
2306 }
d62a17ae 2307
9eb217ff
QY
2308 if (peer->curr == NULL) // no packets to process, hmm...
2309 return 0;
d62a17ae 2310
9eb217ff
QY
2311 /* skip the marker and copy the packet length */
2312 stream_forward_getp(peer->curr, BGP_MARKER_SIZE);
2313 memcpy(notify_data_length, stream_pnt(peer->curr), 2);
2314
2315 /* read in the packet length and type */
2316 size = stream_getw(peer->curr);
2317 type = stream_getc(peer->curr);
2318
584470fb 2319 hook_call(bgp_packet_dump, peer, type, size, peer->curr);
9eb217ff
QY
2320
2321 /* adjust size to exclude the marker + length + type */
2322 size -= BGP_HEADER_SIZE;
2323
2324 /* Read rest of the packet and call each sort of packet routine
2325 */
2326 switch (type) {
2327 case BGP_MSG_OPEN:
0112e9e0
QY
2328 atomic_fetch_add_explicit(&peer->open_in, 1,
2329 memory_order_relaxed);
d8151687
QY
2330 mprc = bgp_open_receive(peer, size);
2331 if (mprc == BGP_Stop)
af4c2728 2332 flog_err(
e50f7cfd 2333 EC_BGP_PKT_OPEN,
d8151687
QY
2334 "%s: BGP OPEN receipt failed for peer: %s",
2335 __FUNCTION__, peer->host);
9eb217ff
QY
2336 break;
2337 case BGP_MSG_UPDATE:
0112e9e0
QY
2338 atomic_fetch_add_explicit(&peer->update_in, 1,
2339 memory_order_relaxed);
9eb217ff 2340 peer->readtime = monotime(NULL);
d8151687
QY
2341 mprc = bgp_update_receive(peer, size);
2342 if (mprc == BGP_Stop)
af4c2728 2343 flog_err(
e50f7cfd 2344 EC_BGP_UPDATE_RCV,
d8151687
QY
2345 "%s: BGP UPDATE receipt failed for peer: %s",
2346 __FUNCTION__, peer->host);
9eb217ff
QY
2347 break;
2348 case BGP_MSG_NOTIFY:
0112e9e0
QY
2349 atomic_fetch_add_explicit(&peer->notify_in, 1,
2350 memory_order_relaxed);
d8151687
QY
2351 mprc = bgp_notify_receive(peer, size);
2352 if (mprc == BGP_Stop)
af4c2728 2353 flog_err(
e50f7cfd 2354 EC_BGP_NOTIFY_RCV,
d8151687
QY
2355 "%s: BGP NOTIFY receipt failed for peer: %s",
2356 __FUNCTION__, peer->host);
9eb217ff
QY
2357 break;
2358 case BGP_MSG_KEEPALIVE:
2359 peer->readtime = monotime(NULL);
0112e9e0
QY
2360 atomic_fetch_add_explicit(&peer->keepalive_in, 1,
2361 memory_order_relaxed);
d8151687
QY
2362 mprc = bgp_keepalive_receive(peer, size);
2363 if (mprc == BGP_Stop)
af4c2728 2364 flog_err(
e50f7cfd 2365 EC_BGP_KEEP_RCV,
d8151687
QY
2366 "%s: BGP KEEPALIVE receipt failed for peer: %s",
2367 __FUNCTION__, peer->host);
9eb217ff
QY
2368 break;
2369 case BGP_MSG_ROUTE_REFRESH_NEW:
2370 case BGP_MSG_ROUTE_REFRESH_OLD:
0112e9e0
QY
2371 atomic_fetch_add_explicit(&peer->refresh_in, 1,
2372 memory_order_relaxed);
d8151687
QY
2373 mprc = bgp_route_refresh_receive(peer, size);
2374 if (mprc == BGP_Stop)
af4c2728 2375 flog_err(
e50f7cfd 2376 EC_BGP_RFSH_RCV,
d8151687
QY
2377 "%s: BGP ROUTEREFRESH receipt failed for peer: %s",
2378 __FUNCTION__, peer->host);
9eb217ff
QY
2379 break;
2380 case BGP_MSG_CAPABILITY:
0112e9e0
QY
2381 atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1,
2382 memory_order_relaxed);
d8151687
QY
2383 mprc = bgp_capability_receive(peer, size);
2384 if (mprc == BGP_Stop)
af4c2728 2385 flog_err(
e50f7cfd 2386 EC_BGP_CAP_RCV,
d8151687
QY
2387 "%s: BGP CAPABILITY receipt failed for peer: %s",
2388 __FUNCTION__, peer->host);
9eb217ff 2389 break;
e3c7270d 2390 default:
db878db0
QY
2391 /* Suppress uninitialized variable warning */
2392 mprc = 0;
5041dc4f 2393 (void)mprc;
becedef6
QY
2394 /*
2395 * The message type should have been sanitized before
2396 * we ever got here. Receipt of a message with an
2397 * invalid header at this point is indicative of a
2398 * security issue.
2399 */
e3c7270d 2400 assert (!"Message of invalid type received during input processing");
9eb217ff
QY
2401 }
2402
d8151687
QY
2403 /* delete processed packet */
2404 stream_free(peer->curr);
2405 peer->curr = NULL;
2406 processed++;
9eb217ff 2407
d8151687
QY
2408 /* Update FSM */
2409 if (mprc != BGP_PACKET_NOOP)
2410 fsm_update_result = bgp_event_update(peer, mprc);
e3c7270d
QY
2411 else
2412 continue;
d8151687 2413
becedef6
QY
2414 /*
2415 * If peer was deleted, do not process any more packets. This
2416 * is usually due to executing BGP_Stop or a stub deletion.
2417 */
d8151687
QY
2418 if (fsm_update_result == FSM_PEER_TRANSFERRED
2419 || fsm_update_result == FSM_PEER_STOPPED)
2420 break;
d62a17ae 2421 }
2422
d8151687
QY
2423 if (fsm_update_result != FSM_PEER_TRANSFERRED
2424 && fsm_update_result != FSM_PEER_STOPPED) {
00dffa8c 2425 frr_with_mutex(&peer->io_mtx) {
becedef6
QY
2426 // more work to do, come back later
2427 if (peer->ibuf->count > 0)
4af76660
QY
2428 thread_add_timer_msec(
2429 bm->master, bgp_process_packet, peer, 0,
2430 &peer->t_process_packet);
d8151687 2431 }
718e3744 2432 }
2433
d62a17ae 2434 return 0;
718e3744 2435}
9e3b51a7 2436
2437/* Send EOR when routes are processed by selection deferral timer */
2438void bgp_send_delayed_eor(struct bgp *bgp)
2439{
2440 struct peer *peer;
2441 struct listnode *node, *nnode;
2442
2443 /* EOR message sent in bgp_write_proceed_actions */
2444 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
2445 bgp_write_proceed_actions(peer);
2446}