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