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