]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_bmp.h
bgpd: Implementing a hash table for connected address - ipv4/ipv6
[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;
185 struct thread *t_timer, *t_read, *t_write;
186};
187
188/* config & state for passive / listening sockets */
189PREDECL_SORTLIST_UNIQ(bmp_listeners)
190
191struct bmp_listener {
192 struct bmp_listeners_item bli;
193
194 struct bmp_targets *targets;
195
196 union sockunion addr;
197 int port;
198
199 struct thread *t_accept;
200 int sock;
201};
202
203/* bmp_targets - plural since it may contain multiple bmp_listener &
204 * bmp_active items. If they have the same config, BMP session should be
205 * put in the same targets since that's a bit more effective.
206 */
207PREDECL_SORTLIST_UNIQ(bmp_targets)
208
209struct bmp_targets {
210 struct bmp_targets_item bti;
211
212 struct bmp_bgp *bmpbgp;
213 struct bgp *bgp;
214 char *name;
215
216 struct bmp_listeners_head listeners;
217
218 char *acl_name;
219 char *acl6_name;
220#define BMP_STAT_DEFAULT_TIMER 60000
221 int stat_msec;
222
223 /* only IPv4 & IPv6 / unicast & multicast supported for now */
224#define BMP_MON_PREPOLICY (1 << 0)
225#define BMP_MON_POSTPOLICY (1 << 1)
226 uint8_t afimon[AFI_MAX][SAFI_MAX];
227 bool mirror;
228
229 struct bmp_actives_head actives;
230
231 struct thread *t_stats;
232 struct bmp_session_head sessions;
233
234 struct bmp_qhash_head updhash;
235 struct bmp_qlist_head updlist;
236
237 uint64_t cnt_accept, cnt_aclrefused;
238
239 QOBJ_FIELDS
240};
241DECLARE_QOBJ_TYPE(bmp_targets)
242
243/* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
244 * deleted in peer_backward hook. */
245PREDECL_HASH(bmp_peerh)
246
247struct bmp_bgp_peer {
248 struct bmp_peerh_item bpi;
249
250 uint64_t peerid;
251 /* struct peer *peer; */
252
253 uint8_t *open_rx;
254 size_t open_rx_len;
255
256 uint8_t *open_tx;
257 size_t open_tx_len;
258};
259
260/* per struct bgp * data */
261PREDECL_HASH(bmp_bgph)
262
263struct bmp_bgp {
264 struct bmp_bgph_item bbi;
265
266 struct bgp *bgp;
267 struct bmp_targets_head targets;
268
269 struct bmp_mirrorq_head mirrorq;
270 size_t mirror_qsize, mirror_qsizemax;
271
272 size_t mirror_qsizelimit;
273};
274
275enum {
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,
281};
282
283enum {
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,
6c29258c
YO
299};
300
ed18356f 301DECLARE_MGROUP(BMP)
6c29258c 302
6c29258c 303#endif /*_BGP_BMP_H_*/