]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_updgrp.h
tests: neuter fuzzing frontend for now
[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
32#define BGP_DEFAULT_SUBGROUP_COALESCE_TIME 200
33
d62a17ae 34#define PEER_UPDGRP_FLAGS \
35 (PEER_FLAG_LOCAL_AS_NO_PREPEND | PEER_FLAG_LOCAL_AS_REPLACE_AS)
36
37#define PEER_UPDGRP_AF_FLAGS \
38 (PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY \
39 | PEER_FLAG_DEFAULT_ORIGINATE | PEER_FLAG_REFLECTOR_CLIENT \
40 | PEER_FLAG_RSERVER_CLIENT | PEER_FLAG_NEXTHOP_SELF \
41 | PEER_FLAG_NEXTHOP_UNCHANGED | PEER_FLAG_FORCE_NEXTHOP_SELF \
42 | PEER_FLAG_AS_PATH_UNCHANGED | PEER_FLAG_MED_UNCHANGED \
43 | PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | PEER_FLAG_REMOVE_PRIVATE_AS \
44 | PEER_FLAG_REMOVE_PRIVATE_AS_ALL \
45 | PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE \
46 | PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE \
47 | PEER_FLAG_ADDPATH_TX_ALL_PATHS \
48 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS | PEER_FLAG_AS_OVERRIDE)
3f9c7369
DS
49
50#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
51
d62a17ae 52#define PEER_UPDGRP_AF_CAP_FLAGS \
53 (PEER_CAP_ORF_PREFIX_SM_RCV | PEER_CAP_ORF_PREFIX_SM_OLD_RCV \
54 | PEER_CAP_ADDPATH_AF_TX_ADV | PEER_CAP_ADDPATH_AF_RX_RCV \
55 | PEER_CAP_ENHE_AF_NEGO)
3f9c7369 56
d62a17ae 57typedef enum { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX } bpacket_attr_vec_type;
3f9c7369 58
d62a17ae 59typedef struct {
60 u_int32_t flags;
61 unsigned long offset;
3f9c7369
DS
62} bpacket_attr_vec;
63
3811f1e2
DS
64#define BPKT_ATTRVEC_FLAGS_UPDATED (1 << 0)
65#define BPKT_ATTRVEC_FLAGS_RMAP_NH_PEER_ADDRESS (1 << 1)
66#define BPKT_ATTRVEC_FLAGS_REFLECTED (1 << 2)
67#define BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED (1 << 3)
68#define BPKT_ATTRVEC_FLAGS_RMAP_IPV4_NH_CHANGED (1 << 4)
69#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_GNH_CHANGED (1 << 5)
70#define BPKT_ATTRVEC_FLAGS_RMAP_IPV6_LNH_CHANGED (1 << 6)
3f9c7369 71
d62a17ae 72typedef struct bpacket_attr_vec_arr {
73 bpacket_attr_vec entries[BGP_ATTR_VEC_MAX];
3f9c7369
DS
74} bpacket_attr_vec_arr;
75
d62a17ae 76struct bpacket {
77 /* for being part of an update subgroup's message list */
78 TAILQ_ENTRY(bpacket) pkt_train;
3f9c7369 79
d62a17ae 80 /* list of peers (well, peer_afs) that the packet needs to be sent to */
81 LIST_HEAD(pkt_peer_list, peer_af) peers;
3f9c7369 82
d62a17ae 83 struct stream *buffer;
84 bpacket_attr_vec_arr arr;
3f9c7369 85
d62a17ae 86 unsigned int ver;
3f9c7369
DS
87};
88
d62a17ae 89struct bpacket_queue {
90 TAILQ_HEAD(pkt_queue, bpacket) pkts;
3f9c7369
DS
91
92#if 0
93 /* A dummy packet that is used to thread all peers that have
94 completed their work */
95 struct bpacket sentinel;
96#endif
97
d62a17ae 98 unsigned int conf_max_count;
99 unsigned int curr_count;
100 unsigned int hwm_count;
101 unsigned int max_count_reached_count;
3f9c7369
DS
102};
103
d62a17ae 104struct update_group {
105 /* back pointer to the BGP instance */
106 struct bgp *bgp;
3f9c7369 107
d62a17ae 108 /* list of subgroups that belong to the update group */
109 LIST_HEAD(subgrp_list, update_subgroup) subgrps;
3f9c7369 110
d62a17ae 111 /* lazy way to store configuration common to all peers
112 hash function will compute from this data */
113 struct peer *conf;
3f9c7369 114
d62a17ae 115 afi_t afi;
116 safi_t safi;
117 int afid;
3f9c7369 118
d62a17ae 119 uint64_t id;
120 time_t uptime;
3f9c7369 121
d62a17ae 122 u_int32_t join_events;
123 u_int32_t prune_events;
124 u_int32_t merge_events;
125 u_int32_t updgrp_switch_events;
126 u_int32_t peer_refreshes_combined;
127 u_int32_t adj_count;
128 u_int32_t split_events;
129 u_int32_t merge_checks_triggered;
3f9c7369 130
d62a17ae 131 u_int32_t subgrps_created;
132 u_int32_t subgrps_deleted;
3f9c7369 133
d62a17ae 134 u_int32_t num_dbg_en_peers;
3f9c7369
DS
135};
136
137/*
138 * Shorthand for a global statistics counter.
139 */
d62a17ae 140#define UPDGRP_GLOBAL_STAT(updgrp, stat) \
141 ((updgrp)->bgp->update_group_stats.stat)
3f9c7369
DS
142
143/*
144 * Add the given value to a counter on an update group and the bgp
145 * instance.
146 */
d62a17ae 147#define UPDGRP_INCR_STAT_BY(updgrp, stat, value) \
148 do { \
149 (updgrp)->stat += (value); \
150 UPDGRP_GLOBAL_STAT(updgrp, stat) += (value); \
151 } while (0)
3f9c7369
DS
152
153/*
154 * Increment a counter on a update group and its parent structures.
155 */
d62a17ae 156#define UPDGRP_INCR_STAT(subgrp, stat) UPDGRP_INCR_STAT_BY(subgrp, stat, 1)
3f9c7369 157
d62a17ae 158struct update_subgroup {
159 /* back pointer to the parent update group */
160 struct update_group *update_group;
3f9c7369 161
d62a17ae 162 /* list of peers that belong to the subgroup */
163 LIST_HEAD(peer_list, peer_af) peers;
164 int peer_count;
3f9c7369 165
d62a17ae 166 /* for being part of an update group's subgroup list */
167 LIST_ENTRY(update_subgroup) updgrp_train;
3f9c7369 168
d62a17ae 169 struct bpacket_queue pkt_queue;
3f9c7369 170
d62a17ae 171 /*
172 * List of adj-out structures for this subgroup.
173 * It essentially represents the snapshot of every prefix that
174 * has been advertised to the members of the subgroup
175 */
176 TAILQ_HEAD(adjout_queue, bgp_adj_out) adjq;
3f9c7369 177
d62a17ae 178 /* packet buffer for update generation */
179 struct stream *work;
3f9c7369 180
d62a17ae 181 /* We use a separate stream to encode MP_REACH_NLRI for efficient
424ab01d 182 * NLRI packing. peer->obuf_work stores all the other attributes. The
d62a17ae 183 * actual packet is then constructed by concatenating the two.
184 */
185 struct stream *scratch;
3f9c7369 186
d62a17ae 187 /* synchronization list and time */
188 struct bgp_synchronize *sync;
3f9c7369 189
d62a17ae 190 /* send prefix count */
191 unsigned long scount;
3f9c7369 192
d62a17ae 193 /* announcement attribute hash */
194 struct hash *hash;
3f9c7369 195
d62a17ae 196 struct thread *t_coalesce;
197 u_int32_t v_coalesce;
3f9c7369 198
d62a17ae 199 struct thread *t_merge_check;
3f9c7369 200
d62a17ae 201 /* table version that the subgroup has caught up to. */
202 uint64_t version;
3f9c7369 203
d62a17ae 204 /* version maintained to record adj changes */
205 uint64_t adj_version;
3f9c7369 206
d62a17ae 207 time_t uptime;
3f9c7369 208
d62a17ae 209 /*
210 * Identifying information about the subgroup that this subgroup was
211 * split
212 * from, if any.
213 */
214 struct {
215 uint64_t update_group_id;
216 uint64_t subgroup_id;
217 } split_from;
3f9c7369 218
d62a17ae 219 u_int32_t join_events;
220 u_int32_t prune_events;
3f9c7369 221
d62a17ae 222 /*
223 * This is bumped up when another subgroup merges into this one.
224 */
225 u_int32_t merge_events;
226 u_int32_t updgrp_switch_events;
227 u_int32_t peer_refreshes_combined;
228 u_int32_t adj_count;
229 u_int32_t split_events;
230 u_int32_t merge_checks_triggered;
3f9c7369 231
d62a17ae 232 uint64_t id;
3f9c7369 233
d62a17ae 234 u_int16_t sflags;
3f9c7369 235
d62a17ae 236 /* Subgroup flags, see below */
237 u_int16_t flags;
3f9c7369
DS
238};
239
240/*
241 * We need to do an outbound refresh to get this subgroup into a
242 * consistent state.
243 */
244#define SUBGRP_FLAG_NEEDS_REFRESH (1 << 0)
245
246#define SUBGRP_STATUS_DEFAULT_ORIGINATE (1 << 0)
247
248/*
249 * Add the given value to the specified counter on a subgroup and its
250 * parent structures.
251 */
d62a17ae 252#define SUBGRP_INCR_STAT_BY(subgrp, stat, value) \
253 do { \
254 (subgrp)->stat += (value); \
255 if ((subgrp)->update_group) \
256 UPDGRP_INCR_STAT_BY((subgrp)->update_group, stat, \
257 value); \
258 } while (0)
3f9c7369
DS
259
260/*
261 * Increment a counter on a subgroup and its parent structures.
262 */
d62a17ae 263#define SUBGRP_INCR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, 1)
3f9c7369
DS
264
265/*
266 * Decrement a counter on a subgroup and its parent structures.
267 */
d62a17ae 268#define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
3f9c7369 269
9d303b37 270
d62a17ae 271typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
3f9c7369
DS
272
273/* really a private structure */
d62a17ae 274struct updwalk_context {
275 struct vty *vty;
276 struct bgp_node *rn;
277 struct bgp_info *ri;
278 uint64_t updgrp_id;
279 uint64_t subgrp_id;
280 bgp_policy_type_e policy_type;
281 const char *policy_name;
282 int policy_event_start_flag;
283 int policy_route_update;
284 updgrp_walkcb cb;
285 void *context;
286 u_int8_t flags;
3f9c7369
DS
287
288#define UPDWALK_FLAGS_ADVQUEUE (1 << 0)
289#define UPDWALK_FLAGS_ADVERTISED (1 << 1)
290};
291
292#define UPDWALK_CONTINUE HASHWALK_CONTINUE
293#define UPDWALK_ABORT HASHWALK_ABORT
294
295#define PAF_PEER(p) ((p)->peer)
296#define PAF_SUBGRP(p) ((p)->subgroup)
297#define PAF_UPDGRP(p) ((p)->subgroup->update_group)
298#define PAF_PKTQ(f) SUBGRP_PKTQ((f)->subgroup)
299
300#define UPDGRP_PEER(u) ((u)->conf)
301#define UPDGRP_AFI(u) ((u)->afi)
302#define UPDGRP_SAFI(u) ((u)->safi)
303#define UPDGRP_INST(u) ((u)->bgp)
d62a17ae 304#define UPDGRP_AFFLAGS(u) ((u)->conf->af_flags[UPDGRP_AFI(u)][UPDGRP_SAFI(u)])
3f9c7369
DS
305#define UPDGRP_DBG_ON(u) ((u)->num_dbg_en_peers)
306#define UPDGRP_PEER_DBG_EN(u) (((u)->num_dbg_en_peers)++)
307#define UPDGRP_PEER_DBG_DIS(u) (((u)->num_dbg_en_peers)--)
308#define UPDGRP_PEER_DBG_OFF(u) (u)->num_dbg_en_peers = 0
309
310#define SUBGRP_AFI(s) UPDGRP_AFI((s)->update_group)
311#define SUBGRP_SAFI(s) UPDGRP_SAFI((s)->update_group)
312#define SUBGRP_PEER(s) UPDGRP_PEER((s)->update_group)
313#define SUBGRP_PCOUNT(s) ((s)->peer_count)
314#define SUBGRP_PFIRST(s) LIST_FIRST(&((s)->peers))
315#define SUBGRP_PKTQ(s) &((s)->pkt_queue)
316#define SUBGRP_INST(s) UPDGRP_INST((s)->update_group)
317#define SUBGRP_AFFLAGS(s) UPDGRP_AFFLAGS((s)->update_group)
318#define SUBGRP_UPDGRP(s) ((s)->update_group)
319
320/*
321 * Walk all subgroups in an update group.
322 */
d62a17ae 323#define UPDGRP_FOREACH_SUBGRP(updgrp, subgrp) \
324 LIST_FOREACH(subgrp, &((updgrp)->subgrps), updgrp_train)
3f9c7369 325
d62a17ae 326#define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp) \
327 LIST_FOREACH_SAFE(subgrp, &((updgrp)->subgrps), updgrp_train, \
328 tmp_subgrp)
3f9c7369 329
d62a17ae 330#define SUBGRP_FOREACH_PEER(subgrp, paf) \
331 LIST_FOREACH(paf, &(subgrp->peers), subgrp_train)
3f9c7369 332
d62a17ae 333#define SUBGRP_FOREACH_PEER_SAFE(subgrp, paf, temp_paf) \
334 LIST_FOREACH_SAFE(paf, &(subgrp->peers), subgrp_train, temp_paf)
3f9c7369 335
d62a17ae 336#define SUBGRP_FOREACH_ADJ(subgrp, adj) \
337 TAILQ_FOREACH(adj, &(subgrp->adjq), subgrp_adj_train)
3f9c7369 338
d62a17ae 339#define SUBGRP_FOREACH_ADJ_SAFE(subgrp, adj, adj_temp) \
340 TAILQ_FOREACH_SAFE(adj, &(subgrp->adjq), subgrp_adj_train, adj_temp)
3f9c7369
DS
341
342/* Prototypes. */
343/* bgp_updgrp.c */
d62a17ae 344extern void update_bgp_group_init(struct bgp *);
345extern void udpate_bgp_group_free(struct bgp *);
346
347extern void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi,
348 struct vty *vty, uint64_t subgrp_id);
349extern void update_group_show_stats(struct bgp *bgp, struct vty *vty);
350extern void update_group_adjust_peer(struct peer_af *paf);
351extern int update_group_adjust_soloness(struct peer *peer, int set);
352
353extern void update_subgroup_remove_peer(struct update_subgroup *,
354 struct peer_af *);
355extern struct bgp_table *update_subgroup_rib(struct update_subgroup *);
356extern void update_subgroup_split_peer(struct peer_af *, struct update_group *);
357extern int update_subgroup_check_merge(struct update_subgroup *, const char *);
358extern int update_subgroup_trigger_merge_check(struct update_subgroup *,
359 int force);
360extern void update_group_policy_update(struct bgp *bgp, bgp_policy_type_e ptype,
361 const char *pname, int route_update,
362 int start_event);
363extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
364 updgrp_walkcb cb, void *ctx);
365extern void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx);
366extern void update_group_periodic_merge(struct bgp *bgp);
3f9c7369 367extern int
d62a17ae 368update_group_refresh_default_originate_route_map(struct thread *thread);
369extern void update_group_start_advtimer(struct bgp *bgp);
370
371extern void update_subgroup_inherit_info(struct update_subgroup *to,
372 struct update_subgroup *from);
3f9c7369
DS
373
374/* bgp_updgrp_packet.c */
d62a17ae 375extern struct bpacket *bpacket_alloc(void);
376extern void bpacket_free(struct bpacket *pkt);
377extern void bpacket_queue_init(struct bpacket_queue *q);
378extern void bpacket_queue_cleanup(struct bpacket_queue *q);
379extern void bpacket_queue_sanity_check(struct bpacket_queue *q);
380extern struct bpacket *bpacket_queue_add(struct bpacket_queue *q,
381 struct stream *s,
382 struct bpacket_attr_vec_arr *vecarr);
383struct bpacket *bpacket_queue_remove(struct bpacket_queue *q);
384extern struct bpacket *bpacket_queue_first(struct bpacket_queue *q);
385struct bpacket *bpacket_queue_last(struct bpacket_queue *q);
386unsigned int bpacket_queue_length(struct bpacket_queue *q);
387unsigned int bpacket_queue_hwm_length(struct bpacket_queue *q);
388int bpacket_queue_is_full(struct bgp *bgp, struct bpacket_queue *q);
389extern void bpacket_queue_advance_peer(struct peer_af *paf);
390extern void bpacket_queue_remove_peer(struct peer_af *paf);
391extern void bpacket_add_peer(struct bpacket *pkt, struct peer_af *paf);
392unsigned int bpacket_queue_virtual_length(struct peer_af *paf);
393extern void bpacket_queue_show_vty(struct bpacket_queue *q, struct vty *vty);
394int subgroup_packets_to_build(struct update_subgroup *subgrp);
395extern struct bpacket *subgroup_update_packet(struct update_subgroup *s);
396extern struct bpacket *subgroup_withdraw_packet(struct update_subgroup *s);
397extern struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
398 struct peer_af *paf);
399extern void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr);
400extern void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
401 bpacket_attr_vec_type type,
402 struct stream *s, struct attr *attr);
403extern void subgroup_default_update_packet(struct update_subgroup *subgrp,
404 struct attr *attr,
405 struct peer *from);
406extern void subgroup_default_withdraw_packet(struct update_subgroup *subgrp);
3f9c7369
DS
407
408/* bgp_updgrp_adv.c */
d62a17ae 409extern struct bgp_advertise *
410bgp_advertise_clean_subgroup(struct update_subgroup *subgrp,
411 struct bgp_adj_out *adj);
412extern void update_group_show_adj_queue(struct bgp *bgp, afi_t afi, safi_t safi,
413 struct vty *vty, uint64_t id);
414extern void update_group_show_advertised(struct bgp *bgp, afi_t afi,
3f9c7369 415 safi_t safi, struct vty *vty,
f43e655e 416 uint64_t id);
d62a17ae 417extern void update_group_show_packet_queue(struct bgp *bgp, afi_t afi,
418 safi_t safi, struct vty *vty,
419 uint64_t id);
420extern void subgroup_announce_route(struct update_subgroup *subgrp);
421extern void subgroup_announce_all(struct update_subgroup *subgrp);
422
423extern void subgroup_default_originate(struct update_subgroup *subgrp,
424 int withdraw);
425extern void group_announce_route(struct bgp *bgp, afi_t afi, safi_t safi,
426 struct bgp_node *rn, struct bgp_info *ri);
427extern void subgroup_clear_table(struct update_subgroup *subgrp);
428extern void update_group_announce(struct bgp *bgp);
429extern void update_group_announce_rrclients(struct bgp *bgp);
430extern void peer_af_announce_route(struct peer_af *paf, int combine);
431extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp,
432 struct bgp_node *rn,
433 u_int32_t addpath_tx_id);
434extern void bgp_adj_out_remove_subgroup(struct bgp_node *rn,
435 struct bgp_adj_out *adj,
436 struct update_subgroup *subgrp);
437extern void bgp_adj_out_set_subgroup(struct bgp_node *rn,
438 struct update_subgroup *subgrp,
439 struct attr *attr, struct bgp_info *binfo);
440extern void bgp_adj_out_unset_subgroup(struct bgp_node *rn,
441 struct update_subgroup *subgrp,
442 char withdraw, u_int32_t addpath_tx_id);
443void subgroup_announce_table(struct update_subgroup *subgrp,
444 struct bgp_table *table);
2fc102e1 445extern void subgroup_trigger_write(struct update_subgroup *subgrp);
d62a17ae 446
447extern int update_group_clear_update_dbg(struct update_group *updgrp,
448 void *arg);
3f9c7369 449
88177fe3 450extern void update_bgp_group_free(struct bgp *bgp);
d62a17ae 451extern int bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi);
452extern int bgp_addpath_tx_path(struct peer *peer, afi_t afi, safi_t safi,
453 struct bgp_info *ri);
88177fe3 454
3f9c7369
DS
455/*
456 * Inline functions
457 */
458
459/*
460 * bpacket_queue_is_empty
461 */
d62a17ae 462static inline int bpacket_queue_is_empty(struct bpacket_queue *queue)
3f9c7369
DS
463{
464
d62a17ae 465 /*
466 * The packet queue is empty if it only contains a sentinel.
467 */
468 if (queue->curr_count != 1)
469 return 0;
3f9c7369 470
d62a17ae 471 assert(bpacket_queue_first(queue)->buffer == NULL);
472 return 1;
3f9c7369
DS
473}
474
475/*
476 * bpacket_next
477 *
478 * Returns the packet after the given packet in a bpacket queue.
479 */
d62a17ae 480static inline struct bpacket *bpacket_next(struct bpacket *pkt)
3f9c7369 481{
d62a17ae 482 return TAILQ_NEXT(pkt, pkt_train);
3f9c7369
DS
483}
484
485/*
486 * update_group_adjust_peer_afs
487 *
488 * Adjust all peer_af structures for the given peer.
489 */
d62a17ae 490static inline void update_group_adjust_peer_afs(struct peer *peer)
3f9c7369 491{
d62a17ae 492 struct peer_af *paf;
493 int afidx;
494
495 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
496 paf = peer->peer_af_array[afidx];
497 if (paf != NULL)
498 update_group_adjust_peer(paf);
499 }
3f9c7369
DS
500}
501
502/*
503 * update_group_remove_peer_afs
504 *
505 * Remove all peer_af structures for the given peer from their subgroups.
506 */
d62a17ae 507static inline void update_group_remove_peer_afs(struct peer *peer)
3f9c7369 508{
d62a17ae 509 struct peer_af *paf;
510 int afidx;
511
512 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
513 paf = peer->peer_af_array[afidx];
514 if (paf != NULL)
515 update_subgroup_remove_peer(PAF_SUBGRP(paf), paf);
516 }
3f9c7369
DS
517}
518
519/*
520 * update_subgroup_needs_refresh
521 */
522static inline int
d62a17ae 523update_subgroup_needs_refresh(const struct update_subgroup *subgrp)
3f9c7369 524{
d62a17ae 525 if (CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH))
526 return 1;
527 else
528 return 0;
3f9c7369
DS
529}
530
531/*
532 * update_subgroup_set_needs_refresh
533 */
534static inline void
d62a17ae 535update_subgroup_set_needs_refresh(struct update_subgroup *subgrp, int value)
3f9c7369 536{
d62a17ae 537 if (value)
538 SET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
539 else
540 UNSET_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH);
3f9c7369
DS
541}
542
d62a17ae 543static inline struct update_subgroup *peer_subgroup(struct peer *peer,
544 afi_t afi, safi_t safi)
3f9c7369 545{
d62a17ae 546 struct peer_af *paf;
3f9c7369 547
d62a17ae 548 paf = peer_af_find(peer, afi, safi);
549 if (paf)
550 return PAF_SUBGRP(paf);
551 return NULL;
3f9c7369
DS
552}
553
554/*
555 * update_group_adjust_peer_afs
556 *
557 * Adjust all peer_af structures for the given peer.
558 */
d62a17ae 559static inline void bgp_announce_peer(struct peer *peer)
3f9c7369 560{
d62a17ae 561 struct peer_af *paf;
562 int afidx;
563
564 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
565 paf = peer->peer_af_array[afidx];
566 if (paf != NULL)
567 subgroup_announce_all(PAF_SUBGRP(paf));
568 }
3f9c7369
DS
569}
570
571/**
572 * advertise_list_is_empty
573 */
d62a17ae 574static inline int advertise_list_is_empty(struct update_subgroup *subgrp)
3f9c7369 575{
d62a17ae 576 if (!BGP_ADV_FIFO_EMPTY(&subgrp->sync->update)
577 || !BGP_ADV_FIFO_EMPTY(&subgrp->sync->withdraw)
578 || !BGP_ADV_FIFO_EMPTY(&subgrp->sync->withdraw_low)) {
579 return 0;
580 }
581
582 return 1;
3f9c7369
DS
583}
584
585#endif /* _QUAGGA_BGP_UPDGRP_H */