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