]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_bmp.h
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / bgpd / bgp_bmp.h
1 /* BMP support.
2 * Copyright (C) 2018 Yasuhiro Ohara
3 * Copyright (C) 2019 David Lamparter for NetDEF, Inc.
4 *
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)
8 * any later version.
9 *
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
13 * more details.
14 *
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
18 */
19
20 #ifndef _BGP_BMP_H_
21 #define _BGP_BMP_H_
22
23 #include "zebra.h"
24 #include "typesafe.h"
25 #include "pullwr.h"
26 #include "qobj.h"
27 #include "resolver.h"
28
29 #define BMP_VERSION_3 3
30
31 #define BMP_LENGTH_POS 1
32
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
41
42 #define BMP_READ_BUFSIZ 1024
43
44 /* bmp->state */
45 #define BMP_None 0
46 #define BMP_PeerUp 2
47 #define BMP_Run 3
48
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.
53 *
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.
58 *
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
61 * bmp_target.
62 *
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.)
67 */
68
69 PREDECL_DLIST(bmp_qlist);
70 PREDECL_HASH(bmp_qhash);
71
72 struct bmp_queue_entry {
73 struct bmp_qlist_item bli;
74 struct bmp_qhash_item bhi;
75
76 struct prefix p;
77 uint64_t peerid;
78 afi_t afi;
79 safi_t safi;
80
81 size_t refcount;
82
83 /* initialized only for L2VPN/EVPN (S)AFIs */
84 struct prefix_rd rd;
85 };
86
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.
90 *
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.
93 */
94
95 PREDECL_LIST(bmp_mirrorq);
96
97 struct bmp_mirrorq {
98 struct bmp_mirrorq_item bmi;
99
100 size_t refcount;
101 uint64_t peerid;
102 struct timeval tv;
103
104 size_t len;
105 uint8_t data[0];
106 };
107
108 enum {
109 BMP_AFI_INACTIVE = 0,
110 BMP_AFI_NEEDSYNC,
111 BMP_AFI_SYNC,
112 BMP_AFI_LIVE,
113 };
114
115 PREDECL_LIST(bmp_session);
116
117 struct bmp_active;
118 struct bmp_targets;
119
120 /* an established BMP session to a peer */
121 struct bmp {
122 struct bmp_session_item bsi;
123 struct bmp_targets *targets;
124 struct bmp_active *active;
125
126 int socket;
127 char remote[SU_ADDRSTRLEN + 6];
128 struct thread *t_read;
129
130 struct pullwr *pullwr;
131
132 int state;
133
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.
139 */
140 struct bmp_queue_entry *queuepos;
141 struct bmp_mirrorq *mirrorpos;
142 bool mirror_lost;
143
144 /* enum BMP_AFI_* */
145 uint8_t afistate[AFI_MAX][SAFI_MAX];
146
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
150 * mirror queue
151 */
152 uint64_t cnt_mirror_overruns;
153 struct timeval t_up;
154
155 /* synchronization / startup works by repeatedly finding the next
156 * table entry, the sync* fields note down what we sent last
157 */
158 struct prefix syncpos;
159 struct bgp_dest *syncrdpos;
160 uint64_t syncpeerid;
161 afi_t syncafi;
162 safi_t syncsafi;
163 };
164
165 /* config & state for an active outbound connection. When the connection
166 * succeeds, "bmp" is set up.
167 */
168
169 PREDECL_SORTLIST_UNIQ(bmp_actives);
170
171 #define BMP_DFLT_MINRETRY 30000
172 #define BMP_DFLT_MAXRETRY 720000
173
174 struct bmp_active {
175 struct bmp_actives_item bai;
176 struct bmp_targets *targets;
177 struct bmp *bmp;
178
179 char *hostname;
180 int port;
181 unsigned minretry, maxretry;
182 char *ifsrc;
183 union sockunion addrsrc;
184
185 struct resolver_query resq;
186
187 unsigned curretry;
188 unsigned addrpos, addrtotal;
189 union sockunion addrs[8];
190 int socket;
191 const char *last_err;
192 struct thread *t_timer, *t_read, *t_write;
193 };
194
195 /* config & state for passive / listening sockets */
196 PREDECL_SORTLIST_UNIQ(bmp_listeners);
197
198 struct bmp_listener {
199 struct bmp_listeners_item bli;
200
201 struct bmp_targets *targets;
202
203 union sockunion addr;
204 int port;
205
206 struct thread *t_accept;
207 int sock;
208 };
209
210 /* bmp_targets - plural since it may contain multiple bmp_listener &
211 * bmp_active items. If they have the same config, BMP session should be
212 * put in the same targets since that's a bit more effective.
213 */
214 PREDECL_SORTLIST_UNIQ(bmp_targets);
215
216 struct bmp_targets {
217 struct bmp_targets_item bti;
218
219 struct bmp_bgp *bmpbgp;
220 struct bgp *bgp;
221 char *name;
222
223 struct bmp_listeners_head listeners;
224
225 char *acl_name;
226 char *acl6_name;
227 #define BMP_STAT_DEFAULT_TIMER 60000
228 int stat_msec;
229
230 /* only supporting:
231 * - IPv4 / unicast & multicast
232 * - IPv6 / unicast & multicast
233 * - L2VPN / EVPN
234 */
235 #define BMP_MON_PREPOLICY (1 << 0)
236 #define BMP_MON_POSTPOLICY (1 << 1)
237 uint8_t afimon[AFI_MAX][SAFI_MAX];
238 bool mirror;
239
240 struct bmp_actives_head actives;
241
242 struct thread *t_stats;
243 struct bmp_session_head sessions;
244
245 struct bmp_qhash_head updhash;
246 struct bmp_qlist_head updlist;
247
248 uint64_t cnt_accept, cnt_aclrefused;
249
250 QOBJ_FIELDS;
251 };
252 DECLARE_QOBJ_TYPE(bmp_targets);
253
254 /* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
255 * deleted in peer_backward hook. */
256 PREDECL_HASH(bmp_peerh);
257
258 struct bmp_bgp_peer {
259 struct bmp_peerh_item bpi;
260
261 uint64_t peerid;
262 /* struct peer *peer; */
263
264 uint8_t *open_rx;
265 size_t open_rx_len;
266
267 uint8_t *open_tx;
268 size_t open_tx_len;
269 };
270
271 /* per struct bgp * data */
272 PREDECL_HASH(bmp_bgph);
273
274 #define BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE 0x00
275
276 struct bmp_bgp {
277 struct bmp_bgph_item bbi;
278
279 struct bgp *bgp;
280 struct bmp_targets_head targets;
281
282 struct bmp_mirrorq_head mirrorq;
283 size_t mirror_qsize, mirror_qsizemax;
284
285 size_t mirror_qsizelimit;
286 };
287
288 enum {
289 BMP_PEERDOWN_LOCAL_NOTIFY = 1,
290 BMP_PEERDOWN_LOCAL_FSM = 2,
291 BMP_PEERDOWN_REMOTE_NOTIFY = 3,
292 BMP_PEERDOWN_REMOTE_CLOSE = 4,
293 BMP_PEERDOWN_ENDMONITOR = 5,
294 };
295
296 enum {
297 BMP_STATS_PFX_REJECTED = 0,
298 BMP_STATS_PFX_DUP_ADV = 1,
299 BMP_STATS_PFX_DUP_WITHDRAW = 2,
300 BMP_STATS_UPD_LOOP_CLUSTER = 3,
301 BMP_STATS_UPD_LOOP_ASPATH = 4,
302 BMP_STATS_UPD_LOOP_ORIGINATOR = 5,
303 BMP_STATS_UPD_LOOP_CONFED = 6,
304 BMP_STATS_SIZE_ADJ_RIB_IN = 7,
305 BMP_STATS_SIZE_LOC_RIB = 8,
306 BMP_STATS_SIZE_ADJ_RIB_IN_SAFI = 9,
307 BMP_STATS_SIZE_LOC_RIB_IN_SAFI = 10,
308 BMP_STATS_UPD_7606_WITHDRAW = 11,
309 BMP_STATS_PFX_7606_WITHDRAW = 12,
310 BMP_STATS_UPD_DUP = 13,
311 BMP_STATS_FRR_NH_INVALID = 65531,
312 };
313
314 DECLARE_MGROUP(BMP);
315
316 #endif /*_BGP_BMP_H_*/