]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_bmp.h
Merge pull request #8063 from ton31337/fix/typo_enum_bestpath
[mirror_frr.git] / bgpd / bgp_bmp.h
CommitLineData
6c29258c
YO
1/* BMP support.
2 * Copyright (C) 2018 Yasuhiro Ohara
ed18356f 3 * Copyright (C) 2019 David Lamparter for NetDEF, Inc.
6c29258c 4 *
ed18356f
DL
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.
6c29258c 9 *
ed18356f
DL
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.
6c29258c
YO
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
ed18356f
DL
23#include "zebra.h"
24#include "typesafe.h"
25#include "pullwr.h"
26#include "qobj.h"
27#include "resolver.h"
28
6c29258c
YO
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
6c29258c 46#define BMP_PeerUp 2
ed18356f
DL
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
69PREDECL_DLIST(bmp_qlist)
70PREDECL_HASH(bmp_qhash)
71
72struct 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;
87102aa0 82
83 /* initialized only for L2VPN/EVPN (S)AFIs */
84 struct prefix_rd rd;
ed18356f
DL
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
95PREDECL_LIST(bmp_mirrorq)
96
97struct 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
108enum {
109 BMP_AFI_INACTIVE = 0,
110 BMP_AFI_NEEDSYNC,
111 BMP_AFI_SYNC,
112 BMP_AFI_LIVE,
113};
114
115PREDECL_LIST(bmp_session)
116
117struct bmp_active;
118struct bmp_targets;
119
120/* an established BMP session to a peer */
121struct bmp {
122 struct bmp_session_item bsi;
123 struct bmp_targets *targets;
124 struct bmp_active *active;
6c29258c 125
6c29258c 126 int socket;
ed18356f 127 char remote[SU_ADDRSTRLEN + 6];
6c29258c 128 struct thread *t_read;
ed18356f
DL
129
130 struct pullwr *pullwr;
6c29258c
YO
131
132 int state;
ed18356f
DL
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;
09319b4e 159 struct bgp_dest *syncrdpos;
ed18356f
DL
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
169PREDECL_SORTLIST_UNIQ(bmp_actives)
170
171#define BMP_DFLT_MINRETRY 30000
172#define BMP_DFLT_MAXRETRY 720000
173
174struct 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
183 struct resolver_query resq;
184
185 unsigned curretry;
186 unsigned addrpos, addrtotal;
187 union sockunion addrs[8];
188 int socket;
3286ca07 189 const char *last_err;
ed18356f
DL
190 struct thread *t_timer, *t_read, *t_write;
191};
192
193/* config & state for passive / listening sockets */
194PREDECL_SORTLIST_UNIQ(bmp_listeners)
195
196struct bmp_listener {
197 struct bmp_listeners_item bli;
198
199 struct bmp_targets *targets;
200
201 union sockunion addr;
202 int port;
203
204 struct thread *t_accept;
205 int sock;
206};
207
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.
211 */
212PREDECL_SORTLIST_UNIQ(bmp_targets)
213
214struct bmp_targets {
215 struct bmp_targets_item bti;
216
217 struct bmp_bgp *bmpbgp;
218 struct bgp *bgp;
219 char *name;
220
221 struct bmp_listeners_head listeners;
222
223 char *acl_name;
224 char *acl6_name;
225#define BMP_STAT_DEFAULT_TIMER 60000
226 int stat_msec;
227
87102aa0 228 /* only supporting:
229 * - IPv4 / unicast & multicast
230 * - IPv6 / unicast & multicast
231 * - L2VPN / EVPN
232 */
ed18356f
DL
233#define BMP_MON_PREPOLICY (1 << 0)
234#define BMP_MON_POSTPOLICY (1 << 1)
235 uint8_t afimon[AFI_MAX][SAFI_MAX];
236 bool mirror;
237
238 struct bmp_actives_head actives;
239
240 struct thread *t_stats;
241 struct bmp_session_head sessions;
242
243 struct bmp_qhash_head updhash;
244 struct bmp_qlist_head updlist;
245
246 uint64_t cnt_accept, cnt_aclrefused;
247
248 QOBJ_FIELDS
249};
250DECLARE_QOBJ_TYPE(bmp_targets)
251
252/* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
253 * deleted in peer_backward hook. */
254PREDECL_HASH(bmp_peerh)
255
256struct bmp_bgp_peer {
257 struct bmp_peerh_item bpi;
258
259 uint64_t peerid;
260 /* struct peer *peer; */
261
262 uint8_t *open_rx;
263 size_t open_rx_len;
264
265 uint8_t *open_tx;
266 size_t open_tx_len;
267};
268
269/* per struct bgp * data */
270PREDECL_HASH(bmp_bgph)
271
272struct bmp_bgp {
273 struct bmp_bgph_item bbi;
274
275 struct bgp *bgp;
276 struct bmp_targets_head targets;
277
278 struct bmp_mirrorq_head mirrorq;
279 size_t mirror_qsize, mirror_qsizemax;
280
281 size_t mirror_qsizelimit;
282};
283
284enum {
285 BMP_PEERDOWN_LOCAL_NOTIFY = 1,
286 BMP_PEERDOWN_LOCAL_FSM = 2,
287 BMP_PEERDOWN_REMOTE_NOTIFY = 3,
288 BMP_PEERDOWN_REMOTE_CLOSE = 4,
289 BMP_PEERDOWN_ENDMONITOR = 5,
290};
291
292enum {
293 BMP_STATS_PFX_REJECTED = 0,
294 BMP_STATS_PFX_DUP_ADV = 1,
295 BMP_STATS_PFX_DUP_WITHDRAW = 2,
296 BMP_STATS_UPD_LOOP_CLUSTER = 3,
297 BMP_STATS_UPD_LOOP_ASPATH = 4,
298 BMP_STATS_UPD_LOOP_ORIGINATOR = 5,
299 BMP_STATS_UPD_LOOP_CONFED = 6,
300 BMP_STATS_SIZE_ADJ_RIB_IN = 7,
301 BMP_STATS_SIZE_LOC_RIB = 8,
302 BMP_STATS_SIZE_ADJ_RIB_IN_SAFI = 9,
303 BMP_STATS_SIZE_LOC_RIB_IN_SAFI = 10,
304 BMP_STATS_UPD_7606_WITHDRAW = 11,
305 BMP_STATS_PFX_7606_WITHDRAW = 12,
306 BMP_STATS_UPD_DUP = 13,
307 BMP_STATS_FRR_NH_INVALID = 65531,
6c29258c
YO
308};
309
ed18356f 310DECLARE_MGROUP(BMP)
6c29258c 311
6c29258c 312#endif /*_BGP_BMP_H_*/