2 * Copyright (C) 2018 Yasuhiro Ohara
3 * Copyright (C) 2019 David Lamparter for NetDEF, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #define BMP_VERSION_3 3
31 #define BMP_LENGTH_POS 1
33 /* BMP message types */
34 #define BMP_TYPE_ROUTE_MONITORING 0
35 #define BMP_TYPE_STATISTICS_REPORT 1
36 #define BMP_TYPE_PEER_DOWN_NOTIFICATION 2
37 #define BMP_TYPE_PEER_UP_NOTIFICATION 3
38 #define BMP_TYPE_INITIATION 4
39 #define BMP_TYPE_TERMINATION 5
40 #define BMP_TYPE_ROUTE_MIRRORING 6
42 #define BMP_READ_BUFSIZ 1024
49 /* This one is for BMP Route Monitoring messages, i.e. delivering updates
50 * in somewhat processed (as opposed to fully raw, see mirroring below) form.
51 * RFC explicitly says that we can skip old updates if we haven't sent them out
52 * yet and another newer update for the same prefix arrives.
54 * So, at most one of these can exist for each (bgp, afi, safi, prefix, peerid)
55 * tuple; if some prefix is "re-added" to the queue, the existing entry is
56 * instead moved to the end of the queue. This ensures that the queue size is
57 * bounded by the BGP table size.
59 * bmp_qlist is the queue itself while bmp_qhash is used to efficiently check
60 * whether a tuple is already on the list. The queue is maintained per
63 * refcount = number of "struct bmp *" whose queue position is before this
64 * entry, i.e. number of BMP sessions where we still want to send this out.
65 * Decremented on send so we know when we're done with an entry (i.e. this
66 * always happens from the front of the queue.)
69 PREDECL_DLIST(bmp_qlist
);
70 PREDECL_HASH(bmp_qhash
);
72 struct bmp_queue_entry
{
73 struct bmp_qlist_item bli
;
74 struct bmp_qhash_item bhi
;
83 /* initialized only for L2VPN/EVPN (S)AFIs */
87 /* This is for BMP Route Mirroring, which feeds fully raw BGP PDUs out to BMP
88 * receivers. So, this goes directly off packet RX/TX handling instead of
89 * grabbing bits from tables.
91 * There is *one* queue for each "struct bgp *" where we throw everything on,
92 * with a size limit. Refcount works the same as for monitoring above.
95 PREDECL_LIST(bmp_mirrorq
);
98 struct bmp_mirrorq_item bmi
;
109 BMP_AFI_INACTIVE
= 0,
115 PREDECL_LIST(bmp_session
);
120 /* an established BMP session to a peer */
122 struct bmp_session_item bsi
;
123 struct bmp_targets
*targets
;
124 struct bmp_active
*active
;
127 char remote
[SU_ADDRSTRLEN
+ 6];
128 struct thread
*t_read
;
130 struct pullwr
*pullwr
;
134 /* queue positions must remain synced with refcounts in the items.
135 * Whenever appending a queue item, we need to know the correct number
136 * of "struct bmp *" that want it, and when moving these positions
137 * ahead we need to make sure that refcount is decremented. Also, on
138 * disconnects we need to walk the queue and drop our reference.
140 struct bmp_queue_entry
*queuepos
;
141 struct bmp_mirrorq
*mirrorpos
;
145 uint8_t afistate
[AFI_MAX
][SAFI_MAX
];
147 /* counters for the various BMP packet types */
148 uint64_t cnt_update
, cnt_mirror
;
149 /* number of times this peer wasn't fast enough in consuming the
152 uint64_t cnt_mirror_overruns
;
155 /* synchronization / startup works by repeatedly finding the next
156 * table entry, the sync* fields note down what we sent last
158 struct prefix syncpos
;
159 struct bgp_dest
*syncrdpos
;
165 /* config & state for an active outbound connection. When the connection
166 * succeeds, "bmp" is set up.
169 PREDECL_SORTLIST_UNIQ(bmp_actives
);
171 #define BMP_DFLT_MINRETRY 30000
172 #define BMP_DFLT_MAXRETRY 720000
175 struct bmp_actives_item bai
;
176 struct bmp_targets
*targets
;
181 unsigned minretry
, maxretry
;
183 struct resolver_query resq
;
186 unsigned addrpos
, addrtotal
;
187 union sockunion addrs
[8];
189 const char *last_err
;
190 struct thread
*t_timer
, *t_read
, *t_write
;
193 /* config & state for passive / listening sockets */
194 PREDECL_SORTLIST_UNIQ(bmp_listeners
);
196 struct bmp_listener
{
197 struct bmp_listeners_item bli
;
199 struct bmp_targets
*targets
;
201 union sockunion addr
;
204 struct thread
*t_accept
;
208 /* bmp_targets - plural since it may contain multiple bmp_listener &
209 * bmp_active items. If they have the same config, BMP session should be
210 * put in the same targets since that's a bit more effective.
212 PREDECL_SORTLIST_UNIQ(bmp_targets
);
215 struct bmp_targets_item bti
;
217 struct bmp_bgp
*bmpbgp
;
221 struct bmp_listeners_head listeners
;
225 #define BMP_STAT_DEFAULT_TIMER 60000
229 * - IPv4 / unicast & multicast
230 * - IPv6 / unicast & multicast
233 #define BMP_MON_PREPOLICY (1 << 0)
234 #define BMP_MON_POSTPOLICY (1 << 1)
235 uint8_t afimon
[AFI_MAX
][SAFI_MAX
];
238 struct bmp_actives_head actives
;
240 struct thread
*t_stats
;
241 struct bmp_session_head sessions
;
243 struct bmp_qhash_head updhash
;
244 struct bmp_qlist_head updlist
;
246 uint64_t cnt_accept
, cnt_aclrefused
;
250 DECLARE_QOBJ_TYPE(bmp_targets
);
252 /* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
253 * deleted in peer_backward hook. */
254 PREDECL_HASH(bmp_peerh
);
256 struct bmp_bgp_peer
{
257 struct bmp_peerh_item bpi
;
260 /* struct peer *peer; */
269 /* per struct bgp * data */
270 PREDECL_HASH(bmp_bgph
);
272 #define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00
275 struct bmp_bgph_item bbi
;
278 struct bmp_targets_head targets
;
280 struct bmp_mirrorq_head mirrorq
;
281 size_t mirror_qsize
, mirror_qsizemax
;
283 size_t mirror_qsizelimit
;
287 BMP_PEERDOWN_LOCAL_NOTIFY
= 1,
288 BMP_PEERDOWN_LOCAL_FSM
= 2,
289 BMP_PEERDOWN_REMOTE_NOTIFY
= 3,
290 BMP_PEERDOWN_REMOTE_CLOSE
= 4,
291 BMP_PEERDOWN_ENDMONITOR
= 5,
295 BMP_STATS_PFX_REJECTED
= 0,
296 BMP_STATS_PFX_DUP_ADV
= 1,
297 BMP_STATS_PFX_DUP_WITHDRAW
= 2,
298 BMP_STATS_UPD_LOOP_CLUSTER
= 3,
299 BMP_STATS_UPD_LOOP_ASPATH
= 4,
300 BMP_STATS_UPD_LOOP_ORIGINATOR
= 5,
301 BMP_STATS_UPD_LOOP_CONFED
= 6,
302 BMP_STATS_SIZE_ADJ_RIB_IN
= 7,
303 BMP_STATS_SIZE_LOC_RIB
= 8,
304 BMP_STATS_SIZE_ADJ_RIB_IN_SAFI
= 9,
305 BMP_STATS_SIZE_LOC_RIB_IN_SAFI
= 10,
306 BMP_STATS_UPD_7606_WITHDRAW
= 11,
307 BMP_STATS_PFX_7606_WITHDRAW
= 12,
308 BMP_STATS_UPD_DUP
= 13,
309 BMP_STATS_FRR_NH_INVALID
= 65531,
314 #endif /*_BGP_BMP_H_*/