1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018 Yasuhiro Ohara
4 * Copyright (C) 2019 David Lamparter for NetDEF, Inc.
16 #define BMP_VERSION_3 3
18 #define BMP_LENGTH_POS 1
20 /* BMP message types */
21 #define BMP_TYPE_ROUTE_MONITORING 0
22 #define BMP_TYPE_STATISTICS_REPORT 1
23 #define BMP_TYPE_PEER_DOWN_NOTIFICATION 2
24 #define BMP_TYPE_PEER_UP_NOTIFICATION 3
25 #define BMP_TYPE_INITIATION 4
26 #define BMP_TYPE_TERMINATION 5
27 #define BMP_TYPE_ROUTE_MIRRORING 6
29 #define BMP_READ_BUFSIZ 1024
36 /* This one is for BMP Route Monitoring messages, i.e. delivering updates
37 * in somewhat processed (as opposed to fully raw, see mirroring below) form.
38 * RFC explicitly says that we can skip old updates if we haven't sent them out
39 * yet and another newer update for the same prefix arrives.
41 * So, at most one of these can exist for each (bgp, afi, safi, prefix, peerid)
42 * tuple; if some prefix is "re-added" to the queue, the existing entry is
43 * instead moved to the end of the queue. This ensures that the queue size is
44 * bounded by the BGP table size.
46 * bmp_qlist is the queue itself while bmp_qhash is used to efficiently check
47 * whether a tuple is already on the list. The queue is maintained per
50 * refcount = number of "struct bmp *" whose queue position is before this
51 * entry, i.e. number of BMP sessions where we still want to send this out.
52 * Decremented on send so we know when we're done with an entry (i.e. this
53 * always happens from the front of the queue.)
56 PREDECL_DLIST(bmp_qlist
);
57 PREDECL_HASH(bmp_qhash
);
59 struct bmp_queue_entry
{
60 struct bmp_qlist_item bli
;
61 struct bmp_qhash_item bhi
;
70 /* initialized only for L2VPN/EVPN (S)AFIs */
74 /* This is for BMP Route Mirroring, which feeds fully raw BGP PDUs out to BMP
75 * receivers. So, this goes directly off packet RX/TX handling instead of
76 * grabbing bits from tables.
78 * There is *one* queue for each "struct bgp *" where we throw everything on,
79 * with a size limit. Refcount works the same as for monitoring above.
82 PREDECL_LIST(bmp_mirrorq
);
85 struct bmp_mirrorq_item bmi
;
102 PREDECL_LIST(bmp_session
);
107 /* an established BMP session to a peer */
109 struct bmp_session_item bsi
;
110 struct bmp_targets
*targets
;
111 struct bmp_active
*active
;
114 char remote
[SU_ADDRSTRLEN
+ 6];
115 struct thread
*t_read
;
117 struct pullwr
*pullwr
;
121 /* queue positions must remain synced with refcounts in the items.
122 * Whenever appending a queue item, we need to know the correct number
123 * of "struct bmp *" that want it, and when moving these positions
124 * ahead we need to make sure that refcount is decremented. Also, on
125 * disconnects we need to walk the queue and drop our reference.
127 struct bmp_queue_entry
*queuepos
;
128 struct bmp_mirrorq
*mirrorpos
;
132 uint8_t afistate
[AFI_MAX
][SAFI_MAX
];
134 /* counters for the various BMP packet types */
135 uint64_t cnt_update
, cnt_mirror
;
136 /* number of times this peer wasn't fast enough in consuming the
139 uint64_t cnt_mirror_overruns
;
142 /* synchronization / startup works by repeatedly finding the next
143 * table entry, the sync* fields note down what we sent last
145 struct prefix syncpos
;
146 struct bgp_dest
*syncrdpos
;
152 /* config & state for an active outbound connection. When the connection
153 * succeeds, "bmp" is set up.
156 PREDECL_SORTLIST_UNIQ(bmp_actives
);
158 #define BMP_DFLT_MINRETRY 30000
159 #define BMP_DFLT_MAXRETRY 720000
162 struct bmp_actives_item bai
;
163 struct bmp_targets
*targets
;
168 unsigned minretry
, maxretry
;
170 union sockunion addrsrc
;
172 struct resolver_query resq
;
175 unsigned addrpos
, addrtotal
;
176 union sockunion addrs
[8];
178 const char *last_err
;
179 struct thread
*t_timer
, *t_read
, *t_write
;
182 /* config & state for passive / listening sockets */
183 PREDECL_SORTLIST_UNIQ(bmp_listeners
);
185 struct bmp_listener
{
186 struct bmp_listeners_item bli
;
188 struct bmp_targets
*targets
;
190 union sockunion addr
;
193 struct thread
*t_accept
;
197 /* bmp_targets - plural since it may contain multiple bmp_listener &
198 * bmp_active items. If they have the same config, BMP session should be
199 * put in the same targets since that's a bit more effective.
201 PREDECL_SORTLIST_UNIQ(bmp_targets
);
204 struct bmp_targets_item bti
;
206 struct bmp_bgp
*bmpbgp
;
210 struct bmp_listeners_head listeners
;
214 #define BMP_STAT_DEFAULT_TIMER 60000
218 * - IPv4 / unicast & multicast
219 * - IPv6 / unicast & multicast
222 #define BMP_MON_PREPOLICY (1 << 0)
223 #define BMP_MON_POSTPOLICY (1 << 1)
224 uint8_t afimon
[AFI_MAX
][SAFI_MAX
];
227 struct bmp_actives_head actives
;
229 struct thread
*t_stats
;
230 struct bmp_session_head sessions
;
232 struct bmp_qhash_head updhash
;
233 struct bmp_qlist_head updlist
;
235 uint64_t cnt_accept
, cnt_aclrefused
;
239 DECLARE_QOBJ_TYPE(bmp_targets
);
241 /* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
242 * deleted in peer_backward hook. */
243 PREDECL_HASH(bmp_peerh
);
245 struct bmp_bgp_peer
{
246 struct bmp_peerh_item bpi
;
249 /* struct peer *peer; */
258 /* per struct bgp * data */
259 PREDECL_HASH(bmp_bgph
);
261 #define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00
264 struct bmp_bgph_item bbi
;
267 struct bmp_targets_head targets
;
269 struct bmp_mirrorq_head mirrorq
;
270 size_t mirror_qsize
, mirror_qsizemax
;
272 size_t mirror_qsizelimit
;
276 BMP_PEERDOWN_LOCAL_NOTIFY
= 1,
277 BMP_PEERDOWN_LOCAL_FSM
= 2,
278 BMP_PEERDOWN_REMOTE_NOTIFY
= 3,
279 BMP_PEERDOWN_REMOTE_CLOSE
= 4,
280 BMP_PEERDOWN_ENDMONITOR
= 5,
284 BMP_STATS_PFX_REJECTED
= 0,
285 BMP_STATS_PFX_DUP_ADV
= 1,
286 BMP_STATS_PFX_DUP_WITHDRAW
= 2,
287 BMP_STATS_UPD_LOOP_CLUSTER
= 3,
288 BMP_STATS_UPD_LOOP_ASPATH
= 4,
289 BMP_STATS_UPD_LOOP_ORIGINATOR
= 5,
290 BMP_STATS_UPD_LOOP_CONFED
= 6,
291 BMP_STATS_SIZE_ADJ_RIB_IN
= 7,
292 BMP_STATS_SIZE_LOC_RIB
= 8,
293 BMP_STATS_SIZE_ADJ_RIB_IN_SAFI
= 9,
294 BMP_STATS_SIZE_LOC_RIB_IN_SAFI
= 10,
295 BMP_STATS_UPD_7606_WITHDRAW
= 11,
296 BMP_STATS_PFX_7606_WITHDRAW
= 12,
297 BMP_STATS_UPD_DUP
= 13,
298 BMP_STATS_FRR_NH_INVALID
= 65531,
303 #endif /*_BGP_BMP_H_*/