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