back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_packet.c (source / functions) Hit Total Coverage
Test: test_bgp_dont_capability_negotiate.py::BGPDontCapabilityNegotiate Lines: 507 1221 41.5 %
Date: 2023-02-24 18:37:16 Functions: 25 40 62.5 %

          Line data    Source code
       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
       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             :  */
      22             : 
      23             : #include <zebra.h>
      24             : #include <sys/time.h>
      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"
      33             : #include "sockunion.h" /* for inet_ntop () */
      34             : #include "sockopt.h"
      35             : #include "linklist.h"
      36             : #include "plist.h"
      37             : #include "queue.h"
      38             : #include "filter.h"
      39             : #include "lib_errors.h"
      40             : 
      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"
      66             : #include "bgpd/bgp_trace.h"
      67             : 
      68          18 : DEFINE_HOOK(bgp_packet_dump,
      69             :                 (struct peer *peer, uint8_t type, bgp_size_t size,
      70             :                         struct stream *s),
      71             :                 (peer, type, size, s));
      72             : 
      73           2 : DEFINE_HOOK(bgp_packet_send,
      74             :                 (struct peer *peer, uint8_t type, bgp_size_t size,
      75             :                         struct stream *s),
      76             :                 (peer, type, size, s));
      77             : 
      78             : /**
      79             :  * Sets marker and type fields for a BGP message.
      80             :  *
      81             :  * @param s the stream containing the packet
      82             :  * @param type the packet type
      83             :  * @return the size of the stream
      84             :  */
      85          10 : int bgp_packet_set_marker(struct stream *s, uint8_t type)
      86             : {
      87          10 :         int i;
      88             : 
      89             :         /* Fill in marker. */
      90         170 :         for (i = 0; i < BGP_MARKER_SIZE; i++)
      91         160 :                 stream_putc(s, 0xff);
      92             : 
      93             :         /* Dummy total length. This field is should be filled in later on. */
      94          10 :         stream_putw(s, 0);
      95             : 
      96             :         /* BGP packet type. */
      97          10 :         stream_putc(s, type);
      98             : 
      99             :         /* Return current stream size. */
     100          10 :         return stream_get_endp(s);
     101             : }
     102             : 
     103             : /**
     104             :  * Sets size field for a BGP message.
     105             :  *
     106             :  * Size field is set to the size of the stream passed.
     107             :  *
     108             :  * @param s the stream containing the packet
     109             :  */
     110          10 : void bgp_packet_set_size(struct stream *s)
     111             : {
     112          10 :         int cp;
     113             : 
     114             :         /* Preserve current pointer. */
     115          10 :         cp = stream_get_endp(s);
     116          10 :         stream_putw_at(s, BGP_MARKER_SIZE, cp);
     117          10 : }
     118             : 
     119             : /*
     120             :  * Push a packet onto the beginning of the peer's output queue.
     121             :  * This function acquires the peer's write mutex before proceeding.
     122             :  */
     123           8 : static void bgp_packet_add(struct peer *peer, struct stream *s)
     124             : {
     125           8 :         intmax_t delta;
     126           8 :         uint32_t holdtime;
     127           8 :         intmax_t sendholdtime;
     128             : 
     129          16 :         frr_with_mutex (&peer->io_mtx) {
     130             :                 /* if the queue is empty, reset the "last OK" timestamp to
     131             :                  * now, otherwise if we write another packet immediately
     132             :                  * after it'll get confused
     133             :                  */
     134           8 :                 if (!stream_fifo_count_safe(peer->obuf))
     135           7 :                         peer->last_sendq_ok = monotime(NULL);
     136             : 
     137           8 :                 stream_fifo_push(peer->obuf, s);
     138             : 
     139           8 :                 delta = monotime(NULL) - peer->last_sendq_ok;
     140             : 
     141           8 :                 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
     142           0 :                         holdtime = atomic_load_explicit(&peer->holdtime,
     143             :                                                         memory_order_relaxed);
     144             :                 else
     145           8 :                         holdtime = peer->bgp->default_holdtime;
     146             : 
     147           8 :                 sendholdtime = holdtime * 2;
     148             : 
     149             :                 /* Note that when we're here, we're adding some packet to the
     150             :                  * OutQ.  That includes keepalives when there is nothing to
     151             :                  * do, so there's a guarantee we pass by here once in a while.
     152             :                  *
     153             :                  * That implies there is no need to go set up another separate
     154             :                  * timer that ticks down SendHoldTime, as we'll be here sooner
     155             :                  * or later anyway and will see the checks below failing.
     156             :                  */
     157           8 :                 if (!holdtime) {
     158             :                         /* no holdtime, do nothing. */
     159           8 :                 } else if (delta > sendholdtime) {
     160           0 :                         flog_err(
     161             :                                 EC_BGP_SENDQ_STUCK_PROPER,
     162             :                                 "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session",
     163             :                                 peer, sendholdtime);
     164           0 :                         BGP_EVENT_ADD(peer, TCP_fatal_error);
     165           8 :                 } else if (delta > (intmax_t)holdtime &&
     166           0 :                            monotime(NULL) - peer->last_sendq_warn > 5) {
     167           0 :                         flog_warn(
     168             :                                 EC_BGP_SENDQ_STUCK_WARN,
     169             :                                 "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?",
     170             :                                 peer, holdtime);
     171           0 :                         peer->last_sendq_warn = monotime(NULL);
     172             :                 }
     173             :         }
     174           8 : }
     175             : 
     176           1 : static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
     177             :                                             safi_t safi)
     178             : {
     179           1 :         struct stream *s;
     180           1 :         iana_afi_t pkt_afi = IANA_AFI_IPV4;
     181           1 :         iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
     182             : 
     183           1 :         if (DISABLE_BGP_ANNOUNCE)
     184             :                 return NULL;
     185             : 
     186           1 :         if (bgp_debug_neighbor_events(peer))
     187           0 :                 zlog_debug("send End-of-RIB for %s to %s",
     188             :                            get_afi_safi_str(afi, safi, false), peer->host);
     189             : 
     190           1 :         s = stream_new(peer->max_packet_size);
     191             : 
     192             :         /* Make BGP update packet. */
     193           1 :         bgp_packet_set_marker(s, BGP_MSG_UPDATE);
     194             : 
     195             :         /* Unfeasible Routes Length */
     196           1 :         stream_putw(s, 0);
     197             : 
     198           1 :         if (afi == AFI_IP && safi == SAFI_UNICAST) {
     199             :                 /* Total Path Attribute Length */
     200           1 :                 stream_putw(s, 0);
     201             :         } else {
     202             :                 /* Convert AFI, SAFI to values for packet. */
     203           0 :                 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
     204             : 
     205             :                 /* Total Path Attribute Length */
     206           0 :                 stream_putw(s, 6);
     207           0 :                 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
     208           0 :                 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
     209           0 :                 stream_putc(s, 3);
     210           0 :                 stream_putw(s, pkt_afi);
     211           0 :                 stream_putc(s, pkt_safi);
     212             :         }
     213             : 
     214           1 :         bgp_packet_set_size(s);
     215           1 :         return s;
     216             : }
     217             : 
     218             : /* Called when there is a change in the EOR(implicit or explicit) status of a
     219             :  * peer. Ends the update-delay if all expected peers are done with EORs. */
     220           0 : void bgp_check_update_delay(struct bgp *bgp)
     221             : {
     222           0 :         struct listnode *node, *nnode;
     223           0 :         struct peer *peer = NULL;
     224             : 
     225           0 :         if (bgp_debug_neighbor_events(peer))
     226           0 :                 zlog_debug("Checking update delay, T: %d R: %d I:%d E: %d",
     227             :                            bgp->established, bgp->restarted_peers,
     228             :                            bgp->implicit_eors, bgp->explicit_eors);
     229             : 
     230           0 :         if (bgp->established
     231           0 :             <= bgp->restarted_peers + bgp->implicit_eors + bgp->explicit_eors) {
     232             :                 /*
     233             :                  * This is an extra sanity check to make sure we wait for all
     234             :                  * the eligible configured peers. This check is performed if
     235             :                  * establish wait timer is on, or establish wait option is not
     236             :                  * given with the update-delay command
     237             :                  */
     238           0 :                 if (bgp->t_establish_wait
     239           0 :                     || (bgp->v_establish_wait == bgp->v_update_delay))
     240           0 :                         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
     241           0 :                                 if (CHECK_FLAG(peer->flags,
     242             :                                                PEER_FLAG_CONFIG_NODE)
     243           0 :                                     && !CHECK_FLAG(peer->flags,
     244             :                                                    PEER_FLAG_SHUTDOWN)
     245           0 :                                     && !CHECK_FLAG(peer->bgp->flags,
     246             :                                                    BGP_FLAG_SHUTDOWN)
     247           0 :                                     && !peer->update_delay_over) {
     248           0 :                                         if (bgp_debug_neighbor_events(peer))
     249           0 :                                                 zlog_debug(
     250             :                                                         " Peer %s pending, continuing read-only mode",
     251             :                                                         peer->host);
     252           0 :                                         return;
     253             :                                 }
     254             :                         }
     255             : 
     256           0 :                 zlog_info(
     257             :                         "Update delay ended, restarted: %d, EORs implicit: %d, explicit: %d",
     258             :                         bgp->restarted_peers, bgp->implicit_eors,
     259             :                         bgp->explicit_eors);
     260           0 :                 bgp_update_delay_end(bgp);
     261             :         }
     262             : }
     263             : 
     264             : /*
     265             :  * Called if peer is known to have restarted. The restart-state bit in
     266             :  * Graceful-Restart capability is used for that
     267             :  */
     268           0 : void bgp_update_restarted_peers(struct peer *peer)
     269             : {
     270           0 :         if (!bgp_update_delay_active(peer->bgp))
     271             :                 return; /* BGP update delay has ended */
     272           0 :         if (peer->update_delay_over)
     273             :                 return; /* This peer has already been considered */
     274             : 
     275           0 :         if (bgp_debug_neighbor_events(peer))
     276           0 :                 zlog_debug("Peer %s: Checking restarted", peer->host);
     277             : 
     278           0 :         if (peer_established(peer)) {
     279           0 :                 peer->update_delay_over = 1;
     280           0 :                 peer->bgp->restarted_peers++;
     281           0 :                 bgp_check_update_delay(peer->bgp);
     282             :         }
     283             : }
     284             : 
     285             : /*
     286             :  * Called as peer receives a keep-alive. Determines if this occurence can be
     287             :  * taken as an implicit EOR for this peer.
     288             :  * NOTE: The very first keep-alive after the Established state of a peer is
     289             :  * considered implicit EOR for the update-delay purposes
     290             :  */
     291           2 : void bgp_update_implicit_eors(struct peer *peer)
     292             : {
     293           2 :         if (!bgp_update_delay_active(peer->bgp))
     294             :                 return; /* BGP update delay has ended */
     295           0 :         if (peer->update_delay_over)
     296             :                 return; /* This peer has already been considered */
     297             : 
     298           0 :         if (bgp_debug_neighbor_events(peer))
     299           0 :                 zlog_debug("Peer %s: Checking implicit EORs", peer->host);
     300             : 
     301           0 :         if (peer_established(peer)) {
     302           0 :                 peer->update_delay_over = 1;
     303           0 :                 peer->bgp->implicit_eors++;
     304           0 :                 bgp_check_update_delay(peer->bgp);
     305             :         }
     306             : }
     307             : 
     308             : /*
     309             :  * Should be called only when there is a change in the EOR_RECEIVED status
     310             :  * for any afi/safi on a peer.
     311             :  */
     312           1 : static void bgp_update_explicit_eors(struct peer *peer)
     313             : {
     314           1 :         afi_t afi;
     315           1 :         safi_t safi;
     316             : 
     317           1 :         if (!bgp_update_delay_active(peer->bgp))
     318             :                 return; /* BGP update delay has ended */
     319           0 :         if (peer->update_delay_over)
     320             :                 return; /* This peer has already been considered */
     321             : 
     322           0 :         if (bgp_debug_neighbor_events(peer))
     323           0 :                 zlog_debug("Peer %s: Checking explicit EORs", peer->host);
     324             : 
     325           0 :         FOREACH_AFI_SAFI (afi, safi) {
     326           0 :                 if (peer->afc_nego[afi][safi]
     327           0 :                     && !CHECK_FLAG(peer->af_sflags[afi][safi],
     328             :                                    PEER_STATUS_EOR_RECEIVED)) {
     329           0 :                         if (bgp_debug_neighbor_events(peer))
     330           0 :                                 zlog_debug(
     331             :                                         "   afi %d safi %d didn't receive EOR",
     332             :                                         afi, safi);
     333           0 :                         return;
     334             :                 }
     335             :         }
     336             : 
     337           0 :         peer->update_delay_over = 1;
     338           0 :         peer->bgp->explicit_eors++;
     339           0 :         bgp_check_update_delay(peer->bgp);
     340             : }
     341             : 
     342             : /**
     343             :  * Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers.
     344             :  *
     345             :  * mp_withdraw, if set, is used to nullify attr structure on most of the
     346             :  * calling safi function and for evpn, passed as parameter
     347             :  */
     348           3 : int bgp_nlri_parse(struct peer *peer, struct attr *attr,
     349             :                    struct bgp_nlri *packet, int mp_withdraw)
     350             : {
     351           3 :         switch (packet->safi) {
     352           3 :         case SAFI_UNICAST:
     353             :         case SAFI_MULTICAST:
     354           3 :                 return bgp_nlri_parse_ip(peer, mp_withdraw ? NULL : attr,
     355             :                                          packet);
     356           0 :         case SAFI_LABELED_UNICAST:
     357           0 :                 return bgp_nlri_parse_label(peer, mp_withdraw ? NULL : attr,
     358             :                                             packet);
     359           0 :         case SAFI_MPLS_VPN:
     360           0 :                 return bgp_nlri_parse_vpn(peer, mp_withdraw ? NULL : attr,
     361             :                                           packet);
     362           0 :         case SAFI_EVPN:
     363           0 :                 return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
     364           0 :         case SAFI_FLOWSPEC:
     365           0 :                 return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
     366             :         }
     367             :         return BGP_NLRI_PARSE_ERROR;
     368             : }
     369             : 
     370             : 
     371             : /*
     372             :  * Check if route-refresh request from peer is pending (received before EoR),
     373             :  * and process it now.
     374             :  */
     375           1 : static void bgp_process_pending_refresh(struct peer *peer, afi_t afi,
     376             :                                         safi_t safi)
     377             : {
     378           1 :         if (CHECK_FLAG(peer->af_sflags[afi][safi],
     379             :                        PEER_STATUS_REFRESH_PENDING)) {
     380           0 :                 UNSET_FLAG(peer->af_sflags[afi][safi],
     381             :                            PEER_STATUS_REFRESH_PENDING);
     382           0 :                 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
     383             :                                        BGP_ROUTE_REFRESH_BORR);
     384           0 :                 if (bgp_debug_neighbor_events(peer))
     385           0 :                         zlog_debug(
     386             :                                 "%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)",
     387             :                                 peer, afi2str(afi), safi2str(safi));
     388             : 
     389           0 :                 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_SEND);
     390           0 :                 UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_SEND);
     391           0 :                 bgp_announce_route(peer, afi, safi, true);
     392             :         }
     393           1 : }
     394             : 
     395             : /*
     396             :  * Checks a variety of conditions to determine whether the peer needs to be
     397             :  * rescheduled for packet generation again, and does so if necessary.
     398             :  *
     399             :  * @param peer to check for rescheduling
     400             :  */
     401           9 : static void bgp_write_proceed_actions(struct peer *peer)
     402             : {
     403           9 :         afi_t afi;
     404           9 :         safi_t safi;
     405           9 :         struct peer_af *paf;
     406           9 :         struct bpacket *next_pkt;
     407           9 :         struct update_subgroup *subgrp;
     408           9 :         enum bgp_af_index index;
     409             : 
     410         126 :         for (index = BGP_AF_START; index < BGP_AF_MAX; index++) {
     411         117 :                 paf = peer->peer_af_array[index];
     412         117 :                 if (!paf)
     413         108 :                         continue;
     414             : 
     415           9 :                 subgrp = paf->subgroup;
     416           9 :                 if (!subgrp)
     417           0 :                         continue;
     418             : 
     419           9 :                 next_pkt = paf->next_pkt_to_send;
     420           9 :                 if (next_pkt && next_pkt->buffer) {
     421           0 :                         BGP_TIMER_ON(peer->t_generate_updgrp_packets,
     422             :                                      bgp_generate_updgrp_packets, 0);
     423           0 :                         return;
     424             :                 }
     425             : 
     426             :                 /* No packets readily available for AFI/SAFI, are there
     427             :                  * subgroup packets
     428             :                  * that need to be generated? */
     429           9 :                 if (bpacket_queue_is_full(SUBGRP_INST(subgrp),
     430             :                                           SUBGRP_PKTQ(subgrp))
     431           9 :                     || subgroup_packets_to_build(subgrp)) {
     432           0 :                         BGP_TIMER_ON(peer->t_generate_updgrp_packets,
     433             :                                      bgp_generate_updgrp_packets, 0);
     434           0 :                         return;
     435             :                 }
     436             : 
     437           9 :                 afi = paf->afi;
     438           9 :                 safi = paf->safi;
     439             : 
     440             :                 /* No packets to send, see if EOR is pending */
     441           9 :                 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
     442           5 :                         if (!subgrp->t_coalesce && peer->afc_nego[afi][safi]
     443           4 :                             && peer->synctime
     444           4 :                             && !CHECK_FLAG(peer->af_sflags[afi][safi],
     445             :                                            PEER_STATUS_EOR_SEND)
     446           0 :                             && safi != SAFI_MPLS_VPN) {
     447           0 :                                 BGP_TIMER_ON(peer->t_generate_updgrp_packets,
     448             :                                              bgp_generate_updgrp_packets, 0);
     449           0 :                                 return;
     450             :                         }
     451             :                 }
     452             :         }
     453             : }
     454             : 
     455             : /*
     456             :  * Generate advertisement information (withdraws, updates, EOR) from each
     457             :  * update group a peer belongs to, encode this information into packets, and
     458             :  * enqueue the packets onto the peer's output buffer.
     459             :  */
     460          14 : void bgp_generate_updgrp_packets(struct thread *thread)
     461             : {
     462          14 :         struct peer *peer = THREAD_ARG(thread);
     463             : 
     464          14 :         struct stream *s;
     465          14 :         struct peer_af *paf;
     466          14 :         struct bpacket *next_pkt;
     467          14 :         uint32_t wpq;
     468          14 :         uint32_t generated = 0;
     469          14 :         afi_t afi;
     470          14 :         safi_t safi;
     471             : 
     472          14 :         wpq = atomic_load_explicit(&peer->bgp->wpkt_quanta,
     473             :                                    memory_order_relaxed);
     474             : 
     475             :         /*
     476             :          * The code beyond this part deals with update packets, proceed only
     477             :          * if peer is Established and updates are not on hold (as part of
     478             :          * update-delay processing).
     479             :          */
     480          14 :         if (!peer_established(peer))
     481             :                 return;
     482             : 
     483          11 :         if ((peer->bgp->main_peers_update_hold)
     484          11 :             || bgp_update_delay_active(peer->bgp))
     485           0 :                 return;
     486             : 
     487          11 :         if (peer->t_routeadv)
     488             :                 return;
     489             : 
     490             :         /*
     491             :          * Since the following is a do while loop
     492             :          * let's stop adding to the outq if we are
     493             :          * already at the limit.
     494             :          */
     495           8 :         if (peer->obuf->count >= bm->outq_limit) {
     496           0 :                 bgp_write_proceed_actions(peer);
     497           0 :                 return;
     498             :         }
     499             : 
     500          12 :         do {
     501          12 :                 enum bgp_af_index index;
     502             : 
     503          12 :                 s = NULL;
     504         168 :                 for (index = BGP_AF_START; index < BGP_AF_MAX; index++) {
     505         156 :                         paf = peer->peer_af_array[index];
     506         156 :                         if (!paf || !PAF_SUBGRP(paf))
     507         144 :                                 continue;
     508             : 
     509          12 :                         afi = paf->afi;
     510          12 :                         safi = paf->safi;
     511          12 :                         next_pkt = paf->next_pkt_to_send;
     512             : 
     513             :                         /*
     514             :                          * Try to generate a packet for the peer if we are at
     515             :                          * the end of the list. Always try to push out
     516             :                          * WITHDRAWs first.
     517             :                          */
     518          12 :                         if (!next_pkt || !next_pkt->buffer) {
     519          12 :                                 next_pkt = subgroup_withdraw_packet(
     520             :                                         PAF_SUBGRP(paf));
     521          12 :                                 if (!next_pkt || !next_pkt->buffer)
     522          12 :                                         subgroup_update_packet(PAF_SUBGRP(paf));
     523          12 :                                 next_pkt = paf->next_pkt_to_send;
     524             :                         }
     525             : 
     526             :                         /*
     527             :                          * If we still don't have a packet to send to the peer,
     528             :                          * then try to find out out if we have to send eor or
     529             :                          * if not, skip to the next AFI, SAFI. Don't send the
     530             :                          * EOR prematurely; if the subgroup's coalesce timer is
     531             :                          * running, the adjacency-out structure is not created
     532             :                          * yet.
     533             :                          */
     534          12 :                         if (!next_pkt || !next_pkt->buffer) {
     535           9 :                                 if (!paf->t_announce_route) {
     536             :                                         /* Make sure we supress BGP UPDATES
     537             :                                          * for normal processing later again.
     538             :                                          */
     539           9 :                                         UNSET_FLAG(paf->subgroup->sflags,
     540             :                                                    SUBGRP_STATUS_FORCE_UPDATES);
     541             : 
     542             :                                         /* If route-refresh BoRR message was
     543             :                                          * already sent and we are done with
     544             :                                          * re-announcing tables for a decent
     545             :                                          * afi/safi, we ready to send
     546             :                                          * EoRR request.
     547             :                                          */
     548           9 :                                         if (CHECK_FLAG(
     549             :                                                     peer->af_sflags[afi][safi],
     550             :                                                     PEER_STATUS_BORR_SEND)) {
     551           0 :                                                 bgp_route_refresh_send(
     552             :                                                         peer, afi, safi, 0, 0,
     553             :                                                         0,
     554             :                                                         BGP_ROUTE_REFRESH_EORR);
     555             : 
     556           0 :                                                 SET_FLAG(peer->af_sflags[afi]
     557             :                                                                         [safi],
     558             :                                                          PEER_STATUS_EORR_SEND);
     559           0 :                                                 UNSET_FLAG(
     560             :                                                         peer->af_sflags[afi]
     561             :                                                                        [safi],
     562             :                                                         PEER_STATUS_BORR_SEND);
     563             : 
     564           0 :                                                 if (bgp_debug_neighbor_events(
     565             :                                                             peer))
     566           0 :                                                         zlog_debug(
     567             :                                                                 "%pBP sending route-refresh (EoRR) for %s/%s",
     568             :                                                                 peer,
     569             :                                                                 afi2str(afi),
     570             :                                                                 safi2str(safi));
     571             :                                         }
     572             :                                 }
     573             : 
     574           9 :                                 if (CHECK_FLAG(peer->cap,
     575             :                                                PEER_CAP_RESTART_RCV)) {
     576           6 :                                         if (!(PAF_SUBGRP(paf))->t_coalesce
     577           5 :                                             && peer->afc_nego[afi][safi]
     578           5 :                                             && peer->synctime
     579           5 :                                             && !CHECK_FLAG(
     580             :                                                     peer->af_sflags[afi][safi],
     581             :                                                     PEER_STATUS_EOR_SEND)) {
     582             :                                                 /* If EOR is disabled,
     583             :                                                  * the message is  not sent
     584             :                                                  */
     585           1 :                                                 if (BGP_SEND_EOR(peer->bgp, afi,
     586             :                                                                  safi)) {
     587           1 :                                                         SET_FLAG(
     588             :                                                                 peer->af_sflags
     589             :                                                                         [afi]
     590             :                                                                         [safi],
     591             :                                                                 PEER_STATUS_EOR_SEND);
     592             : 
     593             :                                                         /* Update EOR
     594             :                                                          * send time
     595             :                                                          */
     596           1 :                                                         peer->eor_stime[afi]
     597           1 :                                                                        [safi] =
     598           1 :                                                                 monotime(NULL);
     599             : 
     600           1 :                                                         BGP_UPDATE_EOR_PKT(
     601             :                                                                 peer, afi, safi,
     602             :                                                                 s);
     603           1 :                                                         bgp_process_pending_refresh(
     604             :                                                                 peer, afi,
     605             :                                                                 safi);
     606             :                                                 }
     607             :                                         }
     608             :                                 }
     609           9 :                                 continue;
     610             :                         }
     611             : 
     612             :                         /* Update packet send time */
     613           3 :                         peer->pkt_stime[afi][safi] = monotime(NULL);
     614             : 
     615             :                         /* Found a packet template to send, overwrite
     616             :                          * packet with appropriate attributes from peer
     617             :                          * and advance peer */
     618           3 :                         s = bpacket_reformat_for_peer(next_pkt, paf);
     619           3 :                         bgp_packet_add(peer, s);
     620           3 :                         bpacket_queue_advance_peer(paf);
     621             :                 }
     622          12 :         } while (s && (++generated < wpq) &&
     623           4 :                  (peer->obuf->count <= bm->outq_limit));
     624             : 
     625           8 :         if (generated)
     626           3 :                 bgp_writes_on(peer);
     627             : 
     628           8 :         bgp_write_proceed_actions(peer);
     629             : }
     630             : 
     631             : /*
     632             :  * Creates a BGP Keepalive packet and appends it to the peer's output queue.
     633             :  */
     634           2 : void bgp_keepalive_send(struct peer *peer)
     635             : {
     636           2 :         struct stream *s;
     637             : 
     638           2 :         s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE);
     639             : 
     640             :         /* Make keepalive packet. */
     641           2 :         bgp_packet_set_marker(s, BGP_MSG_KEEPALIVE);
     642             : 
     643             :         /* Set packet size. */
     644           2 :         bgp_packet_set_size(s);
     645             : 
     646             :         /* Dump packet if debug option is set. */
     647             :         /* bgp_packet_dump (s); */
     648             : 
     649           2 :         if (bgp_debug_keepalive(peer))
     650           0 :                 zlog_debug("%s sending KEEPALIVE", peer->host);
     651             : 
     652             :         /* Add packet to the peer. */
     653           2 :         bgp_packet_add(peer, s);
     654             : 
     655           2 :         bgp_writes_on(peer);
     656           2 : }
     657             : 
     658             : /*
     659             :  * Creates a BGP Open packet and appends it to the peer's output queue.
     660             :  * Sets capabilities as necessary.
     661             :  */
     662           2 : void bgp_open_send(struct peer *peer)
     663             : {
     664           2 :         struct stream *s;
     665           2 :         uint16_t send_holdtime;
     666           2 :         as_t local_as;
     667             : 
     668           2 :         if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
     669           0 :                 send_holdtime = peer->holdtime;
     670             :         else
     671           2 :                 send_holdtime = peer->bgp->default_holdtime;
     672             : 
     673             :         /* local-as Change */
     674           2 :         if (peer->change_local_as)
     675             :                 local_as = peer->change_local_as;
     676             :         else
     677           2 :                 local_as = peer->local_as;
     678             : 
     679           2 :         s = stream_new(BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE);
     680             : 
     681             :         /* Make open packet. */
     682           2 :         bgp_packet_set_marker(s, BGP_MSG_OPEN);
     683             : 
     684             :         /* Set open packet values. */
     685           2 :         stream_putc(s, BGP_VERSION_4); /* BGP version */
     686           2 :         stream_putw(s, (local_as <= BGP_AS_MAX) ? (uint16_t)local_as
     687             :                                                 : BGP_AS_TRANS);
     688           2 :         stream_putw(s, send_holdtime);          /* Hold Time */
     689           2 :         stream_put_in_addr(s, &peer->local_id); /* BGP Identifier */
     690             : 
     691             :         /* Set capabilities */
     692           2 :         if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) {
     693           0 :                 (void)bgp_open_capability(s, peer, true);
     694             :         } else {
     695           2 :                 struct stream *tmp = stream_new(STREAM_SIZE(s));
     696             : 
     697           2 :                 stream_copy(tmp, s);
     698           2 :                 if (bgp_open_capability(tmp, peer, false)
     699             :                     > BGP_OPEN_NON_EXT_OPT_LEN) {
     700           0 :                         stream_free(tmp);
     701           0 :                         (void)bgp_open_capability(s, peer, true);
     702             :                 } else {
     703           2 :                         stream_copy(s, tmp);
     704           2 :                         stream_free(tmp);
     705             :                 }
     706             :         }
     707             : 
     708             :         /* Set BGP packet length. */
     709           2 :         bgp_packet_set_size(s);
     710             : 
     711           2 :         if (bgp_debug_neighbor_events(peer))
     712           0 :                 zlog_debug(
     713             :                         "%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4",
     714             :                         peer->host, BGP_VERSION_4, local_as, send_holdtime,
     715             :                         &peer->local_id);
     716             : 
     717             :         /* Dump packet if debug option is set. */
     718             :         /* bgp_packet_dump (s); */
     719           2 :         hook_call(bgp_packet_send, peer, BGP_MSG_OPEN, stream_get_endp(s), s);
     720             : 
     721             :         /* Add packet to the peer. */
     722           2 :         bgp_packet_add(peer, s);
     723             : 
     724           2 :         bgp_writes_on(peer);
     725           2 : }
     726             : 
     727             : /*
     728             :  * Writes NOTIFICATION message directly to a peer socket without waiting for
     729             :  * the I/O thread.
     730             :  *
     731             :  * There must be exactly one stream on the peer->obuf FIFO, and the data within
     732             :  * this stream must match the format of a BGP NOTIFICATION message.
     733             :  * Transmission is best-effort.
     734             :  *
     735             :  * @requires peer->io_mtx
     736             :  * @param peer
     737             :  * @return 0
     738             :  */
     739           2 : static void bgp_write_notify(struct peer *peer)
     740             : {
     741           2 :         int ret, val;
     742           2 :         uint8_t type;
     743           2 :         struct stream *s;
     744             : 
     745             :         /* There should be at least one packet. */
     746           2 :         s = stream_fifo_pop(peer->obuf);
     747             : 
     748           2 :         if (!s)
     749           0 :                 return;
     750             : 
     751           2 :         assert(stream_get_endp(s) >= BGP_HEADER_SIZE);
     752             : 
     753             :         /*
     754             :          * socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
     755             :          * we only care about getting a clean shutdown at this point.
     756             :          */
     757           2 :         ret = write(peer->fd, STREAM_DATA(s), stream_get_endp(s));
     758             : 
     759             :         /*
     760             :          * only connection reset/close gets counted as TCP_fatal_error, failure
     761             :          * to write the entire NOTIFY doesn't get different FSM treatment
     762             :          */
     763           2 :         if (ret <= 0) {
     764           0 :                 stream_free(s);
     765           0 :                 BGP_EVENT_ADD(peer, TCP_fatal_error);
     766           0 :                 return;
     767             :         }
     768             : 
     769             :         /* Disable Nagle, make NOTIFY packet go out right away */
     770           2 :         val = 1;
     771           2 :         (void)setsockopt(peer->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val,
     772             :                          sizeof(val));
     773             : 
     774             :         /* Retrieve BGP packet type. */
     775           2 :         stream_set_getp(s, BGP_MARKER_SIZE + 2);
     776           2 :         type = stream_getc(s);
     777             : 
     778           2 :         assert(type == BGP_MSG_NOTIFY);
     779             : 
     780             :         /* Type should be notify. */
     781           2 :         atomic_fetch_add_explicit(&peer->notify_out, 1, memory_order_relaxed);
     782             : 
     783             :         /* Double start timer. */
     784           2 :         peer->v_start *= 2;
     785             : 
     786             :         /* Overflow check. */
     787           2 :         if (peer->v_start >= (60 * 2))
     788           0 :                 peer->v_start = (60 * 2);
     789             : 
     790             :         /*
     791             :          * Handle Graceful Restart case where the state changes to
     792             :          * Connect instead of Idle
     793             :          */
     794           2 :         BGP_EVENT_ADD(peer, BGP_Stop);
     795             : 
     796           2 :         stream_free(s);
     797             : }
     798             : 
     799             : /*
     800             :  * Encapsulate an original BGP CEASE Notification into Hard Reset
     801             :  */
     802           0 : static uint8_t *bgp_notify_encapsulate_hard_reset(uint8_t code, uint8_t subcode,
     803             :                                                   uint8_t *data, size_t datalen)
     804             : {
     805           0 :         uint8_t *message = XCALLOC(MTYPE_BGP_NOTIFICATION, datalen + 2);
     806             : 
     807             :         /* ErrCode */
     808           0 :         message[0] = code;
     809             :         /* Subcode */
     810           0 :         message[1] = subcode;
     811             :         /* Data */
     812           0 :         if (datalen)
     813           0 :                 memcpy(message + 2, data, datalen);
     814             : 
     815           0 :         return message;
     816             : }
     817             : 
     818             : /*
     819             :  * Decapsulate an original BGP CEASE Notification from Hard Reset
     820             :  */
     821           0 : struct bgp_notify bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify)
     822             : {
     823           0 :         struct bgp_notify bn = {};
     824             : 
     825           0 :         bn.code = notify->raw_data[0];
     826           0 :         bn.subcode = notify->raw_data[1];
     827           0 :         bn.length = notify->length - 2;
     828             : 
     829           0 :         bn.raw_data = XMALLOC(MTYPE_BGP_NOTIFICATION, bn.length);
     830           0 :         memcpy(bn.raw_data, notify->raw_data + 2, bn.length);
     831             : 
     832           0 :         return bn;
     833             : }
     834             : 
     835             : /* Check if Graceful-Restart N-bit is exchanged */
     836           4 : bool bgp_has_graceful_restart_notification(struct peer *peer)
     837             : {
     838           4 :         return CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV) &&
     839             :                CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV);
     840             : }
     841             : 
     842             : /*
     843             :  * Check if to send BGP CEASE Notification/Hard Reset?
     844             :  */
     845           2 : bool bgp_notify_send_hard_reset(struct peer *peer, uint8_t code,
     846             :                                 uint8_t subcode)
     847             : {
     848             :         /* When the "N" bit has been exchanged, a Hard Reset message is used to
     849             :          * indicate to the peer that the session is to be fully terminated.
     850             :          */
     851           2 :         if (!bgp_has_graceful_restart_notification(peer))
     852             :                 return false;
     853             : 
     854             :         /*
     855             :          * https://datatracker.ietf.org/doc/html/rfc8538#section-5.1
     856             :          */
     857           0 :         if (code == BGP_NOTIFY_CEASE) {
     858           0 :                 switch (subcode) {
     859           0 :                 case BGP_NOTIFY_CEASE_MAX_PREFIX:
     860             :                 case BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN:
     861             :                 case BGP_NOTIFY_CEASE_PEER_UNCONFIG:
     862             :                 case BGP_NOTIFY_CEASE_HARD_RESET:
     863             :                 case BGP_NOTIFY_CEASE_BFD_DOWN:
     864           0 :                         return true;
     865           0 :                 case BGP_NOTIFY_CEASE_ADMIN_RESET:
     866             :                         /* Provide user control:
     867             :                          * `bgp hard-adminstrative-reset`
     868             :                          */
     869           0 :                         if (CHECK_FLAG(peer->bgp->flags,
     870             :                                        BGP_FLAG_HARD_ADMIN_RESET))
     871             :                                 return true;
     872             :                         else
     873           0 :                                 return false;
     874             :                 default:
     875             :                         break;
     876             :                 }
     877             :         }
     878             : 
     879             :         return false;
     880             : }
     881             : 
     882             : /*
     883             :  * Check if received BGP CEASE Notification/Hard Reset?
     884             :  */
     885           1 : bool bgp_notify_received_hard_reset(struct peer *peer, uint8_t code,
     886             :                                     uint8_t subcode)
     887             : {
     888             :         /* When the "N" bit has been exchanged, a Hard Reset message is used to
     889             :          * indicate to the peer that the session is to be fully terminated.
     890             :          */
     891           0 :         if (!bgp_has_graceful_restart_notification(peer))
     892             :                 return false;
     893             : 
     894           0 :         if (code == BGP_NOTIFY_CEASE && subcode == BGP_NOTIFY_CEASE_HARD_RESET)
     895             :                 return true;
     896             : 
     897             :         return false;
     898             : }
     899             : 
     900             : /*
     901             :  * Creates a BGP Notify and appends it to the peer's output queue.
     902             :  *
     903             :  * This function attempts to write the packet from the thread it is called
     904             :  * from, to ensure the packet gets out ASAP.
     905             :  *
     906             :  * This function may be called from multiple threads. Since the function
     907             :  * modifies I/O buffer(s) in the peer, these are locked for the duration of the
     908             :  * call to prevent tampering from other threads.
     909             :  *
     910             :  * Delivery of the NOTIFICATION is attempted once and is best-effort. After
     911             :  * return, the peer structure *must* be reset; no assumptions about session
     912             :  * state are valid.
     913             :  *
     914             :  * @param peer
     915             :  * @param code      BGP error code
     916             :  * @param sub_code  BGP error subcode
     917             :  * @param data      Data portion
     918             :  * @param datalen   length of data portion
     919             :  */
     920           2 : static void bgp_notify_send_internal(struct peer *peer, uint8_t code,
     921             :                                      uint8_t sub_code, uint8_t *data,
     922             :                                      size_t datalen, bool use_curr)
     923             : {
     924           2 :         struct stream *s;
     925           2 :         bool hard_reset = bgp_notify_send_hard_reset(peer, code, sub_code);
     926             : 
     927             :         /* Lock I/O mutex to prevent other threads from pushing packets */
     928           2 :         frr_mutex_lock_autounlock(&peer->io_mtx);
     929             :         /* ============================================== */
     930             : 
     931             :         /* Allocate new stream. */
     932           2 :         s = stream_new(peer->max_packet_size);
     933             : 
     934             :         /* Make notify packet. */
     935           2 :         bgp_packet_set_marker(s, BGP_MSG_NOTIFY);
     936             : 
     937             :         /* Check if we should send Hard Reset Notification or not */
     938           2 :         if (hard_reset) {
     939           0 :                 uint8_t *hard_reset_message = bgp_notify_encapsulate_hard_reset(
     940             :                         code, sub_code, data, datalen);
     941             : 
     942             :                 /* Hard Reset encapsulates another NOTIFICATION message
     943             :                  * in its data portion.
     944             :                  */
     945           0 :                 stream_putc(s, BGP_NOTIFY_CEASE);
     946           0 :                 stream_putc(s, BGP_NOTIFY_CEASE_HARD_RESET);
     947           0 :                 stream_write(s, hard_reset_message, datalen + 2);
     948             : 
     949           0 :                 XFREE(MTYPE_BGP_NOTIFICATION, hard_reset_message);
     950             :         } else {
     951           2 :                 stream_putc(s, code);
     952           2 :                 stream_putc(s, sub_code);
     953           2 :                 if (data)
     954           0 :                         stream_write(s, data, datalen);
     955             :         }
     956             : 
     957             :         /* Set BGP packet length. */
     958           2 :         bgp_packet_set_size(s);
     959             : 
     960             :         /* wipe output buffer */
     961           2 :         stream_fifo_clean(peer->obuf);
     962             : 
     963             :         /*
     964             :          * If possible, store last packet for debugging purposes. This check is
     965             :          * in place because we are sometimes called with a doppelganger peer,
     966             :          * who tends to have a plethora of fields nulled out.
     967             :          *
     968             :          * Some callers should not attempt this - the io pthread for example
     969             :          * should not touch internals of the peer struct.
     970             :          */
     971           2 :         if (use_curr && peer->curr) {
     972           0 :                 size_t packetsize = stream_get_endp(peer->curr);
     973           0 :                 assert(packetsize <= peer->max_packet_size);
     974           0 :                 memcpy(peer->last_reset_cause, peer->curr->data, packetsize);
     975           0 :                 peer->last_reset_cause_size = packetsize;
     976             :         }
     977             : 
     978             :         /* For debug */
     979             :         {
     980           2 :                 struct bgp_notify bgp_notify;
     981           2 :                 int first = 0;
     982           2 :                 int i;
     983           2 :                 char c[4];
     984             : 
     985           2 :                 bgp_notify.code = code;
     986           2 :                 bgp_notify.subcode = sub_code;
     987           2 :                 bgp_notify.data = NULL;
     988           2 :                 bgp_notify.length = datalen;
     989           2 :                 bgp_notify.raw_data = data;
     990             : 
     991           2 :                 peer->notify.code = bgp_notify.code;
     992           2 :                 peer->notify.subcode = bgp_notify.subcode;
     993           2 :                 peer->notify.length = bgp_notify.length;
     994             : 
     995           2 :                 if (bgp_notify.length && data) {
     996           0 :                         bgp_notify.data = XMALLOC(MTYPE_BGP_NOTIFICATION,
     997             :                                                   bgp_notify.length * 3);
     998           0 :                         for (i = 0; i < bgp_notify.length; i++)
     999           0 :                                 if (first) {
    1000           0 :                                         snprintf(c, sizeof(c), " %02x",
    1001           0 :                                                  data[i]);
    1002             : 
    1003           0 :                                         strlcat(bgp_notify.data, c,
    1004           0 :                                                 bgp_notify.length);
    1005             : 
    1006             :                                 } else {
    1007           0 :                                         first = 1;
    1008           0 :                                         snprintf(c, sizeof(c), "%02x", data[i]);
    1009             : 
    1010           0 :                                         strlcpy(bgp_notify.data, c,
    1011           0 :                                                 bgp_notify.length);
    1012             :                                 }
    1013             :                 }
    1014           2 :                 bgp_notify_print(peer, &bgp_notify, "sending", hard_reset);
    1015             : 
    1016           2 :                 if (bgp_notify.data) {
    1017           0 :                         if (data) {
    1018           0 :                                 XFREE(MTYPE_BGP_NOTIFICATION,
    1019             :                                       peer->notify.data);
    1020           0 :                                 peer->notify.data = XCALLOC(
    1021             :                                         MTYPE_BGP_NOTIFICATION, datalen);
    1022           0 :                                 memcpy(peer->notify.data, data, datalen);
    1023             :                         }
    1024             : 
    1025           0 :                         XFREE(MTYPE_BGP_NOTIFICATION, bgp_notify.data);
    1026           0 :                         bgp_notify.length = 0;
    1027             :                 }
    1028             :         }
    1029             : 
    1030             :         /* peer reset cause */
    1031           2 :         if (code == BGP_NOTIFY_CEASE) {
    1032           2 :                 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
    1033           0 :                         peer->last_reset = PEER_DOWN_USER_RESET;
    1034           2 :                 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN) {
    1035           1 :                         if (CHECK_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN))
    1036           0 :                                 peer->last_reset = PEER_DOWN_RTT_SHUTDOWN;
    1037             :                         else
    1038           1 :                                 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
    1039             :                 } else
    1040           1 :                         peer->last_reset = PEER_DOWN_NOTIFY_SEND;
    1041             :         } else
    1042           0 :                 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
    1043             : 
    1044             :         /* Add packet to peer's output queue */
    1045           2 :         stream_fifo_push(peer->obuf, s);
    1046             : 
    1047           2 :         bgp_peer_gr_flags_update(peer);
    1048           6 :         BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
    1049             :                                                           peer->bgp->peer);
    1050             : 
    1051           2 :         bgp_write_notify(peer);
    1052           2 : }
    1053             : 
    1054             : /*
    1055             :  * Creates a BGP Notify and appends it to the peer's output queue.
    1056             :  *
    1057             :  * This function attempts to write the packet from the thread it is called
    1058             :  * from, to ensure the packet gets out ASAP.
    1059             :  *
    1060             :  * @param peer
    1061             :  * @param code      BGP error code
    1062             :  * @param sub_code  BGP error subcode
    1063             :  */
    1064           2 : void bgp_notify_send(struct peer *peer, uint8_t code, uint8_t sub_code)
    1065             : {
    1066           2 :         bgp_notify_send_internal(peer, code, sub_code, NULL, 0, true);
    1067           0 : }
    1068             : 
    1069             : /*
    1070             :  * Enqueue notification; called from the main pthread, peer object access is ok.
    1071             :  */
    1072           0 : void bgp_notify_send_with_data(struct peer *peer, uint8_t code,
    1073             :                                uint8_t sub_code, uint8_t *data, size_t datalen)
    1074             : {
    1075           0 :         bgp_notify_send_internal(peer, code, sub_code, data, datalen, true);
    1076           0 : }
    1077             : 
    1078             : /*
    1079             :  * For use by the io pthread, queueing a notification but avoiding access to
    1080             :  * the peer object.
    1081             :  */
    1082           0 : void bgp_notify_io_invalid(struct peer *peer, uint8_t code, uint8_t sub_code,
    1083             :                            uint8_t *data, size_t datalen)
    1084             : {
    1085             :         /* Avoid touching the peer object */
    1086           0 :         bgp_notify_send_internal(peer, code, sub_code, data, datalen, false);
    1087           0 : }
    1088             : 
    1089             : /*
    1090             :  * Creates BGP Route Refresh packet and appends it to the peer's output queue.
    1091             :  *
    1092             :  * @param peer
    1093             :  * @param afi               Address Family Identifier
    1094             :  * @param safi              Subsequent Address Family Identifier
    1095             :  * @param orf_type          Outbound Route Filtering type
    1096             :  * @param when_to_refresh   Whether to refresh immediately or defer
    1097             :  * @param remove            Whether to remove ORF for specified AFI/SAFI
    1098             :  */
    1099           0 : void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
    1100             :                             uint8_t orf_type, uint8_t when_to_refresh,
    1101             :                             int remove, uint8_t subtype)
    1102             : {
    1103           0 :         struct stream *s;
    1104           0 :         struct bgp_filter *filter;
    1105           0 :         int orf_refresh = 0;
    1106           0 :         iana_afi_t pkt_afi = IANA_AFI_IPV4;
    1107           0 :         iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
    1108             : 
    1109           0 :         if (DISABLE_BGP_ANNOUNCE)
    1110             :                 return;
    1111             : 
    1112           0 :         filter = &peer->filter[afi][safi];
    1113             : 
    1114             :         /* Convert AFI, SAFI to values for packet. */
    1115           0 :         bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
    1116             : 
    1117           0 :         s = stream_new(peer->max_packet_size);
    1118             : 
    1119             :         /* Make BGP update packet. */
    1120           0 :         if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
    1121           0 :                 bgp_packet_set_marker(s, BGP_MSG_ROUTE_REFRESH_NEW);
    1122             :         else
    1123           0 :                 bgp_packet_set_marker(s, BGP_MSG_ROUTE_REFRESH_OLD);
    1124             : 
    1125             :         /* Encode Route Refresh message. */
    1126           0 :         stream_putw(s, pkt_afi);
    1127           0 :         if (subtype)
    1128           0 :                 stream_putc(s, subtype);
    1129             :         else
    1130           0 :                 stream_putc(s, 0);
    1131           0 :         stream_putc(s, pkt_safi);
    1132             : 
    1133           0 :         if (orf_type == ORF_TYPE_PREFIX || orf_type == ORF_TYPE_PREFIX_OLD)
    1134           0 :                 if (remove || filter->plist[FILTER_IN].plist) {
    1135           0 :                         uint16_t orf_len;
    1136           0 :                         unsigned long orfp;
    1137             : 
    1138           0 :                         orf_refresh = 1;
    1139           0 :                         stream_putc(s, when_to_refresh);
    1140           0 :                         stream_putc(s, orf_type);
    1141           0 :                         orfp = stream_get_endp(s);
    1142           0 :                         stream_putw(s, 0);
    1143             : 
    1144           0 :                         if (remove) {
    1145           0 :                                 UNSET_FLAG(peer->af_sflags[afi][safi],
    1146             :                                            PEER_STATUS_ORF_PREFIX_SEND);
    1147           0 :                                 stream_putc(s, ORF_COMMON_PART_REMOVE_ALL);
    1148           0 :                                 if (bgp_debug_neighbor_events(peer))
    1149           0 :                                         zlog_debug(
    1150             :                                                 "%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s",
    1151             :                                                 peer, orf_type,
    1152             :                                                 (when_to_refresh ==
    1153             :                                                                  REFRESH_DEFER
    1154             :                                                          ? "defer"
    1155             :                                                          : "immediate"),
    1156             :                                                 iana_afi2str(pkt_afi),
    1157             :                                                 iana_safi2str(pkt_safi));
    1158             :                         } else {
    1159           0 :                                 SET_FLAG(peer->af_sflags[afi][safi],
    1160             :                                          PEER_STATUS_ORF_PREFIX_SEND);
    1161           0 :                                 prefix_bgp_orf_entry(
    1162             :                                         s, filter->plist[FILTER_IN].plist,
    1163             :                                         ORF_COMMON_PART_ADD,
    1164             :                                         ORF_COMMON_PART_PERMIT,
    1165             :                                         ORF_COMMON_PART_DENY);
    1166           0 :                                 if (bgp_debug_neighbor_events(peer))
    1167           0 :                                         zlog_debug(
    1168             :                                                 "%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s",
    1169             :                                                 peer, orf_type,
    1170             :                                                 (when_to_refresh ==
    1171             :                                                                  REFRESH_DEFER
    1172             :                                                          ? "defer"
    1173             :                                                          : "immediate"),
    1174             :                                                 iana_afi2str(pkt_afi),
    1175             :                                                 iana_safi2str(pkt_safi));
    1176             :                         }
    1177             : 
    1178             :                         /* Total ORF Entry Len. */
    1179           0 :                         orf_len = stream_get_endp(s) - orfp - 2;
    1180           0 :                         stream_putw_at(s, orfp, orf_len);
    1181             :                 }
    1182             : 
    1183             :         /* Set packet size. */
    1184           0 :         bgp_packet_set_size(s);
    1185             : 
    1186           0 :         if (bgp_debug_neighbor_events(peer)) {
    1187           0 :                 if (!orf_refresh)
    1188           0 :                         zlog_debug(
    1189             :                                 "%pBP sending REFRESH_REQ for afi/safi: %s/%s",
    1190             :                                 peer, iana_afi2str(pkt_afi),
    1191             :                                 iana_safi2str(pkt_safi));
    1192             :         }
    1193             : 
    1194             :         /* Add packet to the peer. */
    1195           0 :         bgp_packet_add(peer, s);
    1196             : 
    1197           0 :         bgp_writes_on(peer);
    1198             : }
    1199             : 
    1200             : /*
    1201             :  * Create a BGP Capability packet and append it to the peer's output queue.
    1202             :  *
    1203             :  * @param peer
    1204             :  * @param afi              Address Family Identifier
    1205             :  * @param safi             Subsequent Address Family Identifier
    1206             :  * @param capability_code  BGP Capability Code
    1207             :  * @param action           Set or Remove capability
    1208             :  */
    1209           0 : void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
    1210             :                          int capability_code, int action)
    1211             : {
    1212           0 :         struct stream *s;
    1213           0 :         iana_afi_t pkt_afi = IANA_AFI_IPV4;
    1214           0 :         iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
    1215             : 
    1216             :         /* Convert AFI, SAFI to values for packet. */
    1217           0 :         bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
    1218             : 
    1219           0 :         s = stream_new(peer->max_packet_size);
    1220             : 
    1221             :         /* Make BGP update packet. */
    1222           0 :         bgp_packet_set_marker(s, BGP_MSG_CAPABILITY);
    1223             : 
    1224             :         /* Encode MP_EXT capability. */
    1225           0 :         if (capability_code == CAPABILITY_CODE_MP) {
    1226           0 :                 stream_putc(s, action);
    1227           0 :                 stream_putc(s, CAPABILITY_CODE_MP);
    1228           0 :                 stream_putc(s, CAPABILITY_CODE_MP_LEN);
    1229           0 :                 stream_putw(s, pkt_afi);
    1230           0 :                 stream_putc(s, 0);
    1231           0 :                 stream_putc(s, pkt_safi);
    1232             : 
    1233           0 :                 if (bgp_debug_neighbor_events(peer))
    1234           0 :                         zlog_debug(
    1235             :                                 "%pBP sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s",
    1236             :                                 peer,
    1237             :                                 action == CAPABILITY_ACTION_SET ? "Advertising"
    1238             :                                                                 : "Removing",
    1239             :                                 iana_afi2str(pkt_afi), iana_safi2str(pkt_safi));
    1240             :         }
    1241             : 
    1242             :         /* Set packet size. */
    1243           0 :         bgp_packet_set_size(s);
    1244             : 
    1245             :         /* Add packet to the peer. */
    1246           0 :         bgp_packet_add(peer, s);
    1247             : 
    1248           0 :         bgp_writes_on(peer);
    1249           0 : }
    1250             : 
    1251             : /* RFC1771 6.8 Connection collision detection. */
    1252           2 : static int bgp_collision_detect(struct peer *new, struct in_addr remote_id)
    1253             : {
    1254           2 :         struct peer *peer;
    1255             : 
    1256             :         /*
    1257             :          * Upon receipt of an OPEN message, the local system must examine
    1258             :          * all of its connections that are in the OpenConfirm state.  A BGP
    1259             :          * speaker may also examine connections in an OpenSent state if it
    1260             :          * knows the BGP Identifier of the peer by means outside of the
    1261             :          * protocol.  If among these connections there is a connection to a
    1262             :          * remote BGP speaker whose BGP Identifier equals the one in the
    1263             :          * OPEN message, then the local system performs the following
    1264             :          * collision resolution procedure:
    1265             :          */
    1266           2 :         peer = new->doppelganger;
    1267           2 :         if (peer == NULL)
    1268             :                 return 0;
    1269             : 
    1270             :         /*
    1271             :          * Do not accept the new connection in Established or Clearing
    1272             :          * states. Note that a peer GR is handled by closing the existing
    1273             :          * connection upon receipt of new one.
    1274             :          */
    1275           1 :         if (peer_established(peer) || peer->status == Clearing) {
    1276           0 :                 bgp_notify_send(new, BGP_NOTIFY_CEASE,
    1277             :                                 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
    1278           0 :                 return -1;
    1279             :         }
    1280             : 
    1281           1 :         if ((peer->status != OpenConfirm) && (peer->status != OpenSent))
    1282             :                 return 0;
    1283             : 
    1284             :         /*
    1285             :          * 1. The BGP Identifier of the local system is
    1286             :          * compared to the BGP Identifier of the remote
    1287             :          * system (as specified in the OPEN message).
    1288             :          *
    1289             :          * If the BGP Identifiers of the peers
    1290             :          * involved in the connection collision
    1291             :          * are identical, then the connection
    1292             :          * initiated by the BGP speaker with the
    1293             :          * larger AS number is preserved.
    1294             :          */
    1295           0 :         if (ntohl(peer->local_id.s_addr) < ntohl(remote_id.s_addr)
    1296           0 :             || (ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)
    1297           0 :                 && peer->local_as < peer->as))
    1298           0 :                 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) {
    1299             :                         /*
    1300             :                          * 2. If the value of the local BGP
    1301             :                          * Identifier is less than the remote one,
    1302             :                          * the local system closes BGP connection
    1303             :                          * that already exists (the one that is
    1304             :                          * already in the OpenConfirm state),
    1305             :                          * and accepts BGP connection initiated by
    1306             :                          * the remote system.
    1307             :                          */
    1308           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
    1309             :                                         BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
    1310           0 :                         return 1;
    1311             :                 } else {
    1312           0 :                         bgp_notify_send(new, BGP_NOTIFY_CEASE,
    1313             :                                         BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
    1314           0 :                         return -1;
    1315             :                 }
    1316             :         else {
    1317           0 :                 if (ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)
    1318           0 :                     && peer->local_as == peer->as)
    1319           0 :                         flog_err(EC_BGP_ROUTER_ID_SAME,
    1320             :                                  "Peer's router-id %pI4 is the same as ours",
    1321             :                                  &remote_id);
    1322             : 
    1323             :                 /*
    1324             :                  * 3. Otherwise, the local system closes newly
    1325             :                  * created BGP connection (the one associated with the
    1326             :                  * newly received OPEN message), and continues to use
    1327             :                  * the existing one (the one that is already in the
    1328             :                  * OpenConfirm state).
    1329             :                  */
    1330           0 :                 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) {
    1331           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
    1332             :                                         BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
    1333           0 :                         return 1;
    1334             :                 } else {
    1335           0 :                         bgp_notify_send(new, BGP_NOTIFY_CEASE,
    1336             :                                         BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
    1337           0 :                         return -1;
    1338             :                 }
    1339             :         }
    1340             : }
    1341             : 
    1342             : /* Packet processing routines ---------------------------------------------- */
    1343             : /*
    1344             :  * This is a family of functions designed to be called from
    1345             :  * bgp_process_packet(). These functions all share similar behavior and should
    1346             :  * adhere to the following invariants and restrictions:
    1347             :  *
    1348             :  * Return codes
    1349             :  * ------------
    1350             :  * The return code of any one of those functions should be one of the FSM event
    1351             :  * codes specified in bgpd.h. If a NOTIFY was sent, this event code MUST be
    1352             :  * BGP_Stop. Otherwise, the code SHOULD correspond to the function's expected
    1353             :  * packet type. For example, bgp_open_receive() should return BGP_Stop upon
    1354             :  * error and Receive_OPEN_message otherwise.
    1355             :  *
    1356             :  * If no action is necessary, the correct return code is BGP_PACKET_NOOP as
    1357             :  * defined below.
    1358             :  *
    1359             :  * Side effects
    1360             :  * ------------
    1361             :  * - May send NOTIFY messages
    1362             :  * - May not modify peer->status
    1363             :  * - May not call bgp_event_update()
    1364             :  */
    1365             : 
    1366             : #define BGP_PACKET_NOOP 0
    1367             : 
    1368             : /**
    1369             :  * Process BGP OPEN message for peer.
    1370             :  *
    1371             :  * If any errors are encountered in the OPEN message, immediately sends NOTIFY
    1372             :  * and returns BGP_Stop.
    1373             :  *
    1374             :  * @param peer
    1375             :  * @param size size of the packet
    1376             :  * @return as in summary
    1377             :  */
    1378           2 : static int bgp_open_receive(struct peer *peer, bgp_size_t size)
    1379             : {
    1380           2 :         int ret;
    1381           2 :         uint8_t version;
    1382           2 :         uint16_t optlen;
    1383           2 :         uint16_t holdtime;
    1384           2 :         uint16_t send_holdtime;
    1385           2 :         as_t remote_as;
    1386           2 :         as_t as4 = 0, as4_be;
    1387           2 :         struct in_addr remote_id;
    1388           2 :         int mp_capability;
    1389           2 :         uint8_t notify_data_remote_as[2];
    1390           2 :         uint8_t notify_data_remote_as4[4];
    1391           2 :         uint8_t notify_data_remote_id[4];
    1392           2 :         uint16_t *holdtime_ptr;
    1393             : 
    1394             :         /* Parse open packet. */
    1395           2 :         version = stream_getc(peer->curr);
    1396           2 :         memcpy(notify_data_remote_as, stream_pnt(peer->curr), 2);
    1397           2 :         remote_as = stream_getw(peer->curr);
    1398           2 :         holdtime_ptr = (uint16_t *)stream_pnt(peer->curr);
    1399           2 :         holdtime = stream_getw(peer->curr);
    1400           2 :         memcpy(notify_data_remote_id, stream_pnt(peer->curr), 4);
    1401           2 :         remote_id.s_addr = stream_get_ipv4(peer->curr);
    1402             : 
    1403             :         /* BEGIN to read the capability here, but dont do it yet */
    1404           2 :         mp_capability = 0;
    1405           2 :         optlen = stream_getc(peer->curr);
    1406             : 
    1407             :         /* Extended Optional Parameters Length for BGP OPEN Message */
    1408           2 :         if (optlen == BGP_OPEN_NON_EXT_OPT_LEN
    1409           2 :             || CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) {
    1410           0 :                 uint8_t opttype;
    1411             : 
    1412           0 :                 if (STREAM_READABLE(peer->curr) < 1) {
    1413           0 :                         flog_err(
    1414             :                                 EC_BGP_PKT_OPEN,
    1415             :                                 "%s: stream does not have enough bytes for extended optional parameters",
    1416             :                                 peer->host);
    1417           0 :                         bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
    1418             :                                         BGP_NOTIFY_OPEN_MALFORMED_ATTR);
    1419           0 :                         return BGP_Stop;
    1420             :                 }
    1421             : 
    1422           0 :                 opttype = stream_getc(peer->curr);
    1423           0 :                 if (opttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) {
    1424           0 :                         if (STREAM_READABLE(peer->curr) < 2) {
    1425           0 :                                 flog_err(
    1426             :                                         EC_BGP_PKT_OPEN,
    1427             :                                         "%s: stream does not have enough bytes to read the extended optional parameters optlen",
    1428             :                                         peer->host);
    1429           0 :                                 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
    1430             :                                                 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
    1431           0 :                                 return BGP_Stop;
    1432             :                         }
    1433           0 :                         optlen = stream_getw(peer->curr);
    1434           0 :                         SET_FLAG(peer->sflags,
    1435             :                                  PEER_STATUS_EXT_OPT_PARAMS_LENGTH);
    1436             :                 }
    1437             :         }
    1438             : 
    1439             :         /* Receive OPEN message log  */
    1440           2 :         if (bgp_debug_neighbor_events(peer))
    1441           0 :                 zlog_debug(
    1442             :                         "%s rcv OPEN%s, version %d, remote-as (in open) %u, holdtime %d, id %pI4",
    1443             :                         peer->host,
    1444             :                         CHECK_FLAG(peer->sflags,
    1445             :                                    PEER_STATUS_EXT_OPT_PARAMS_LENGTH)
    1446             :                                 ? " (Extended)"
    1447             :                                 : "",
    1448             :                         version, remote_as, holdtime, &remote_id);
    1449             : 
    1450           2 :         if (optlen != 0) {
    1451             :                 /* If not enough bytes, it is an error. */
    1452           1 :                 if (STREAM_READABLE(peer->curr) < optlen) {
    1453           0 :                         flog_err(EC_BGP_PKT_OPEN,
    1454             :                                  "%s: stream has not enough bytes (%u)",
    1455             :                                  peer->host, optlen);
    1456           0 :                         bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
    1457             :                                         BGP_NOTIFY_OPEN_MALFORMED_ATTR);
    1458           0 :                         return BGP_Stop;
    1459             :                 }
    1460             : 
    1461             :                 /* We need the as4 capability value *right now* because
    1462             :                  * if it is there, we have not got the remote_as yet, and
    1463             :                  * without
    1464             :                  * that we do not know which peer is connecting to us now.
    1465             :                  */
    1466           1 :                 as4 = peek_for_as4_capability(peer, optlen);
    1467             :         }
    1468             : 
    1469           2 :         as4_be = htonl(as4);
    1470           2 :         memcpy(notify_data_remote_as4, &as4_be, 4);
    1471             : 
    1472             :         /* Just in case we have a silly peer who sends AS4 capability set to 0
    1473             :          */
    1474           2 :         if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) && !as4) {
    1475           0 :                 flog_err(EC_BGP_PKT_OPEN,
    1476             :                          "%s bad OPEN, got AS4 capability, but AS4 set to 0",
    1477             :                          peer->host);
    1478           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1479             :                                           BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1480             :                                           notify_data_remote_as4, 4);
    1481           0 :                 return BGP_Stop;
    1482             :         }
    1483             : 
    1484             :         /* Codification of AS 0 Processing */
    1485           2 :         if (remote_as == BGP_AS_ZERO) {
    1486           0 :                 flog_err(EC_BGP_PKT_OPEN, "%s bad OPEN, got AS set to 0",
    1487             :                          peer->host);
    1488           0 :                 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
    1489             :                                 BGP_NOTIFY_OPEN_BAD_PEER_AS);
    1490           0 :                 return BGP_Stop;
    1491             :         }
    1492             : 
    1493           2 :         if (remote_as == BGP_AS_TRANS) {
    1494             :                 /* Take the AS4 from the capability.  We must have received the
    1495             :                  * capability now!  Otherwise we have a asn16 peer who uses
    1496             :                  * BGP_AS_TRANS, for some unknown reason.
    1497             :                  */
    1498           0 :                 if (as4 == BGP_AS_TRANS) {
    1499           0 :                         flog_err(
    1500             :                                 EC_BGP_PKT_OPEN,
    1501             :                                 "%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
    1502             :                                 peer->host);
    1503           0 :                         bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1504             :                                                   BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1505             :                                                   notify_data_remote_as4, 4);
    1506           0 :                         return BGP_Stop;
    1507             :                 }
    1508             : 
    1509           0 :                 if (!as4 && BGP_DEBUG(as4, AS4))
    1510           0 :                         zlog_debug(
    1511             :                                 "%s [AS4] OPEN remote_as is AS_TRANS, but no AS4. Odd, but proceeding.",
    1512             :                                 peer->host);
    1513           0 :                 else if (as4 < BGP_AS_MAX && BGP_DEBUG(as4, AS4))
    1514           0 :                         zlog_debug(
    1515             :                                 "%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits in 2-bytes, very odd peer.",
    1516             :                                 peer->host, as4);
    1517           0 :                 if (as4)
    1518             :                         remote_as = as4;
    1519             :         } else {
    1520             :                 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX
    1521             :                  */
    1522             :                 /* If we have got the capability, peer->as4cap must match
    1523             :                  * remote_as */
    1524           2 :                 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
    1525           1 :                     && as4 != remote_as) {
    1526             :                         /* raise error, log this, close session */
    1527           0 :                         flog_err(
    1528             :                                 EC_BGP_PKT_OPEN,
    1529             :                                 "%s bad OPEN, got AS4 capability, but remote_as %u mismatch with 16bit 'myasn' %u in open",
    1530             :                                 peer->host, as4, remote_as);
    1531           0 :                         bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1532             :                                                   BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1533             :                                                   notify_data_remote_as4, 4);
    1534           0 :                         return BGP_Stop;
    1535             :                 }
    1536             :         }
    1537             : 
    1538             :         /* rfc6286:
    1539             :          * If the BGP Identifier field of the OPEN message
    1540             :          * is zero, or if it is the same as the BGP Identifier
    1541             :          * of the local BGP speaker and the message is from an
    1542             :          * internal peer, then the Error Subcode is set to
    1543             :          * "Bad BGP Identifier".
    1544             :          */
    1545           2 :         if (remote_id.s_addr == INADDR_ANY
    1546           2 :             || (peer->sort == BGP_PEER_IBGP
    1547           0 :                 && ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr))) {
    1548           0 :                 if (bgp_debug_neighbor_events(peer))
    1549           0 :                         zlog_debug("%s bad OPEN, wrong router identifier %pI4",
    1550             :                                    peer->host, &remote_id);
    1551           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1552             :                                           BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
    1553             :                                           notify_data_remote_id, 4);
    1554           0 :                 return BGP_Stop;
    1555             :         }
    1556             : 
    1557             :         /* Peer BGP version check. */
    1558           2 :         if (version != BGP_VERSION_4) {
    1559           0 :                 uint16_t maxver = htons(BGP_VERSION_4);
    1560             :                 /* XXX this reply may not be correct if version < 4  XXX */
    1561           0 :                 if (bgp_debug_neighbor_events(peer))
    1562           0 :                         zlog_debug(
    1563             :                                 "%s bad protocol version, remote requested %d, local request %d",
    1564             :                                 peer->host, version, BGP_VERSION_4);
    1565             :                 /* Data must be in network byte order here */
    1566           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1567             :                                           BGP_NOTIFY_OPEN_UNSUP_VERSION,
    1568             :                                           (uint8_t *)&maxver, 2);
    1569           0 :                 return BGP_Stop;
    1570             :         }
    1571             : 
    1572             :         /* Check neighbor as number. */
    1573           2 :         if (peer->as_type == AS_UNSPECIFIED) {
    1574           0 :                 if (bgp_debug_neighbor_events(peer))
    1575           0 :                         zlog_debug(
    1576             :                                 "%s bad OPEN, remote AS is unspecified currently",
    1577             :                                 peer->host);
    1578           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1579             :                                           BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1580             :                                           notify_data_remote_as, 2);
    1581           0 :                 return BGP_Stop;
    1582           2 :         } else if (peer->as_type == AS_INTERNAL) {
    1583           0 :                 if (remote_as != peer->bgp->as) {
    1584           0 :                         if (bgp_debug_neighbor_events(peer))
    1585           0 :                                 zlog_debug(
    1586             :                                         "%s bad OPEN, remote AS is %u, internal specified",
    1587             :                                         peer->host, remote_as);
    1588           0 :                         bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1589             :                                                   BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1590             :                                                   notify_data_remote_as, 2);
    1591           0 :                         return BGP_Stop;
    1592             :                 }
    1593           0 :                 peer->as = peer->local_as;
    1594           2 :         } else if (peer->as_type == AS_EXTERNAL) {
    1595           2 :                 if (remote_as == peer->bgp->as) {
    1596           0 :                         if (bgp_debug_neighbor_events(peer))
    1597           0 :                                 zlog_debug(
    1598             :                                         "%s bad OPEN, remote AS is %u, external specified",
    1599             :                                         peer->host, remote_as);
    1600           0 :                         bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1601             :                                                   BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1602             :                                                   notify_data_remote_as, 2);
    1603           0 :                         return BGP_Stop;
    1604             :                 }
    1605           2 :                 peer->as = remote_as;
    1606           0 :         } else if ((peer->as_type == AS_SPECIFIED) && (remote_as != peer->as)) {
    1607           0 :                 if (bgp_debug_neighbor_events(peer))
    1608           0 :                         zlog_debug("%s bad OPEN, remote AS is %u, expected %u",
    1609             :                                    peer->host, remote_as, peer->as);
    1610           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1611             :                                           BGP_NOTIFY_OPEN_BAD_PEER_AS,
    1612             :                                           notify_data_remote_as, 2);
    1613           0 :                 return BGP_Stop;
    1614             :         }
    1615             : 
    1616             :         /*
    1617             :          * When collision is detected and this peer is closed.
    1618             :          * Return immediately.
    1619             :          */
    1620           2 :         ret = bgp_collision_detect(peer, remote_id);
    1621           2 :         if (ret < 0)
    1622             :                 return BGP_Stop;
    1623             : 
    1624             :         /* Get sockname. */
    1625           2 :         if (bgp_getsockname(peer) < 0) {
    1626           0 :                 flog_err_sys(EC_LIB_SOCKET,
    1627             :                              "%s: bgp_getsockname() failed for peer: %s",
    1628             :                              __func__, peer->host);
    1629           0 :                 return BGP_Stop;
    1630             :         }
    1631             : 
    1632             :         /* Set remote router-id */
    1633           2 :         peer->remote_id = remote_id;
    1634             : 
    1635             :         /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
    1636             :            calculate the value of the Hold Timer by using the smaller of its
    1637             :            configured Hold Time and the Hold Time received in the OPEN message.
    1638             :            The Hold Time MUST be either zero or at least three seconds.  An
    1639             :            implementation may reject connections on the basis of the Hold Time.
    1640             :            */
    1641             : 
    1642           2 :         if (holdtime < 3 && holdtime != 0) {
    1643           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1644             :                                           BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
    1645             :                                           (uint8_t *)holdtime_ptr, 2);
    1646           0 :                 return BGP_Stop;
    1647             :         }
    1648             : 
    1649             :         /* Send notification message when Hold Time received in the OPEN message
    1650             :          * is smaller than configured minimum Hold Time. */
    1651           2 :         if (holdtime < peer->bgp->default_min_holdtime
    1652             :             && peer->bgp->default_min_holdtime != 0) {
    1653           0 :                 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
    1654             :                                           BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
    1655             :                                           (uint8_t *)holdtime_ptr, 2);
    1656           0 :                 return BGP_Stop;
    1657             :         }
    1658             : 
    1659             :         /* From the rfc: A reasonable maximum time between KEEPALIVE messages
    1660             :            would be one third of the Hold Time interval.  KEEPALIVE messages
    1661             :            MUST NOT be sent more frequently than one per second.  An
    1662             :            implementation MAY adjust the rate at which it sends KEEPALIVE
    1663             :            messages as a function of the Hold Time interval. */
    1664             : 
    1665           2 :         if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
    1666           0 :                 send_holdtime = peer->holdtime;
    1667             :         else
    1668           2 :                 send_holdtime = peer->bgp->default_holdtime;
    1669             : 
    1670           2 :         if (holdtime < send_holdtime)
    1671           0 :                 peer->v_holdtime = holdtime;
    1672             :         else
    1673           2 :                 peer->v_holdtime = send_holdtime;
    1674             : 
    1675             :         /* Set effective keepalive to 1/3 the effective holdtime.
    1676             :          * Use configured keeplive when < effective keepalive.
    1677             :          */
    1678           2 :         peer->v_keepalive = peer->v_holdtime / 3;
    1679           2 :         if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
    1680           0 :                 if (peer->keepalive && peer->keepalive < peer->v_keepalive)
    1681           0 :                         peer->v_keepalive = peer->keepalive;
    1682             :         } else {
    1683           2 :                 if (peer->bgp->default_keepalive
    1684           2 :                     && peer->bgp->default_keepalive < peer->v_keepalive)
    1685           0 :                         peer->v_keepalive = peer->bgp->default_keepalive;
    1686             :         }
    1687             : 
    1688             :         /* Open option part parse. */
    1689           2 :         if (optlen != 0) {
    1690           1 :                 if (bgp_open_option_parse(peer, optlen, &mp_capability) < 0)
    1691             :                         return BGP_Stop;
    1692             :         } else {
    1693           1 :                 if (bgp_debug_neighbor_events(peer))
    1694           0 :                         zlog_debug("%s rcvd OPEN w/ OPTION parameter len: 0",
    1695             :                                    peer->host);
    1696             :         }
    1697             : 
    1698             :         /*
    1699             :          * Assume that the peer supports the locally configured set of
    1700             :          * AFI/SAFIs if the peer did not send us any Mulitiprotocol
    1701             :          * capabilities, or if 'override-capability' is configured.
    1702             :          */
    1703           2 :         if (!mp_capability
    1704           1 :             || CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
    1705           1 :                 peer->afc_nego[AFI_IP][SAFI_UNICAST] =
    1706           1 :                         peer->afc[AFI_IP][SAFI_UNICAST];
    1707           1 :                 peer->afc_nego[AFI_IP][SAFI_MULTICAST] =
    1708           1 :                         peer->afc[AFI_IP][SAFI_MULTICAST];
    1709           1 :                 peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] =
    1710           1 :                         peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
    1711           1 :                 peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] =
    1712           1 :                         peer->afc[AFI_IP][SAFI_FLOWSPEC];
    1713           1 :                 peer->afc_nego[AFI_IP6][SAFI_UNICAST] =
    1714           1 :                         peer->afc[AFI_IP6][SAFI_UNICAST];
    1715           1 :                 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] =
    1716           1 :                         peer->afc[AFI_IP6][SAFI_MULTICAST];
    1717           1 :                 peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST] =
    1718           1 :                         peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
    1719           1 :                 peer->afc_nego[AFI_L2VPN][SAFI_EVPN] =
    1720           1 :                         peer->afc[AFI_L2VPN][SAFI_EVPN];
    1721           1 :                 peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] =
    1722           1 :                         peer->afc[AFI_IP6][SAFI_FLOWSPEC];
    1723             :         }
    1724             : 
    1725             :         /* Verify valid local address present based on negotiated
    1726             :          * address-families. */
    1727           2 :         if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
    1728             :             || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
    1729             :             || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
    1730             :             || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
    1731             :             || peer->afc_nego[AFI_IP][SAFI_ENCAP]) {
    1732             :                 if (peer->nexthop.v4.s_addr == INADDR_ANY) {
    1733             : #if defined(HAVE_CUMULUS)
    1734             :                         zlog_warn("%s: No local IPv4 addr, BGP routing may not work",
    1735             :                                   peer->host);
    1736             : #endif
    1737           2 :                 }
    1738             :         }
    1739           2 :         if (peer->afc_nego[AFI_IP6][SAFI_UNICAST]
    1740             :             || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
    1741             :             || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
    1742             :             || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
    1743             :             || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) {
    1744           2 :                 if (IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_global)) {
    1745             : #if defined(HAVE_CUMULUS)
    1746             :                         zlog_warn("%s: No local IPv6 address, BGP routing may not work",
    1747             :                                   peer->host);
    1748             : #endif
    1749           2 :                 }
    1750             :         }
    1751           2 :         peer->rtt = sockopt_tcp_rtt(peer->fd);
    1752             : 
    1753           2 :         return Receive_OPEN_message;
    1754             : }
    1755             : 
    1756             : /**
    1757             :  * Process BGP KEEPALIVE message for peer.
    1758             :  *
    1759             :  * @param peer
    1760             :  * @param size size of the packet
    1761             :  * @return as in summary
    1762             :  */
    1763           2 : static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size)
    1764             : {
    1765           2 :         if (bgp_debug_keepalive(peer))
    1766           0 :                 zlog_debug("%s KEEPALIVE rcvd", peer->host);
    1767             : 
    1768           2 :         bgp_update_implicit_eors(peer);
    1769             : 
    1770           2 :         peer->rtt = sockopt_tcp_rtt(peer->fd);
    1771             : 
    1772             :         /* If the peer's RTT is higher than expected, shutdown
    1773             :          * the peer automatically.
    1774             :          */
    1775           2 :         if (!CHECK_FLAG(peer->flags, PEER_FLAG_RTT_SHUTDOWN))
    1776             :                 return Receive_KEEPALIVE_message;
    1777             : 
    1778           0 :         if (peer->rtt > peer->rtt_expected) {
    1779           0 :                 peer->rtt_keepalive_rcv++;
    1780             : 
    1781           0 :                 if (peer->rtt_keepalive_rcv > peer->rtt_keepalive_conf) {
    1782           0 :                         char rtt_shutdown_reason[BUFSIZ] = {};
    1783             : 
    1784           0 :                         snprintfrr(
    1785             :                                 rtt_shutdown_reason,
    1786             :                                 sizeof(rtt_shutdown_reason),
    1787             :                                 "shutdown due to high round-trip-time (%dms > %dms, hit %u times)",
    1788             :                                 peer->rtt, peer->rtt_expected,
    1789             :                                 peer->rtt_keepalive_rcv);
    1790           0 :                         zlog_warn("%s %s", peer->host, rtt_shutdown_reason);
    1791           0 :                         SET_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN);
    1792           0 :                         peer_tx_shutdown_message_set(peer, rtt_shutdown_reason);
    1793           0 :                         peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
    1794             :                 }
    1795             :         } else {
    1796           0 :                 if (peer->rtt_keepalive_rcv)
    1797           0 :                         peer->rtt_keepalive_rcv--;
    1798             :         }
    1799             : 
    1800             :         return Receive_KEEPALIVE_message;
    1801             : }
    1802             : 
    1803           0 : static void bgp_refresh_stalepath_timer_expire(struct thread *thread)
    1804             : {
    1805           0 :         struct peer_af *paf;
    1806             : 
    1807           0 :         paf = THREAD_ARG(thread);
    1808             : 
    1809           0 :         afi_t afi = paf->afi;
    1810           0 :         safi_t safi = paf->safi;
    1811           0 :         struct peer *peer = paf->peer;
    1812             : 
    1813           0 :         peer->t_refresh_stalepath = NULL;
    1814             : 
    1815           0 :         if (peer->nsf[afi][safi])
    1816           0 :                 bgp_clear_stale_route(peer, afi, safi);
    1817             : 
    1818           0 :         if (bgp_debug_neighbor_events(peer))
    1819           0 :                 zlog_debug(
    1820             :                         "%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d",
    1821             :                         peer, afi, safi);
    1822             : 
    1823           0 :         bgp_timer_set(peer);
    1824           0 : }
    1825             : 
    1826             : /**
    1827             :  * Process BGP UPDATE message for peer.
    1828             :  *
    1829             :  * Parses UPDATE and creates attribute object.
    1830             :  *
    1831             :  * @param peer
    1832             :  * @param size size of the packet
    1833             :  * @return as in summary
    1834             :  */
    1835           4 : static int bgp_update_receive(struct peer *peer, bgp_size_t size)
    1836             : {
    1837           4 :         int ret, nlri_ret;
    1838           4 :         uint8_t *end;
    1839           4 :         struct stream *s;
    1840           4 :         struct attr attr;
    1841           4 :         bgp_size_t attribute_len;
    1842           4 :         bgp_size_t update_len;
    1843           4 :         bgp_size_t withdraw_len;
    1844           4 :         bool restart = false;
    1845             : 
    1846           4 :         enum NLRI_TYPES {
    1847             :                 NLRI_UPDATE,
    1848             :                 NLRI_WITHDRAW,
    1849             :                 NLRI_MP_UPDATE,
    1850             :                 NLRI_MP_WITHDRAW,
    1851             :                 NLRI_TYPE_MAX
    1852             :         };
    1853           4 :         struct bgp_nlri nlris[NLRI_TYPE_MAX];
    1854             : 
    1855             :         /* Status must be Established. */
    1856           4 :         if (!peer_established(peer)) {
    1857           0 :                 flog_err(EC_BGP_INVALID_STATUS,
    1858             :                          "%s [FSM] Update packet received under status %s",
    1859             :                          peer->host,
    1860             :                          lookup_msg(bgp_status_msg, peer->status, NULL));
    1861           0 :                 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
    1862           0 :                                 bgp_fsm_error_subcode(peer->status));
    1863           0 :                 return BGP_Stop;
    1864             :         }
    1865             : 
    1866             :         /* Set initial values. */
    1867           4 :         memset(&attr, 0, sizeof(attr));
    1868           4 :         attr.label_index = BGP_INVALID_LABEL_INDEX;
    1869           4 :         attr.label = MPLS_INVALID_LABEL;
    1870           4 :         memset(&nlris, 0, sizeof(nlris));
    1871           4 :         memset(peer->rcvd_attr_str, 0, BUFSIZ);
    1872           4 :         peer->rcvd_attr_printed = 0;
    1873             : 
    1874           4 :         s = peer->curr;
    1875           4 :         end = stream_pnt(s) + size;
    1876             : 
    1877             :         /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
    1878             :            Length is too large (i.e., if Unfeasible Routes Length + Total
    1879             :            Attribute Length + 23 exceeds the message Length), then the Error
    1880             :            Subcode is set to Malformed Attribute List.  */
    1881           4 :         if (stream_pnt(s) + 2 > end) {
    1882           0 :                 flog_err(EC_BGP_UPDATE_RCV,
    1883             :                          "%s [Error] Update packet error (packet length is short for unfeasible length)",
    1884             :                          peer->host);
    1885           0 :                 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
    1886             :                                 BGP_NOTIFY_UPDATE_MAL_ATTR);
    1887           0 :                 return BGP_Stop;
    1888             :         }
    1889             : 
    1890             :         /* Unfeasible Route Length. */
    1891           4 :         withdraw_len = stream_getw(s);
    1892             : 
    1893             :         /* Unfeasible Route Length check. */
    1894           4 :         if (stream_pnt(s) + withdraw_len > end) {
    1895           0 :                 flog_err(EC_BGP_UPDATE_RCV,
    1896             :                          "%s [Error] Update packet error (packet unfeasible length overflow %d)",
    1897             :                          peer->host, withdraw_len);
    1898           0 :                 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
    1899             :                                 BGP_NOTIFY_UPDATE_MAL_ATTR);
    1900           0 :                 return BGP_Stop;
    1901             :         }
    1902             : 
    1903             :         /* Unfeasible Route packet format check. */
    1904           4 :         if (withdraw_len > 0) {
    1905           0 :                 nlris[NLRI_WITHDRAW].afi = AFI_IP;
    1906           0 :                 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
    1907           0 :                 nlris[NLRI_WITHDRAW].nlri = stream_pnt(s);
    1908           0 :                 nlris[NLRI_WITHDRAW].length = withdraw_len;
    1909           0 :                 stream_forward_getp(s, withdraw_len);
    1910             :         }
    1911             : 
    1912             :         /* Attribute total length check. */
    1913           4 :         if (stream_pnt(s) + 2 > end) {
    1914           0 :                 flog_warn(
    1915             :                         EC_BGP_UPDATE_PACKET_SHORT,
    1916             :                         "%s [Error] Packet Error (update packet is short for attribute length)",
    1917             :                         peer->host);
    1918           0 :                 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
    1919             :                                 BGP_NOTIFY_UPDATE_MAL_ATTR);
    1920           0 :                 return BGP_Stop;
    1921             :         }
    1922             : 
    1923             :         /* Fetch attribute total length. */
    1924           4 :         attribute_len = stream_getw(s);
    1925             : 
    1926             :         /* Attribute length check. */
    1927           4 :         if (stream_pnt(s) + attribute_len > end) {
    1928           0 :                 flog_warn(
    1929             :                         EC_BGP_UPDATE_PACKET_LONG,
    1930             :                         "%s [Error] Packet Error (update packet attribute length overflow %d)",
    1931             :                         peer->host, attribute_len);
    1932           0 :                 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
    1933             :                                 BGP_NOTIFY_UPDATE_MAL_ATTR);
    1934           0 :                 return BGP_Stop;
    1935             :         }
    1936             : 
    1937             :         /* Certain attribute parsing errors should not be considered bad enough
    1938             :          * to reset the session for, most particularly any partial/optional
    1939             :          * attributes that have 'tunneled' over speakers that don't understand
    1940             :          * them. Instead we withdraw only the prefix concerned.
    1941             :          *
    1942             :          * Complicates the flow a little though..
    1943             :          */
    1944           4 :         enum bgp_attr_parse_ret attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
    1945             : /* This define morphs the update case into a withdraw when lower levels
    1946             :  * have signalled an error condition where this is best.
    1947             :  */
    1948             : #define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
    1949             : 
    1950             :         /* Parse attribute when it exists. */
    1951           4 :         if (attribute_len) {
    1952           3 :                 attr_parse_ret = bgp_attr_parse(peer, &attr, attribute_len,
    1953             :                                                 &nlris[NLRI_MP_UPDATE],
    1954             :                                                 &nlris[NLRI_MP_WITHDRAW]);
    1955           3 :                 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR) {
    1956           0 :                         bgp_attr_unintern_sub(&attr);
    1957           0 :                         return BGP_Stop;
    1958             :                 }
    1959             :         }
    1960             : 
    1961             :         /* Logging the attribute. */
    1962           3 :         if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
    1963             :             || BGP_DEBUG(update, UPDATE_IN)
    1964           4 :             || BGP_DEBUG(update, UPDATE_PREFIX)) {
    1965           0 :                 ret = bgp_dump_attr(&attr, peer->rcvd_attr_str,
    1966             :                                     sizeof(peer->rcvd_attr_str));
    1967             : 
    1968           0 :                 peer->stat_upd_7606++;
    1969             : 
    1970           0 :                 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
    1971           0 :                         flog_err(
    1972             :                                 EC_BGP_UPDATE_RCV,
    1973             :                                 "%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
    1974             :                                 peer);
    1975             : 
    1976           0 :                 if (ret && bgp_debug_update(peer, NULL, NULL, 1)) {
    1977           0 :                         zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
    1978             :                                    peer->rcvd_attr_str);
    1979           0 :                         peer->rcvd_attr_printed = 1;
    1980             :                 }
    1981             :         }
    1982             : 
    1983             :         /* Network Layer Reachability Information. */
    1984           4 :         update_len = end - stream_pnt(s);
    1985             : 
    1986           4 :         if (update_len) {
    1987             :                 /* Set NLRI portion to structure. */
    1988           3 :                 nlris[NLRI_UPDATE].afi = AFI_IP;
    1989           3 :                 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
    1990           3 :                 nlris[NLRI_UPDATE].nlri = stream_pnt(s);
    1991           3 :                 nlris[NLRI_UPDATE].length = update_len;
    1992           3 :                 stream_forward_getp(s, update_len);
    1993             : 
    1994           3 :                 if (CHECK_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
    1995             :                         /*
    1996             :                          * We skipped nexthop attribute validation earlier so
    1997             :                          * validate the nexthop now.
    1998             :                          */
    1999           0 :                         if (bgp_attr_nexthop_valid(peer, &attr) < 0) {
    2000           0 :                                 bgp_attr_unintern_sub(&attr);
    2001           0 :                                 return BGP_Stop;
    2002             :                         }
    2003             :                 }
    2004             :         }
    2005             : 
    2006           4 :         if (BGP_DEBUG(update, UPDATE_IN))
    2007           0 :                 zlog_debug("%pBP rcvd UPDATE wlen %d attrlen %d alen %d", peer,
    2008             :                            withdraw_len, attribute_len, update_len);
    2009             : 
    2010             :         /* Parse any given NLRIs */
    2011          20 :         for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) {
    2012          16 :                 if (!nlris[i].nlri)
    2013          13 :                         continue;
    2014             : 
    2015             :                 /* NLRI is processed iff the peer if configured for the specific
    2016             :                  * afi/safi */
    2017           3 :                 if (!peer->afc[nlris[i].afi][nlris[i].safi]) {
    2018           0 :                         zlog_info(
    2019             :                                 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
    2020             :                                 peer->host, nlris[i].afi, nlris[i].safi);
    2021           0 :                         continue;
    2022             :                 }
    2023             : 
    2024             :                 /* EoR handled later */
    2025           3 :                 if (nlris[i].length == 0)
    2026           0 :                         continue;
    2027             : 
    2028           3 :                 switch (i) {
    2029           3 :                 case NLRI_UPDATE:
    2030             :                 case NLRI_MP_UPDATE:
    2031           3 :                         nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG,
    2032             :                                                   &nlris[i], 0);
    2033           3 :                         break;
    2034           0 :                 case NLRI_WITHDRAW:
    2035             :                 case NLRI_MP_WITHDRAW:
    2036           0 :                         nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG,
    2037             :                                                   &nlris[i], 1);
    2038           0 :                         break;
    2039             :                 default:
    2040             :                         nlri_ret = BGP_NLRI_PARSE_ERROR;
    2041             :                 }
    2042             : 
    2043           3 :                 if (nlri_ret < BGP_NLRI_PARSE_OK
    2044             :                     && nlri_ret != BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW) {
    2045           0 :                         flog_err(EC_BGP_UPDATE_RCV,
    2046             :                                  "%s [Error] Error parsing NLRI", peer->host);
    2047           0 :                         if (peer_established(peer))
    2048           0 :                                 bgp_notify_send(
    2049             :                                         peer, BGP_NOTIFY_UPDATE_ERR,
    2050             :                                         i <= NLRI_WITHDRAW
    2051             :                                                 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
    2052             :                                                 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
    2053           0 :                         bgp_attr_unintern_sub(&attr);
    2054           0 :                         return BGP_Stop;
    2055             :                 }
    2056             :         }
    2057             : 
    2058             :         /* EoR checks
    2059             :          *
    2060             :          * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
    2061             :          * and MP EoR should have only an empty MP_UNREACH
    2062             :          */
    2063           4 :         if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0)
    2064           3 :             || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
    2065           1 :                 afi_t afi = 0;
    2066           1 :                 safi_t safi;
    2067           1 :                 struct graceful_restart_info *gr_info;
    2068             : 
    2069             :                 /* Restarting router */
    2070           1 :                 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
    2071           0 :                     && BGP_PEER_RESTARTING_MODE(peer))
    2072           1 :                         restart = true;
    2073             : 
    2074             :                 /* Non-MP IPv4/Unicast is a completely emtpy UPDATE - already
    2075             :                  * checked
    2076             :                  * update and withdraw NLRI lengths are 0.
    2077             :                  */
    2078           1 :                 if (!attribute_len) {
    2079             :                         afi = AFI_IP;
    2080             :                         safi = SAFI_UNICAST;
    2081           0 :                 } else if (attr.flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI)
    2082           0 :                            && nlris[NLRI_MP_WITHDRAW].length == 0) {
    2083           0 :                         afi = nlris[NLRI_MP_WITHDRAW].afi;
    2084           0 :                         safi = nlris[NLRI_MP_WITHDRAW].safi;
    2085           0 :                 } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) {
    2086           0 :                         afi = nlris[NLRI_MP_UPDATE].afi;
    2087           0 :                         safi = nlris[NLRI_MP_UPDATE].safi;
    2088             :                 }
    2089             : 
    2090           1 :                 if (afi && peer->afc[afi][safi]) {
    2091           1 :                         struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
    2092             : 
    2093             :                         /* End-of-RIB received */
    2094           1 :                         if (!CHECK_FLAG(peer->af_sflags[afi][safi],
    2095             :                                         PEER_STATUS_EOR_RECEIVED)) {
    2096           1 :                                 SET_FLAG(peer->af_sflags[afi][safi],
    2097             :                                          PEER_STATUS_EOR_RECEIVED);
    2098           1 :                                 bgp_update_explicit_eors(peer);
    2099             :                                 /* Update graceful restart information */
    2100           1 :                                 gr_info = &(peer->bgp->gr_info[afi][safi]);
    2101           1 :                                 if (restart)
    2102           0 :                                         gr_info->eor_received++;
    2103             :                                 /* If EOR received from all peers and selection
    2104             :                                  * deferral timer is running, cancel the timer
    2105             :                                  * and invoke the best path calculation
    2106             :                                  */
    2107           1 :                                 if (gr_info->eor_required
    2108           1 :                                     == gr_info->eor_received) {
    2109           1 :                                         if (bgp_debug_neighbor_events(peer))
    2110           0 :                                                 zlog_debug(
    2111             :                                                         "%s %d, %s %d",
    2112             :                                                         "EOR REQ",
    2113             :                                                         gr_info->eor_required,
    2114             :                                                         "EOR RCV",
    2115             :                                                         gr_info->eor_received);
    2116           1 :                                         if (gr_info->t_select_deferral) {
    2117           0 :                                                 void *info = THREAD_ARG(
    2118             :                                                         gr_info->t_select_deferral);
    2119           0 :                                                 XFREE(MTYPE_TMP, info);
    2120             :                                         }
    2121           1 :                                         THREAD_OFF(gr_info->t_select_deferral);
    2122           1 :                                         gr_info->eor_required = 0;
    2123           1 :                                         gr_info->eor_received = 0;
    2124             :                                         /* Best path selection */
    2125           1 :                                         bgp_best_path_select_defer(peer->bgp,
    2126             :                                                                    afi, safi);
    2127             :                                 }
    2128             :                         }
    2129             : 
    2130             :                         /* NSF delete stale route */
    2131           1 :                         if (peer->nsf[afi][safi])
    2132           0 :                                 bgp_clear_stale_route(peer, afi, safi);
    2133             : 
    2134           1 :                         zlog_info(
    2135             :                                 "%s: rcvd End-of-RIB for %s from %s in vrf %s",
    2136             :                                 __func__, get_afi_safi_str(afi, safi, false),
    2137             :                                 peer->host, vrf ? vrf->name : VRF_DEFAULT_NAME);
    2138             :                 }
    2139             :         }
    2140             : 
    2141             :         /* Everything is done.  We unintern temporary structures which
    2142             :            interned in bgp_attr_parse(). */
    2143           4 :         bgp_attr_unintern_sub(&attr);
    2144             : 
    2145           4 :         peer->update_time = monotime(NULL);
    2146             : 
    2147             :         /* Notify BGP Conditional advertisement scanner process */
    2148           4 :         peer->advmap_table_change = true;
    2149             : 
    2150           4 :         return Receive_UPDATE_message;
    2151             : }
    2152             : 
    2153             : /**
    2154             :  * Process BGP NOTIFY message for peer.
    2155             :  *
    2156             :  * @param peer
    2157             :  * @param size size of the packet
    2158             :  * @return as in summary
    2159             :  */
    2160           1 : static int bgp_notify_receive(struct peer *peer, bgp_size_t size)
    2161             : {
    2162           1 :         struct bgp_notify outer = {};
    2163           1 :         struct bgp_notify inner = {};
    2164           1 :         bool hard_reset = false;
    2165             : 
    2166           1 :         if (peer->notify.data) {
    2167           0 :                 XFREE(MTYPE_BGP_NOTIFICATION, peer->notify.data);
    2168           0 :                 peer->notify.length = 0;
    2169           0 :                 peer->notify.hard_reset = false;
    2170             :         }
    2171             : 
    2172           1 :         outer.code = stream_getc(peer->curr);
    2173           1 :         outer.subcode = stream_getc(peer->curr);
    2174           1 :         outer.length = size - 2;
    2175           1 :         outer.data = NULL;
    2176           1 :         outer.raw_data = NULL;
    2177           1 :         if (outer.length) {
    2178           0 :                 outer.raw_data = XMALLOC(MTYPE_BGP_NOTIFICATION, outer.length);
    2179           0 :                 memcpy(outer.raw_data, stream_pnt(peer->curr), outer.length);
    2180             :         }
    2181             : 
    2182           1 :         hard_reset =
    2183           1 :                 bgp_notify_received_hard_reset(peer, outer.code, outer.subcode);
    2184           0 :         if (hard_reset && outer.length) {
    2185           0 :                 inner = bgp_notify_decapsulate_hard_reset(&outer);
    2186           0 :                 peer->notify.hard_reset = true;
    2187             :         } else {
    2188           1 :                 inner = outer;
    2189             :         }
    2190             : 
    2191             :         /* Preserv notify code and sub code. */
    2192           1 :         peer->notify.code = inner.code;
    2193           1 :         peer->notify.subcode = inner.subcode;
    2194             :         /* For further diagnostic record returned Data. */
    2195           1 :         if (inner.length) {
    2196           0 :                 peer->notify.length = inner.length;
    2197           0 :                 peer->notify.data =
    2198           0 :                         XMALLOC(MTYPE_BGP_NOTIFICATION, inner.length);
    2199           0 :                 memcpy(peer->notify.data, inner.raw_data, inner.length);
    2200             :         }
    2201             : 
    2202             :         /* For debug */
    2203             :         {
    2204           1 :                 int i;
    2205           1 :                 int first = 0;
    2206           1 :                 char c[4];
    2207             : 
    2208           1 :                 if (inner.length) {
    2209           0 :                         inner.data = XMALLOC(MTYPE_BGP_NOTIFICATION,
    2210             :                                              inner.length * 3);
    2211           0 :                         for (i = 0; i < inner.length; i++)
    2212           0 :                                 if (first) {
    2213           0 :                                         snprintf(c, sizeof(c), " %02x",
    2214           0 :                                                 stream_getc(peer->curr));
    2215             : 
    2216           0 :                                         strlcat(inner.data, c,
    2217           0 :                                                 inner.length * 3);
    2218             : 
    2219             :                                 } else {
    2220           0 :                                         first = 1;
    2221           0 :                                         snprintf(c, sizeof(c), "%02x",
    2222           0 :                                                  stream_getc(peer->curr));
    2223             : 
    2224           0 :                                         strlcpy(inner.data, c,
    2225           0 :                                                 inner.length * 3);
    2226             :                                 }
    2227             :                 }
    2228             : 
    2229           1 :                 bgp_notify_print(peer, &inner, "received", hard_reset);
    2230           1 :                 if (inner.length) {
    2231           0 :                         XFREE(MTYPE_BGP_NOTIFICATION, inner.data);
    2232           0 :                         inner.length = 0;
    2233             :                 }
    2234           1 :                 if (outer.length) {
    2235           0 :                         XFREE(MTYPE_BGP_NOTIFICATION, outer.data);
    2236           0 :                         XFREE(MTYPE_BGP_NOTIFICATION, outer.raw_data);
    2237             : 
    2238             :                         /* If this is a Hard Reset notification, we MUST free
    2239             :                          * the inner (encapsulated) notification too.
    2240             :                          */
    2241           0 :                         if (hard_reset)
    2242           0 :                                 XFREE(MTYPE_BGP_NOTIFICATION, inner.raw_data);
    2243           0 :                         outer.length = 0;
    2244             :                 }
    2245             :         }
    2246             : 
    2247             :         /* peer count update */
    2248           1 :         atomic_fetch_add_explicit(&peer->notify_in, 1, memory_order_relaxed);
    2249             : 
    2250           1 :         peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
    2251             : 
    2252             :         /* We have to check for Notify with Unsupported Optional Parameter.
    2253             :            in that case we fallback to open without the capability option.
    2254             :            But this done in bgp_stop. We just mark it here to avoid changing
    2255             :            the fsm tables.  */
    2256           1 :         if (inner.code == BGP_NOTIFY_OPEN_ERR &&
    2257             :             inner.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM)
    2258           0 :                 UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
    2259             : 
    2260             :         /* If Graceful-Restart N-bit (Notification) is exchanged,
    2261             :          * and it's not a Hard Reset, let's retain the routes.
    2262             :          */
    2263           1 :         if (bgp_has_graceful_restart_notification(peer) && !hard_reset &&
    2264           0 :             CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
    2265           0 :                 SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
    2266             : 
    2267           1 :         bgp_peer_gr_flags_update(peer);
    2268           3 :         BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
    2269             :                                                           peer->bgp->peer);
    2270             : 
    2271           1 :         return Receive_NOTIFICATION_message;
    2272             : }
    2273             : 
    2274             : /**
    2275             :  * Process BGP ROUTEREFRESH message for peer.
    2276             :  *
    2277             :  * @param peer
    2278             :  * @param size size of the packet
    2279             :  * @return as in summary
    2280             :  */
    2281           0 : static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
    2282             : {
    2283           0 :         iana_afi_t pkt_afi;
    2284           0 :         afi_t afi;
    2285           0 :         iana_safi_t pkt_safi;
    2286           0 :         safi_t safi;
    2287           0 :         struct stream *s;
    2288           0 :         struct peer_af *paf;
    2289           0 :         struct update_group *updgrp;
    2290           0 :         struct peer *updgrp_peer;
    2291           0 :         uint8_t subtype;
    2292           0 :         bool force_update = false;
    2293           0 :         bgp_size_t msg_length =
    2294             :                 size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE);
    2295             : 
    2296             :         /* If peer does not have the capability, send notification. */
    2297           0 :         if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) {
    2298           0 :                 flog_err(EC_BGP_NO_CAP,
    2299             :                          "%s [Error] BGP route refresh is not enabled",
    2300             :                          peer->host);
    2301           0 :                 bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
    2302             :                                 BGP_NOTIFY_HEADER_BAD_MESTYPE);
    2303           0 :                 return BGP_Stop;
    2304             :         }
    2305             : 
    2306             :         /* Status must be Established. */
    2307           0 :         if (!peer_established(peer)) {
    2308           0 :                 flog_err(
    2309             :                         EC_BGP_INVALID_STATUS,
    2310             :                         "%s [Error] Route refresh packet received under status %s",
    2311             :                         peer->host,
    2312             :                         lookup_msg(bgp_status_msg, peer->status, NULL));
    2313           0 :                 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
    2314           0 :                                 bgp_fsm_error_subcode(peer->status));
    2315           0 :                 return BGP_Stop;
    2316             :         }
    2317             : 
    2318           0 :         s = peer->curr;
    2319             : 
    2320             :         /* Parse packet. */
    2321           0 :         pkt_afi = stream_getw(s);
    2322           0 :         subtype = stream_getc(s);
    2323           0 :         pkt_safi = stream_getc(s);
    2324             : 
    2325             :         /* Convert AFI, SAFI to internal values and check. */
    2326           0 :         if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
    2327           0 :                 zlog_info(
    2328             :                         "%s REFRESH_REQ for unrecognized afi/safi: %s/%s - ignored",
    2329             :                         peer->host, iana_afi2str(pkt_afi),
    2330             :                         iana_safi2str(pkt_safi));
    2331           0 :                 return BGP_PACKET_NOOP;
    2332             :         }
    2333             : 
    2334           0 :         if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) {
    2335           0 :                 uint8_t *end;
    2336           0 :                 uint8_t when_to_refresh;
    2337           0 :                 uint8_t orf_type;
    2338           0 :                 uint16_t orf_len;
    2339             : 
    2340           0 :                 if (subtype) {
    2341             :                         /* If the length, excluding the fixed-size message
    2342             :                          * header, of the received ROUTE-REFRESH message with
    2343             :                          * Message Subtype 1 and 2 is not 4, then the BGP
    2344             :                          * speaker MUST send a NOTIFICATION message with the
    2345             :                          * Error Code of "ROUTE-REFRESH Message Error" and the
    2346             :                          * subcode of "Invalid Message Length".
    2347             :                          */
    2348           0 :                         if (msg_length != 4) {
    2349           0 :                                 zlog_err(
    2350             :                                         "%s Enhanced Route Refresh message length error",
    2351             :                                         peer->host);
    2352           0 :                                 bgp_notify_send(
    2353             :                                         peer, BGP_NOTIFY_ROUTE_REFRESH_ERR,
    2354             :                                         BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN);
    2355             :                         }
    2356             : 
    2357             :                         /* When the BGP speaker receives a ROUTE-REFRESH message
    2358             :                          * with a "Message Subtype" field other than 0, 1, or 2,
    2359             :                          * it MUST ignore the received ROUTE-REFRESH message.
    2360             :                          */
    2361           0 :                         if (subtype > 2)
    2362           0 :                                 zlog_err(
    2363             :                                         "%s Enhanced Route Refresh invalid subtype",
    2364             :                                         peer->host);
    2365             :                 }
    2366             : 
    2367           0 :                 if (msg_length < 5) {
    2368           0 :                         zlog_info("%s ORF route refresh length error",
    2369             :                                   peer->host);
    2370           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
    2371             :                                         BGP_NOTIFY_SUBCODE_UNSPECIFIC);
    2372           0 :                         return BGP_Stop;
    2373             :                 }
    2374             : 
    2375           0 :                 when_to_refresh = stream_getc(s);
    2376           0 :                 end = stream_pnt(s) + (size - 5);
    2377             : 
    2378           0 :                 while ((stream_pnt(s) + 2) < end) {
    2379           0 :                         orf_type = stream_getc(s);
    2380           0 :                         orf_len = stream_getw(s);
    2381             : 
    2382             :                         /* orf_len in bounds? */
    2383           0 :                         if ((stream_pnt(s) + orf_len) > end)
    2384             :                                 break; /* XXX: Notify instead?? */
    2385           0 :                         if (orf_type == ORF_TYPE_PREFIX
    2386           0 :                             || orf_type == ORF_TYPE_PREFIX_OLD) {
    2387           0 :                                 uint8_t *p_pnt = stream_pnt(s);
    2388           0 :                                 uint8_t *p_end = stream_pnt(s) + orf_len;
    2389           0 :                                 struct orf_prefix orfp;
    2390           0 :                                 uint8_t common = 0;
    2391           0 :                                 uint32_t seq;
    2392           0 :                                 int psize;
    2393           0 :                                 char name[BUFSIZ];
    2394           0 :                                 int ret = CMD_SUCCESS;
    2395             : 
    2396           0 :                                 if (bgp_debug_neighbor_events(peer)) {
    2397           0 :                                         zlog_debug(
    2398             :                                                 "%pBP rcvd Prefixlist ORF(%d) length %d",
    2399             :                                                 peer, orf_type, orf_len);
    2400             :                                 }
    2401             : 
    2402             :                                 /* ORF prefix-list name */
    2403           0 :                                 snprintf(name, sizeof(name), "%s.%d.%d",
    2404             :                                          peer->host, afi, safi);
    2405             : 
    2406             :                                 /* we're going to read at least 1 byte of common
    2407             :                                  * ORF header,
    2408             :                                  * and 7 bytes of ORF Address-filter entry from
    2409             :                                  * the stream
    2410             :                                  */
    2411           0 :                                 if (*p_pnt & ORF_COMMON_PART_REMOVE_ALL) {
    2412           0 :                                         if (bgp_debug_neighbor_events(peer))
    2413           0 :                                                 zlog_debug(
    2414             :                                                         "%pBP rcvd Remove-All pfxlist ORF request",
    2415             :                                                         peer);
    2416           0 :                                         prefix_bgp_orf_remove_all(afi, name);
    2417           0 :                                         break;
    2418             :                                 }
    2419             : 
    2420           0 :                                 if (orf_len < 7)
    2421             :                                         break;
    2422             : 
    2423           0 :                                 while (p_pnt < p_end) {
    2424             :                                         /* If the ORF entry is malformed, want
    2425             :                                          * to read as much of it
    2426             :                                          * as possible without going beyond the
    2427             :                                          * bounds of the entry,
    2428             :                                          * to maximise debug information.
    2429             :                                          */
    2430           0 :                                         int ok;
    2431           0 :                                         memset(&orfp, 0, sizeof(orfp));
    2432           0 :                                         common = *p_pnt++;
    2433             :                                         /* after ++: p_pnt <= p_end */
    2434           0 :                                         ok = ((uint32_t)(p_end - p_pnt)
    2435           0 :                                               >= sizeof(uint32_t));
    2436           0 :                                         if (ok) {
    2437           0 :                                                 memcpy(&seq, p_pnt,
    2438             :                                                        sizeof(uint32_t));
    2439           0 :                                                 p_pnt += sizeof(uint32_t);
    2440           0 :                                                 orfp.seq = ntohl(seq);
    2441             :                                         } else
    2442             :                                                 p_pnt = p_end;
    2443             : 
    2444             :                                         /* val checked in prefix_bgp_orf_set */
    2445           0 :                                         if (p_pnt < p_end)
    2446           0 :                                                 orfp.ge = *p_pnt++;
    2447             : 
    2448             :                                         /* val checked in prefix_bgp_orf_set */
    2449           0 :                                         if (p_pnt < p_end)
    2450           0 :                                                 orfp.le = *p_pnt++;
    2451             : 
    2452           0 :                                         if ((ok = (p_pnt < p_end)))
    2453           0 :                                                 orfp.p.prefixlen = *p_pnt++;
    2454             : 
    2455             :                                         /* afi checked already */
    2456           0 :                                         orfp.p.family = afi2family(afi);
    2457             : 
    2458             :                                         /* 0 if not ok */
    2459           0 :                                         psize = PSIZE(orfp.p.prefixlen);
    2460             :                                         /* valid for family ? */
    2461           0 :                                         if (psize > prefix_blen(&orfp.p)) {
    2462           0 :                                                 ok = 0;
    2463           0 :                                                 psize = prefix_blen(&orfp.p);
    2464             :                                         }
    2465             :                                         /* valid for packet ? */
    2466           0 :                                         if (psize > (p_end - p_pnt)) {
    2467           0 :                                                 ok = 0;
    2468           0 :                                                 psize = p_end - p_pnt;
    2469             :                                         }
    2470             : 
    2471           0 :                                         if (psize > 0)
    2472           0 :                                                 memcpy(&orfp.p.u.prefix, p_pnt,
    2473             :                                                        psize);
    2474           0 :                                         p_pnt += psize;
    2475             : 
    2476           0 :                                         if (bgp_debug_neighbor_events(peer)) {
    2477           0 :                                                 char buf[INET6_BUFSIZ];
    2478             : 
    2479           0 :                                                 zlog_debug(
    2480             :                                                         "%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s",
    2481             :                                                         peer,
    2482             :                                                         (common & ORF_COMMON_PART_REMOVE
    2483             :                                                                  ? "Remove"
    2484             :                                                                  : "Add"),
    2485             :                                                         (common & ORF_COMMON_PART_DENY
    2486             :                                                                  ? "deny"
    2487             :                                                                  : "permit"),
    2488             :                                                         orfp.seq,
    2489             :                                                         inet_ntop(
    2490             :                                                                 orfp.p.family,
    2491             :                                                                 &orfp.p.u.prefix,
    2492             :                                                                 buf,
    2493             :                                                                 INET6_BUFSIZ),
    2494             :                                                         orfp.p.prefixlen,
    2495             :                                                         orfp.ge, orfp.le,
    2496             :                                                         ok ? "" : " MALFORMED");
    2497             :                                         }
    2498             : 
    2499           0 :                                         if (ok)
    2500           0 :                                                 ret = prefix_bgp_orf_set(
    2501             :                                                         name, afi, &orfp,
    2502             :                                                         (common & ORF_COMMON_PART_DENY
    2503             :                                                                  ? 0
    2504             :                                                                  : 1),
    2505             :                                                         (common & ORF_COMMON_PART_REMOVE
    2506           0 :                                                                  ? 0
    2507             :                                                                  : 1));
    2508             : 
    2509           0 :                                         if (!ok || (ok && ret != CMD_SUCCESS)) {
    2510           0 :                                                 zlog_info(
    2511             :                                                         "%pBP Received misformatted prefixlist ORF. Remove All pfxlist",
    2512             :                                                         peer);
    2513           0 :                                                 prefix_bgp_orf_remove_all(afi,
    2514             :                                                                           name);
    2515           0 :                                                 break;
    2516             :                                         }
    2517             :                                 }
    2518             : 
    2519           0 :                                 peer->orf_plist[afi][safi] =
    2520           0 :                                         prefix_bgp_orf_lookup(afi, name);
    2521             :                         }
    2522           0 :                         stream_forward_getp(s, orf_len);
    2523             :                 }
    2524           0 :                 if (bgp_debug_neighbor_events(peer))
    2525           0 :                         zlog_debug("%pBP rcvd Refresh %s ORF request", peer,
    2526             :                                    when_to_refresh == REFRESH_DEFER
    2527             :                                            ? "Defer"
    2528             :                                            : "Immediate");
    2529           0 :                 if (when_to_refresh == REFRESH_DEFER)
    2530             :                         return BGP_PACKET_NOOP;
    2531             :         }
    2532             : 
    2533             :         /* First update is deferred until ORF or ROUTE-REFRESH is received */
    2534           0 :         if (CHECK_FLAG(peer->af_sflags[afi][safi],
    2535             :                        PEER_STATUS_ORF_WAIT_REFRESH))
    2536           0 :                 UNSET_FLAG(peer->af_sflags[afi][safi],
    2537             :                            PEER_STATUS_ORF_WAIT_REFRESH);
    2538             : 
    2539           0 :         paf = peer_af_find(peer, afi, safi);
    2540           0 :         if (paf && paf->subgroup) {
    2541           0 :                 if (peer->orf_plist[afi][safi]) {
    2542           0 :                         updgrp = PAF_UPDGRP(paf);
    2543           0 :                         updgrp_peer = UPDGRP_PEER(updgrp);
    2544           0 :                         updgrp_peer->orf_plist[afi][safi] =
    2545             :                                 peer->orf_plist[afi][safi];
    2546             :                 }
    2547             : 
    2548             :                 /* Avoid supressing duplicate routes later
    2549             :                  * when processing in subgroup_announce_table().
    2550             :                  */
    2551           0 :                 force_update = true;
    2552             : 
    2553             :                 /* If the peer is configured for default-originate clear the
    2554             :                  * SUBGRP_STATUS_DEFAULT_ORIGINATE flag so that we will
    2555             :                  * re-advertise the
    2556             :                  * default
    2557             :                  */
    2558           0 :                 if (CHECK_FLAG(paf->subgroup->sflags,
    2559             :                                SUBGRP_STATUS_DEFAULT_ORIGINATE))
    2560           0 :                         UNSET_FLAG(paf->subgroup->sflags,
    2561             :                                    SUBGRP_STATUS_DEFAULT_ORIGINATE);
    2562             :         }
    2563             : 
    2564           0 :         if (subtype == BGP_ROUTE_REFRESH_BORR) {
    2565             :                 /* A BGP speaker that has received the Graceful Restart
    2566             :                  * Capability from its neighbor MUST ignore any BoRRs for
    2567             :                  * an <AFI, SAFI> from the neighbor before the speaker
    2568             :                  * receives the EoR for the given <AFI, SAFI> from the
    2569             :                  * neighbor.
    2570             :                  */
    2571           0 :                 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)
    2572           0 :                     && !CHECK_FLAG(peer->af_sflags[afi][safi],
    2573             :                                    PEER_STATUS_EOR_RECEIVED)) {
    2574           0 :                         if (bgp_debug_neighbor_events(peer))
    2575           0 :                                 zlog_debug(
    2576             :                                         "%pBP rcvd route-refresh (BoRR) for %s/%s before EoR",
    2577             :                                         peer, afi2str(afi), safi2str(safi));
    2578           0 :                         return BGP_PACKET_NOOP;
    2579             :                 }
    2580             : 
    2581           0 :                 if (peer->t_refresh_stalepath) {
    2582           0 :                         if (bgp_debug_neighbor_events(peer))
    2583           0 :                                 zlog_debug(
    2584             :                                         "%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received",
    2585             :                                         peer, afi2str(afi), safi2str(safi));
    2586           0 :                         return BGP_PACKET_NOOP;
    2587             :                 }
    2588             : 
    2589           0 :                 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_RECEIVED);
    2590           0 :                 UNSET_FLAG(peer->af_sflags[afi][safi],
    2591             :                            PEER_STATUS_EORR_RECEIVED);
    2592             : 
    2593             :                 /* When a BGP speaker receives a BoRR message from
    2594             :                  * a peer, it MUST mark all the routes with the given
    2595             :                  * Address Family Identifier and Subsequent Address
    2596             :                  * Family Identifier, <AFI, SAFI> [RFC2918], from
    2597             :                  * that peer as stale.
    2598             :                  */
    2599           0 :                 if (peer_active_nego(peer)) {
    2600           0 :                         SET_FLAG(peer->af_sflags[afi][safi],
    2601             :                                  PEER_STATUS_ENHANCED_REFRESH);
    2602           0 :                         bgp_set_stale_route(peer, afi, safi);
    2603             :                 }
    2604             : 
    2605           0 :                 if (peer_established(peer))
    2606           0 :                         thread_add_timer(bm->master,
    2607             :                                          bgp_refresh_stalepath_timer_expire,
    2608             :                                          paf, peer->bgp->stalepath_time,
    2609             :                                          &peer->t_refresh_stalepath);
    2610             : 
    2611           0 :                 if (bgp_debug_neighbor_events(peer))
    2612           0 :                         zlog_debug(
    2613             :                                 "%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds",
    2614             :                                 peer, afi2str(afi), safi2str(safi),
    2615             :                                 peer->bgp->stalepath_time);
    2616           0 :         } else if (subtype == BGP_ROUTE_REFRESH_EORR) {
    2617           0 :                 if (!peer->t_refresh_stalepath) {
    2618           0 :                         zlog_err(
    2619             :                                 "%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received",
    2620             :                                 peer, afi2str(afi), safi2str(safi));
    2621           0 :                         return BGP_PACKET_NOOP;
    2622             :                 }
    2623             : 
    2624           0 :                 THREAD_OFF(peer->t_refresh_stalepath);
    2625             : 
    2626           0 :                 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_RECEIVED);
    2627           0 :                 UNSET_FLAG(peer->af_sflags[afi][safi],
    2628             :                            PEER_STATUS_BORR_RECEIVED);
    2629             : 
    2630           0 :                 if (bgp_debug_neighbor_events(peer))
    2631           0 :                         zlog_debug(
    2632             :                                 "%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer",
    2633             :                                 peer, afi2str(afi), safi2str(safi));
    2634             : 
    2635           0 :                 if (peer->nsf[afi][safi])
    2636           0 :                         bgp_clear_stale_route(peer, afi, safi);
    2637             :         } else {
    2638           0 :                 if (bgp_debug_neighbor_events(peer))
    2639           0 :                         zlog_debug(
    2640             :                                 "%pBP rcvd route-refresh (REQUEST) for %s/%s",
    2641             :                                 peer, afi2str(afi), safi2str(safi));
    2642             : 
    2643             :                 /* In response to a "normal route refresh request" from the
    2644             :                  * peer, the speaker MUST send a BoRR message.
    2645             :                  */
    2646           0 :                 if (CHECK_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV)) {
    2647             :                         /* For a BGP speaker that supports the BGP Graceful
    2648             :                          * Restart, it MUST NOT send a BoRR for an <AFI, SAFI>
    2649             :                          * to a neighbor before it sends the EoR for the
    2650             :                          * <AFI, SAFI> to the neighbor.
    2651             :                          */
    2652           0 :                         if (!CHECK_FLAG(peer->af_sflags[afi][safi],
    2653             :                                         PEER_STATUS_EOR_SEND)) {
    2654           0 :                                 if (bgp_debug_neighbor_events(peer))
    2655           0 :                                         zlog_debug(
    2656             :                                                 "%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR",
    2657             :                                                 peer, afi2str(afi),
    2658             :                                                 safi2str(safi));
    2659             :                                 /* Can't send BoRR now, postpone after EoR */
    2660           0 :                                 SET_FLAG(peer->af_sflags[afi][safi],
    2661             :                                          PEER_STATUS_REFRESH_PENDING);
    2662           0 :                                 return BGP_PACKET_NOOP;
    2663             :                         }
    2664             : 
    2665           0 :                         bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
    2666             :                                                BGP_ROUTE_REFRESH_BORR);
    2667             : 
    2668           0 :                         if (bgp_debug_neighbor_events(peer))
    2669           0 :                                 zlog_debug(
    2670             :                                         "%pBP sending route-refresh (BoRR) for %s/%s",
    2671             :                                         peer, afi2str(afi), safi2str(safi));
    2672             : 
    2673             :                         /* Set flag Ready-To-Send to know when we can send EoRR
    2674             :                          * message.
    2675             :                          */
    2676           0 :                         SET_FLAG(peer->af_sflags[afi][safi],
    2677             :                                  PEER_STATUS_BORR_SEND);
    2678           0 :                         UNSET_FLAG(peer->af_sflags[afi][safi],
    2679             :                                    PEER_STATUS_EORR_SEND);
    2680             :                 }
    2681             :         }
    2682             : 
    2683             :         /* Perform route refreshment to the peer */
    2684           0 :         bgp_announce_route(peer, afi, safi, force_update);
    2685             : 
    2686             :         /* No FSM action necessary */
    2687           0 :         return BGP_PACKET_NOOP;
    2688             : }
    2689             : 
    2690             : /**
    2691             :  * Parse BGP CAPABILITY message for peer.
    2692             :  *
    2693             :  * @param peer
    2694             :  * @param size size of the packet
    2695             :  * @return as in summary
    2696             :  */
    2697           0 : static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
    2698             :                                     bgp_size_t length)
    2699             : {
    2700           0 :         uint8_t *end;
    2701           0 :         struct capability_mp_data mpc;
    2702           0 :         struct capability_header *hdr;
    2703           0 :         uint8_t action;
    2704           0 :         iana_afi_t pkt_afi;
    2705           0 :         afi_t afi;
    2706           0 :         iana_safi_t pkt_safi;
    2707           0 :         safi_t safi;
    2708             : 
    2709           0 :         end = pnt + length;
    2710             : 
    2711           0 :         while (pnt < end) {
    2712             :                 /* We need at least action, capability code and capability
    2713             :                  * length. */
    2714           0 :                 if (pnt + 3 > end) {
    2715           0 :                         zlog_info("%s Capability length error", peer->host);
    2716           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
    2717             :                                         BGP_NOTIFY_SUBCODE_UNSPECIFIC);
    2718           0 :                         return BGP_Stop;
    2719             :                 }
    2720           0 :                 action = *pnt;
    2721           0 :                 hdr = (struct capability_header *)(pnt + 1);
    2722             : 
    2723             :                 /* Action value check.  */
    2724           0 :                 if (action != CAPABILITY_ACTION_SET
    2725             :                     && action != CAPABILITY_ACTION_UNSET) {
    2726           0 :                         zlog_info("%s Capability Action Value error %d",
    2727             :                                   peer->host, action);
    2728           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
    2729             :                                         BGP_NOTIFY_SUBCODE_UNSPECIFIC);
    2730           0 :                         return BGP_Stop;
    2731             :                 }
    2732             : 
    2733           0 :                 if (bgp_debug_neighbor_events(peer))
    2734           0 :                         zlog_debug(
    2735             :                                 "%s CAPABILITY has action: %d, code: %u, length %u",
    2736             :                                 peer->host, action, hdr->code, hdr->length);
    2737             : 
    2738           0 :                 if (hdr->length < sizeof(struct capability_mp_data)) {
    2739           0 :                         zlog_info(
    2740             :                                 "%pBP Capability structure is not properly filled out, expected at least %zu bytes but header length specified is %d",
    2741             :                                 peer, sizeof(struct capability_mp_data),
    2742             :                                 hdr->length);
    2743           0 :                         return BGP_Stop;
    2744             :                 }
    2745             : 
    2746             :                 /* Capability length check. */
    2747           0 :                 if ((pnt + hdr->length + 3) > end) {
    2748           0 :                         zlog_info("%s Capability length error", peer->host);
    2749           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
    2750             :                                         BGP_NOTIFY_SUBCODE_UNSPECIFIC);
    2751           0 :                         return BGP_Stop;
    2752             :                 }
    2753             : 
    2754             :                 /* Fetch structure to the byte stream. */
    2755           0 :                 memcpy(&mpc, pnt + 3, sizeof(struct capability_mp_data));
    2756           0 :                 pnt += hdr->length + 3;
    2757             : 
    2758             :                 /* We know MP Capability Code. */
    2759           0 :                 if (hdr->code == CAPABILITY_CODE_MP) {
    2760           0 :                         pkt_afi = ntohs(mpc.afi);
    2761           0 :                         pkt_safi = mpc.safi;
    2762             : 
    2763             :                         /* Ignore capability when override-capability is set. */
    2764           0 :                         if (CHECK_FLAG(peer->flags,
    2765             :                                        PEER_FLAG_OVERRIDE_CAPABILITY))
    2766           0 :                                 continue;
    2767             : 
    2768             :                         /* Convert AFI, SAFI to internal values. */
    2769           0 :                         if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi,
    2770             :                                                       &safi)) {
    2771           0 :                                 if (bgp_debug_neighbor_events(peer))
    2772           0 :                                         zlog_debug(
    2773             :                                                 "%s Dynamic Capability MP_EXT afi/safi invalid (%s/%s)",
    2774             :                                                 peer->host,
    2775             :                                                 iana_afi2str(pkt_afi),
    2776             :                                                 iana_safi2str(pkt_safi));
    2777           0 :                                 continue;
    2778             :                         }
    2779             : 
    2780             :                         /* Address family check.  */
    2781           0 :                         if (bgp_debug_neighbor_events(peer))
    2782           0 :                                 zlog_debug(
    2783             :                                         "%s CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s",
    2784             :                                         peer->host,
    2785             :                                         action == CAPABILITY_ACTION_SET
    2786             :                                                 ? "Advertising"
    2787             :                                                 : "Removing",
    2788             :                                         iana_afi2str(pkt_afi),
    2789             :                                         iana_safi2str(pkt_safi));
    2790             : 
    2791           0 :                         if (action == CAPABILITY_ACTION_SET) {
    2792           0 :                                 peer->afc_recv[afi][safi] = 1;
    2793           0 :                                 if (peer->afc[afi][safi]) {
    2794           0 :                                         peer->afc_nego[afi][safi] = 1;
    2795           0 :                                         bgp_announce_route(peer, afi, safi,
    2796             :                                                            false);
    2797             :                                 }
    2798             :                         } else {
    2799           0 :                                 peer->afc_recv[afi][safi] = 0;
    2800           0 :                                 peer->afc_nego[afi][safi] = 0;
    2801             : 
    2802           0 :                                 if (peer_active_nego(peer))
    2803           0 :                                         bgp_clear_route(peer, afi, safi);
    2804             :                                 else
    2805             :                                         return BGP_Stop;
    2806             :                         }
    2807             :                 } else {
    2808           0 :                         flog_warn(
    2809             :                                 EC_BGP_UNRECOGNIZED_CAPABILITY,
    2810             :                                 "%s unrecognized capability code: %d - ignored",
    2811             :                                 peer->host, hdr->code);
    2812             :                 }
    2813             :         }
    2814             : 
    2815             :         /* No FSM action necessary */
    2816             :         return BGP_PACKET_NOOP;
    2817             : }
    2818             : 
    2819             : /**
    2820             :  * Parse BGP CAPABILITY message for peer.
    2821             :  *
    2822             :  * Exported for unit testing.
    2823             :  *
    2824             :  * @param peer
    2825             :  * @param size size of the packet
    2826             :  * @return as in summary
    2827             :  */
    2828           0 : int bgp_capability_receive(struct peer *peer, bgp_size_t size)
    2829             : {
    2830           0 :         uint8_t *pnt;
    2831             : 
    2832             :         /* Fetch pointer. */
    2833           0 :         pnt = stream_pnt(peer->curr);
    2834             : 
    2835           0 :         if (bgp_debug_neighbor_events(peer))
    2836           0 :                 zlog_debug("%s rcv CAPABILITY", peer->host);
    2837             : 
    2838             :         /* If peer does not have the capability, send notification. */
    2839           0 :         if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) {
    2840           0 :                 flog_err(EC_BGP_NO_CAP,
    2841             :                          "%s [Error] BGP dynamic capability is not enabled",
    2842             :                          peer->host);
    2843           0 :                 bgp_notify_send(peer, BGP_NOTIFY_HEADER_ERR,
    2844             :                                 BGP_NOTIFY_HEADER_BAD_MESTYPE);
    2845           0 :                 return BGP_Stop;
    2846             :         }
    2847             : 
    2848             :         /* Status must be Established. */
    2849           0 :         if (!peer_established(peer)) {
    2850           0 :                 flog_err(
    2851             :                         EC_BGP_NO_CAP,
    2852             :                         "%s [Error] Dynamic capability packet received under status %s",
    2853             :                         peer->host,
    2854             :                         lookup_msg(bgp_status_msg, peer->status, NULL));
    2855           0 :                 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
    2856           0 :                                 bgp_fsm_error_subcode(peer->status));
    2857           0 :                 return BGP_Stop;
    2858             :         }
    2859             : 
    2860             :         /* Parse packet. */
    2861           0 :         return bgp_capability_msg_parse(peer, pnt, size);
    2862             : }
    2863             : 
    2864             : /**
    2865             :  * Processes a peer's input buffer.
    2866             :  *
    2867             :  * This function sidesteps the event loop and directly calls bgp_event_update()
    2868             :  * after processing each BGP message. This is necessary to ensure proper
    2869             :  * ordering of FSM events and unifies the behavior that was present previously,
    2870             :  * whereby some of the packet handling functions would update the FSM and some
    2871             :  * would not, making event flow difficult to understand. Please think twice
    2872             :  * before hacking this.
    2873             :  *
    2874             :  * Thread type: THREAD_EVENT
    2875             :  * @param thread
    2876             :  * @return 0
    2877             :  */
    2878           8 : void bgp_process_packet(struct thread *thread)
    2879             : {
    2880             :         /* Yes first of all get peer pointer. */
    2881           8 :         struct peer *peer;      // peer
    2882           8 :         uint32_t rpkt_quanta_old; // how many packets to read
    2883           8 :         int fsm_update_result;    // return code of bgp_event_update()
    2884           8 :         int mprc;                 // message processing return code
    2885             : 
    2886           8 :         peer = THREAD_ARG(thread);
    2887           8 :         rpkt_quanta_old = atomic_load_explicit(&peer->bgp->rpkt_quanta,
    2888             :                                                memory_order_relaxed);
    2889           8 :         fsm_update_result = 0;
    2890             : 
    2891             :         /* Guard against scheduled events that occur after peer deletion. */
    2892           8 :         if (peer->status == Deleted || peer->status == Clearing)
    2893             :                 return;
    2894             : 
    2895             :         unsigned int processed = 0;
    2896             : 
    2897          16 :         while (processed < rpkt_quanta_old) {
    2898          16 :                 uint8_t type = 0;
    2899          16 :                 bgp_size_t size;
    2900          16 :                 char notify_data_length[2];
    2901             : 
    2902          16 :                 frr_with_mutex (&peer->io_mtx) {
    2903          16 :                         peer->curr = stream_fifo_pop(peer->ibuf);
    2904             :                 }
    2905             : 
    2906          16 :                 if (peer->curr == NULL) // no packets to process, hmm...
    2907           7 :                         return;
    2908             : 
    2909             :                 /* skip the marker and copy the packet length */
    2910           9 :                 stream_forward_getp(peer->curr, BGP_MARKER_SIZE);
    2911           9 :                 memcpy(notify_data_length, stream_pnt(peer->curr), 2);
    2912             : 
    2913             :                 /* read in the packet length and type */
    2914           9 :                 size = stream_getw(peer->curr);
    2915           9 :                 type = stream_getc(peer->curr);
    2916             : 
    2917           9 :                 hook_call(bgp_packet_dump, peer, type, size, peer->curr);
    2918             : 
    2919             :                 /* adjust size to exclude the marker + length + type */
    2920           9 :                 size -= BGP_HEADER_SIZE;
    2921             : 
    2922             :                 /* Read rest of the packet and call each sort of packet routine
    2923             :                  */
    2924           9 :                 switch (type) {
    2925           2 :                 case BGP_MSG_OPEN:
    2926           2 :                         frrtrace(2, frr_bgp, open_process, peer, size);
    2927           2 :                         atomic_fetch_add_explicit(&peer->open_in, 1,
    2928             :                                                   memory_order_relaxed);
    2929           2 :                         mprc = bgp_open_receive(peer, size);
    2930           2 :                         if (mprc == BGP_Stop)
    2931           0 :                                 flog_err(
    2932             :                                         EC_BGP_PKT_OPEN,
    2933             :                                         "%s: BGP OPEN receipt failed for peer: %s",
    2934             :                                         __func__, peer->host);
    2935             :                         break;
    2936           4 :                 case BGP_MSG_UPDATE:
    2937           4 :                         frrtrace(2, frr_bgp, update_process, peer, size);
    2938           4 :                         atomic_fetch_add_explicit(&peer->update_in, 1,
    2939             :                                                   memory_order_relaxed);
    2940           4 :                         peer->readtime = monotime(NULL);
    2941           4 :                         mprc = bgp_update_receive(peer, size);
    2942           4 :                         if (mprc == BGP_Stop)
    2943           0 :                                 flog_err(
    2944             :                                         EC_BGP_UPDATE_RCV,
    2945             :                                         "%s: BGP UPDATE receipt failed for peer: %s",
    2946             :                                         __func__, peer->host);
    2947             :                         break;
    2948           1 :                 case BGP_MSG_NOTIFY:
    2949           1 :                         frrtrace(2, frr_bgp, notification_process, peer, size);
    2950           1 :                         atomic_fetch_add_explicit(&peer->notify_in, 1,
    2951             :                                                   memory_order_relaxed);
    2952           1 :                         mprc = bgp_notify_receive(peer, size);
    2953           1 :                         if (mprc == BGP_Stop)
    2954           0 :                                 flog_err(
    2955             :                                         EC_BGP_NOTIFY_RCV,
    2956             :                                         "%s: BGP NOTIFY receipt failed for peer: %s",
    2957             :                                         __func__, peer->host);
    2958             :                         break;
    2959           2 :                 case BGP_MSG_KEEPALIVE:
    2960           2 :                         frrtrace(2, frr_bgp, keepalive_process, peer, size);
    2961           2 :                         peer->readtime = monotime(NULL);
    2962           2 :                         atomic_fetch_add_explicit(&peer->keepalive_in, 1,
    2963             :                                                   memory_order_relaxed);
    2964           2 :                         mprc = bgp_keepalive_receive(peer, size);
    2965           2 :                         if (mprc == BGP_Stop)
    2966           0 :                                 flog_err(
    2967             :                                         EC_BGP_KEEP_RCV,
    2968             :                                         "%s: BGP KEEPALIVE receipt failed for peer: %s",
    2969             :                                         __func__, peer->host);
    2970             :                         break;
    2971           0 :                 case BGP_MSG_ROUTE_REFRESH_NEW:
    2972             :                 case BGP_MSG_ROUTE_REFRESH_OLD:
    2973           0 :                         frrtrace(2, frr_bgp, refresh_process, peer, size);
    2974           0 :                         atomic_fetch_add_explicit(&peer->refresh_in, 1,
    2975             :                                                   memory_order_relaxed);
    2976           0 :                         mprc = bgp_route_refresh_receive(peer, size);
    2977           0 :                         if (mprc == BGP_Stop)
    2978           0 :                                 flog_err(
    2979             :                                         EC_BGP_RFSH_RCV,
    2980             :                                         "%s: BGP ROUTEREFRESH receipt failed for peer: %s",
    2981             :                                         __func__, peer->host);
    2982             :                         break;
    2983           0 :                 case BGP_MSG_CAPABILITY:
    2984           0 :                         frrtrace(2, frr_bgp, capability_process, peer, size);
    2985           0 :                         atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1,
    2986             :                                                   memory_order_relaxed);
    2987           0 :                         mprc = bgp_capability_receive(peer, size);
    2988           0 :                         if (mprc == BGP_Stop)
    2989           0 :                                 flog_err(
    2990             :                                         EC_BGP_CAP_RCV,
    2991             :                                         "%s: BGP CAPABILITY receipt failed for peer: %s",
    2992             :                                         __func__, peer->host);
    2993             :                         break;
    2994           0 :                 default:
    2995             :                         /* Suppress uninitialized variable warning */
    2996           0 :                         mprc = 0;
    2997           0 :                         (void)mprc;
    2998             :                         /*
    2999             :                          * The message type should have been sanitized before
    3000             :                          * we ever got here. Receipt of a message with an
    3001             :                          * invalid header at this point is indicative of a
    3002             :                          * security issue.
    3003             :                          */
    3004           0 :                         assert (!"Message of invalid type received during input processing");
    3005             :                 }
    3006             : 
    3007             :                 /* delete processed packet */
    3008           9 :                 stream_free(peer->curr);
    3009           9 :                 peer->curr = NULL;
    3010           9 :                 processed++;
    3011             : 
    3012             :                 /* Update FSM */
    3013           9 :                 if (mprc != BGP_PACKET_NOOP)
    3014           9 :                         fsm_update_result = bgp_event_update(peer, mprc);
    3015             :                 else
    3016           0 :                         continue;
    3017             : 
    3018             :                 /*
    3019             :                  * If peer was deleted, do not process any more packets. This
    3020             :                  * is usually due to executing BGP_Stop or a stub deletion.
    3021             :                  */
    3022           9 :                 if (fsm_update_result == FSM_PEER_TRANSFERRED
    3023           9 :                     || fsm_update_result == FSM_PEER_STOPPED)
    3024             :                         break;
    3025             :         }
    3026             : 
    3027           1 :         if (fsm_update_result != FSM_PEER_TRANSFERRED
    3028           1 :             && fsm_update_result != FSM_PEER_STOPPED) {
    3029           0 :                 frr_with_mutex (&peer->io_mtx) {
    3030             :                         // more work to do, come back later
    3031           0 :                         if (peer->ibuf->count > 0)
    3032           0 :                                 thread_add_event(
    3033             :                                         bm->master, bgp_process_packet, peer, 0,
    3034             :                                         &peer->t_process_packet);
    3035             :                 }
    3036             :         }
    3037             : }
    3038             : 
    3039             : /* Send EOR when routes are processed by selection deferral timer */
    3040           1 : void bgp_send_delayed_eor(struct bgp *bgp)
    3041             : {
    3042           1 :         struct peer *peer;
    3043           1 :         struct listnode *node, *nnode;
    3044             : 
    3045             :         /* EOR message sent in bgp_write_proceed_actions */
    3046           3 :         for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
    3047           1 :                 bgp_write_proceed_actions(peer);
    3048           1 : }
    3049             : 
    3050             : /*
    3051             :  * Task callback to handle socket error encountered in the io pthread. We avoid
    3052             :  * having the io pthread try to enqueue fsm events or mess with the peer
    3053             :  * struct.
    3054             :  */
    3055           0 : void bgp_packet_process_error(struct thread *thread)
    3056             : {
    3057           0 :         struct peer *peer;
    3058           0 :         int code;
    3059             : 
    3060           0 :         peer = THREAD_ARG(thread);
    3061           0 :         code = THREAD_VAL(thread);
    3062             : 
    3063           0 :         if (bgp_debug_neighbor_events(peer))
    3064           0 :                 zlog_debug("%s [Event] BGP error %d on fd %d",
    3065             :                            peer->host, code, peer->fd);
    3066             : 
    3067             :         /* Closed connection or error on the socket */
    3068           0 :         if (peer_established(peer)) {
    3069           0 :                 if ((CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
    3070           0 :                      || CHECK_FLAG(peer->flags,
    3071             :                                    PEER_FLAG_GRACEFUL_RESTART_HELPER))
    3072           0 :                     && CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)) {
    3073           0 :                         peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
    3074           0 :                         SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
    3075             :                 } else
    3076           0 :                         peer->last_reset = PEER_DOWN_CLOSE_SESSION;
    3077             :         }
    3078             : 
    3079           0 :         bgp_event_update(peer, code);
    3080           0 : }

Generated by: LCOV version v1.16-topotato