]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_bmp.h
bgpd: Adding BGP GR Global & Per Neighbour FSM changes
[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;
82};
83
84/* This is for BMP Route Mirroring, which feeds fully raw BGP PDUs out to BMP
85 * receivers. So, this goes directly off packet RX/TX handling instead of
86 * grabbing bits from tables.
87 *
88 * There is *one* queue for each "struct bgp *" where we throw everything on,
89 * with a size limit. Refcount works the same as for monitoring above.
90 */
91
92PREDECL_LIST(bmp_mirrorq)
93
94struct bmp_mirrorq {
95 struct bmp_mirrorq_item bmi;
96
97 size_t refcount;
98 uint64_t peerid;
99 struct timeval tv;
100
101 size_t len;
102 uint8_t data[0];
103};
104
105enum {
106 BMP_AFI_INACTIVE = 0,
107 BMP_AFI_NEEDSYNC,
108 BMP_AFI_SYNC,
109 BMP_AFI_LIVE,
110};
111
112PREDECL_LIST(bmp_session)
113
114struct bmp_active;
115struct bmp_targets;
116
117/* an established BMP session to a peer */
118struct bmp {
119 struct bmp_session_item bsi;
120 struct bmp_targets *targets;
121 struct bmp_active *active;
6c29258c 122
6c29258c 123 int socket;
ed18356f 124 char remote[SU_ADDRSTRLEN + 6];
6c29258c 125 struct thread *t_read;
ed18356f
DL
126
127 struct pullwr *pullwr;
6c29258c
YO
128
129 int state;
ed18356f
DL
130
131 /* queue positions must remain synced with refcounts in the items.
132 * Whenever appending a queue item, we need to know the correct number
133 * of "struct bmp *" that want it, and when moving these positions
134 * ahead we need to make sure that refcount is decremented. Also, on
135 * disconnects we need to walk the queue and drop our reference.
136 */
137 struct bmp_queue_entry *queuepos;
138 struct bmp_mirrorq *mirrorpos;
139 bool mirror_lost;
140
141 /* enum BMP_AFI_* */
142 uint8_t afistate[AFI_MAX][SAFI_MAX];
143
144 /* counters for the various BMP packet types */
145 uint64_t cnt_update, cnt_mirror;
146 /* number of times this peer wasn't fast enough in consuming the
147 * mirror queue
148 */
149 uint64_t cnt_mirror_overruns;
150 struct timeval t_up;
151
152 /* synchronization / startup works by repeatedly finding the next
153 * table entry, the sync* fields note down what we sent last
154 */
155 struct prefix syncpos;
156 uint64_t syncpeerid;
157 afi_t syncafi;
158 safi_t syncsafi;
159};
160
161/* config & state for an active outbound connection. When the connection
162 * succeeds, "bmp" is set up.
163 */
164
165PREDECL_SORTLIST_UNIQ(bmp_actives)
166
167#define BMP_DFLT_MINRETRY 30000
168#define BMP_DFLT_MAXRETRY 720000
169
170struct bmp_active {
171 struct bmp_actives_item bai;
172 struct bmp_targets *targets;
173 struct bmp *bmp;
174
175 char *hostname;
176 int port;
177 unsigned minretry, maxretry;
178
179 struct resolver_query resq;
180
181 unsigned curretry;
182 unsigned addrpos, addrtotal;
183 union sockunion addrs[8];
184 int socket;
3286ca07 185 const char *last_err;
ed18356f
DL
186 struct thread *t_timer, *t_read, *t_write;
187};
188
189/* config & state for passive / listening sockets */
190PREDECL_SORTLIST_UNIQ(bmp_listeners)
191
192struct bmp_listener {
193 struct bmp_listeners_item bli;
194
195 struct bmp_targets *targets;
196
197 union sockunion addr;
198 int port;
199
200 struct thread *t_accept;
201 int sock;
202};
203
204/* bmp_targets - plural since it may contain multiple bmp_listener &
205 * bmp_active items. If they have the same config, BMP session should be
206 * put in the same targets since that's a bit more effective.
207 */
208PREDECL_SORTLIST_UNIQ(bmp_targets)
209
210struct bmp_targets {
211 struct bmp_targets_item bti;
212
213 struct bmp_bgp *bmpbgp;
214 struct bgp *bgp;
215 char *name;
216
217 struct bmp_listeners_head listeners;
218
219 char *acl_name;
220 char *acl6_name;
221#define BMP_STAT_DEFAULT_TIMER 60000
222 int stat_msec;
223
224 /* only IPv4 & IPv6 / unicast & multicast supported for now */
225#define BMP_MON_PREPOLICY (1 << 0)
226#define BMP_MON_POSTPOLICY (1 << 1)
227 uint8_t afimon[AFI_MAX][SAFI_MAX];
228 bool mirror;
229
230 struct bmp_actives_head actives;
231
232 struct thread *t_stats;
233 struct bmp_session_head sessions;
234
235 struct bmp_qhash_head updhash;
236 struct bmp_qlist_head updlist;
237
238 uint64_t cnt_accept, cnt_aclrefused;
239
240 QOBJ_FIELDS
241};
242DECLARE_QOBJ_TYPE(bmp_targets)
243
244/* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
245 * deleted in peer_backward hook. */
246PREDECL_HASH(bmp_peerh)
247
248struct bmp_bgp_peer {
249 struct bmp_peerh_item bpi;
250
251 uint64_t peerid;
252 /* struct peer *peer; */
253
254 uint8_t *open_rx;
255 size_t open_rx_len;
256
257 uint8_t *open_tx;
258 size_t open_tx_len;
259};
260
261/* per struct bgp * data */
262PREDECL_HASH(bmp_bgph)
263
264struct bmp_bgp {
265 struct bmp_bgph_item bbi;
266
267 struct bgp *bgp;
268 struct bmp_targets_head targets;
269
270 struct bmp_mirrorq_head mirrorq;
271 size_t mirror_qsize, mirror_qsizemax;
272
273 size_t mirror_qsizelimit;
274};
275
276enum {
277 BMP_PEERDOWN_LOCAL_NOTIFY = 1,
278 BMP_PEERDOWN_LOCAL_FSM = 2,
279 BMP_PEERDOWN_REMOTE_NOTIFY = 3,
280 BMP_PEERDOWN_REMOTE_CLOSE = 4,
281 BMP_PEERDOWN_ENDMONITOR = 5,
282};
283
284enum {
285 BMP_STATS_PFX_REJECTED = 0,
286 BMP_STATS_PFX_DUP_ADV = 1,
287 BMP_STATS_PFX_DUP_WITHDRAW = 2,
288 BMP_STATS_UPD_LOOP_CLUSTER = 3,
289 BMP_STATS_UPD_LOOP_ASPATH = 4,
290 BMP_STATS_UPD_LOOP_ORIGINATOR = 5,
291 BMP_STATS_UPD_LOOP_CONFED = 6,
292 BMP_STATS_SIZE_ADJ_RIB_IN = 7,
293 BMP_STATS_SIZE_LOC_RIB = 8,
294 BMP_STATS_SIZE_ADJ_RIB_IN_SAFI = 9,
295 BMP_STATS_SIZE_LOC_RIB_IN_SAFI = 10,
296 BMP_STATS_UPD_7606_WITHDRAW = 11,
297 BMP_STATS_PFX_7606_WITHDRAW = 12,
298 BMP_STATS_UPD_DUP = 13,
299 BMP_STATS_FRR_NH_INVALID = 65531,
6c29258c
YO
300};
301
ed18356f 302DECLARE_MGROUP(BMP)
6c29258c 303
6c29258c 304#endif /*_BGP_BMP_H_*/