]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_updgrp.h
zebra: clang-format style fixes
[mirror_frr.git] / bgpd / bgp_updgrp.h
CommitLineData
3f9c7369
DS
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 *
896014f4
DL
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
3f9c7369
DS
25 */
26
27#ifndef _QUAGGA_BGP_UPDGRP_H
28#define _QUAGGA_BGP_UPDGRP_H
29
30#include "bgp_advertise.h"
31
4961a5a2
QY
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
3f9c7369 53
d62a17ae 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 \
a78ba1c3 59 | PEER_FLAG_SEND_LARGE_COMMUNITY \
d62a17ae 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 \
dcc68b5e 68 | PEER_FLAG_AS_OVERRIDE)
3f9c7369
DS
69
70#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
71
d62a17ae 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)
3f9c7369 76
682abee1 77enum bpacket_attr_vec_type { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX };
3f9c7369 78
d62a17ae 79typedef struct {
d7c0a89a 80 uint32_t flags;
d62a17ae 81 unsigned long offset;
3f9c7369
DS
82} bpacket_attr_vec;
83
3811f1e2
DS
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)
6eeb9255
DA
91#define BPKT_ATTRVEC_FLAGS_RMAP_VPNV4_NH_CHANGED (1 << 7)
92#define BPKT_ATTRVEC_FLAGS_RMAP_VPNV6_GNH_CHANGED (1 << 8)
3f9c7369 93
d62a17ae 94typedef struct bpacket_attr_vec_arr {
95 bpacket_attr_vec entries[BGP_ATTR_VEC_MAX];
3f9c7369
DS
96} bpacket_attr_vec_arr;
97
d62a17ae 98struct bpacket {
99 /* for being part of an update subgroup's message list */
100 TAILQ_ENTRY(bpacket) pkt_train;
3f9c7369 101
d62a17ae 102 /* list of peers (well, peer_afs) that the packet needs to be sent to */
103 LIST_HEAD(pkt_peer_list, peer_af) peers;
3f9c7369 104
d62a17ae 105 struct stream *buffer;
106 bpacket_attr_vec_arr arr;
3f9c7369 107
d62a17ae 108 unsigned int ver;
3f9c7369
DS
109};
110
d62a17ae 111struct bpacket_queue {
112 TAILQ_HEAD(pkt_queue, bpacket) pkts;
3f9c7369 113
d62a17ae 114 unsigned int conf_max_count;
115 unsigned int curr_count;
116 unsigned int hwm_count;
117 unsigned int max_count_reached_count;
3f9c7369
DS
118};
119
d62a17ae 120struct update_group {
121 /* back pointer to the BGP instance */
122 struct bgp *bgp;
3f9c7369 123
d62a17ae 124 /* list of subgroups that belong to the update group */
125 LIST_HEAD(subgrp_list, update_subgroup) subgrps;
3f9c7369 126
d62a17ae 127 /* lazy way to store configuration common to all peers
128 hash function will compute from this data */
129 struct peer *conf;
3f9c7369 130
d62a17ae 131 afi_t afi;
132 safi_t safi;
133 int afid;
3f9c7369 134
d62a17ae 135 uint64_t id;
136 time_t uptime;
3f9c7369 137
d7c0a89a
QY
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;
3f9c7369 146
d7c0a89a
QY
147 uint32_t subgrps_created;
148 uint32_t subgrps_deleted;
3f9c7369 149
d7c0a89a 150 uint32_t num_dbg_en_peers;
3f9c7369
DS
151};
152
153/*
154 * Shorthand for a global statistics counter.
155 */
d62a17ae 156#define UPDGRP_GLOBAL_STAT(updgrp, stat) \
157 ((updgrp)->bgp->update_group_stats.stat)
3f9c7369
DS
158
159/*
160 * Add the given value to a counter on an update group and the bgp
161 * instance.
162 */
d62a17ae 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)
3f9c7369
DS
168
169/*
170 * Increment a counter on a update group and its parent structures.
171 */
d62a17ae 172#define UPDGRP_INCR_STAT(subgrp, stat) UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
3f9c7369 173
d62a17ae 174struct update_subgroup {
175 /* back pointer to the parent update group */
176 struct update_group *update_group;
3f9c7369 177
d62a17ae 178 /* list of peers that belong to the subgroup */
179 LIST_HEAD(peer_list, peer_af) peers;
180 int peer_count;
3f9c7369 181
d62a17ae 182 /* for being part of an update group's subgroup list */
183 LIST_ENTRY(update_subgroup) updgrp_train;
3f9c7369 184
d62a17ae 185 struct bpacket_queue pkt_queue;
3f9c7369 186
d62a17ae 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;
3f9c7369 193
d62a17ae 194 /* packet buffer for update generation */
195 struct stream *work;
3f9c7369 196
d62a17ae 197 /* We use a separate stream to encode MP_REACH_NLRI for efficient
424ab01d 198 * NLRI packing. peer->obuf_work stores all the other attributes. The
d62a17ae 199 * actual packet is then constructed by concatenating the two.
200 */
201 struct stream *scratch;
3f9c7369 202
d62a17ae 203 /* synchronization list and time */
204 struct bgp_synchronize *sync;
3f9c7369 205
d62a17ae 206 /* send prefix count */
fde246e8 207 uint32_t scount;
3f9c7369 208
d0bf49ec
LS
209 /* send prefix count prior to packet update */
210 uint32_t pscount;
211
d62a17ae 212 /* announcement attribute hash */
213 struct hash *hash;
3f9c7369 214
d62a17ae 215 struct thread *t_coalesce;
d7c0a89a 216 uint32_t v_coalesce;
3f9c7369 217
d62a17ae 218 struct thread *t_merge_check;
3f9c7369 219
d62a17ae 220 /* table version that the subgroup has caught up to. */
221 uint64_t version;
3f9c7369 222
d62a17ae 223 /* version maintained to record adj changes */
224 uint64_t adj_version;
3f9c7369 225
d62a17ae 226 time_t uptime;
3f9c7369 227
d62a17ae 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;
3f9c7369 237
d7c0a89a
QY
238 uint32_t join_events;
239 uint32_t prune_events;
3f9c7369 240
d62a17ae 241 /*
242 * This is bumped up when another subgroup merges into this one.
243 */
d7c0a89a
QY
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;
3f9c7369 250
d62a17ae 251 uint64_t id;
3f9c7369 252
d7c0a89a 253 uint16_t sflags;
2adac256
DA
254#define SUBGRP_STATUS_DEFAULT_ORIGINATE (1 << 0)
255#define SUBGRP_STATUS_FORCE_UPDATES (1 << 1)
d0bf49ec 256#define SUBGRP_STATUS_TABLE_REPARSING (1 << 2)
46c4f05b
IS
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)
3f9c7369 264
d7c0a89a 265 uint16_t flags;
2adac256 266#define SUBGRP_FLAG_NEEDS_REFRESH (1 << 0)
3f9c7369
DS
267};
268
3f9c7369
DS
269/*
270 * Add the given value to the specified counter on a subgroup and its
271 * parent structures.
272 */
d62a17ae 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)
3f9c7369
DS
280
281/*
282 * Increment a counter on a subgroup and its parent structures.
283 */
d62a17ae 284#define SUBGRP_INCR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
3f9c7369
DS
285
286/*
287 * Decrement a counter on a subgroup and its parent structures.
288 */
d62a17ae 289#define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
3f9c7369 290
d62a17ae 291typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
3f9c7369
DS
292
293/* really a private structure */
d62a17ae 294struct updwalk_context {
295 struct vty *vty;
9bcb3eef 296 struct bgp_dest *dest;
40381db7 297 struct bgp_path_info *pi;
d62a17ae 298 uint64_t updgrp_id;
299 uint64_t subgrp_id;
d54f55f2 300 enum bgp_policy_type policy_type;
d62a17ae 301 const char *policy_name;
302 int policy_event_start_flag;
f1aa4929 303 bool policy_route_update;
d62a17ae 304 updgrp_walkcb cb;
305 void *context;
d7c0a89a 306 uint8_t flags;
fa5a9276
AR
307 bool uj;
308 json_object *json_updategrps;
3f9c7369
DS
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)
d62a17ae 326#define UPDGRP_AFFLAGS(u) ((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
3f9c7369
DS
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 */
d62a17ae 345#define UPDGRP_FOREACH_SUBGRP(updgrp, subgrp) \
996c9314 346 LIST_FOREACH (subgrp, &((updgrp)->subgrps), updgrp_train)
3f9c7369 347
d62a17ae 348#define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp) \
996c9314
LB
349 LIST_FOREACH_SAFE (subgrp, &((updgrp)->subgrps), updgrp_train, \
350 tmp_subgrp)
3f9c7369 351
d62a17ae 352#define SUBGRP_FOREACH_PEER(subgrp, paf) \
996c9314 353 LIST_FOREACH (paf, &(subgrp->peers), subgrp_train)
3f9c7369 354
d62a17ae 355#define SUBGRP_FOREACH_PEER_SAFE(subgrp, paf, temp_paf) \
996c9314 356 LIST_FOREACH_SAFE (paf, &(subgrp->peers), subgrp_train, temp_paf)
3f9c7369 357
d62a17ae 358#define SUBGRP_FOREACH_ADJ(subgrp, adj) \
996c9314 359 TAILQ_FOREACH (adj, &(subgrp->adjq), subgrp_adj_train)
3f9c7369 360
d62a17ae 361#define SUBGRP_FOREACH_ADJ_SAFE(subgrp, adj, adj_temp) \
996c9314 362 TAILQ_FOREACH_SAFE (adj, &(subgrp->adjq), subgrp_adj_train, adj_temp)
3f9c7369
DS
363
364/* Prototypes. */
365/* bgp_updgrp.c */
d62a17ae 366extern void update_bgp_group_init(struct bgp *);
367extern void udpate_bgp_group_free(struct bgp *);
368
369extern void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi,
fa5a9276 370 struct vty *vty, uint64_t subgrp_id, bool uj);
d62a17ae 371extern void update_group_show_stats(struct bgp *bgp, struct vty *vty);
372extern void update_group_adjust_peer(struct peer_af *paf);
373extern int update_group_adjust_soloness(struct peer *peer, int set);
374
375extern void update_subgroup_remove_peer(struct update_subgroup *,
376 struct peer_af *);
377extern struct bgp_table *update_subgroup_rib(struct update_subgroup *);
378extern void update_subgroup_split_peer(struct peer_af *, struct update_group *);
3dc339cd
DA
379extern bool update_subgroup_check_merge(struct update_subgroup *, const char *);
380extern bool update_subgroup_trigger_merge_check(struct update_subgroup *,
381 int force);
d54f55f2
DA
382extern void update_group_policy_update(struct bgp *bgp,
383 enum bgp_policy_type ptype,
f1aa4929 384 const char *pname, bool route_update,
d62a17ae 385 int start_event);
386extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
387 updgrp_walkcb cb, void *ctx);
388extern void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx);
389extern void update_group_periodic_merge(struct bgp *bgp);
cc9f21da 390extern void
d62a17ae 391update_group_refresh_default_originate_route_map(struct thread *thread);
392extern void update_group_start_advtimer(struct bgp *bgp);
393
394extern void update_subgroup_inherit_info(struct update_subgroup *to,
395 struct update_subgroup *from);
3f9c7369
DS
396
397/* bgp_updgrp_packet.c */
d62a17ae 398extern struct bpacket *bpacket_alloc(void);
399extern void bpacket_free(struct bpacket *pkt);
400extern void bpacket_queue_init(struct bpacket_queue *q);
401extern void bpacket_queue_cleanup(struct bpacket_queue *q);
402extern void bpacket_queue_sanity_check(struct bpacket_queue *q);
403extern struct bpacket *bpacket_queue_add(struct bpacket_queue *q,
404 struct stream *s,
405 struct bpacket_attr_vec_arr *vecarr);
406struct bpacket *bpacket_queue_remove(struct bpacket_queue *q);
407extern struct bpacket *bpacket_queue_first(struct bpacket_queue *q);
408struct bpacket *bpacket_queue_last(struct bpacket_queue *q);
409unsigned int bpacket_queue_length(struct bpacket_queue *q);
410unsigned int bpacket_queue_hwm_length(struct bpacket_queue *q);
3dc339cd 411bool bpacket_queue_is_full(struct bgp *bgp, struct bpacket_queue *q);
d62a17ae 412extern void bpacket_queue_advance_peer(struct peer_af *paf);
413extern void bpacket_queue_remove_peer(struct peer_af *paf);
414extern void bpacket_add_peer(struct bpacket *pkt, struct peer_af *paf);
415unsigned int bpacket_queue_virtual_length(struct peer_af *paf);
416extern void bpacket_queue_show_vty(struct bpacket_queue *q, struct vty *vty);
3dc339cd 417bool subgroup_packets_to_build(struct update_subgroup *subgrp);
d62a17ae 418extern struct bpacket *subgroup_update_packet(struct update_subgroup *s);
419extern struct bpacket *subgroup_withdraw_packet(struct update_subgroup *s);
420extern struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
421 struct peer_af *paf);
422extern void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr);
423extern void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
e8e36ff3 424 enum bpacket_attr_vec_type type,
d62a17ae 425 struct stream *s, struct attr *attr);
426extern void subgroup_default_update_packet(struct update_subgroup *subgrp,
427 struct attr *attr,
428 struct peer *from);
429extern void subgroup_default_withdraw_packet(struct update_subgroup *subgrp);
3f9c7369
DS
430
431/* bgp_updgrp_adv.c */
d62a17ae 432extern struct bgp_advertise *
433bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
434 struct bgp_adj_out *adj);
435extern void update_group_show_adj_queue(struct bgp *bgp, afi_t afi, safi_t safi,
436 struct vty *vty, uint64_t id);
437extern void update_group_show_advertised(struct bgp *bgp, afi_t afi,
3f9c7369 438 safi_t safi, struct vty *vty,
f43e655e 439 uint64_t id);
d62a17ae 440extern void update_group_show_packet_queue(struct bgp *bgp, afi_t afi,
441 safi_t safi, struct vty *vty,
442 uint64_t id);
443extern void subgroup_announce_route(struct update_subgroup *subgrp);
444extern void subgroup_announce_all(struct update_subgroup *subgrp);
445
446extern void subgroup_default_originate(struct update_subgroup *subgrp,
447 int withdraw);
448extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
9bcb3eef
DS
449 struct bgp_dest *dest,
450 struct bgp_path_info *pi);
d62a17ae 451extern void subgroup_clear_table(struct update_subgroup *subgrp);
452extern void update_group_announce(struct bgp *bgp);
453extern void update_group_announce_rrclients(struct bgp *bgp);
454extern void peer_af_announce_route(struct peer_af *paf, int combine);
455extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp,
9bcb3eef 456 struct bgp_dest *dest,
d7c0a89a 457 uint32_t addpath_tx_id);
9bcb3eef 458extern void bgp_adj_out_remove_subgroup(struct bgp_dest *dest,
d62a17ae 459 struct bgp_adj_out *adj,
460 struct update_subgroup *subgrp);
9bcb3eef 461extern void bgp_adj_out_set_subgroup(struct bgp_dest *dest,
d62a17ae 462 struct update_subgroup *subgrp,
4b7e6066 463 struct attr *attr,
9b6d8fcf 464 struct bgp_path_info *path);
9bcb3eef 465extern void bgp_adj_out_unset_subgroup(struct bgp_dest *dest,
d62a17ae 466 struct update_subgroup *subgrp,
d7c0a89a 467 char withdraw, uint32_t addpath_tx_id);
d62a17ae 468void subgroup_announce_table(struct update_subgroup *subgrp,
469 struct bgp_table *table);
2fc102e1 470extern void subgroup_trigger_write(struct update_subgroup *subgrp);
d62a17ae 471
472extern int update_group_clear_update_dbg(struct update_group *updgrp,
473 void *arg);
3f9c7369 474
88177fe3 475extern void update_bgp_group_free(struct bgp *bgp);
be92fc9f 476extern bool bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
b1dd7180
DA
477extern bool bgp_check_selected(struct bgp_path_info *bpi, struct peer *peer,
478 bool addpath_capable, afi_t afi, safi_t safi);
8ccee4b8
DA
479extern bool bgp_addpath_capable(struct bgp_path_info *bpi, struct peer *peer,
480 afi_t afi, safi_t safi);
88177fe3 481
3f9c7369
DS
482/*
483 * Inline functions
484 */
485
486/*
487 * bpacket_queue_is_empty
488 */
d62a17ae 489static inline int bpacket_queue_is_empty(struct bpacket_queue *queue)
3f9c7369
DS
490{
491
d62a17ae 492 /*
493 * The packet queue is empty if it only contains a sentinel.
494 */
495 if (queue->curr_count != 1)
496 return 0;
3f9c7369 497
d62a17ae 498 assert(bpacket_queue_first(queue)->buffer == NULL);
499 return 1;
3f9c7369
DS
500}
501
502/*
503 * bpacket_next
504 *
505 * Returns the packet after the given packet in a bpacket queue.
506 */
d62a17ae 507static inline struct bpacket *bpacket_next(struct bpacket *pkt)
3f9c7369 508{
d62a17ae 509 return TAILQ_NEXT(pkt, pkt_train);
3f9c7369
DS
510}
511
512/*
513 * update_group_adjust_peer_afs
514 *
515 * Adjust all peer_af structures for the given peer.
516 */
d62a17ae 517static inline void update_group_adjust_peer_afs(struct peer *peer)
3f9c7369 518{
d62a17ae 519 struct peer_af *paf;
520 int afidx;
521
522 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
523 paf = peer->peer_af_array[afidx];
524 if (paf != NULL)
525 update_group_adjust_peer(paf);
526 }
3f9c7369
DS
527}
528
529/*
530 * update_group_remove_peer_afs
531 *
532 * Remove all peer_af structures for the given peer from their subgroups.
533 */
d62a17ae 534static inline void update_group_remove_peer_afs(struct peer *peer)
3f9c7369 535{
d62a17ae 536 struct peer_af *paf;
537 int afidx;
538
539 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
540 paf = peer->peer_af_array[afidx];
541 if (paf != NULL)
542 update_subgroup_remove_peer(PAF_SUBGRP(paf), paf);
543 }
3f9c7369
DS
544}
545
546/*
547 * update_subgroup_needs_refresh
548 */
549static inline int
d62a17ae 550update_subgroup_needs_refresh(const struct update_subgroup *subgrp)
3f9c7369 551{
d62a17ae 552 if (CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH))
553 return 1;
554 else
555 return 0;
3f9c7369
DS
556}
557
558/*
559 * update_subgroup_set_needs_refresh
560 */
561static inline void
d62a17ae 562update_subgroup_set_needs_refresh(struct update_subgroup *subgrp, int value)
3f9c7369 563{
d62a17ae 564 if (value)
565 SET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
566 else
567 UNSET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
3f9c7369
DS
568}
569
d62a17ae 570static inline struct update_subgroup *peer_subgroup(struct peer *peer,
571 afi_t afi, safi_t safi)
3f9c7369 572{
d62a17ae 573 struct peer_af *paf;
3f9c7369 574
d62a17ae 575 paf = peer_af_find(peer, afi, safi);
576 if (paf)
577 return PAF_SUBGRP(paf);
578 return NULL;
3f9c7369
DS
579}
580
581/*
582 * update_group_adjust_peer_afs
583 *
584 * Adjust all peer_af structures for the given peer.
585 */
d62a17ae 586static inline void bgp_announce_peer(struct peer *peer)
3f9c7369 587{
d62a17ae 588 struct peer_af *paf;
589 int afidx;
590
591 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
592 paf = peer->peer_af_array[afidx];
593 if (paf != NULL)
594 subgroup_announce_all(PAF_SUBGRP(paf));
595 }
3f9c7369
DS
596}
597
598/**
599 * advertise_list_is_empty
600 */
d62a17ae 601static inline int advertise_list_is_empty(struct update_subgroup *subgrp)
3f9c7369 602{
a274fef8
DL
603 if (bgp_adv_fifo_count(&subgrp->sync->update)
604 || bgp_adv_fifo_count(&subgrp->sync->withdraw)
605 || bgp_adv_fifo_count(&subgrp->sync->withdraw_low)) {
d62a17ae 606 return 0;
607 }
608
609 return 1;
3f9c7369
DS
610}
611
612#endif /* _QUAGGA_BGP_UPDGRP_H */