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