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