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