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