1 /* BGP packet management routine.
2 * Contains utility functions for constructing and consuming BGP messages.
3 * Copyright (C) 2017 Cumulus Networks
4 * Copyright (C) 1999 Kunihiro Ishiguro
6 * This file is part of GNU Zebra.
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
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.
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
33 #include "sockunion.h" /* for inet_ntop () */
39 #include "lib_errors.h"
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_dump.h"
44 #include "bgpd/bgp_bmp.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_errors.h"
48 #include "bgpd/bgp_fsm.h"
49 #include "bgpd/bgp_route.h"
50 #include "bgpd/bgp_packet.h"
51 #include "bgpd/bgp_open.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_ecommunity.h"
55 #include "bgpd/bgp_lcommunity.h"
56 #include "bgpd/bgp_network.h"
57 #include "bgpd/bgp_mplsvpn.h"
58 #include "bgpd/bgp_evpn.h"
59 #include "bgpd/bgp_advertise.h"
60 #include "bgpd/bgp_vty.h"
61 #include "bgpd/bgp_updgrp.h"
62 #include "bgpd/bgp_label.h"
63 #include "bgpd/bgp_io.h"
64 #include "bgpd/bgp_keepalives.h"
65 #include "bgpd/bgp_flowspec.h"
67 DEFINE_HOOK(bgp_packet_dump
,
68 (struct peer
*peer
, uint8_t type
, bgp_size_t size
,
70 (peer
, type
, size
, s
))
72 DEFINE_HOOK(bgp_packet_send
,
73 (struct peer
*peer
, uint8_t type
, bgp_size_t size
,
75 (peer
, type
, size
, s
))
78 * Sets marker and type fields for a BGP message.
80 * @param s the stream containing the packet
81 * @param type the packet type
82 * @return the size of the stream
84 int bgp_packet_set_marker(struct stream
*s
, uint8_t type
)
89 for (i
= 0; i
< BGP_MARKER_SIZE
; i
++)
92 /* Dummy total length. This field is should be filled in later on. */
95 /* BGP packet type. */
98 /* Return current stream size. */
99 return stream_get_endp(s
);
103 * Sets size field for a BGP message.
105 * Size field is set to the size of the stream passed.
107 * @param s the stream containing the packet
108 * @return the size of the stream
110 int bgp_packet_set_size(struct stream
*s
)
114 /* Preserve current pointer. */
115 cp
= stream_get_endp(s
);
116 stream_putw_at(s
, BGP_MARKER_SIZE
, cp
);
122 * Push a packet onto the beginning of the peer's output queue.
123 * This function acquires the peer's write mutex before proceeding.
125 static void bgp_packet_add(struct peer
*peer
, struct stream
*s
)
127 frr_with_mutex(&peer
->io_mtx
) {
128 stream_fifo_push(peer
->obuf
, s
);
132 static struct stream
*bgp_update_packet_eor(struct peer
*peer
, afi_t afi
,
137 iana_safi_t pkt_safi
;
139 if (DISABLE_BGP_ANNOUNCE
)
142 if (bgp_debug_neighbor_events(peer
))
143 zlog_debug("send End-of-RIB for %s to %s",
144 get_afi_safi_str(afi
, safi
, false), peer
->host
);
146 s
= stream_new(BGP_MAX_PACKET_SIZE
);
148 /* Make BGP update packet. */
149 bgp_packet_set_marker(s
, BGP_MSG_UPDATE
);
151 /* Unfeasible Routes Length */
154 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
155 /* Total Path Attribute Length */
158 /* Convert AFI, SAFI to values for packet. */
159 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
, &pkt_safi
);
161 /* Total Path Attribute Length */
163 stream_putc(s
, BGP_ATTR_FLAG_OPTIONAL
);
164 stream_putc(s
, BGP_ATTR_MP_UNREACH_NLRI
);
166 stream_putw(s
, pkt_afi
);
167 stream_putc(s
, pkt_safi
);
170 bgp_packet_set_size(s
);
174 /* Called when there is a change in the EOR(implicit or explicit) status of a
175 * peer. Ends the update-delay if all expected peers are done with EORs. */
176 void bgp_check_update_delay(struct bgp
*bgp
)
178 struct listnode
*node
, *nnode
;
179 struct peer
*peer
= NULL
;
181 if (bgp_debug_neighbor_events(peer
))
182 zlog_debug("Checking update delay, T: %d R: %d I:%d E: %d",
183 bgp
->established
, bgp
->restarted_peers
,
184 bgp
->implicit_eors
, bgp
->explicit_eors
);
187 <= bgp
->restarted_peers
+ bgp
->implicit_eors
+ bgp
->explicit_eors
) {
189 * This is an extra sanity check to make sure we wait for all
190 * the eligible configured peers. This check is performed if
191 * establish wait timer is on, or establish wait option is not
192 * given with the update-delay command
194 if (bgp
->t_establish_wait
195 || (bgp
->v_establish_wait
== bgp
->v_update_delay
))
196 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
197 if (CHECK_FLAG(peer
->flags
,
198 PEER_FLAG_CONFIG_NODE
)
199 && !CHECK_FLAG(peer
->flags
,
201 && !peer
->update_delay_over
) {
202 if (bgp_debug_neighbor_events(peer
))
204 " Peer %s pending, continuing read-only mode",
211 "Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d",
212 bgp
->restarted_peers
, bgp
->implicit_eors
,
214 bgp_update_delay_end(bgp
);
219 * Called if peer is known to have restarted. The restart-state bit in
220 * Graceful-Restart capability is used for that
222 void bgp_update_restarted_peers(struct peer
*peer
)
224 if (!bgp_update_delay_active(peer
->bgp
))
225 return; /* BGP update delay has ended */
226 if (peer
->update_delay_over
)
227 return; /* This peer has already been considered */
229 if (bgp_debug_neighbor_events(peer
))
230 zlog_debug("Peer %s: Checking restarted", peer
->host
);
232 if (peer
->status
== Established
) {
233 peer
->update_delay_over
= 1;
234 peer
->bgp
->restarted_peers
++;
235 bgp_check_update_delay(peer
->bgp
);
240 * Called as peer receives a keep-alive. Determines if this occurence can be
241 * taken as an implicit EOR for this peer.
242 * NOTE: The very first keep-alive after the Established state of a peer is
243 * considered implicit EOR for the update-delay purposes
245 void bgp_update_implicit_eors(struct peer
*peer
)
247 if (!bgp_update_delay_active(peer
->bgp
))
248 return; /* BGP update delay has ended */
249 if (peer
->update_delay_over
)
250 return; /* This peer has already been considered */
252 if (bgp_debug_neighbor_events(peer
))
253 zlog_debug("Peer %s: Checking implicit EORs", peer
->host
);
255 if (peer
->status
== Established
) {
256 peer
->update_delay_over
= 1;
257 peer
->bgp
->implicit_eors
++;
258 bgp_check_update_delay(peer
->bgp
);
263 * Should be called only when there is a change in the EOR_RECEIVED status
264 * for any afi/safi on a peer.
266 static void bgp_update_explicit_eors(struct peer
*peer
)
271 if (!bgp_update_delay_active(peer
->bgp
))
272 return; /* BGP update delay has ended */
273 if (peer
->update_delay_over
)
274 return; /* This peer has already been considered */
276 if (bgp_debug_neighbor_events(peer
))
277 zlog_debug("Peer %s: Checking explicit EORs", peer
->host
);
279 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
280 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
281 if (peer
->afc_nego
[afi
][safi
]
282 && !CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
283 PEER_STATUS_EOR_RECEIVED
)) {
284 if (bgp_debug_neighbor_events(peer
))
286 " afi %d safi %d didn't receive EOR",
292 peer
->update_delay_over
= 1;
293 peer
->bgp
->explicit_eors
++;
294 bgp_check_update_delay(peer
->bgp
);
298 * Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers.
300 * mp_withdraw, if set, is used to nullify attr structure on most of the
301 * calling safi function and for evpn, passed as parameter
303 int bgp_nlri_parse(struct peer
*peer
, struct attr
*attr
,
304 struct bgp_nlri
*packet
, int mp_withdraw
)
306 switch (packet
->safi
) {
309 return bgp_nlri_parse_ip(peer
, mp_withdraw
? NULL
: attr
,
311 case SAFI_LABELED_UNICAST
:
312 return bgp_nlri_parse_label(peer
, mp_withdraw
? NULL
: attr
,
315 return bgp_nlri_parse_vpn(peer
, mp_withdraw
? NULL
: attr
,
318 return bgp_nlri_parse_evpn(peer
, attr
, packet
, mp_withdraw
);
320 return bgp_nlri_parse_flowspec(peer
, attr
, packet
, mp_withdraw
);
322 return BGP_NLRI_PARSE_ERROR
;
326 * Checks a variety of conditions to determine whether the peer needs to be
327 * rescheduled for packet generation again, and does so if necessary.
329 * @param peer to check for rescheduling
331 static void bgp_write_proceed_actions(struct peer
*peer
)
336 struct bpacket
*next_pkt
;
337 struct update_subgroup
*subgrp
;
339 FOREACH_AFI_SAFI (afi
, safi
) {
340 paf
= peer_af_find(peer
, afi
, safi
);
343 subgrp
= paf
->subgroup
;
347 next_pkt
= paf
->next_pkt_to_send
;
348 if (next_pkt
&& next_pkt
->buffer
) {
349 BGP_TIMER_ON(peer
->t_generate_updgrp_packets
,
350 bgp_generate_updgrp_packets
, 0);
354 /* No packets readily available for AFI/SAFI, are there
356 * that need to be generated? */
357 if (bpacket_queue_is_full(SUBGRP_INST(subgrp
),
359 || subgroup_packets_to_build(subgrp
)) {
360 BGP_TIMER_ON(peer
->t_generate_updgrp_packets
,
361 bgp_generate_updgrp_packets
, 0);
365 /* No packets to send, see if EOR is pending */
366 if (CHECK_FLAG(peer
->cap
, PEER_CAP_RESTART_RCV
)) {
367 if (!subgrp
->t_coalesce
&& peer
->afc_nego
[afi
][safi
]
369 && !CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
370 PEER_STATUS_EOR_SEND
)
371 && safi
!= SAFI_MPLS_VPN
) {
372 BGP_TIMER_ON(peer
->t_generate_updgrp_packets
,
373 bgp_generate_updgrp_packets
, 0);
381 * Generate advertisement information (withdraws, updates, EOR) from each
382 * update group a peer belongs to, encode this information into packets, and
383 * enqueue the packets onto the peer's output buffer.
385 int bgp_generate_updgrp_packets(struct thread
*thread
)
387 struct peer
*peer
= THREAD_ARG(thread
);
391 struct bpacket
*next_pkt
;
393 uint32_t generated
= 0;
397 wpq
= atomic_load_explicit(&peer
->bgp
->wpkt_quanta
,
398 memory_order_relaxed
);
401 * The code beyond this part deals with update packets, proceed only
402 * if peer is Established and updates are not on hold (as part of
403 * update-delay post processing).
405 if (peer
->status
!= Established
)
408 if (peer
->bgp
->main_peers_update_hold
)
413 FOREACH_AFI_SAFI (afi
, safi
) {
414 paf
= peer_af_find(peer
, afi
, safi
);
415 if (!paf
|| !PAF_SUBGRP(paf
))
417 next_pkt
= paf
->next_pkt_to_send
;
420 * Try to generate a packet for the peer if we are at
421 * the end of the list. Always try to push out
424 if (!next_pkt
|| !next_pkt
->buffer
) {
425 next_pkt
= subgroup_withdraw_packet(
427 if (!next_pkt
|| !next_pkt
->buffer
)
428 subgroup_update_packet(PAF_SUBGRP(paf
));
429 next_pkt
= paf
->next_pkt_to_send
;
433 * If we still don't have a packet to send to the peer,
434 * then try to find out out if we have to send eor or
435 * if not, skip to the next AFI, SAFI. Don't send the
436 * EOR prematurely; if the subgroup's coalesce timer is
437 * running, the adjacency-out structure is not created
440 if (!next_pkt
|| !next_pkt
->buffer
) {
441 if (CHECK_FLAG(peer
->cap
,
442 PEER_CAP_RESTART_RCV
)) {
443 if (!(PAF_SUBGRP(paf
))->t_coalesce
444 && peer
->afc_nego
[afi
][safi
]
449 PEER_STATUS_EOR_SEND
)) {
450 SET_FLAG(peer
->af_sflags
[afi
]
452 PEER_STATUS_EOR_SEND
);
454 if ((s
= bgp_update_packet_eor(
457 bgp_packet_add(peer
, s
);
465 /* Found a packet template to send, overwrite
466 * packet with appropriate attributes from peer
467 * and advance peer */
468 s
= bpacket_reformat_for_peer(next_pkt
, paf
);
469 bgp_packet_add(peer
, s
);
470 bpacket_queue_advance_peer(paf
);
472 } while (s
&& (++generated
< wpq
));
477 bgp_write_proceed_actions(peer
);
483 * Creates a BGP Keepalive packet and appends it to the peer's output queue.
485 void bgp_keepalive_send(struct peer
*peer
)
489 s
= stream_new(BGP_MAX_PACKET_SIZE
);
491 /* Make keepalive packet. */
492 bgp_packet_set_marker(s
, BGP_MSG_KEEPALIVE
);
494 /* Set packet size. */
495 (void)bgp_packet_set_size(s
);
497 /* Dump packet if debug option is set. */
498 /* bgp_packet_dump (s); */
500 if (bgp_debug_keepalive(peer
))
501 zlog_debug("%s sending KEEPALIVE", peer
->host
);
503 /* Add packet to the peer. */
504 bgp_packet_add(peer
, s
);
510 * Creates a BGP Open packet and appends it to the peer's output queue.
511 * Sets capabilities as necessary.
513 void bgp_open_send(struct peer
*peer
)
516 uint16_t send_holdtime
;
519 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
520 send_holdtime
= peer
->holdtime
;
522 send_holdtime
= peer
->bgp
->default_holdtime
;
524 /* local-as Change */
525 if (peer
->change_local_as
)
526 local_as
= peer
->change_local_as
;
528 local_as
= peer
->local_as
;
530 s
= stream_new(BGP_MAX_PACKET_SIZE
);
532 /* Make open packet. */
533 bgp_packet_set_marker(s
, BGP_MSG_OPEN
);
535 /* Set open packet values. */
536 stream_putc(s
, BGP_VERSION_4
); /* BGP version */
537 stream_putw(s
, (local_as
<= BGP_AS_MAX
) ? (uint16_t)local_as
539 stream_putw(s
, send_holdtime
); /* Hold Time */
540 stream_put_in_addr(s
, &peer
->local_id
); /* BGP Identifier */
542 /* Set capability code. */
543 bgp_open_capability(s
, peer
);
545 /* Set BGP packet length. */
546 (void)bgp_packet_set_size(s
);
548 if (bgp_debug_neighbor_events(peer
))
550 "%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
551 peer
->host
, BGP_VERSION_4
, local_as
, send_holdtime
,
552 inet_ntoa(peer
->local_id
));
554 /* Dump packet if debug option is set. */
555 /* bgp_packet_dump (s); */
556 hook_call(bgp_packet_send
, peer
, BGP_MSG_OPEN
, stream_get_endp(s
), s
);
558 /* Add packet to the peer. */
559 bgp_packet_add(peer
, s
);
565 * Writes NOTIFICATION message directly to a peer socket without waiting for
568 * There must be exactly one stream on the peer->obuf FIFO, and the data within
569 * this stream must match the format of a BGP NOTIFICATION message.
570 * Transmission is best-effort.
572 * @requires peer->io_mtx
576 static int bgp_write_notify(struct peer
*peer
)
582 /* There should be at least one packet. */
583 s
= stream_fifo_pop(peer
->obuf
);
588 assert(stream_get_endp(s
) >= BGP_HEADER_SIZE
);
590 /* Stop collecting data within the socket */
591 sockopt_cork(peer
->fd
, 0);
594 * socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
595 * we only care about getting a clean shutdown at this point.
597 ret
= write(peer
->fd
, STREAM_DATA(s
), stream_get_endp(s
));
600 * only connection reset/close gets counted as TCP_fatal_error, failure
601 * to write the entire NOTIFY doesn't get different FSM treatment
605 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
609 /* Disable Nagle, make NOTIFY packet go out right away */
611 (void)setsockopt(peer
->fd
, IPPROTO_TCP
, TCP_NODELAY
, (char *)&val
,
614 /* Retrieve BGP packet type. */
615 stream_set_getp(s
, BGP_MARKER_SIZE
+ 2);
616 type
= stream_getc(s
);
618 assert(type
== BGP_MSG_NOTIFY
);
620 /* Type should be notify. */
621 atomic_fetch_add_explicit(&peer
->notify_out
, 1, memory_order_relaxed
);
624 /* Double start timer. */
627 /* Overflow check. */
628 if (peer
->v_start
>= (60 * 2))
629 peer
->v_start
= (60 * 2);
632 * Handle Graceful Restart case where the state changes to
633 * Connect instead of Idle
635 BGP_EVENT_ADD(peer
, BGP_Stop
);
643 * Creates a BGP Notify and appends it to the peer's output queue.
645 * This function attempts to write the packet from the thread it is called
646 * from, to ensure the packet gets out ASAP.
648 * This function may be called from multiple threads. Since the function
649 * modifies I/O buffer(s) in the peer, these are locked for the duration of the
650 * call to prevent tampering from other threads.
652 * Delivery of the NOTIFICATION is attempted once and is best-effort. After
653 * return, the peer structure *must* be reset; no assumptions about session
657 * @param code BGP error code
658 * @param sub_code BGP error subcode
659 * @param data Data portion
660 * @param datalen length of data portion
662 void bgp_notify_send_with_data(struct peer
*peer
, uint8_t code
,
663 uint8_t sub_code
, uint8_t *data
, size_t datalen
)
667 /* Lock I/O mutex to prevent other threads from pushing packets */
668 frr_mutex_lock_autounlock(&peer
->io_mtx
);
669 /* ============================================== */
671 /* Allocate new stream. */
672 s
= stream_new(BGP_MAX_PACKET_SIZE
);
674 /* Make notify packet. */
675 bgp_packet_set_marker(s
, BGP_MSG_NOTIFY
);
677 /* Set notify packet values. */
678 stream_putc(s
, code
); /* BGP notify code */
679 stream_putc(s
, sub_code
); /* BGP notify sub_code */
681 /* If notify data is present. */
683 stream_write(s
, data
, datalen
);
685 /* Set BGP packet length. */
686 bgp_packet_set_size(s
);
688 /* wipe output buffer */
689 stream_fifo_clean(peer
->obuf
);
692 * If possible, store last packet for debugging purposes. This check is
693 * in place because we are sometimes called with a doppelganger peer,
694 * who tends to have a plethora of fields nulled out.
697 size_t packetsize
= stream_get_endp(peer
->curr
);
698 assert(packetsize
<= sizeof(peer
->last_reset_cause
));
699 memcpy(peer
->last_reset_cause
, peer
->curr
->data
, packetsize
);
700 peer
->last_reset_cause_size
= packetsize
;
705 struct bgp_notify bgp_notify
;
710 bgp_notify
.code
= code
;
711 bgp_notify
.subcode
= sub_code
;
712 bgp_notify
.data
= NULL
;
713 bgp_notify
.length
= datalen
;
714 bgp_notify
.raw_data
= data
;
716 peer
->notify
.code
= bgp_notify
.code
;
717 peer
->notify
.subcode
= bgp_notify
.subcode
;
719 if (bgp_notify
.length
&& data
) {
721 XMALLOC(MTYPE_TMP
, bgp_notify
.length
* 3);
722 for (i
= 0; i
< bgp_notify
.length
; i
++)
724 snprintf(c
, sizeof(c
), " %02x",
726 strlcat(bgp_notify
.data
, c
,
730 snprintf(c
, sizeof(c
), "%02x", data
[i
]);
731 strlcpy(bgp_notify
.data
, c
,
735 bgp_notify_print(peer
, &bgp_notify
, "sending");
737 if (bgp_notify
.data
) {
738 XFREE(MTYPE_TMP
, bgp_notify
.data
);
739 bgp_notify
.data
= NULL
;
740 bgp_notify
.length
= 0;
744 /* peer reset cause */
745 if (code
== BGP_NOTIFY_CEASE
) {
746 if (sub_code
== BGP_NOTIFY_CEASE_ADMIN_RESET
)
747 peer
->last_reset
= PEER_DOWN_USER_RESET
;
748 else if (sub_code
== BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
)
749 peer
->last_reset
= PEER_DOWN_USER_SHUTDOWN
;
751 peer
->last_reset
= PEER_DOWN_NOTIFY_SEND
;
753 peer
->last_reset
= PEER_DOWN_NOTIFY_SEND
;
755 /* Add packet to peer's output queue */
756 stream_fifo_push(peer
->obuf
, s
);
758 bgp_write_notify(peer
);
762 * Creates a BGP Notify and appends it to the peer's output queue.
764 * This function attempts to write the packet from the thread it is called
765 * from, to ensure the packet gets out ASAP.
768 * @param code BGP error code
769 * @param sub_code BGP error subcode
771 void bgp_notify_send(struct peer
*peer
, uint8_t code
, uint8_t sub_code
)
773 bgp_notify_send_with_data(peer
, code
, sub_code
, NULL
, 0);
777 * Creates BGP Route Refresh packet and appends it to the peer's output queue.
780 * @param afi Address Family Identifier
781 * @param safi Subsequent Address Family Identifier
782 * @param orf_type Outbound Route Filtering type
783 * @param when_to_refresh Whether to refresh immediately or defer
784 * @param remove Whether to remove ORF for specified AFI/SAFI
786 void bgp_route_refresh_send(struct peer
*peer
, afi_t afi
, safi_t safi
,
787 uint8_t orf_type
, uint8_t when_to_refresh
,
791 struct bgp_filter
*filter
;
794 iana_safi_t pkt_safi
;
796 if (DISABLE_BGP_ANNOUNCE
)
799 filter
= &peer
->filter
[afi
][safi
];
801 /* Convert AFI, SAFI to values for packet. */
802 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
, &pkt_safi
);
804 s
= stream_new(BGP_MAX_PACKET_SIZE
);
806 /* Make BGP update packet. */
807 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
808 bgp_packet_set_marker(s
, BGP_MSG_ROUTE_REFRESH_NEW
);
810 bgp_packet_set_marker(s
, BGP_MSG_ROUTE_REFRESH_OLD
);
812 /* Encode Route Refresh message. */
813 stream_putw(s
, pkt_afi
);
815 stream_putc(s
, pkt_safi
);
817 if (orf_type
== ORF_TYPE_PREFIX
|| orf_type
== ORF_TYPE_PREFIX_OLD
)
818 if (remove
|| filter
->plist
[FILTER_IN
].plist
) {
823 stream_putc(s
, when_to_refresh
);
824 stream_putc(s
, orf_type
);
825 orfp
= stream_get_endp(s
);
829 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
830 PEER_STATUS_ORF_PREFIX_SEND
);
831 stream_putc(s
, ORF_COMMON_PART_REMOVE_ALL
);
832 if (bgp_debug_neighbor_events(peer
))
834 "%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s",
835 peer
->host
, orf_type
,
836 (when_to_refresh
== REFRESH_DEFER
839 iana_afi2str(pkt_afi
),
840 iana_safi2str(pkt_safi
));
842 SET_FLAG(peer
->af_sflags
[afi
][safi
],
843 PEER_STATUS_ORF_PREFIX_SEND
);
844 prefix_bgp_orf_entry(
845 s
, filter
->plist
[FILTER_IN
].plist
,
847 ORF_COMMON_PART_PERMIT
,
848 ORF_COMMON_PART_DENY
);
849 if (bgp_debug_neighbor_events(peer
))
851 "%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s",
852 peer
->host
, orf_type
,
853 (when_to_refresh
== REFRESH_DEFER
856 iana_afi2str(pkt_afi
),
857 iana_safi2str(pkt_safi
));
860 /* Total ORF Entry Len. */
861 orf_len
= stream_get_endp(s
) - orfp
- 2;
862 stream_putw_at(s
, orfp
, orf_len
);
865 /* Set packet size. */
866 (void)bgp_packet_set_size(s
);
868 if (bgp_debug_neighbor_events(peer
)) {
870 zlog_debug("%s sending REFRESH_REQ for afi/safi: %s/%s",
871 peer
->host
, iana_afi2str(pkt_afi
),
872 iana_safi2str(pkt_safi
));
875 /* Add packet to the peer. */
876 bgp_packet_add(peer
, s
);
882 * Create a BGP Capability packet and append it to the peer's output queue.
885 * @param afi Address Family Identifier
886 * @param safi Subsequent Address Family Identifier
887 * @param capability_code BGP Capability Code
888 * @param action Set or Remove capability
890 void bgp_capability_send(struct peer
*peer
, afi_t afi
, safi_t safi
,
891 int capability_code
, int action
)
895 iana_safi_t pkt_safi
;
897 /* Convert AFI, SAFI to values for packet. */
898 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
, &pkt_safi
);
900 s
= stream_new(BGP_MAX_PACKET_SIZE
);
902 /* Make BGP update packet. */
903 bgp_packet_set_marker(s
, BGP_MSG_CAPABILITY
);
905 /* Encode MP_EXT capability. */
906 if (capability_code
== CAPABILITY_CODE_MP
) {
907 stream_putc(s
, action
);
908 stream_putc(s
, CAPABILITY_CODE_MP
);
909 stream_putc(s
, CAPABILITY_CODE_MP_LEN
);
910 stream_putw(s
, pkt_afi
);
912 stream_putc(s
, pkt_safi
);
914 if (bgp_debug_neighbor_events(peer
))
916 "%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s",
918 action
== CAPABILITY_ACTION_SET
? "Advertising"
920 iana_afi2str(pkt_afi
), iana_safi2str(pkt_safi
));
923 /* Set packet size. */
924 (void)bgp_packet_set_size(s
);
926 /* Add packet to the peer. */
927 bgp_packet_add(peer
, s
);
932 /* RFC1771 6.8 Connection collision detection. */
933 static int bgp_collision_detect(struct peer
*new, struct in_addr remote_id
)
937 /* Upon receipt of an OPEN message, the local system must examine
938 all of its connections that are in the OpenConfirm state. A BGP
939 speaker may also examine connections in an OpenSent state if it
940 knows the BGP Identifier of the peer by means outside of the
941 protocol. If among these connections there is a connection to a
942 remote BGP speaker whose BGP Identifier equals the one in the
943 OPEN message, then the local system performs the following
944 collision resolution procedure: */
946 if ((peer
= new->doppelganger
) != NULL
) {
947 /* Do not accept the new connection in Established or Clearing
949 * Note that a peer GR is handled by closing the existing
951 * upon receipt of new one.
953 if (peer
->status
== Established
|| peer
->status
== Clearing
) {
954 bgp_notify_send(new, BGP_NOTIFY_CEASE
,
955 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
957 } else if ((peer
->status
== OpenConfirm
)
958 || (peer
->status
== OpenSent
)) {
959 /* 1. The BGP Identifier of the local system is compared
961 the BGP Identifier of the remote system (as specified
963 the OPEN message). */
965 if (ntohl(peer
->local_id
.s_addr
)
966 < ntohl(remote_id
.s_addr
))
967 if (!CHECK_FLAG(peer
->sflags
,
968 PEER_STATUS_ACCEPT_PEER
)) {
969 /* 2. If the value of the local BGP
971 than the remote one, the local system
973 connection that already exists (the
975 already in the OpenConfirm state),
977 connection initiated by the remote
980 peer
, BGP_NOTIFY_CEASE
,
981 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
985 new, BGP_NOTIFY_CEASE
,
986 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
990 /* 3. Otherwise, the local system closes newly
992 BGP connection (the one associated with the
994 received OPEN message), and continues to use
996 existing one (the one that is already in the
997 OpenConfirm state). */
998 if (CHECK_FLAG(peer
->sflags
,
999 PEER_STATUS_ACCEPT_PEER
)) {
1001 peer
, BGP_NOTIFY_CEASE
,
1002 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
1006 new, BGP_NOTIFY_CEASE
,
1007 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
1016 /* Packet processing routines ---------------------------------------------- */
1018 * This is a family of functions designed to be called from
1019 * bgp_process_packet(). These functions all share similar behavior and should
1020 * adhere to the following invariants and restrictions:
1024 * The return code of any one of those functions should be one of the FSM event
1025 * codes specified in bgpd.h. If a NOTIFY was sent, this event code MUST be
1026 * BGP_Stop. Otherwise, the code SHOULD correspond to the function's expected
1027 * packet type. For example, bgp_open_receive() should return BGP_Stop upon
1028 * error and Receive_OPEN_message otherwise.
1030 * If no action is necessary, the correct return code is BGP_PACKET_NOOP as
1035 * - May send NOTIFY messages
1036 * - May not modify peer->status
1037 * - May not call bgp_event_update()
1040 #define BGP_PACKET_NOOP 0
1043 * Process BGP OPEN message for peer.
1045 * If any errors are encountered in the OPEN message, immediately sends NOTIFY
1046 * and returns BGP_Stop.
1049 * @param size size of the packet
1050 * @return as in summary
1052 static int bgp_open_receive(struct peer
*peer
, bgp_size_t size
)
1058 uint16_t send_holdtime
;
1060 as_t as4
= 0, as4_be
;
1061 struct in_addr remote_id
;
1063 uint8_t notify_data_remote_as
[2];
1064 uint8_t notify_data_remote_as4
[4];
1065 uint8_t notify_data_remote_id
[4];
1066 uint16_t *holdtime_ptr
;
1068 /* Parse open packet. */
1069 version
= stream_getc(peer
->curr
);
1070 memcpy(notify_data_remote_as
, stream_pnt(peer
->curr
), 2);
1071 remote_as
= stream_getw(peer
->curr
);
1072 holdtime_ptr
= (uint16_t *)stream_pnt(peer
->curr
);
1073 holdtime
= stream_getw(peer
->curr
);
1074 memcpy(notify_data_remote_id
, stream_pnt(peer
->curr
), 4);
1075 remote_id
.s_addr
= stream_get_ipv4(peer
->curr
);
1077 /* Receive OPEN message log */
1078 if (bgp_debug_neighbor_events(peer
))
1080 "%s rcv OPEN, version %d, remote-as (in open) %u,"
1081 " holdtime %d, id %s",
1082 peer
->host
, version
, remote_as
, holdtime
,
1083 inet_ntoa(remote_id
));
1085 /* BEGIN to read the capability here, but dont do it yet */
1087 optlen
= stream_getc(peer
->curr
);
1090 /* If not enough bytes, it is an error. */
1091 if (STREAM_READABLE(peer
->curr
) < optlen
) {
1092 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
1093 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
1097 /* We need the as4 capability value *right now* because
1098 * if it is there, we have not got the remote_as yet, and
1100 * that we do not know which peer is connecting to us now.
1102 as4
= peek_for_as4_capability(peer
, optlen
);
1105 as4_be
= htonl(as4
);
1106 memcpy(notify_data_remote_as4
, &as4_be
, 4);
1108 /* Just in case we have a silly peer who sends AS4 capability set to 0
1110 if (CHECK_FLAG(peer
->cap
, PEER_CAP_AS4_RCV
) && !as4
) {
1111 flog_err(EC_BGP_PKT_OPEN
,
1112 "%s bad OPEN, got AS4 capability, but AS4 set to 0",
1114 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1115 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1116 notify_data_remote_as4
, 4);
1120 if (remote_as
== BGP_AS_TRANS
) {
1121 /* Take the AS4 from the capability. We must have received the
1122 * capability now! Otherwise we have a asn16 peer who uses
1123 * BGP_AS_TRANS, for some unknown reason.
1125 if (as4
== BGP_AS_TRANS
) {
1128 "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1130 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1131 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1132 notify_data_remote_as4
, 4);
1136 if (!as4
&& BGP_DEBUG(as4
, AS4
))
1138 "%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1139 " Odd, but proceeding.",
1141 else if (as4
< BGP_AS_MAX
&& BGP_DEBUG(as4
, AS4
))
1143 "%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
1144 "in 2-bytes, very odd peer.",
1149 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX
1151 /* If we have got the capability, peer->as4cap must match
1153 if (CHECK_FLAG(peer
->cap
, PEER_CAP_AS4_RCV
)
1154 && as4
!= remote_as
) {
1155 /* raise error, log this, close session */
1158 "%s bad OPEN, got AS4 capability, but remote_as %u"
1159 " mismatch with 16bit 'myasn' %u in open",
1160 peer
->host
, as4
, remote_as
);
1161 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1162 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1163 notify_data_remote_as4
, 4);
1168 /* remote router-id check. */
1169 if (remote_id
.s_addr
== 0 || IPV4_CLASS_DE(ntohl(remote_id
.s_addr
))
1170 || ntohl(peer
->local_id
.s_addr
) == ntohl(remote_id
.s_addr
)) {
1171 if (bgp_debug_neighbor_events(peer
))
1172 zlog_debug("%s bad OPEN, wrong router identifier %s",
1173 peer
->host
, inet_ntoa(remote_id
));
1174 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1175 BGP_NOTIFY_OPEN_BAD_BGP_IDENT
,
1176 notify_data_remote_id
, 4);
1180 /* Set remote router-id */
1181 peer
->remote_id
= remote_id
;
1183 /* Peer BGP version check. */
1184 if (version
!= BGP_VERSION_4
) {
1185 uint16_t maxver
= htons(BGP_VERSION_4
);
1186 /* XXX this reply may not be correct if version < 4 XXX */
1187 if (bgp_debug_neighbor_events(peer
))
1189 "%s bad protocol version, remote requested %d, local request %d",
1190 peer
->host
, version
, BGP_VERSION_4
);
1191 /* Data must be in network byte order here */
1192 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1193 BGP_NOTIFY_OPEN_UNSUP_VERSION
,
1194 (uint8_t *)&maxver
, 2);
1198 /* Check neighbor as number. */
1199 if (peer
->as_type
== AS_UNSPECIFIED
) {
1200 if (bgp_debug_neighbor_events(peer
))
1202 "%s bad OPEN, remote AS is unspecified currently",
1204 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1205 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1206 notify_data_remote_as
, 2);
1208 } else if (peer
->as_type
== AS_INTERNAL
) {
1209 if (remote_as
!= peer
->bgp
->as
) {
1210 if (bgp_debug_neighbor_events(peer
))
1212 "%s bad OPEN, remote AS is %u, internal specified",
1213 peer
->host
, remote_as
);
1214 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1215 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1216 notify_data_remote_as
, 2);
1219 peer
->as
= peer
->local_as
;
1220 } else if (peer
->as_type
== AS_EXTERNAL
) {
1221 if (remote_as
== peer
->bgp
->as
) {
1222 if (bgp_debug_neighbor_events(peer
))
1224 "%s bad OPEN, remote AS is %u, external specified",
1225 peer
->host
, remote_as
);
1226 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1227 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1228 notify_data_remote_as
, 2);
1231 peer
->as
= remote_as
;
1232 } else if ((peer
->as_type
== AS_SPECIFIED
) && (remote_as
!= peer
->as
)) {
1233 if (bgp_debug_neighbor_events(peer
))
1234 zlog_debug("%s bad OPEN, remote AS is %u, expected %u",
1235 peer
->host
, remote_as
, peer
->as
);
1236 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1237 BGP_NOTIFY_OPEN_BAD_PEER_AS
,
1238 notify_data_remote_as
, 2);
1242 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1243 calculate the value of the Hold Timer by using the smaller of its
1244 configured Hold Time and the Hold Time received in the OPEN message.
1245 The Hold Time MUST be either zero or at least three seconds. An
1246 implementation may reject connections on the basis of the Hold Time.
1249 if (holdtime
< 3 && holdtime
!= 0) {
1250 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1251 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME
,
1252 (uint8_t *)holdtime_ptr
, 2);
1256 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1257 would be one third of the Hold Time interval. KEEPALIVE messages
1258 MUST NOT be sent more frequently than one per second. An
1259 implementation MAY adjust the rate at which it sends KEEPALIVE
1260 messages as a function of the Hold Time interval. */
1262 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
1263 send_holdtime
= peer
->holdtime
;
1265 send_holdtime
= peer
->bgp
->default_holdtime
;
1267 if (holdtime
< send_holdtime
)
1268 peer
->v_holdtime
= holdtime
;
1270 peer
->v_holdtime
= send_holdtime
;
1272 if ((CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
))
1273 && (peer
->keepalive
< peer
->v_holdtime
/ 3))
1274 peer
->v_keepalive
= peer
->keepalive
;
1276 peer
->v_keepalive
= peer
->v_holdtime
/ 3;
1278 /* Open option part parse. */
1280 if ((ret
= bgp_open_option_parse(peer
, optlen
, &mp_capability
))
1284 if (bgp_debug_neighbor_events(peer
))
1285 zlog_debug("%s rcvd OPEN w/ OPTION parameter len: 0",
1290 * Assume that the peer supports the locally configured set of
1291 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1292 * capabilities, or if 'override-capability' is configured.
1295 || CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
1296 peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
] =
1297 peer
->afc
[AFI_IP
][SAFI_UNICAST
];
1298 peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
] =
1299 peer
->afc
[AFI_IP
][SAFI_MULTICAST
];
1300 peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
] =
1301 peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
];
1302 peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
] =
1303 peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
];
1304 peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
] =
1305 peer
->afc
[AFI_IP6
][SAFI_UNICAST
];
1306 peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
] =
1307 peer
->afc
[AFI_IP6
][SAFI_MULTICAST
];
1308 peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
] =
1309 peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
];
1310 peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
] =
1311 peer
->afc
[AFI_L2VPN
][SAFI_EVPN
];
1312 peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
] =
1313 peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
];
1316 /* When collision is detected and this peer is closed. Retrun
1318 ret
= bgp_collision_detect(peer
, remote_id
);
1323 if ((ret
= bgp_getsockname(peer
)) < 0) {
1324 flog_err_sys(EC_LIB_SOCKET
,
1325 "%s: bgp_getsockname() failed for peer: %s",
1326 __FUNCTION__
, peer
->host
);
1330 /* Verify valid local address present based on negotiated
1331 * address-families. */
1332 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
1333 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
1334 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
1335 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
1336 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]) {
1337 if (!peer
->nexthop
.v4
.s_addr
) {
1338 #if defined(HAVE_CUMULUS)
1341 "%s: No local IPv4 addr resetting connection, fd %d",
1342 peer
->host
, peer
->fd
);
1343 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1344 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
1349 if (peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
1350 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
1351 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
1352 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
1353 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]) {
1354 if (IN6_IS_ADDR_UNSPECIFIED(&peer
->nexthop
.v6_global
)) {
1355 #if defined(HAVE_CUMULUS)
1358 "%s: No local IPv6 addr resetting connection, fd %d",
1359 peer
->host
, peer
->fd
);
1360 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1361 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
1366 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
1368 return Receive_OPEN_message
;
1372 * Process BGP KEEPALIVE message for peer.
1375 * @param size size of the packet
1376 * @return as in summary
1378 static int bgp_keepalive_receive(struct peer
*peer
, bgp_size_t size
)
1380 if (bgp_debug_keepalive(peer
))
1381 zlog_debug("%s KEEPALIVE rcvd", peer
->host
);
1383 bgp_update_implicit_eors(peer
);
1385 return Receive_KEEPALIVE_message
;
1390 * Process BGP UPDATE message for peer.
1392 * Parses UPDATE and creates attribute object.
1395 * @param size size of the packet
1396 * @return as in summary
1398 static int bgp_update_receive(struct peer
*peer
, bgp_size_t size
)
1404 bgp_size_t attribute_len
;
1405 bgp_size_t update_len
;
1406 bgp_size_t withdraw_len
;
1415 struct bgp_nlri nlris
[NLRI_TYPE_MAX
];
1417 /* Status must be Established. */
1418 if (peer
->status
!= Established
) {
1419 flog_err(EC_BGP_INVALID_STATUS
,
1420 "%s [FSM] Update packet received under status %s",
1422 lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
1423 bgp_notify_send(peer
, BGP_NOTIFY_FSM_ERR
,
1424 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
1428 /* Set initial values. */
1429 memset(&attr
, 0, sizeof(struct attr
));
1430 attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
1431 attr
.label
= MPLS_INVALID_LABEL
;
1432 memset(&nlris
, 0, sizeof(nlris
));
1433 memset(peer
->rcvd_attr_str
, 0, BUFSIZ
);
1434 peer
->rcvd_attr_printed
= 0;
1437 end
= stream_pnt(s
) + size
;
1439 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1440 Length is too large (i.e., if Unfeasible Routes Length + Total
1441 Attribute Length + 23 exceeds the message Length), then the Error
1442 Subcode is set to Malformed Attribute List. */
1443 if (stream_pnt(s
) + 2 > end
) {
1444 flog_err(EC_BGP_UPDATE_RCV
,
1445 "%s [Error] Update packet error"
1446 " (packet length is short for unfeasible length)",
1448 bgp_notify_send(peer
, BGP_NOTIFY_UPDATE_ERR
,
1449 BGP_NOTIFY_UPDATE_MAL_ATTR
);
1453 /* Unfeasible Route Length. */
1454 withdraw_len
= stream_getw(s
);
1456 /* Unfeasible Route Length check. */
1457 if (stream_pnt(s
) + withdraw_len
> end
) {
1458 flog_err(EC_BGP_UPDATE_RCV
,
1459 "%s [Error] Update packet error"
1460 " (packet unfeasible length overflow %d)",
1461 peer
->host
, withdraw_len
);
1462 bgp_notify_send(peer
, BGP_NOTIFY_UPDATE_ERR
,
1463 BGP_NOTIFY_UPDATE_MAL_ATTR
);
1467 /* Unfeasible Route packet format check. */
1468 if (withdraw_len
> 0) {
1469 nlris
[NLRI_WITHDRAW
].afi
= AFI_IP
;
1470 nlris
[NLRI_WITHDRAW
].safi
= SAFI_UNICAST
;
1471 nlris
[NLRI_WITHDRAW
].nlri
= stream_pnt(s
);
1472 nlris
[NLRI_WITHDRAW
].length
= withdraw_len
;
1473 stream_forward_getp(s
, withdraw_len
);
1476 /* Attribute total length check. */
1477 if (stream_pnt(s
) + 2 > end
) {
1479 EC_BGP_UPDATE_PACKET_SHORT
,
1480 "%s [Error] Packet Error (update packet is short for attribute length)",
1482 bgp_notify_send(peer
, BGP_NOTIFY_UPDATE_ERR
,
1483 BGP_NOTIFY_UPDATE_MAL_ATTR
);
1487 /* Fetch attribute total length. */
1488 attribute_len
= stream_getw(s
);
1490 /* Attribute length check. */
1491 if (stream_pnt(s
) + attribute_len
> end
) {
1493 EC_BGP_UPDATE_PACKET_LONG
,
1494 "%s [Error] Packet Error (update packet attribute length overflow %d)",
1495 peer
->host
, attribute_len
);
1496 bgp_notify_send(peer
, BGP_NOTIFY_UPDATE_ERR
,
1497 BGP_NOTIFY_UPDATE_MAL_ATTR
);
1501 /* Certain attribute parsing errors should not be considered bad enough
1502 * to reset the session for, most particularly any partial/optional
1503 * attributes that have 'tunneled' over speakers that don't understand
1504 * them. Instead we withdraw only the prefix concerned.
1506 * Complicates the flow a little though..
1508 bgp_attr_parse_ret_t attr_parse_ret
= BGP_ATTR_PARSE_PROCEED
;
1509 /* This define morphs the update case into a withdraw when lower levels
1510 * have signalled an error condition where this is best.
1512 #define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
1514 /* Parse attribute when it exists. */
1515 if (attribute_len
) {
1516 attr_parse_ret
= bgp_attr_parse(peer
, &attr
, attribute_len
,
1517 &nlris
[NLRI_MP_UPDATE
],
1518 &nlris
[NLRI_MP_WITHDRAW
]);
1519 if (attr_parse_ret
== BGP_ATTR_PARSE_ERROR
) {
1520 bgp_attr_unintern_sub(&attr
);
1525 /* Logging the attribute. */
1526 if (attr_parse_ret
== BGP_ATTR_PARSE_WITHDRAW
1527 || BGP_DEBUG(update
, UPDATE_IN
)
1528 || BGP_DEBUG(update
, UPDATE_PREFIX
)) {
1529 ret
= bgp_dump_attr(&attr
, peer
->rcvd_attr_str
, BUFSIZ
);
1531 peer
->stat_upd_7606
++;
1533 if (attr_parse_ret
== BGP_ATTR_PARSE_WITHDRAW
)
1536 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1539 if (ret
&& bgp_debug_update(peer
, NULL
, NULL
, 1)) {
1540 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
1541 peer
->rcvd_attr_str
);
1542 peer
->rcvd_attr_printed
= 1;
1546 /* Network Layer Reachability Information. */
1547 update_len
= end
- stream_pnt(s
);
1550 /* Set NLRI portion to structure. */
1551 nlris
[NLRI_UPDATE
].afi
= AFI_IP
;
1552 nlris
[NLRI_UPDATE
].safi
= SAFI_UNICAST
;
1553 nlris
[NLRI_UPDATE
].nlri
= stream_pnt(s
);
1554 nlris
[NLRI_UPDATE
].length
= update_len
;
1555 stream_forward_getp(s
, update_len
);
1557 if (CHECK_FLAG(attr
.flag
, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI
))) {
1559 * We skipped nexthop attribute validation earlier so
1560 * validate the nexthop now.
1562 if (bgp_attr_nexthop_valid(peer
, &attr
) < 0) {
1563 bgp_attr_unintern_sub(&attr
);
1569 if (BGP_DEBUG(update
, UPDATE_IN
))
1570 zlog_debug("%s rcvd UPDATE wlen %d attrlen %d alen %d",
1571 peer
->host
, withdraw_len
, attribute_len
, update_len
);
1573 /* Parse any given NLRIs */
1574 for (int i
= NLRI_UPDATE
; i
< NLRI_TYPE_MAX
; i
++) {
1578 /* NLRI is processed iff the peer if configured for the specific
1580 if (!peer
->afc
[nlris
[i
].afi
][nlris
[i
].safi
]) {
1582 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1583 peer
->host
, nlris
[i
].afi
, nlris
[i
].safi
);
1587 /* EoR handled later */
1588 if (nlris
[i
].length
== 0)
1593 case NLRI_MP_UPDATE
:
1594 nlri_ret
= bgp_nlri_parse(peer
, NLRI_ATTR_ARG
,
1598 case NLRI_MP_WITHDRAW
:
1599 nlri_ret
= bgp_nlri_parse(peer
, &attr
, &nlris
[i
], 1);
1602 nlri_ret
= BGP_NLRI_PARSE_ERROR
;
1605 if (nlri_ret
< BGP_NLRI_PARSE_OK
1606 && nlri_ret
!= BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW
) {
1607 flog_err(EC_BGP_UPDATE_RCV
,
1608 "%s [Error] Error parsing NLRI", peer
->host
);
1609 if (peer
->status
== Established
)
1611 peer
, BGP_NOTIFY_UPDATE_ERR
,
1613 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1614 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR
);
1615 bgp_attr_unintern_sub(&attr
);
1622 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1623 * and MP EoR should have only an empty MP_UNREACH
1625 if ((!update_len
&& !withdraw_len
&& nlris
[NLRI_MP_UPDATE
].length
== 0)
1626 || (attr_parse_ret
== BGP_ATTR_PARSE_EOR
)) {
1630 /* Non-MP IPv4/Unicast is a completely emtpy UPDATE - already
1632 * update and withdraw NLRI lengths are 0.
1634 if (!attribute_len
) {
1636 safi
= SAFI_UNICAST
;
1637 } else if (attr
.flag
& ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI
)
1638 && nlris
[NLRI_MP_WITHDRAW
].length
== 0) {
1639 afi
= nlris
[NLRI_MP_WITHDRAW
].afi
;
1640 safi
= nlris
[NLRI_MP_WITHDRAW
].safi
;
1641 } else if (attr_parse_ret
== BGP_ATTR_PARSE_EOR
) {
1642 afi
= nlris
[NLRI_MP_UPDATE
].afi
;
1643 safi
= nlris
[NLRI_MP_UPDATE
].safi
;
1646 if (afi
&& peer
->afc
[afi
][safi
]) {
1647 struct vrf
*vrf
= vrf_lookup_by_id(peer
->bgp
->vrf_id
);
1649 /* End-of-RIB received */
1650 if (!CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
1651 PEER_STATUS_EOR_RECEIVED
)) {
1652 SET_FLAG(peer
->af_sflags
[afi
][safi
],
1653 PEER_STATUS_EOR_RECEIVED
);
1654 bgp_update_explicit_eors(peer
);
1657 /* NSF delete stale route */
1658 if (peer
->nsf
[afi
][safi
])
1659 bgp_clear_stale_route(peer
, afi
, safi
);
1661 zlog_info("%%NOTIFICATION: rcvd End-of-RIB for %s from %s in vrf %s",
1662 get_afi_safi_str(afi
, safi
, false), peer
->host
,
1663 vrf
? vrf
->name
: VRF_DEFAULT_NAME
);
1667 /* Everything is done. We unintern temporary structures which
1668 interned in bgp_attr_parse(). */
1669 bgp_attr_unintern_sub(&attr
);
1671 peer
->update_time
= bgp_clock();
1673 /* Rearm holdtime timer */
1674 BGP_TIMER_OFF(peer
->t_holdtime
);
1675 bgp_timer_set(peer
);
1677 return Receive_UPDATE_message
;
1681 * Process BGP NOTIFY message for peer.
1684 * @param size size of the packet
1685 * @return as in summary
1687 static int bgp_notify_receive(struct peer
*peer
, bgp_size_t size
)
1689 struct bgp_notify bgp_notify
;
1691 if (peer
->notify
.data
) {
1692 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1693 peer
->notify
.data
= NULL
;
1694 peer
->notify
.length
= 0;
1697 bgp_notify
.code
= stream_getc(peer
->curr
);
1698 bgp_notify
.subcode
= stream_getc(peer
->curr
);
1699 bgp_notify
.length
= size
- 2;
1700 bgp_notify
.data
= NULL
;
1702 /* Preserv notify code and sub code. */
1703 peer
->notify
.code
= bgp_notify
.code
;
1704 peer
->notify
.subcode
= bgp_notify
.subcode
;
1705 /* For further diagnostic record returned Data. */
1706 if (bgp_notify
.length
) {
1707 peer
->notify
.length
= size
- 2;
1708 peer
->notify
.data
= XMALLOC(MTYPE_TMP
, size
- 2);
1709 memcpy(peer
->notify
.data
, stream_pnt(peer
->curr
), size
- 2);
1718 if (bgp_notify
.length
) {
1720 XMALLOC(MTYPE_TMP
, bgp_notify
.length
* 3);
1721 for (i
= 0; i
< bgp_notify
.length
; i
++)
1723 snprintf(c
, sizeof(c
), " %02x",
1724 stream_getc(peer
->curr
));
1725 strlcat(bgp_notify
.data
, c
,
1729 snprintf(c
, sizeof(c
), "%02x",
1730 stream_getc(peer
->curr
));
1731 strlcpy(bgp_notify
.data
, c
,
1734 bgp_notify
.raw_data
= (uint8_t *)peer
->notify
.data
;
1737 bgp_notify_print(peer
, &bgp_notify
, "received");
1738 if (bgp_notify
.data
) {
1739 XFREE(MTYPE_TMP
, bgp_notify
.data
);
1740 bgp_notify
.data
= NULL
;
1741 bgp_notify
.length
= 0;
1745 /* peer count update */
1746 atomic_fetch_add_explicit(&peer
->notify_in
, 1, memory_order_relaxed
);
1748 peer
->last_reset
= PEER_DOWN_NOTIFY_RECEIVED
;
1750 /* We have to check for Notify with Unsupported Optional Parameter.
1751 in that case we fallback to open without the capability option.
1752 But this done in bgp_stop. We just mark it here to avoid changing
1754 if (bgp_notify
.code
== BGP_NOTIFY_OPEN_ERR
1755 && bgp_notify
.subcode
== BGP_NOTIFY_OPEN_UNSUP_PARAM
)
1756 UNSET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1758 return Receive_NOTIFICATION_message
;
1762 * Process BGP ROUTEREFRESH message for peer.
1765 * @param size size of the packet
1766 * @return as in summary
1768 static int bgp_route_refresh_receive(struct peer
*peer
, bgp_size_t size
)
1772 iana_safi_t pkt_safi
;
1775 struct peer_af
*paf
;
1776 struct update_group
*updgrp
;
1777 struct peer
*updgrp_peer
;
1779 /* If peer does not have the capability, send notification. */
1780 if (!CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_ADV
)) {
1781 flog_err(EC_BGP_NO_CAP
,
1782 "%s [Error] BGP route refresh is not enabled",
1784 bgp_notify_send(peer
, BGP_NOTIFY_HEADER_ERR
,
1785 BGP_NOTIFY_HEADER_BAD_MESTYPE
);
1789 /* Status must be Established. */
1790 if (peer
->status
!= Established
) {
1792 EC_BGP_INVALID_STATUS
,
1793 "%s [Error] Route refresh packet received under status %s",
1795 lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
1796 bgp_notify_send(peer
, BGP_NOTIFY_FSM_ERR
,
1797 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
1804 pkt_afi
= stream_getw(s
);
1805 (void)stream_getc(s
);
1806 pkt_safi
= stream_getc(s
);
1808 if (bgp_debug_update(peer
, NULL
, NULL
, 0))
1809 zlog_debug("%s rcvd REFRESH_REQ for afi/safi: %s/%s",
1810 peer
->host
, iana_afi2str(pkt_afi
),
1811 iana_safi2str(pkt_safi
));
1813 /* Convert AFI, SAFI to internal values and check. */
1814 if (bgp_map_afi_safi_iana2int(pkt_afi
, pkt_safi
, &afi
, &safi
)) {
1816 "%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored",
1817 peer
->host
, iana_afi2str(pkt_afi
),
1818 iana_safi2str(pkt_safi
));
1819 return BGP_PACKET_NOOP
;
1822 if (size
!= BGP_MSG_ROUTE_REFRESH_MIN_SIZE
- BGP_HEADER_SIZE
) {
1824 uint8_t when_to_refresh
;
1828 if (size
- (BGP_MSG_ROUTE_REFRESH_MIN_SIZE
- BGP_HEADER_SIZE
)
1830 zlog_info("%s ORF route refresh length error",
1832 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1833 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
1837 when_to_refresh
= stream_getc(s
);
1838 end
= stream_pnt(s
) + (size
- 5);
1840 while ((stream_pnt(s
) + 2) < end
) {
1841 orf_type
= stream_getc(s
);
1842 orf_len
= stream_getw(s
);
1844 /* orf_len in bounds? */
1845 if ((stream_pnt(s
) + orf_len
) > end
)
1846 break; /* XXX: Notify instead?? */
1847 if (orf_type
== ORF_TYPE_PREFIX
1848 || orf_type
== ORF_TYPE_PREFIX_OLD
) {
1849 uint8_t *p_pnt
= stream_pnt(s
);
1850 uint8_t *p_end
= stream_pnt(s
) + orf_len
;
1851 struct orf_prefix orfp
;
1856 int ret
= CMD_SUCCESS
;
1858 if (bgp_debug_neighbor_events(peer
)) {
1860 "%s rcvd Prefixlist ORF(%d) length %d",
1861 peer
->host
, orf_type
, orf_len
);
1864 /* we're going to read at least 1 byte of common
1866 * and 7 bytes of ORF Address-filter entry from
1872 /* ORF prefix-list name */
1873 sprintf(name
, "%s.%d.%d", peer
->host
, afi
,
1876 while (p_pnt
< p_end
) {
1877 /* If the ORF entry is malformed, want
1878 * to read as much of it
1879 * as possible without going beyond the
1880 * bounds of the entry,
1881 * to maximise debug information.
1885 sizeof(struct orf_prefix
));
1887 /* after ++: p_pnt <= p_end */
1889 & ORF_COMMON_PART_REMOVE_ALL
) {
1890 if (bgp_debug_neighbor_events(
1893 "%s rcvd Remove-All pfxlist ORF request",
1895 prefix_bgp_orf_remove_all(afi
,
1899 ok
= ((uint32_t)(p_end
- p_pnt
)
1900 >= sizeof(uint32_t));
1904 p_pnt
+= sizeof(uint32_t);
1905 orfp
.seq
= ntohl(seq
);
1909 if ((ok
= (p_pnt
< p_end
)))
1913 prefix_bgp_orf_set()
1915 if ((ok
= (p_pnt
< p_end
)))
1919 prefix_bgp_orf_set()
1921 if ((ok
= (p_pnt
< p_end
)))
1922 orfp
.p
.prefixlen
= *p_pnt
++;
1923 orfp
.p
.family
= afi2family(
1924 afi
); /* afi checked already */
1927 orfp
.p
.prefixlen
); /* 0 if not
1931 &orfp
.p
)) /* valid for
1935 psize
= prefix_blen(&orfp
.p
);
1938 > (p_end
- p_pnt
)) /* valid for
1942 psize
= p_end
- p_pnt
;
1946 memcpy(&orfp
.p
.u
.prefix
, p_pnt
,
1950 if (bgp_debug_neighbor_events(peer
)) {
1951 char buf
[INET6_BUFSIZ
];
1954 "%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
1956 (common
& ORF_COMMON_PART_REMOVE
1959 (common
& ORF_COMMON_PART_DENY
1970 ok
? "" : " MALFORMED");
1974 ret
= prefix_bgp_orf_set(
1976 (common
& ORF_COMMON_PART_DENY
1979 (common
& ORF_COMMON_PART_REMOVE
1983 if (!ok
|| (ok
&& ret
!= CMD_SUCCESS
)) {
1985 "%s Received misformatted prefixlist ORF."
1986 " Remove All pfxlist",
1988 prefix_bgp_orf_remove_all(afi
,
1994 peer
->orf_plist
[afi
][safi
] =
1995 prefix_bgp_orf_lookup(afi
, name
);
1997 stream_forward_getp(s
, orf_len
);
1999 if (bgp_debug_neighbor_events(peer
))
2000 zlog_debug("%s rcvd Refresh %s ORF request", peer
->host
,
2001 when_to_refresh
== REFRESH_DEFER
2004 if (when_to_refresh
== REFRESH_DEFER
)
2005 return BGP_PACKET_NOOP
;
2008 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2009 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2010 PEER_STATUS_ORF_WAIT_REFRESH
))
2011 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2012 PEER_STATUS_ORF_WAIT_REFRESH
);
2014 paf
= peer_af_find(peer
, afi
, safi
);
2015 if (paf
&& paf
->subgroup
) {
2016 if (peer
->orf_plist
[afi
][safi
]) {
2017 updgrp
= PAF_UPDGRP(paf
);
2018 updgrp_peer
= UPDGRP_PEER(updgrp
);
2019 updgrp_peer
->orf_plist
[afi
][safi
] =
2020 peer
->orf_plist
[afi
][safi
];
2023 /* If the peer is configured for default-originate clear the
2024 * SUBGRP_STATUS_DEFAULT_ORIGINATE flag so that we will
2028 if (CHECK_FLAG(paf
->subgroup
->sflags
,
2029 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
2030 UNSET_FLAG(paf
->subgroup
->sflags
,
2031 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
2034 /* Perform route refreshment to the peer */
2035 bgp_announce_route(peer
, afi
, safi
);
2037 /* No FSM action necessary */
2038 return BGP_PACKET_NOOP
;
2042 * Parse BGP CAPABILITY message for peer.
2045 * @param size size of the packet
2046 * @return as in summary
2048 static int bgp_capability_msg_parse(struct peer
*peer
, uint8_t *pnt
,
2052 struct capability_mp_data mpc
;
2053 struct capability_header
*hdr
;
2057 iana_safi_t pkt_safi
;
2063 /* We need at least action, capability code and capability
2065 if (pnt
+ 3 > end
) {
2066 zlog_info("%s Capability length error", peer
->host
);
2067 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2068 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
2072 hdr
= (struct capability_header
*)(pnt
+ 1);
2074 /* Action value check. */
2075 if (action
!= CAPABILITY_ACTION_SET
2076 && action
!= CAPABILITY_ACTION_UNSET
) {
2077 zlog_info("%s Capability Action Value error %d",
2078 peer
->host
, action
);
2079 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2080 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
2084 if (bgp_debug_neighbor_events(peer
))
2086 "%s CAPABILITY has action: %d, code: %u, length %u",
2087 peer
->host
, action
, hdr
->code
, hdr
->length
);
2089 /* Capability length check. */
2090 if ((pnt
+ hdr
->length
+ 3) > end
) {
2091 zlog_info("%s Capability length error", peer
->host
);
2092 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2093 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
2097 /* Fetch structure to the byte stream. */
2098 memcpy(&mpc
, pnt
+ 3, sizeof(struct capability_mp_data
));
2099 pnt
+= hdr
->length
+ 3;
2101 /* We know MP Capability Code. */
2102 if (hdr
->code
== CAPABILITY_CODE_MP
) {
2103 pkt_afi
= ntohs(mpc
.afi
);
2104 pkt_safi
= mpc
.safi
;
2106 /* Ignore capability when override-capability is set. */
2107 if (CHECK_FLAG(peer
->flags
,
2108 PEER_FLAG_OVERRIDE_CAPABILITY
))
2111 /* Convert AFI, SAFI to internal values. */
2112 if (bgp_map_afi_safi_iana2int(pkt_afi
, pkt_safi
, &afi
,
2114 if (bgp_debug_neighbor_events(peer
))
2116 "%s Dynamic Capability MP_EXT afi/safi invalid "
2119 iana_afi2str(pkt_afi
),
2120 iana_safi2str(pkt_safi
));
2124 /* Address family check. */
2125 if (bgp_debug_neighbor_events(peer
))
2127 "%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2129 action
== CAPABILITY_ACTION_SET
2134 if (action
== CAPABILITY_ACTION_SET
) {
2135 peer
->afc_recv
[afi
][safi
] = 1;
2136 if (peer
->afc
[afi
][safi
]) {
2137 peer
->afc_nego
[afi
][safi
] = 1;
2138 bgp_announce_route(peer
, afi
, safi
);
2141 peer
->afc_recv
[afi
][safi
] = 0;
2142 peer
->afc_nego
[afi
][safi
] = 0;
2144 if (peer_active_nego(peer
))
2145 bgp_clear_route(peer
, afi
, safi
);
2151 EC_BGP_UNRECOGNIZED_CAPABILITY
,
2152 "%s unrecognized capability code: %d - ignored",
2153 peer
->host
, hdr
->code
);
2157 /* No FSM action necessary */
2158 return BGP_PACKET_NOOP
;
2162 * Parse BGP CAPABILITY message for peer.
2164 * Exported for unit testing.
2167 * @param size size of the packet
2168 * @return as in summary
2170 int bgp_capability_receive(struct peer
*peer
, bgp_size_t size
)
2174 /* Fetch pointer. */
2175 pnt
= stream_pnt(peer
->curr
);
2177 if (bgp_debug_neighbor_events(peer
))
2178 zlog_debug("%s rcv CAPABILITY", peer
->host
);
2180 /* If peer does not have the capability, send notification. */
2181 if (!CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_ADV
)) {
2182 flog_err(EC_BGP_NO_CAP
,
2183 "%s [Error] BGP dynamic capability is not enabled",
2185 bgp_notify_send(peer
, BGP_NOTIFY_HEADER_ERR
,
2186 BGP_NOTIFY_HEADER_BAD_MESTYPE
);
2190 /* Status must be Established. */
2191 if (peer
->status
!= Established
) {
2194 "%s [Error] Dynamic capability packet received under status %s",
2196 lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
2197 bgp_notify_send(peer
, BGP_NOTIFY_FSM_ERR
,
2198 BGP_NOTIFY_SUBCODE_UNSPECIFIC
);
2203 return bgp_capability_msg_parse(peer
, pnt
, size
);
2207 * Processes a peer's input buffer.
2209 * This function sidesteps the event loop and directly calls bgp_event_update()
2210 * after processing each BGP message. This is necessary to ensure proper
2211 * ordering of FSM events and unifies the behavior that was present previously,
2212 * whereby some of the packet handling functions would update the FSM and some
2213 * would not, making event flow difficult to understand. Please think twice
2214 * before hacking this.
2216 * Thread type: THREAD_EVENT
2220 int bgp_process_packet(struct thread
*thread
)
2222 /* Yes first of all get peer pointer. */
2223 struct peer
*peer
; // peer
2224 uint32_t rpkt_quanta_old
; // how many packets to read
2225 int fsm_update_result
; // return code of bgp_event_update()
2226 int mprc
; // message processing return code
2228 peer
= THREAD_ARG(thread
);
2229 rpkt_quanta_old
= atomic_load_explicit(&peer
->bgp
->rpkt_quanta
,
2230 memory_order_relaxed
);
2231 fsm_update_result
= 0;
2233 /* Guard against scheduled events that occur after peer deletion. */
2234 if (peer
->status
== Deleted
|| peer
->status
== Clearing
)
2237 unsigned int processed
= 0;
2239 while (processed
< rpkt_quanta_old
) {
2242 char notify_data_length
[2];
2244 frr_with_mutex(&peer
->io_mtx
) {
2245 peer
->curr
= stream_fifo_pop(peer
->ibuf
);
2248 if (peer
->curr
== NULL
) // no packets to process, hmm...
2251 /* skip the marker and copy the packet length */
2252 stream_forward_getp(peer
->curr
, BGP_MARKER_SIZE
);
2253 memcpy(notify_data_length
, stream_pnt(peer
->curr
), 2);
2255 /* read in the packet length and type */
2256 size
= stream_getw(peer
->curr
);
2257 type
= stream_getc(peer
->curr
);
2259 hook_call(bgp_packet_dump
, peer
, type
, size
, peer
->curr
);
2261 /* adjust size to exclude the marker + length + type */
2262 size
-= BGP_HEADER_SIZE
;
2264 /* Read rest of the packet and call each sort of packet routine
2268 atomic_fetch_add_explicit(&peer
->open_in
, 1,
2269 memory_order_relaxed
);
2270 mprc
= bgp_open_receive(peer
, size
);
2271 if (mprc
== BGP_Stop
)
2274 "%s: BGP OPEN receipt failed for peer: %s",
2275 __FUNCTION__
, peer
->host
);
2277 case BGP_MSG_UPDATE
:
2278 atomic_fetch_add_explicit(&peer
->update_in
, 1,
2279 memory_order_relaxed
);
2280 peer
->readtime
= monotime(NULL
);
2281 mprc
= bgp_update_receive(peer
, size
);
2282 if (mprc
== BGP_Stop
)
2285 "%s: BGP UPDATE receipt failed for peer: %s",
2286 __FUNCTION__
, peer
->host
);
2288 case BGP_MSG_NOTIFY
:
2289 atomic_fetch_add_explicit(&peer
->notify_in
, 1,
2290 memory_order_relaxed
);
2291 mprc
= bgp_notify_receive(peer
, size
);
2292 if (mprc
== BGP_Stop
)
2295 "%s: BGP NOTIFY receipt failed for peer: %s",
2296 __FUNCTION__
, peer
->host
);
2298 case BGP_MSG_KEEPALIVE
:
2299 peer
->readtime
= monotime(NULL
);
2300 atomic_fetch_add_explicit(&peer
->keepalive_in
, 1,
2301 memory_order_relaxed
);
2302 mprc
= bgp_keepalive_receive(peer
, size
);
2303 if (mprc
== BGP_Stop
)
2306 "%s: BGP KEEPALIVE receipt failed for peer: %s",
2307 __FUNCTION__
, peer
->host
);
2309 case BGP_MSG_ROUTE_REFRESH_NEW
:
2310 case BGP_MSG_ROUTE_REFRESH_OLD
:
2311 atomic_fetch_add_explicit(&peer
->refresh_in
, 1,
2312 memory_order_relaxed
);
2313 mprc
= bgp_route_refresh_receive(peer
, size
);
2314 if (mprc
== BGP_Stop
)
2317 "%s: BGP ROUTEREFRESH receipt failed for peer: %s",
2318 __FUNCTION__
, peer
->host
);
2320 case BGP_MSG_CAPABILITY
:
2321 atomic_fetch_add_explicit(&peer
->dynamic_cap_in
, 1,
2322 memory_order_relaxed
);
2323 mprc
= bgp_capability_receive(peer
, size
);
2324 if (mprc
== BGP_Stop
)
2327 "%s: BGP CAPABILITY receipt failed for peer: %s",
2328 __FUNCTION__
, peer
->host
);
2331 /* Suppress uninitialized variable warning */
2335 * The message type should have been sanitized before
2336 * we ever got here. Receipt of a message with an
2337 * invalid header at this point is indicative of a
2340 assert (!"Message of invalid type received during input processing");
2343 /* delete processed packet */
2344 stream_free(peer
->curr
);
2349 if (mprc
!= BGP_PACKET_NOOP
)
2350 fsm_update_result
= bgp_event_update(peer
, mprc
);
2355 * If peer was deleted, do not process any more packets. This
2356 * is usually due to executing BGP_Stop or a stub deletion.
2358 if (fsm_update_result
== FSM_PEER_TRANSFERRED
2359 || fsm_update_result
== FSM_PEER_STOPPED
)
2363 if (fsm_update_result
!= FSM_PEER_TRANSFERRED
2364 && fsm_update_result
!= FSM_PEER_STOPPED
) {
2365 frr_with_mutex(&peer
->io_mtx
) {
2366 // more work to do, come back later
2367 if (peer
->ibuf
->count
> 0)
2368 thread_add_timer_msec(
2369 bm
->master
, bgp_process_packet
, peer
, 0,
2370 &peer
->t_process_packet
);