back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_updgrp.h (source / functions) Hit Total Coverage
Test: test_bgp_aspath_zero.py::BGPAggregatorZero Lines: 24 46 52.2 %
Date: 2023-02-24 18:36:48 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /**
       2             :  * bgp_updgrp.c: BGP update group structures
       3             :  *
       4             :  * @copyright Copyright (C) 2014 Cumulus Networks, Inc.
       5             :  *
       6             :  * @author Avneesh Sachdev <avneesh@sproute.net>
       7             :  * @author Rajesh Varadarajan <rajesh@sproute.net>
       8             :  * @author Pradosh Mohapatra <pradosh@sproute.net>
       9             :  *
      10             :  * This file is part of GNU Zebra.
      11             :  *
      12             :  * GNU Zebra is free software; you can redistribute it and/or modify it
      13             :  * under the terms of the GNU General Public License as published by the
      14             :  * Free Software Foundation; either version 2, or (at your option) any
      15             :  * later version.
      16             :  *
      17             :  * GNU Zebra is distributed in the hope that it will be useful, but
      18             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      20             :  * General Public License for more details.
      21             :  *
      22             :  * You should have received a copy of the GNU General Public License along
      23             :  * with this program; see the file COPYING; if not, write to the Free Software
      24             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      25             :  */
      26             : 
      27             : #ifndef _QUAGGA_BGP_UPDGRP_H
      28             : #define _QUAGGA_BGP_UPDGRP_H
      29             : 
      30             : #include "bgp_advertise.h"
      31             : 
      32             : /*
      33             :  * The following three heuristic constants determine how long advertisement to
      34             :  * a subgroup will be delayed after it is created. The intent is to allow
      35             :  * transient changes in peer state (primarily session establishment) to settle,
      36             :  * so that more peers can be grouped together and benefit from sharing
      37             :  * advertisement computations with the subgroup.
      38             :  *
      39             :  * These values have a very large impact on initial convergence time; any
      40             :  * changes should be accompanied by careful performance testing at all scales.
      41             :  *
      42             :  * The coalesce time 'C' for a new subgroup within a particular BGP instance
      43             :  * 'B' with total number of known peers 'P', established or not, is computed as
      44             :  * follows:
      45             :  *
      46             :  * C = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME,
      47             :  *         BGP_DEFAULT_SUBGROUP_COALESCE_TIME +
      48             :  *         (P*BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME))
      49             :  */
      50             : #define BGP_DEFAULT_SUBGROUP_COALESCE_TIME 1000
      51             : #define BGP_MAX_SUBGROUP_COALESCE_TIME 10000
      52             : #define BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME 50
      53             : 
      54             : #define PEER_UPDGRP_FLAGS                                                      \
      55             :         (PEER_FLAG_LOCAL_AS_NO_PREPEND | PEER_FLAG_LOCAL_AS_REPLACE_AS)
      56             : 
      57             : #define PEER_UPDGRP_AF_FLAGS                                                   \
      58             :         (PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY               \
      59             :          | PEER_FLAG_SEND_LARGE_COMMUNITY                                      \
      60             :          | PEER_FLAG_DEFAULT_ORIGINATE | PEER_FLAG_REFLECTOR_CLIENT            \
      61             :          | PEER_FLAG_RSERVER_CLIENT | PEER_FLAG_NEXTHOP_SELF                   \
      62             :          | PEER_FLAG_NEXTHOP_UNCHANGED | PEER_FLAG_FORCE_NEXTHOP_SELF          \
      63             :          | PEER_FLAG_AS_PATH_UNCHANGED | PEER_FLAG_MED_UNCHANGED               \
      64             :          | PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | PEER_FLAG_REMOVE_PRIVATE_AS     \
      65             :          | PEER_FLAG_REMOVE_PRIVATE_AS_ALL                                     \
      66             :          | PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE                                 \
      67             :          | PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE                             \
      68             :          | PEER_FLAG_AS_OVERRIDE)
      69             : 
      70             : #define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
      71             : 
      72             : #define PEER_UPDGRP_AF_CAP_FLAGS                                               \
      73             :         (PEER_CAP_ORF_PREFIX_SM_RCV | PEER_CAP_ORF_PREFIX_SM_OLD_RCV           \
      74             :          | PEER_CAP_ADDPATH_AF_TX_ADV | PEER_CAP_ADDPATH_AF_RX_RCV             \
      75             :          | PEER_CAP_ENHE_AF_NEGO)
      76             : 
      77             : enum bpacket_attr_vec_type { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX };
      78             : 
      79             : typedef struct {
      80             :         uint32_t flags;
      81             :         unsigned long offset;
      82             : } bpacket_attr_vec;
      83             : 
      84             : #define BPKT_ATTRVEC_FLAGS_UPDATED        (1 << 0)
      85             : #define BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS   (1 << 1)
      86             : #define BPKT_ATTRVEC_FLAGS_REFLECTED (1 << 2)
      87             : #define BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED   (1 << 3)
      88             : #define BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED   (1 << 4)
      89             : #define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED  (1 << 5)
      90             : #define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_LNH_CHANGED  (1 << 6)
      91             : #define BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED  (1 << 7)
      92             : #define BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED (1 << 8)
      93             : 
      94             : typedef struct bpacket_attr_vec_arr {
      95             :         bpacket_attr_vec entries[BGP_ATTR_VEC_MAX];
      96             : } bpacket_attr_vec_arr;
      97             : 
      98             : struct bpacket {
      99             :         /* for being part of an update subgroup's message list */
     100             :         TAILQ_ENTRY(bpacket) pkt_train;
     101             : 
     102             :         /* list of peers (well, peer_afs) that the packet needs to be sent to */
     103             :         LIST_HEAD(pkt_peer_list, peer_af) peers;
     104             : 
     105             :         struct stream *buffer;
     106             :         bpacket_attr_vec_arr arr;
     107             : 
     108             :         unsigned int ver;
     109             : };
     110             : 
     111             : struct bpacket_queue {
     112             :         TAILQ_HEAD(pkt_queue, bpacket) pkts;
     113             : 
     114             :         unsigned int conf_max_count;
     115             :         unsigned int curr_count;
     116             :         unsigned int hwm_count;
     117             :         unsigned int max_count_reached_count;
     118             : };
     119             : 
     120             : struct update_group {
     121             :         /* back pointer to the BGP instance */
     122             :         struct bgp *bgp;
     123             : 
     124             :         /* list of subgroups that belong to the update group */
     125             :         LIST_HEAD(subgrp_list, update_subgroup) subgrps;
     126             : 
     127             :         /* lazy way to store configuration common to all peers
     128             :            hash function will compute from this data */
     129             :         struct peer *conf;
     130             : 
     131             :         afi_t afi;
     132             :         safi_t safi;
     133             :         int afid;
     134             : 
     135             :         uint64_t id;
     136             :         time_t uptime;
     137             : 
     138             :         uint32_t join_events;
     139             :         uint32_t prune_events;
     140             :         uint32_t merge_events;
     141             :         uint32_t updgrp_switch_events;
     142             :         uint32_t peer_refreshes_combined;
     143             :         uint32_t adj_count;
     144             :         uint32_t split_events;
     145             :         uint32_t merge_checks_triggered;
     146             : 
     147             :         uint32_t subgrps_created;
     148             :         uint32_t subgrps_deleted;
     149             : 
     150             :         uint32_t num_dbg_en_peers;
     151             : };
     152             : 
     153             : /*
     154             :  * Shorthand for a global statistics counter.
     155             :  */
     156             : #define UPDGRP_GLOBAL_STAT(updgrp, stat)                                       \
     157             :         ((updgrp)->bgp->update_group_stats.stat)
     158             : 
     159             : /*
     160             :  * Add the given value to a counter on an update group and the bgp
     161             :  * instance.
     162             :  */
     163             : #define UPDGRP_INCR_STAT_BY(updgrp, stat, value)                               \
     164             :         do {                                                                   \
     165             :                 (updgrp)->stat += (value);                                     \
     166             :                 UPDGRP_GLOBAL_STAT(updgrp, stat) += (value);                   \
     167             :         } while (0)
     168             : 
     169             : /*
     170             :  * Increment a counter on a update group and its parent structures.
     171             :  */
     172             : #define UPDGRP_INCR_STAT(subgrp, stat) UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
     173             : 
     174             : struct update_subgroup {
     175             :         /* back pointer to the parent update group */
     176             :         struct update_group *update_group;
     177             : 
     178             :         /* list of peers that belong to the subgroup */
     179             :         LIST_HEAD(peer_list, peer_af) peers;
     180             :         int peer_count;
     181             : 
     182             :         /* for being part of an update group's subgroup list */
     183             :         LIST_ENTRY(update_subgroup) updgrp_train;
     184             : 
     185             :         struct bpacket_queue pkt_queue;
     186             : 
     187             :         /*
     188             :          * List of adj-out structures for this subgroup.
     189             :          * It essentially represents the snapshot of every prefix that
     190             :          * has been advertised to the members of the subgroup
     191             :          */
     192             :         TAILQ_HEAD(adjout_queue, bgp_adj_out) adjq;
     193             : 
     194             :         /* packet buffer for update generation */
     195             :         struct stream *work;
     196             : 
     197             :         /* We use a separate stream to encode MP_REACH_NLRI for efficient
     198             :          * NLRI packing. peer->obuf_work stores all the other attributes. The
     199             :          * actual packet is then constructed by concatenating the two.
     200             :          */
     201             :         struct stream *scratch;
     202             : 
     203             :         /* synchronization list and time */
     204             :         struct bgp_synchronize *sync;
     205             : 
     206             :         /* send prefix count */
     207             :         uint32_t scount;
     208             : 
     209             :         /* send prefix count prior to packet update */
     210             :         uint32_t pscount;
     211             : 
     212             :         /* announcement attribute hash */
     213             :         struct hash *hash;
     214             : 
     215             :         struct thread *t_coalesce;
     216             :         uint32_t v_coalesce;
     217             : 
     218             :         struct thread *t_merge_check;
     219             : 
     220             :         /* table version that the subgroup has caught up to. */
     221             :         uint64_t version;
     222             : 
     223             :         /* version maintained to record adj changes */
     224             :         uint64_t adj_version;
     225             : 
     226             :         time_t uptime;
     227             : 
     228             :         /*
     229             :          * Identifying information about the subgroup that this subgroup was
     230             :          * split
     231             :          * from, if any.
     232             :          */
     233             :         struct {
     234             :                 uint64_t update_group_id;
     235             :                 uint64_t subgroup_id;
     236             :         } split_from;
     237             : 
     238             :         uint32_t join_events;
     239             :         uint32_t prune_events;
     240             : 
     241             :         /*
     242             :          * This is bumped up when another subgroup merges into this one.
     243             :          */
     244             :         uint32_t merge_events;
     245             :         uint32_t updgrp_switch_events;
     246             :         uint32_t peer_refreshes_combined;
     247             :         uint32_t adj_count;
     248             :         uint32_t split_events;
     249             :         uint32_t merge_checks_triggered;
     250             : 
     251             :         uint64_t id;
     252             : 
     253             :         uint16_t sflags;
     254             : #define SUBGRP_STATUS_DEFAULT_ORIGINATE (1 << 0)
     255             : #define SUBGRP_STATUS_FORCE_UPDATES (1 << 1)
     256             : #define SUBGRP_STATUS_TABLE_REPARSING (1 << 2)
     257             : /*
     258             :  * This flag has been added to ensure that the SNT counters
     259             :  * gets incremented and decremented only during the creation
     260             :  * and deletion workflows of default originate,
     261             :  * not during the update workflow.
     262             :  */
     263             : #define SUBGRP_STATUS_PEER_DEFAULT_ORIGINATED (1 << 3)
     264             : 
     265             :         uint16_t flags;
     266             : #define SUBGRP_FLAG_NEEDS_REFRESH (1 << 0)
     267             : };
     268             : 
     269             : /*
     270             :  * Add the given value to the specified counter on a subgroup and its
     271             :  * parent structures.
     272             :  */
     273             : #define SUBGRP_INCR_STAT_BY(subgrp, stat, value)                               \
     274             :         do {                                                                   \
     275             :                 (subgrp)->stat += (value);                                     \
     276             :                 if ((subgrp)->update_group)                                    \
     277             :                         UPDGRP_INCR_STAT_BY((subgrp)->update_group, stat,      \
     278             :                                             value);                            \
     279             :         } while (0)
     280             : 
     281             : /*
     282             :  * Increment a counter on a subgroup and its parent structures.
     283             :  */
     284             : #define SUBGRP_INCR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
     285             : 
     286             : /*
     287             :  * Decrement a counter on a subgroup and its parent structures.
     288             :  */
     289             : #define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
     290             : 
     291             : typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
     292             : 
     293             : /* really a private structure */
     294             : struct updwalk_context {
     295             :         struct vty *vty;
     296             :         struct bgp_dest *dest;
     297             :         struct bgp_path_info *pi;
     298             :         uint64_t updgrp_id;
     299             :         uint64_t subgrp_id;
     300             :         enum bgp_policy_type policy_type;
     301             :         const char *policy_name;
     302             :         int policy_event_start_flag;
     303             :         bool policy_route_update;
     304             :         updgrp_walkcb cb;
     305             :         void *context;
     306             :         uint8_t flags;
     307             :         bool uj;
     308             :         json_object *json_updategrps;
     309             : 
     310             : #define UPDWALK_FLAGS_ADVQUEUE   (1 << 0)
     311             : #define UPDWALK_FLAGS_ADVERTISED (1 << 1)
     312             : };
     313             : 
     314             : #define UPDWALK_CONTINUE HASHWALK_CONTINUE
     315             : #define UPDWALK_ABORT HASHWALK_ABORT
     316             : 
     317             : #define PAF_PEER(p)        ((p)->peer)
     318             : #define PAF_SUBGRP(p)      ((p)->subgroup)
     319             : #define PAF_UPDGRP(p)      ((p)->subgroup->update_group)
     320             : #define PAF_PKTQ(f)        SUBGRP_PKTQ((f)->subgroup)
     321             : 
     322             : #define UPDGRP_PEER(u)     ((u)->conf)
     323             : #define UPDGRP_AFI(u)      ((u)->afi)
     324             : #define UPDGRP_SAFI(u)     ((u)->safi)
     325             : #define UPDGRP_INST(u)     ((u)->bgp)
     326             : #define UPDGRP_AFFLAGS(u) ((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
     327             : #define UPDGRP_DBG_ON(u)   ((u)->num_dbg_en_peers)
     328             : #define UPDGRP_PEER_DBG_EN(u)  (((u)->num_dbg_en_peers)++)
     329             : #define UPDGRP_PEER_DBG_DIS(u) (((u)->num_dbg_en_peers)--)
     330             : #define UPDGRP_PEER_DBG_OFF(u) (u)->num_dbg_en_peers = 0
     331             : 
     332             : #define SUBGRP_AFI(s)      UPDGRP_AFI((s)->update_group)
     333             : #define SUBGRP_SAFI(s)     UPDGRP_SAFI((s)->update_group)
     334             : #define SUBGRP_PEER(s)     UPDGRP_PEER((s)->update_group)
     335             : #define SUBGRP_PCOUNT(s)   ((s)->peer_count)
     336             : #define SUBGRP_PFIRST(s)   LIST_FIRST(&((s)->peers))
     337             : #define SUBGRP_PKTQ(s)     &((s)->pkt_queue)
     338             : #define SUBGRP_INST(s)     UPDGRP_INST((s)->update_group)
     339             : #define SUBGRP_AFFLAGS(s)  UPDGRP_AFFLAGS((s)->update_group)
     340             : #define SUBGRP_UPDGRP(s)   ((s)->update_group)
     341             : 
     342             : /*
     343             :  * Walk all subgroups in an update group.
     344             :  */
     345             : #define UPDGRP_FOREACH_SUBGRP(updgrp, subgrp)                                  \
     346             :         LIST_FOREACH (subgrp, &((updgrp)->subgrps), updgrp_train)
     347             : 
     348             : #define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp)                 \
     349             :         LIST_FOREACH_SAFE (subgrp, &((updgrp)->subgrps), updgrp_train,         \
     350             :                            tmp_subgrp)
     351             : 
     352             : #define SUBGRP_FOREACH_PEER(subgrp, paf)                                       \
     353             :         LIST_FOREACH (paf, &(subgrp->peers), subgrp_train)
     354             : 
     355             : #define SUBGRP_FOREACH_PEER_SAFE(subgrp, paf, temp_paf)                        \
     356             :         LIST_FOREACH_SAFE (paf, &(subgrp->peers), subgrp_train, temp_paf)
     357             : 
     358             : #define SUBGRP_FOREACH_ADJ(subgrp, adj)                                        \
     359             :         TAILQ_FOREACH (adj, &(subgrp->adjq), subgrp_adj_train)
     360             : 
     361             : #define SUBGRP_FOREACH_ADJ_SAFE(subgrp, adj, adj_temp)                         \
     362             :         TAILQ_FOREACH_SAFE (adj, &(subgrp->adjq), subgrp_adj_train, adj_temp)
     363             : 
     364             : /* Prototypes.  */
     365             : /* bgp_updgrp.c */
     366             : extern void update_bgp_group_init(struct bgp *);
     367             : extern void udpate_bgp_group_free(struct bgp *);
     368             : 
     369             : extern void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi,
     370             :                               struct vty *vty, uint64_t subgrp_id, bool uj);
     371             : extern void update_group_show_stats(struct bgp *bgp, struct vty *vty);
     372             : extern void update_group_adjust_peer(struct peer_af *paf);
     373             : extern int update_group_adjust_soloness(struct peer *peer, int set);
     374             : 
     375             : extern void update_subgroup_remove_peer(struct update_subgroup *,
     376             :                                         struct peer_af *);
     377             : extern struct bgp_table *update_subgroup_rib(struct update_subgroup *);
     378             : extern void update_subgroup_split_peer(struct peer_af *, struct update_group *);
     379             : extern bool update_subgroup_check_merge(struct update_subgroup *, const char *);
     380             : extern bool update_subgroup_trigger_merge_check(struct update_subgroup *,
     381             :                                                 int force);
     382             : extern void update_group_policy_update(struct bgp *bgp,
     383             :                                        enum bgp_policy_type ptype,
     384             :                                        const char *pname, bool route_update,
     385             :                                        int start_event);
     386             : extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
     387             :                                  updgrp_walkcb cb, void *ctx);
     388             : extern void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx);
     389             : extern void update_group_periodic_merge(struct bgp *bgp);
     390             : extern void
     391             : update_group_refresh_default_originate_route_map(struct thread *thread);
     392             : extern void update_group_start_advtimer(struct bgp *bgp);
     393             : 
     394             : extern void update_subgroup_inherit_info(struct update_subgroup *to,
     395             :                                          struct update_subgroup *from);
     396             : 
     397             : /* bgp_updgrp_packet.c */
     398             : extern struct bpacket *bpacket_alloc(void);
     399             : extern void bpacket_free(struct bpacket *pkt);
     400             : extern void bpacket_queue_init(struct bpacket_queue *q);
     401             : extern void bpacket_queue_cleanup(struct bpacket_queue *q);
     402             : extern void bpacket_queue_sanity_check(struct bpacket_queue *q);
     403             : extern struct bpacket *bpacket_queue_add(struct bpacket_queue *q,
     404             :                                          struct stream *s,
     405             :                                          struct bpacket_attr_vec_arr *vecarr);
     406             : struct bpacket *bpacket_queue_remove(struct bpacket_queue *q);
     407             : extern struct bpacket *bpacket_queue_first(struct bpacket_queue *q);
     408             : struct bpacket *bpacket_queue_last(struct bpacket_queue *q);
     409             : unsigned int bpacket_queue_length(struct bpacket_queue *q);
     410             : unsigned int bpacket_queue_hwm_length(struct bpacket_queue *q);
     411             : bool bpacket_queue_is_full(struct bgp *bgp, struct bpacket_queue *q);
     412             : extern void bpacket_queue_advance_peer(struct peer_af *paf);
     413             : extern void bpacket_queue_remove_peer(struct peer_af *paf);
     414             : extern void bpacket_add_peer(struct bpacket *pkt, struct peer_af *paf);
     415             : unsigned int bpacket_queue_virtual_length(struct peer_af *paf);
     416             : extern void bpacket_queue_show_vty(struct bpacket_queue *q, struct vty *vty);
     417             : bool subgroup_packets_to_build(struct update_subgroup *subgrp);
     418             : extern struct bpacket *subgroup_update_packet(struct update_subgroup *s);
     419             : extern struct bpacket *subgroup_withdraw_packet(struct update_subgroup *s);
     420             : extern struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
     421             :                                                 struct peer_af *paf);
     422             : extern void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr);
     423             : extern void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
     424             :                                          enum bpacket_attr_vec_type type,
     425             :                                          struct stream *s, struct attr *attr);
     426             : extern void subgroup_default_update_packet(struct update_subgroup *subgrp,
     427             :                                            struct attr *attr,
     428             :                                            struct peer *from);
     429             : extern void subgroup_default_withdraw_packet(struct update_subgroup *subgrp);
     430             : 
     431             : /* bgp_updgrp_adv.c */
     432             : extern struct bgp_advertise *
     433             : bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
     434             :                              struct bgp_adj_out *adj);
     435             : extern void update_group_show_adj_queue(struct bgp *bgp, afi_t afi, safi_t safi,
     436             :                                         struct vty *vty, uint64_t id);
     437             : extern void update_group_show_advertised(struct bgp *bgp, afi_t afi,
     438             :                                          safi_t safi, struct vty *vty,
     439             :                                          uint64_t id);
     440             : extern void update_group_show_packet_queue(struct bgp *bgp, afi_t afi,
     441             :                                            safi_t safi, struct vty *vty,
     442             :                                            uint64_t id);
     443             : extern void subgroup_announce_route(struct update_subgroup *subgrp);
     444             : extern void subgroup_announce_all(struct update_subgroup *subgrp);
     445             : 
     446             : extern void subgroup_default_originate(struct update_subgroup *subgrp,
     447             :                                        int withdraw);
     448             : extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
     449             :                                  struct bgp_dest *dest,
     450             :                                  struct bgp_path_info *pi);
     451             : extern void subgroup_clear_table(struct update_subgroup *subgrp);
     452             : extern void update_group_announce(struct bgp *bgp);
     453             : extern void update_group_announce_rrclients(struct bgp *bgp);
     454             : extern void peer_af_announce_route(struct peer_af *paf, int combine);
     455             : extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp,
     456             :                                              struct bgp_dest *dest,
     457             :                                              uint32_t addpath_tx_id);
     458             : extern void bgp_adj_out_remove_subgroup(struct bgp_dest *dest,
     459             :                                         struct bgp_adj_out *adj,
     460             :                                         struct update_subgroup *subgrp);
     461             : extern void bgp_adj_out_set_subgroup(struct bgp_dest *dest,
     462             :                                      struct update_subgroup *subgrp,
     463             :                                      struct attr *attr,
     464             :                                      struct bgp_path_info *path);
     465             : extern void bgp_adj_out_unset_subgroup(struct bgp_dest *dest,
     466             :                                        struct update_subgroup *subgrp,
     467             :                                        char withdraw, uint32_t addpath_tx_id);
     468             : void subgroup_announce_table(struct update_subgroup *subgrp,
     469             :                              struct bgp_table *table);
     470             : extern void subgroup_trigger_write(struct update_subgroup *subgrp);
     471             : 
     472             : extern int update_group_clear_update_dbg(struct update_group *updgrp,
     473             :                                          void *arg);
     474             : 
     475             : extern void update_bgp_group_free(struct bgp *bgp);
     476             : extern bool bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
     477             : extern bool bgp_check_selected(struct bgp_path_info *bpi, struct peer *peer,
     478             :                                bool addpath_capable, afi_t afi, safi_t safi);
     479             : extern bool bgp_addpath_capable(struct bgp_path_info *bpi, struct peer *peer,
     480             :                                 afi_t afi, safi_t safi);
     481             : 
     482             : /*
     483             :  * Inline functions
     484             :  */
     485             : 
     486             : /*
     487             :  * bpacket_queue_is_empty
     488             :  */
     489           0 : static inline int bpacket_queue_is_empty(struct bpacket_queue *queue)
     490             : {
     491             : 
     492             :         /*
     493             :          * The packet queue is empty if it only contains a sentinel.
     494             :          */
     495           0 :         if (queue->curr_count != 1)
     496             :                 return 0;
     497             : 
     498           0 :         assert(bpacket_queue_first(queue)->buffer == NULL);
     499             :         return 1;
     500             : }
     501             : 
     502             : /*
     503             :  * bpacket_next
     504             :  *
     505             :  * Returns the packet after the given packet in a bpacket queue.
     506             :  */
     507           0 : static inline struct bpacket *bpacket_next(struct bpacket *pkt)
     508             : {
     509           0 :         return TAILQ_NEXT(pkt, pkt_train);
     510             : }
     511             : 
     512             : /*
     513             :  * update_group_adjust_peer_afs
     514             :  *
     515             :  * Adjust all peer_af structures for the given peer.
     516             :  */
     517           1 : static inline void update_group_adjust_peer_afs(struct peer *peer)
     518             : {
     519           1 :         struct peer_af *paf;
     520           1 :         int afidx;
     521             : 
     522          14 :         for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
     523          13 :                 paf = peer->peer_af_array[afidx];
     524          13 :                 if (paf != NULL)
     525           1 :                         update_group_adjust_peer(paf);
     526             :         }
     527           1 : }
     528             : 
     529             : /*
     530             :  * update_group_remove_peer_afs
     531             :  *
     532             :  * Remove all peer_af structures for the given peer from their subgroups.
     533             :  */
     534           1 : static inline void update_group_remove_peer_afs(struct peer *peer)
     535             : {
     536           1 :         struct peer_af *paf;
     537           1 :         int afidx;
     538             : 
     539          14 :         for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
     540          13 :                 paf = peer->peer_af_array[afidx];
     541          13 :                 if (paf != NULL)
     542           1 :                         update_subgroup_remove_peer(PAF_SUBGRP(paf), paf);
     543             :         }
     544           1 : }
     545             : 
     546             : /*
     547             :  * update_subgroup_needs_refresh
     548             :  */
     549             : static inline int
     550           0 : update_subgroup_needs_refresh(const struct update_subgroup *subgrp)
     551             : {
     552           0 :         if (CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH))
     553             :                 return 1;
     554             :         else
     555             :                 return 0;
     556             : }
     557             : 
     558             : /*
     559             :  * update_subgroup_set_needs_refresh
     560             :  */
     561             : static inline void
     562           0 : update_subgroup_set_needs_refresh(struct update_subgroup *subgrp, int value)
     563             : {
     564           0 :         if (value)
     565           0 :                 SET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
     566             :         else
     567           0 :                 UNSET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
     568           0 : }
     569             : 
     570           0 : static inline struct update_subgroup *peer_subgroup(struct peer *peer,
     571             :                                                     afi_t afi, safi_t safi)
     572             : {
     573           0 :         struct peer_af *paf;
     574             : 
     575           0 :         paf = peer_af_find(peer, afi, safi);
     576           0 :         if (paf)
     577           0 :                 return PAF_SUBGRP(paf);
     578             :         return NULL;
     579             : }
     580             : 
     581             : /*
     582             :  * update_group_adjust_peer_afs
     583             :  *
     584             :  * Adjust all peer_af structures for the given peer.
     585             :  */
     586           1 : static inline void bgp_announce_peer(struct peer *peer)
     587             : {
     588           1 :         struct peer_af *paf;
     589           1 :         int afidx;
     590             : 
     591          14 :         for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
     592          13 :                 paf = peer->peer_af_array[afidx];
     593          13 :                 if (paf != NULL)
     594           1 :                         subgroup_announce_all(PAF_SUBGRP(paf));
     595             :         }
     596           1 : }
     597             : 
     598             : /**
     599             :  * advertise_list_is_empty
     600             :  */
     601           0 : static inline int advertise_list_is_empty(struct update_subgroup *subgrp)
     602             : {
     603           0 :         if (bgp_adv_fifo_count(&subgrp->sync->update)
     604           0 :             || bgp_adv_fifo_count(&subgrp->sync->withdraw)
     605           0 :             || bgp_adv_fifo_count(&subgrp->sync->withdraw_low)) {
     606           0 :                 return 0;
     607             :         }
     608             : 
     609             :         return 1;
     610             : }
     611             : 
     612             : #endif /* _QUAGGA_BGP_UPDGRP_H */

Generated by: LCOV version v1.16-topotato