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