]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_bmp.c
Merge pull request #11723 from anlancs/fix/minor-10
[mirror_frr.git] / bgpd / bgp_bmp.c
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 #include <zebra.h>
21
22 #include "log.h"
23 #include "stream.h"
24 #include "sockunion.h"
25 #include "command.h"
26 #include "prefix.h"
27 #include "thread.h"
28 #include "linklist.h"
29 #include "queue.h"
30 #include "pullwr.h"
31 #include "memory.h"
32 #include "network.h"
33 #include "filter.h"
34 #include "lib_errors.h"
35 #include "stream.h"
36 #include "libfrr.h"
37 #include "lib/version.h"
38 #include "jhash.h"
39 #include "termtable.h"
40
41 #include "bgpd/bgp_table.h"
42 #include "bgpd/bgpd.h"
43 #include "bgpd/bgp_route.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_dump.h"
46 #include "bgpd/bgp_errors.h"
47 #include "bgpd/bgp_packet.h"
48 #include "bgpd/bgp_bmp.h"
49 #include "bgpd/bgp_fsm.h"
50 #include "bgpd/bgp_updgrp.h"
51 #include "bgpd/bgp_vty.h"
52 #include "bgpd/bgp_trace.h"
53 #include "bgpd/bgp_network.h"
54
55 static void bmp_close(struct bmp *bmp);
56 static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp);
57 static void bmp_targets_put(struct bmp_targets *bt);
58 static struct bmp_bgp_peer *bmp_bgp_peer_find(uint64_t peerid);
59 static struct bmp_bgp_peer *bmp_bgp_peer_get(struct peer *peer);
60 static void bmp_active_disconnected(struct bmp_active *ba);
61 static void bmp_active_put(struct bmp_active *ba);
62
63 DEFINE_MGROUP(BMP, "BMP (BGP Monitoring Protocol)");
64
65 DEFINE_MTYPE_STATIC(BMP, BMP_CONN, "BMP connection state");
66 DEFINE_MTYPE_STATIC(BMP, BMP_TARGETS, "BMP targets");
67 DEFINE_MTYPE_STATIC(BMP, BMP_TARGETSNAME, "BMP targets name");
68 DEFINE_MTYPE_STATIC(BMP, BMP_LISTENER, "BMP listener");
69 DEFINE_MTYPE_STATIC(BMP, BMP_ACTIVE, "BMP active connection config");
70 DEFINE_MTYPE_STATIC(BMP, BMP_ACLNAME, "BMP access-list name");
71 DEFINE_MTYPE_STATIC(BMP, BMP_QUEUE, "BMP update queue item");
72 DEFINE_MTYPE_STATIC(BMP, BMP, "BMP instance state");
73 DEFINE_MTYPE_STATIC(BMP, BMP_MIRRORQ, "BMP route mirroring buffer");
74 DEFINE_MTYPE_STATIC(BMP, BMP_PEER, "BMP per BGP peer data");
75 DEFINE_MTYPE_STATIC(BMP, BMP_OPEN, "BMP stored BGP OPEN message");
76
77 DEFINE_QOBJ_TYPE(bmp_targets);
78
79 static int bmp_bgp_cmp(const struct bmp_bgp *a, const struct bmp_bgp *b)
80 {
81 if (a->bgp < b->bgp)
82 return -1;
83 if (a->bgp > b->bgp)
84 return 1;
85 return 0;
86 }
87
88 static uint32_t bmp_bgp_hash(const struct bmp_bgp *e)
89 {
90 return jhash(&e->bgp, sizeof(e->bgp), 0x55aa5a5a);
91 }
92
93 DECLARE_HASH(bmp_bgph, struct bmp_bgp, bbi, bmp_bgp_cmp, bmp_bgp_hash);
94
95 struct bmp_bgph_head bmp_bgph;
96
97 static int bmp_bgp_peer_cmp(const struct bmp_bgp_peer *a,
98 const struct bmp_bgp_peer *b)
99 {
100 if (a->peerid < b->peerid)
101 return -1;
102 if (a->peerid > b->peerid)
103 return 1;
104 return 0;
105 }
106
107 static uint32_t bmp_bgp_peer_hash(const struct bmp_bgp_peer *e)
108 {
109 return e->peerid;
110 }
111
112 DECLARE_HASH(bmp_peerh, struct bmp_bgp_peer, bpi,
113 bmp_bgp_peer_cmp, bmp_bgp_peer_hash);
114
115 struct bmp_peerh_head bmp_peerh;
116
117 DECLARE_LIST(bmp_mirrorq, struct bmp_mirrorq, bmi);
118
119 /* listener management */
120
121 static int bmp_listener_cmp(const struct bmp_listener *a,
122 const struct bmp_listener *b)
123 {
124 int c;
125
126 c = sockunion_cmp(&a->addr, &b->addr);
127 if (c)
128 return c;
129 if (a->port < b->port)
130 return -1;
131 if (a->port > b->port)
132 return 1;
133 return 0;
134 }
135
136 DECLARE_SORTLIST_UNIQ(bmp_listeners, struct bmp_listener, bli,
137 bmp_listener_cmp);
138
139 static void bmp_listener_put(struct bmp_listener *bl)
140 {
141 bmp_listeners_del(&bl->targets->listeners, bl);
142 XFREE(MTYPE_BMP_LISTENER, bl);
143 }
144
145 static int bmp_targets_cmp(const struct bmp_targets *a,
146 const struct bmp_targets *b)
147 {
148 return strcmp(a->name, b->name);
149 }
150
151 DECLARE_SORTLIST_UNIQ(bmp_targets, struct bmp_targets, bti, bmp_targets_cmp);
152
153 DECLARE_LIST(bmp_session, struct bmp, bsi);
154
155 DECLARE_DLIST(bmp_qlist, struct bmp_queue_entry, bli);
156
157 static int bmp_qhash_cmp(const struct bmp_queue_entry *a,
158 const struct bmp_queue_entry *b)
159 {
160 int ret;
161 if (a->afi == AFI_L2VPN && a->safi == SAFI_EVPN && b->afi == AFI_L2VPN
162 && b->safi == SAFI_EVPN) {
163 ret = prefix_cmp(&a->rd, &b->rd);
164 if (ret)
165 return ret;
166 } else if (a->afi == AFI_L2VPN && a->safi == SAFI_EVPN)
167 return 1;
168 else if (b->afi == AFI_L2VPN && b->safi == SAFI_EVPN)
169 return -1;
170
171 if (a->afi == b->afi && a->safi == SAFI_MPLS_VPN &&
172 b->safi == SAFI_MPLS_VPN) {
173 ret = prefix_cmp(&a->rd, &b->rd);
174 if (ret)
175 return ret;
176 } else if (a->safi == SAFI_MPLS_VPN)
177 return 1;
178 else if (b->safi == SAFI_MPLS_VPN)
179 return -1;
180
181 ret = prefix_cmp(&a->p, &b->p);
182 if (ret)
183 return ret;
184 ret = memcmp(&a->peerid, &b->peerid,
185 offsetof(struct bmp_queue_entry, refcount) -
186 offsetof(struct bmp_queue_entry, peerid));
187 return ret;
188 }
189
190 static uint32_t bmp_qhash_hkey(const struct bmp_queue_entry *e)
191 {
192 uint32_t key;
193
194 key = prefix_hash_key((void *)&e->p);
195 key = jhash(&e->peerid,
196 offsetof(struct bmp_queue_entry, refcount)
197 - offsetof(struct bmp_queue_entry, peerid),
198 key);
199 if ((e->afi == AFI_L2VPN && e->safi == SAFI_EVPN) ||
200 (e->safi == SAFI_MPLS_VPN))
201 key = jhash(&e->rd,
202 offsetof(struct bmp_queue_entry, rd)
203 - offsetof(struct bmp_queue_entry, refcount)
204 + PSIZE(e->rd.prefixlen),
205 key);
206
207 return key;
208 }
209
210 DECLARE_HASH(bmp_qhash, struct bmp_queue_entry, bhi,
211 bmp_qhash_cmp, bmp_qhash_hkey);
212
213 static int bmp_active_cmp(const struct bmp_active *a,
214 const struct bmp_active *b)
215 {
216 int c;
217
218 c = strcmp(a->hostname, b->hostname);
219 if (c)
220 return c;
221 if (a->port < b->port)
222 return -1;
223 if (a->port > b->port)
224 return 1;
225 return 0;
226 }
227
228 DECLARE_SORTLIST_UNIQ(bmp_actives, struct bmp_active, bai, bmp_active_cmp);
229
230 static struct bmp *bmp_new(struct bmp_targets *bt, int bmp_sock)
231 {
232 struct bmp *new = XCALLOC(MTYPE_BMP_CONN, sizeof(struct bmp));
233 afi_t afi;
234 safi_t safi;
235
236 monotime(&new->t_up);
237 new->targets = bt;
238 new->socket = bmp_sock;
239 new->syncafi = AFI_MAX;
240
241 FOREACH_AFI_SAFI (afi, safi) {
242 new->afistate[afi][safi] = bt->afimon[afi][safi]
243 ? BMP_AFI_NEEDSYNC : BMP_AFI_INACTIVE;
244 }
245
246 bmp_session_add_tail(&bt->sessions, new);
247 return new;
248 }
249
250 static void bmp_free(struct bmp *bmp)
251 {
252 bmp_session_del(&bmp->targets->sessions, bmp);
253 XFREE(MTYPE_BMP_CONN, bmp);
254 }
255
256 static void bmp_common_hdr(struct stream *s, uint8_t ver, uint8_t type)
257 {
258 stream_putc(s, ver);
259 stream_putl(s, 0); //dummy message length. will be set later.
260 stream_putc(s, type);
261 }
262
263 static void bmp_per_peer_hdr(struct stream *s, struct peer *peer,
264 uint8_t flags, const struct timeval *tv)
265 {
266 char peer_distinguisher[8];
267
268 #define BMP_PEER_TYPE_GLOBAL_INSTANCE 0
269 #define BMP_PEER_TYPE_RD_INSTANCE 1
270 #define BMP_PEER_TYPE_LOCAL_INSTANCE 2
271
272 #define BMP_PEER_FLAG_V (1 << 7)
273 #define BMP_PEER_FLAG_L (1 << 6)
274 #define BMP_PEER_FLAG_A (1 << 5)
275
276 /* Peer Type */
277 stream_putc(s, BMP_PEER_TYPE_GLOBAL_INSTANCE);
278
279 /* Peer Flags */
280 if (peer->su.sa.sa_family == AF_INET6)
281 SET_FLAG(flags, BMP_PEER_FLAG_V);
282 else
283 UNSET_FLAG(flags, BMP_PEER_FLAG_V);
284 stream_putc(s, flags);
285
286 /* Peer Distinguisher */
287 memset (&peer_distinguisher[0], 0, 8);
288 stream_put(s, &peer_distinguisher[0], 8);
289
290 /* Peer Address */
291 if (peer->su.sa.sa_family == AF_INET6)
292 stream_put(s, &peer->su.sin6.sin6_addr, 16);
293 else if (peer->su.sa.sa_family == AF_INET) {
294 stream_putl(s, 0);
295 stream_putl(s, 0);
296 stream_putl(s, 0);
297 stream_put_in_addr(s, &peer->su.sin.sin_addr);
298 } else {
299 stream_putl(s, 0);
300 stream_putl(s, 0);
301 stream_putl(s, 0);
302 stream_putl(s, 0);
303 }
304
305 /* Peer AS */
306 stream_putl(s, peer->as);
307
308 /* Peer BGP ID */
309 stream_put_in_addr(s, &peer->remote_id);
310
311 /* Timestamp */
312 if (tv) {
313 stream_putl(s, tv->tv_sec);
314 stream_putl(s, tv->tv_usec);
315 } else {
316 stream_putl(s, 0);
317 stream_putl(s, 0);
318 }
319 }
320
321 static void bmp_put_info_tlv(struct stream *s, uint16_t type,
322 const char *string)
323 {
324 int len = strlen (string);
325 stream_putw(s, type);
326 stream_putw(s, len);
327 stream_put(s, string, len);
328 }
329
330 static int bmp_send_initiation(struct bmp *bmp)
331 {
332 int len;
333 struct stream *s;
334 s = stream_new(BGP_MAX_PACKET_SIZE);
335 bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_INITIATION);
336
337 #define BMP_INFO_TYPE_SYSDESCR 1
338 #define BMP_INFO_TYPE_SYSNAME 2
339 bmp_put_info_tlv(s, BMP_INFO_TYPE_SYSDESCR,
340 FRR_FULL_NAME " " FRR_VER_SHORT);
341 bmp_put_info_tlv(s, BMP_INFO_TYPE_SYSNAME, cmd_hostname_get());
342
343 len = stream_get_endp(s);
344 stream_putl_at(s, BMP_LENGTH_POS, len); //message length is set.
345
346 pullwr_write_stream(bmp->pullwr, s);
347 stream_free(s);
348 return 0;
349 }
350
351 static void bmp_notify_put(struct stream *s, struct bgp_notify *nfy)
352 {
353 size_t len_pos;
354 uint8_t marker[16] = {
355 0xff, 0xff, 0xff, 0xff,
356 0xff, 0xff, 0xff, 0xff,
357 0xff, 0xff, 0xff, 0xff,
358 0xff, 0xff, 0xff, 0xff,
359 };
360
361 stream_put(s, marker, sizeof(marker));
362 len_pos = stream_get_endp(s);
363 stream_putw(s, 0);
364 stream_putc(s, BGP_MSG_NOTIFY);
365 stream_putc(s, nfy->code);
366 stream_putc(s, nfy->subcode);
367 stream_put(s, nfy->data, nfy->length);
368
369 stream_putw_at(s, len_pos, stream_get_endp(s) - len_pos
370 + sizeof(marker));
371 }
372
373 static struct stream *bmp_peerstate(struct peer *peer, bool down)
374 {
375 struct stream *s;
376 size_t len;
377 struct timeval uptime, uptime_real;
378
379 uptime.tv_sec = peer->uptime;
380 uptime.tv_usec = 0;
381 monotime_to_realtime(&uptime, &uptime_real);
382
383 #define BGP_BMP_MAX_PACKET_SIZE 1024
384 s = stream_new(BGP_MAX_PACKET_SIZE);
385
386 if (peer_established(peer) && !down) {
387 struct bmp_bgp_peer *bbpeer;
388
389 bmp_common_hdr(s, BMP_VERSION_3,
390 BMP_TYPE_PEER_UP_NOTIFICATION);
391 bmp_per_peer_hdr(s, peer, 0, &uptime_real);
392
393 /* Local Address (16 bytes) */
394 if (peer->su_local->sa.sa_family == AF_INET6)
395 stream_put(s, &peer->su_local->sin6.sin6_addr, 16);
396 else if (peer->su_local->sa.sa_family == AF_INET) {
397 stream_putl(s, 0);
398 stream_putl(s, 0);
399 stream_putl(s, 0);
400 stream_put_in_addr(s, &peer->su_local->sin.sin_addr);
401 }
402
403 /* Local Port, Remote Port */
404 if (peer->su_local->sa.sa_family == AF_INET6)
405 stream_putw(s, peer->su_local->sin6.sin6_port);
406 else if (peer->su_local->sa.sa_family == AF_INET)
407 stream_putw(s, peer->su_local->sin.sin_port);
408 if (peer->su_remote->sa.sa_family == AF_INET6)
409 stream_putw(s, peer->su_remote->sin6.sin6_port);
410 else if (peer->su_remote->sa.sa_family == AF_INET)
411 stream_putw(s, peer->su_remote->sin.sin_port);
412
413 static const uint8_t dummy_open[] = {
414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
415 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
416 0x00, 0x13, 0x01,
417 };
418
419 bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
420
421 if (bbpeer && bbpeer->open_tx)
422 stream_put(s, bbpeer->open_tx, bbpeer->open_tx_len);
423 else {
424 stream_put(s, dummy_open, sizeof(dummy_open));
425 zlog_warn("bmp: missing TX OPEN message for peer %s",
426 peer->host);
427 }
428 if (bbpeer && bbpeer->open_rx)
429 stream_put(s, bbpeer->open_rx, bbpeer->open_rx_len);
430 else {
431 stream_put(s, dummy_open, sizeof(dummy_open));
432 zlog_warn("bmp: missing RX OPEN message for peer %s",
433 peer->host);
434 }
435
436 if (peer->desc)
437 bmp_put_info_tlv(s, 0, peer->desc);
438 } else {
439 uint8_t type;
440 size_t type_pos;
441
442 bmp_common_hdr(s, BMP_VERSION_3,
443 BMP_TYPE_PEER_DOWN_NOTIFICATION);
444 bmp_per_peer_hdr(s, peer, 0, &uptime_real);
445
446 type_pos = stream_get_endp(s);
447 stream_putc(s, 0); /* placeholder for down reason */
448
449 switch (peer->last_reset) {
450 case PEER_DOWN_NOTIFY_RECEIVED:
451 type = BMP_PEERDOWN_REMOTE_NOTIFY;
452 bmp_notify_put(s, &peer->notify);
453 break;
454 case PEER_DOWN_CLOSE_SESSION:
455 type = BMP_PEERDOWN_REMOTE_CLOSE;
456 break;
457 case PEER_DOWN_WAITING_NHT:
458 type = BMP_PEERDOWN_LOCAL_FSM;
459 stream_putw(s, BGP_FSM_TcpConnectionFails);
460 break;
461 /*
462 * TODO: Map remaining PEER_DOWN_* reasons to RFC event codes.
463 * TODO: Implement BMP_PEERDOWN_LOCAL_NOTIFY.
464 *
465 * See RFC7854 ss. 4.9
466 */
467 default:
468 type = BMP_PEERDOWN_LOCAL_FSM;
469 stream_putw(s, BMP_PEER_DOWN_NO_RELEVANT_EVENT_CODE);
470 break;
471 }
472 stream_putc_at(s, type_pos, type);
473 }
474
475 len = stream_get_endp(s);
476 stream_putl_at(s, BMP_LENGTH_POS, len); //message length is set.
477 return s;
478 }
479
480
481 static int bmp_send_peerup(struct bmp *bmp)
482 {
483 struct peer *peer;
484 struct listnode *node;
485 struct stream *s;
486
487 /* Walk down all peers */
488 for (ALL_LIST_ELEMENTS_RO(bmp->targets->bgp->peer, node, peer)) {
489 s = bmp_peerstate(peer, false);
490 pullwr_write_stream(bmp->pullwr, s);
491 stream_free(s);
492 }
493
494 return 0;
495 }
496
497 /* XXX: kludge - filling the pullwr's buffer */
498 static void bmp_send_all(struct bmp_bgp *bmpbgp, struct stream *s)
499 {
500 struct bmp_targets *bt;
501 struct bmp *bmp;
502
503 frr_each(bmp_targets, &bmpbgp->targets, bt)
504 frr_each(bmp_session, &bt->sessions, bmp)
505 pullwr_write_stream(bmp->pullwr, s);
506 stream_free(s);
507 }
508
509 /*
510 * Route Mirroring
511 */
512
513 #define BMP_MIRROR_TLV_TYPE_BGP_MESSAGE 0
514 #define BMP_MIRROR_TLV_TYPE_INFO 1
515
516 #define BMP_MIRROR_INFO_CODE_ERRORPDU 0
517 #define BMP_MIRROR_INFO_CODE_LOSTMSGS 1
518
519 static struct bmp_mirrorq *bmp_pull_mirror(struct bmp *bmp)
520 {
521 struct bmp_mirrorq *bmq;
522
523 bmq = bmp->mirrorpos;
524 if (!bmq)
525 return NULL;
526
527 bmp->mirrorpos = bmp_mirrorq_next(&bmp->targets->bmpbgp->mirrorq, bmq);
528
529 bmq->refcount--;
530 if (!bmq->refcount) {
531 bmp->targets->bmpbgp->mirror_qsize -= sizeof(*bmq) + bmq->len;
532 bmp_mirrorq_del(&bmp->targets->bmpbgp->mirrorq, bmq);
533 }
534 return bmq;
535 }
536
537 static void bmp_mirror_cull(struct bmp_bgp *bmpbgp)
538 {
539 while (bmpbgp->mirror_qsize > bmpbgp->mirror_qsizelimit) {
540 struct bmp_mirrorq *bmq, *inner;
541 struct bmp_targets *bt;
542 struct bmp *bmp;
543
544 bmq = bmp_mirrorq_first(&bmpbgp->mirrorq);
545
546 frr_each(bmp_targets, &bmpbgp->targets, bt) {
547 if (!bt->mirror)
548 continue;
549 frr_each(bmp_session, &bt->sessions, bmp) {
550 if (bmp->mirrorpos != bmq)
551 continue;
552
553 while ((inner = bmp_pull_mirror(bmp))) {
554 if (!inner->refcount)
555 XFREE(MTYPE_BMP_MIRRORQ,
556 inner);
557 }
558
559 zlog_warn("bmp[%s] lost mirror messages due to buffer size limit",
560 bmp->remote);
561 bmp->mirror_lost = true;
562 pullwr_bump(bmp->pullwr);
563 }
564 }
565 }
566 }
567
568 static int bmp_mirror_packet(struct peer *peer, uint8_t type, bgp_size_t size,
569 struct stream *packet)
570 {
571 struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
572 struct timeval tv;
573 struct bmp_mirrorq *qitem;
574 struct bmp_targets *bt;
575 struct bmp *bmp;
576
577 frrtrace(3, frr_bgp, bmp_mirror_packet, peer, type, packet);
578
579 gettimeofday(&tv, NULL);
580
581 if (type == BGP_MSG_OPEN) {
582 struct bmp_bgp_peer *bbpeer = bmp_bgp_peer_get(peer);
583
584 XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx);
585
586 bbpeer->open_rx_len = size;
587 bbpeer->open_rx = XMALLOC(MTYPE_BMP_OPEN, size);
588 memcpy(bbpeer->open_rx, packet->data, size);
589 }
590
591 if (!bmpbgp)
592 return 0;
593
594 qitem = XCALLOC(MTYPE_BMP_MIRRORQ, sizeof(*qitem) + size);
595 qitem->peerid = peer->qobj_node.nid;
596 qitem->tv = tv;
597 qitem->len = size;
598 memcpy(qitem->data, packet->data, size);
599
600 frr_each(bmp_targets, &bmpbgp->targets, bt) {
601 if (!bt->mirror)
602 continue;
603 frr_each(bmp_session, &bt->sessions, bmp) {
604 qitem->refcount++;
605 if (!bmp->mirrorpos)
606 bmp->mirrorpos = qitem;
607 pullwr_bump(bmp->pullwr);
608 }
609 }
610 if (qitem->refcount == 0)
611 XFREE(MTYPE_BMP_MIRRORQ, qitem);
612 else {
613 bmpbgp->mirror_qsize += sizeof(*qitem) + size;
614 bmp_mirrorq_add_tail(&bmpbgp->mirrorq, qitem);
615
616 bmp_mirror_cull(bmpbgp);
617
618 bmpbgp->mirror_qsizemax = MAX(bmpbgp->mirror_qsizemax,
619 bmpbgp->mirror_qsize);
620 }
621 return 0;
622 }
623
624 static void bmp_wrmirror_lost(struct bmp *bmp, struct pullwr *pullwr)
625 {
626 struct stream *s;
627 struct timeval tv;
628
629 gettimeofday(&tv, NULL);
630
631 s = stream_new(BGP_MAX_PACKET_SIZE);
632
633 bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_ROUTE_MIRRORING);
634 bmp_per_peer_hdr(s, bmp->targets->bgp->peer_self, 0, &tv);
635
636 stream_putw(s, BMP_MIRROR_TLV_TYPE_INFO);
637 stream_putw(s, 2);
638 stream_putw(s, BMP_MIRROR_INFO_CODE_LOSTMSGS);
639 stream_putl_at(s, BMP_LENGTH_POS, stream_get_endp(s));
640
641 bmp->cnt_mirror_overruns++;
642 pullwr_write_stream(bmp->pullwr, s);
643 stream_free(s);
644 }
645
646 static bool bmp_wrmirror(struct bmp *bmp, struct pullwr *pullwr)
647 {
648 struct bmp_mirrorq *bmq;
649 struct peer *peer;
650 bool written = false;
651
652 if (bmp->mirror_lost) {
653 bmp_wrmirror_lost(bmp, pullwr);
654 bmp->mirror_lost = false;
655 return true;
656 }
657
658 bmq = bmp_pull_mirror(bmp);
659 if (!bmq)
660 return false;
661
662 peer = QOBJ_GET_TYPESAFE(bmq->peerid, peer);
663 if (!peer) {
664 zlog_info("bmp: skipping mirror message for deleted peer");
665 goto out;
666 }
667
668 struct stream *s;
669 s = stream_new(BGP_MAX_PACKET_SIZE);
670
671 bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_ROUTE_MIRRORING);
672 bmp_per_peer_hdr(s, peer, 0, &bmq->tv);
673
674 /* BMP Mirror TLV. */
675 stream_putw(s, BMP_MIRROR_TLV_TYPE_BGP_MESSAGE);
676 stream_putw(s, bmq->len);
677 stream_putl_at(s, BMP_LENGTH_POS, stream_get_endp(s) + bmq->len);
678
679 bmp->cnt_mirror++;
680 pullwr_write_stream(bmp->pullwr, s);
681 pullwr_write(bmp->pullwr, bmq->data, bmq->len);
682
683 stream_free(s);
684 written = true;
685
686 out:
687 if (!bmq->refcount)
688 XFREE(MTYPE_BMP_MIRRORQ, bmq);
689 return written;
690 }
691
692 static int bmp_outgoing_packet(struct peer *peer, uint8_t type, bgp_size_t size,
693 struct stream *packet)
694 {
695 if (type == BGP_MSG_OPEN) {
696 frrtrace(2, frr_bgp, bmp_update_saved_open, peer, packet);
697
698 struct bmp_bgp_peer *bbpeer = bmp_bgp_peer_get(peer);
699
700 XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx);
701
702 bbpeer->open_tx_len = size;
703 bbpeer->open_tx = XMALLOC(MTYPE_BMP_OPEN, size);
704 memcpy(bbpeer->open_tx, packet->data, size);
705 }
706 return 0;
707 }
708
709 static int bmp_peer_status_changed(struct peer *peer)
710 {
711 struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
712 struct bmp_bgp_peer *bbpeer, *bbdopp;
713
714 frrtrace(1, frr_bgp, bmp_peer_status_changed, peer);
715
716 if (!bmpbgp)
717 return 0;
718
719 if (peer->status == Deleted) {
720 bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
721 if (bbpeer) {
722 XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx);
723 XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx);
724 bmp_peerh_del(&bmp_peerh, bbpeer);
725 XFREE(MTYPE_BMP_PEER, bbpeer);
726 }
727 return 0;
728 }
729
730 /* Check if this peer just went to Established */
731 if ((peer->ostatus != OpenConfirm) || !(peer_established(peer)))
732 return 0;
733
734 if (peer->doppelganger && (peer->doppelganger->status != Deleted)) {
735 bbpeer = bmp_bgp_peer_get(peer);
736 bbdopp = bmp_bgp_peer_find(peer->doppelganger->qobj_node.nid);
737 if (bbdopp) {
738 XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx);
739 XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx);
740
741 bbpeer->open_tx = bbdopp->open_tx;
742 bbpeer->open_tx_len = bbdopp->open_tx_len;
743 bbpeer->open_rx = bbdopp->open_rx;
744 bbpeer->open_rx_len = bbdopp->open_rx_len;
745
746 bmp_peerh_del(&bmp_peerh, bbdopp);
747 XFREE(MTYPE_BMP_PEER, bbdopp);
748 }
749 }
750
751 bmp_send_all(bmpbgp, bmp_peerstate(peer, false));
752 return 0;
753 }
754
755 static int bmp_peer_backward(struct peer *peer)
756 {
757 struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
758 struct bmp_bgp_peer *bbpeer;
759
760 frrtrace(1, frr_bgp, bmp_peer_backward_transition, peer);
761
762 if (!bmpbgp)
763 return 0;
764
765 bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
766 if (bbpeer) {
767 XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx);
768 bbpeer->open_tx_len = 0;
769 XFREE(MTYPE_BMP_OPEN, bbpeer->open_rx);
770 bbpeer->open_rx_len = 0;
771 }
772
773 bmp_send_all(bmpbgp, bmp_peerstate(peer, true));
774 return 0;
775 }
776
777 static void bmp_eor(struct bmp *bmp, afi_t afi, safi_t safi, uint8_t flags)
778 {
779 struct peer *peer;
780 struct listnode *node;
781 struct stream *s, *s2;
782 iana_afi_t pkt_afi = IANA_AFI_IPV4;
783 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
784
785 frrtrace(3, frr_bgp, bmp_eor, afi, safi, flags);
786
787 s = stream_new(BGP_MAX_PACKET_SIZE);
788
789 /* Make BGP update packet. */
790 bgp_packet_set_marker(s, BGP_MSG_UPDATE);
791
792 /* Unfeasible Routes Length */
793 stream_putw(s, 0);
794
795 if (afi == AFI_IP && safi == SAFI_UNICAST) {
796 /* Total Path Attribute Length */
797 stream_putw(s, 0);
798 } else {
799 /* Convert AFI, SAFI to values for packet. */
800 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
801
802 /* Total Path Attribute Length */
803 stream_putw(s, 6);
804 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
805 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
806 stream_putc(s, 3);
807 stream_putw(s, pkt_afi);
808 stream_putc(s, pkt_safi);
809 }
810
811 bgp_packet_set_size(s);
812
813 for (ALL_LIST_ELEMENTS_RO(bmp->targets->bgp->peer, node, peer)) {
814 if (!peer->afc_nego[afi][safi])
815 continue;
816
817 s2 = stream_new(BGP_MAX_PACKET_SIZE);
818
819 bmp_common_hdr(s2, BMP_VERSION_3,
820 BMP_TYPE_ROUTE_MONITORING);
821 bmp_per_peer_hdr(s2, peer, flags, NULL);
822
823 stream_putl_at(s2, BMP_LENGTH_POS,
824 stream_get_endp(s) + stream_get_endp(s2));
825
826 bmp->cnt_update++;
827 pullwr_write_stream(bmp->pullwr, s2);
828 pullwr_write_stream(bmp->pullwr, s);
829 stream_free(s2);
830 }
831 stream_free(s);
832 }
833
834 static struct stream *bmp_update(const struct prefix *p, struct prefix_rd *prd,
835 struct peer *peer, struct attr *attr,
836 afi_t afi, safi_t safi)
837 {
838 struct bpacket_attr_vec_arr vecarr;
839 struct stream *s;
840 size_t attrlen_pos = 0, mpattrlen_pos = 0;
841 bgp_size_t total_attr_len = 0;
842
843 bpacket_attr_vec_arr_reset(&vecarr);
844
845 s = stream_new(BGP_MAX_PACKET_SIZE);
846 bgp_packet_set_marker(s, BGP_MSG_UPDATE);
847
848 /* 2: withdrawn routes length */
849 stream_putw(s, 0);
850
851 /* 3: total attributes length - attrlen_pos stores the position */
852 attrlen_pos = stream_get_endp(s);
853 stream_putw(s, 0);
854
855 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
856 total_attr_len = bgp_packet_attribute(NULL, peer, s, attr,
857 &vecarr, NULL, afi, safi, peer, NULL, NULL, 0, 0, 0);
858
859 /* space check? */
860
861 /* peer_cap_enhe & add-path removed */
862 if (afi == AFI_IP && safi == SAFI_UNICAST)
863 stream_put_prefix(s, p);
864 else {
865 size_t p1 = stream_get_endp(s);
866
867 /* MPLS removed for now */
868
869 mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
870 &vecarr, attr);
871 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, NULL, 0, 0, 0,
872 attr);
873 bgp_packet_mpattr_end(s, mpattrlen_pos);
874 total_attr_len += stream_get_endp(s) - p1;
875 }
876
877 /* set the total attribute length correctly */
878 stream_putw_at(s, attrlen_pos, total_attr_len);
879 bgp_packet_set_size(s);
880 return s;
881 }
882
883 static struct stream *bmp_withdraw(const struct prefix *p,
884 struct prefix_rd *prd, afi_t afi,
885 safi_t safi)
886 {
887 struct stream *s;
888 size_t attrlen_pos = 0, mp_start, mplen_pos;
889 bgp_size_t total_attr_len = 0;
890 bgp_size_t unfeasible_len;
891
892 s = stream_new(BGP_MAX_PACKET_SIZE);
893
894 bgp_packet_set_marker(s, BGP_MSG_UPDATE);
895 stream_putw(s, 0);
896
897 if (afi == AFI_IP && safi == SAFI_UNICAST) {
898 stream_put_prefix(s, p);
899 unfeasible_len = stream_get_endp(s) - BGP_HEADER_SIZE
900 - BGP_UNFEASIBLE_LEN;
901 stream_putw_at(s, BGP_HEADER_SIZE, unfeasible_len);
902 stream_putw(s, 0);
903 } else {
904 attrlen_pos = stream_get_endp(s);
905 /* total attr length = 0 for now. reevaluate later */
906 stream_putw(s, 0);
907 mp_start = stream_get_endp(s);
908 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
909
910 bgp_packet_mpunreach_prefix(s, p, afi, safi, prd, NULL, 0, 0, 0,
911 NULL);
912 /* Set the mp_unreach attr's length */
913 bgp_packet_mpunreach_end(s, mplen_pos);
914
915 /* Set total path attribute length. */
916 total_attr_len = stream_get_endp(s) - mp_start;
917 stream_putw_at(s, attrlen_pos, total_attr_len);
918 }
919
920 bgp_packet_set_size(s);
921 return s;
922 }
923
924 static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags,
925 const struct prefix *p, struct prefix_rd *prd,
926 struct attr *attr, afi_t afi, safi_t safi,
927 time_t uptime)
928 {
929 struct stream *hdr, *msg;
930 struct timeval tv = { .tv_sec = uptime, .tv_usec = 0 };
931 struct timeval uptime_real;
932
933 monotime_to_realtime(&tv, &uptime_real);
934 if (attr)
935 msg = bmp_update(p, prd, peer, attr, afi, safi);
936 else
937 msg = bmp_withdraw(p, prd, afi, safi);
938
939 hdr = stream_new(BGP_MAX_PACKET_SIZE);
940 bmp_common_hdr(hdr, BMP_VERSION_3, BMP_TYPE_ROUTE_MONITORING);
941 bmp_per_peer_hdr(hdr, peer, flags, &uptime_real);
942
943 stream_putl_at(hdr, BMP_LENGTH_POS,
944 stream_get_endp(hdr) + stream_get_endp(msg));
945
946 bmp->cnt_update++;
947 pullwr_write_stream(bmp->pullwr, hdr);
948 pullwr_write_stream(bmp->pullwr, msg);
949 stream_free(hdr);
950 stream_free(msg);
951 }
952
953 static bool bmp_wrsync(struct bmp *bmp, struct pullwr *pullwr)
954 {
955 afi_t afi;
956 safi_t safi;
957
958 if (bmp->syncafi == AFI_MAX) {
959 FOREACH_AFI_SAFI (afi, safi) {
960 if (bmp->afistate[afi][safi] != BMP_AFI_NEEDSYNC)
961 continue;
962
963 bmp->afistate[afi][safi] = BMP_AFI_SYNC;
964
965 bmp->syncafi = afi;
966 bmp->syncsafi = safi;
967 bmp->syncpeerid = 0;
968 memset(&bmp->syncpos, 0, sizeof(bmp->syncpos));
969 bmp->syncpos.family = afi2family(afi);
970 bmp->syncrdpos = NULL;
971 zlog_info("bmp[%s] %s %s sending table",
972 bmp->remote,
973 afi2str(bmp->syncafi),
974 safi2str(bmp->syncsafi));
975 /* break does not work here, 2 loops... */
976 goto afibreak;
977 }
978 if (bmp->syncafi == AFI_MAX)
979 return false;
980 }
981
982 afibreak:
983 afi = bmp->syncafi;
984 safi = bmp->syncsafi;
985
986 if (!bmp->targets->afimon[afi][safi]) {
987 /* shouldn't happen */
988 bmp->afistate[afi][safi] = BMP_AFI_INACTIVE;
989 bmp->syncafi = AFI_MAX;
990 bmp->syncsafi = SAFI_MAX;
991 return true;
992 }
993
994 struct bgp_table *table = bmp->targets->bgp->rib[afi][safi];
995 struct bgp_dest *bn = NULL;
996 struct bgp_path_info *bpi = NULL, *bpiter;
997 struct bgp_adj_in *adjin = NULL, *adjiter;
998
999 if ((afi == AFI_L2VPN && safi == SAFI_EVPN) ||
1000 (safi == SAFI_MPLS_VPN)) {
1001 /* initialize syncrdpos to the first
1002 * mid-layer table entry
1003 */
1004 if (!bmp->syncrdpos) {
1005 bmp->syncrdpos = bgp_table_top(table);
1006 if (!bmp->syncrdpos)
1007 goto eor;
1008 }
1009
1010 /* look for a valid mid-layer table */
1011 do {
1012 table = bgp_dest_get_bgp_table_info(bmp->syncrdpos);
1013 if (table) {
1014 break;
1015 }
1016 bmp->syncrdpos = bgp_route_next(bmp->syncrdpos);
1017 } while (bmp->syncrdpos);
1018
1019 /* mid-layer table completed */
1020 if (!bmp->syncrdpos)
1021 goto eor;
1022 }
1023
1024 bn = bgp_node_lookup(table, &bmp->syncpos);
1025 do {
1026 if (!bn) {
1027 bn = bgp_table_get_next(table, &bmp->syncpos);
1028 if (!bn) {
1029 if ((afi == AFI_L2VPN && safi == SAFI_EVPN) ||
1030 (safi == SAFI_MPLS_VPN)) {
1031 /* reset bottom-layer pointer */
1032 memset(&bmp->syncpos, 0,
1033 sizeof(bmp->syncpos));
1034 bmp->syncpos.family = afi2family(afi);
1035 /* check whethere there is a valid
1036 * next mid-layer table, otherwise
1037 * declare table completed (eor)
1038 */
1039 for (bmp->syncrdpos = bgp_route_next(
1040 bmp->syncrdpos);
1041 bmp->syncrdpos;
1042 bmp->syncrdpos = bgp_route_next(
1043 bmp->syncrdpos))
1044 if (bgp_dest_get_bgp_table_info(
1045 bmp->syncrdpos))
1046 return true;
1047 }
1048 eor:
1049 zlog_info("bmp[%s] %s %s table completed (EoR)",
1050 bmp->remote, afi2str(afi),
1051 safi2str(safi));
1052 bmp_eor(bmp, afi, safi, BMP_PEER_FLAG_L);
1053 bmp_eor(bmp, afi, safi, 0);
1054
1055 bmp->afistate[afi][safi] = BMP_AFI_LIVE;
1056 bmp->syncafi = AFI_MAX;
1057 bmp->syncsafi = SAFI_MAX;
1058 return true;
1059 }
1060 bmp->syncpeerid = 0;
1061 prefix_copy(&bmp->syncpos, bgp_dest_get_prefix(bn));
1062 }
1063
1064 if (bmp->targets->afimon[afi][safi] & BMP_MON_POSTPOLICY) {
1065 for (bpiter = bgp_dest_get_bgp_path_info(bn); bpiter;
1066 bpiter = bpiter->next) {
1067 if (!CHECK_FLAG(bpiter->flags, BGP_PATH_VALID))
1068 continue;
1069 if (bpiter->peer->qobj_node.nid
1070 <= bmp->syncpeerid)
1071 continue;
1072 if (bpi && bpiter->peer->qobj_node.nid
1073 > bpi->peer->qobj_node.nid)
1074 continue;
1075 bpi = bpiter;
1076 }
1077 }
1078 if (bmp->targets->afimon[afi][safi] & BMP_MON_PREPOLICY) {
1079 for (adjiter = bn->adj_in; adjiter;
1080 adjiter = adjiter->next) {
1081 if (adjiter->peer->qobj_node.nid
1082 <= bmp->syncpeerid)
1083 continue;
1084 if (adjin && adjiter->peer->qobj_node.nid
1085 > adjin->peer->qobj_node.nid)
1086 continue;
1087 adjin = adjiter;
1088 }
1089 }
1090 if (bpi || adjin)
1091 break;
1092
1093 bn = NULL;
1094 } while (1);
1095
1096 if (adjin && bpi
1097 && adjin->peer->qobj_node.nid < bpi->peer->qobj_node.nid) {
1098 bpi = NULL;
1099 bmp->syncpeerid = adjin->peer->qobj_node.nid;
1100 } else if (adjin && bpi
1101 && adjin->peer->qobj_node.nid > bpi->peer->qobj_node.nid) {
1102 adjin = NULL;
1103 bmp->syncpeerid = bpi->peer->qobj_node.nid;
1104 } else if (bpi) {
1105 bmp->syncpeerid = bpi->peer->qobj_node.nid;
1106 } else if (adjin) {
1107 bmp->syncpeerid = adjin->peer->qobj_node.nid;
1108 }
1109
1110 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
1111 struct prefix_rd *prd = NULL;
1112 if (((afi == AFI_L2VPN) && (safi == SAFI_EVPN)) ||
1113 (safi == SAFI_MPLS_VPN))
1114 prd = (struct prefix_rd *)bgp_dest_get_prefix(bmp->syncrdpos);
1115
1116 if (bpi)
1117 bmp_monitor(bmp, bpi->peer, BMP_PEER_FLAG_L, bn_p, prd,
1118 bpi->attr, afi, safi, bpi->uptime);
1119 if (adjin)
1120 bmp_monitor(bmp, adjin->peer, 0, bn_p, prd, adjin->attr, afi,
1121 safi, adjin->uptime);
1122
1123 if (bn)
1124 bgp_dest_unlock_node(bn);
1125
1126 return true;
1127 }
1128
1129 static struct bmp_queue_entry *bmp_pull(struct bmp *bmp)
1130 {
1131 struct bmp_queue_entry *bqe;
1132
1133 bqe = bmp->queuepos;
1134 if (!bqe)
1135 return NULL;
1136
1137 bmp->queuepos = bmp_qlist_next(&bmp->targets->updlist, bqe);
1138
1139 bqe->refcount--;
1140 if (!bqe->refcount) {
1141 bmp_qhash_del(&bmp->targets->updhash, bqe);
1142 bmp_qlist_del(&bmp->targets->updlist, bqe);
1143 }
1144 return bqe;
1145 }
1146
1147 static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr)
1148 {
1149 struct bmp_queue_entry *bqe;
1150 struct peer *peer;
1151 struct bgp_dest *bn = NULL;
1152 bool written = false;
1153
1154 bqe = bmp_pull(bmp);
1155 if (!bqe)
1156 return false;
1157
1158 afi_t afi = bqe->afi;
1159 safi_t safi = bqe->safi;
1160
1161 switch (bmp->afistate[afi][safi]) {
1162 case BMP_AFI_INACTIVE:
1163 case BMP_AFI_NEEDSYNC:
1164 goto out;
1165 case BMP_AFI_SYNC:
1166 if (prefix_cmp(&bqe->p, &bmp->syncpos) <= 0)
1167 /* currently syncing but have already passed this
1168 * prefix => send it. */
1169 break;
1170
1171 /* currently syncing & haven't reached this prefix yet
1172 * => it'll be sent as part of the table sync, no need here */
1173 goto out;
1174 case BMP_AFI_LIVE:
1175 break;
1176 }
1177
1178 peer = QOBJ_GET_TYPESAFE(bqe->peerid, peer);
1179 if (!peer) {
1180 zlog_info("bmp: skipping queued item for deleted peer");
1181 goto out;
1182 }
1183 if (!peer_established(peer))
1184 goto out;
1185
1186 bool is_vpn = (bqe->afi == AFI_L2VPN && bqe->safi == SAFI_EVPN) ||
1187 (bqe->safi == SAFI_MPLS_VPN);
1188
1189 struct prefix_rd *prd = is_vpn ? &bqe->rd : NULL;
1190 bn = bgp_afi_node_lookup(bmp->targets->bgp->rib[afi][safi], afi, safi,
1191 &bqe->p, prd);
1192
1193
1194 if (bmp->targets->afimon[afi][safi] & BMP_MON_POSTPOLICY) {
1195 struct bgp_path_info *bpi;
1196
1197 for (bpi = bn ? bgp_dest_get_bgp_path_info(bn) : NULL; bpi;
1198 bpi = bpi->next) {
1199 if (!CHECK_FLAG(bpi->flags, BGP_PATH_VALID))
1200 continue;
1201 if (bpi->peer == peer)
1202 break;
1203 }
1204
1205 bmp_monitor(bmp, peer, BMP_PEER_FLAG_L, &bqe->p, prd,
1206 bpi ? bpi->attr : NULL, afi, safi,
1207 bpi ? bpi->uptime : monotime(NULL));
1208 written = true;
1209 }
1210
1211 if (bmp->targets->afimon[afi][safi] & BMP_MON_PREPOLICY) {
1212 struct bgp_adj_in *adjin;
1213
1214 for (adjin = bn ? bn->adj_in : NULL; adjin;
1215 adjin = adjin->next) {
1216 if (adjin->peer == peer)
1217 break;
1218 }
1219 bmp_monitor(bmp, peer, 0, &bqe->p, prd,
1220 adjin ? adjin->attr : NULL, afi, safi,
1221 adjin ? adjin->uptime : monotime(NULL));
1222 written = true;
1223 }
1224
1225 out:
1226 if (!bqe->refcount)
1227 XFREE(MTYPE_BMP_QUEUE, bqe);
1228
1229 if (bn)
1230 bgp_dest_unlock_node(bn);
1231
1232 return written;
1233 }
1234
1235 static void bmp_wrfill(struct bmp *bmp, struct pullwr *pullwr)
1236 {
1237 switch(bmp->state) {
1238 case BMP_PeerUp:
1239 bmp_send_peerup(bmp);
1240 bmp->state = BMP_Run;
1241 break;
1242
1243 case BMP_Run:
1244 if (bmp_wrmirror(bmp, pullwr))
1245 break;
1246 if (bmp_wrqueue(bmp, pullwr))
1247 break;
1248 if (bmp_wrsync(bmp, pullwr))
1249 break;
1250 break;
1251 }
1252 }
1253
1254 static void bmp_wrerr(struct bmp *bmp, struct pullwr *pullwr, bool eof)
1255 {
1256 if (eof)
1257 zlog_info("bmp[%s] disconnected", bmp->remote);
1258 else
1259 flog_warn(EC_LIB_SYSTEM_CALL, "bmp[%s] connection error: %s",
1260 bmp->remote, strerror(errno));
1261
1262 bmp_close(bmp);
1263 bmp_free(bmp);
1264 }
1265
1266 static void bmp_process_one(struct bmp_targets *bt, struct bgp *bgp, afi_t afi,
1267 safi_t safi, struct bgp_dest *bn, struct peer *peer)
1268 {
1269 struct bmp *bmp;
1270 struct bmp_queue_entry *bqe, bqeref;
1271 size_t refcount;
1272
1273 refcount = bmp_session_count(&bt->sessions);
1274 if (refcount == 0)
1275 return;
1276
1277 memset(&bqeref, 0, sizeof(bqeref));
1278 prefix_copy(&bqeref.p, bgp_dest_get_prefix(bn));
1279 bqeref.peerid = peer->qobj_node.nid;
1280 bqeref.afi = afi;
1281 bqeref.safi = safi;
1282
1283 if ((afi == AFI_L2VPN && safi == SAFI_EVPN && bn->pdest) ||
1284 (safi == SAFI_MPLS_VPN))
1285 prefix_copy(&bqeref.rd,
1286 (struct prefix_rd *)bgp_dest_get_prefix(bn->pdest));
1287
1288 bqe = bmp_qhash_find(&bt->updhash, &bqeref);
1289 if (bqe) {
1290 if (bqe->refcount >= refcount)
1291 /* nothing to do here */
1292 return;
1293
1294 bmp_qlist_del(&bt->updlist, bqe);
1295 } else {
1296 bqe = XMALLOC(MTYPE_BMP_QUEUE, sizeof(*bqe));
1297 memcpy(bqe, &bqeref, sizeof(*bqe));
1298
1299 bmp_qhash_add(&bt->updhash, bqe);
1300 }
1301
1302 bqe->refcount = refcount;
1303 bmp_qlist_add_tail(&bt->updlist, bqe);
1304
1305 frr_each (bmp_session, &bt->sessions, bmp)
1306 if (!bmp->queuepos)
1307 bmp->queuepos = bqe;
1308 }
1309
1310 static int bmp_process(struct bgp *bgp, afi_t afi, safi_t safi,
1311 struct bgp_dest *bn, struct peer *peer, bool withdraw)
1312 {
1313 struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
1314 struct bmp_targets *bt;
1315 struct bmp *bmp;
1316
1317 if (frrtrace_enabled(frr_bgp, bmp_process)) {
1318 char pfxprint[PREFIX2STR_BUFFER];
1319
1320 prefix2str(&bn->p, pfxprint, sizeof(pfxprint));
1321 frrtrace(5, frr_bgp, bmp_process, peer, pfxprint, afi, safi,
1322 withdraw);
1323 }
1324
1325 if (!bmpbgp)
1326 return 0;
1327
1328 frr_each(bmp_targets, &bmpbgp->targets, bt) {
1329 if (!bt->afimon[afi][safi])
1330 continue;
1331
1332 bmp_process_one(bt, bgp, afi, safi, bn, peer);
1333
1334 frr_each(bmp_session, &bt->sessions, bmp) {
1335 pullwr_bump(bmp->pullwr);
1336 }
1337 }
1338 return 0;
1339 }
1340
1341 static void bmp_stat_put_u32(struct stream *s, size_t *cnt, uint16_t type,
1342 uint32_t value)
1343 {
1344 stream_putw(s, type);
1345 stream_putw(s, 4);
1346 stream_putl(s, value);
1347 (*cnt)++;
1348 }
1349
1350 static void bmp_stats(struct thread *thread)
1351 {
1352 struct bmp_targets *bt = THREAD_ARG(thread);
1353 struct stream *s;
1354 struct peer *peer;
1355 struct listnode *node;
1356 struct timeval tv;
1357
1358 if (bt->stat_msec)
1359 thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
1360 &bt->t_stats);
1361
1362 gettimeofday(&tv, NULL);
1363
1364 /* Walk down all peers */
1365 for (ALL_LIST_ELEMENTS_RO(bt->bgp->peer, node, peer)) {
1366 size_t count = 0, count_pos, len;
1367
1368 if (!peer_established(peer))
1369 continue;
1370
1371 s = stream_new(BGP_MAX_PACKET_SIZE);
1372 bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_STATISTICS_REPORT);
1373 bmp_per_peer_hdr(s, peer, 0, &tv);
1374
1375 count_pos = stream_get_endp(s);
1376 stream_putl(s, 0);
1377
1378 bmp_stat_put_u32(s, &count, BMP_STATS_PFX_REJECTED,
1379 peer->stat_pfx_filter);
1380 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_LOOP_ASPATH,
1381 peer->stat_pfx_aspath_loop);
1382 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_LOOP_ORIGINATOR,
1383 peer->stat_pfx_originator_loop);
1384 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_LOOP_CLUSTER,
1385 peer->stat_pfx_cluster_loop);
1386 bmp_stat_put_u32(s, &count, BMP_STATS_PFX_DUP_WITHDRAW,
1387 peer->stat_pfx_dup_withdraw);
1388 bmp_stat_put_u32(s, &count, BMP_STATS_UPD_7606_WITHDRAW,
1389 peer->stat_upd_7606);
1390 bmp_stat_put_u32(s, &count, BMP_STATS_FRR_NH_INVALID,
1391 peer->stat_pfx_nh_invalid);
1392
1393 stream_putl_at(s, count_pos, count);
1394
1395 len = stream_get_endp(s);
1396 stream_putl_at(s, BMP_LENGTH_POS, len);
1397
1398 bmp_send_all(bt->bmpbgp, s);
1399 }
1400 }
1401
1402 /* read from the BMP socket to detect session termination */
1403 static void bmp_read(struct thread *t)
1404 {
1405 struct bmp *bmp = THREAD_ARG(t);
1406 char buf[1024];
1407 ssize_t n;
1408
1409 bmp->t_read = NULL;
1410
1411 n = read(bmp->socket, buf, sizeof(buf));
1412 if (n >= 1) {
1413 zlog_info("bmp[%s]: unexpectedly received %zu bytes", bmp->remote, n);
1414 } else if (n == 0) {
1415 /* the TCP session was terminated by the far end */
1416 bmp_wrerr(bmp, NULL, true);
1417 return;
1418 } else if (!(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
1419 /* the TCP session experienced a fatal error, likely a timeout */
1420 bmp_wrerr(bmp, NULL, false);
1421 return;
1422 }
1423
1424 thread_add_read(bm->master, bmp_read, bmp, bmp->socket, &bmp->t_read);
1425 }
1426
1427 static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock)
1428 {
1429 union sockunion su, *sumem;
1430 struct prefix p;
1431 int on = 1;
1432 struct access_list *acl = NULL;
1433 enum filter_type ret;
1434 char buf[SU_ADDRSTRLEN];
1435 struct bmp *bmp;
1436
1437 sumem = sockunion_getpeername(bmp_sock);
1438 if (!sumem) {
1439 close(bmp_sock);
1440 return NULL;
1441 }
1442 memcpy(&su, sumem, sizeof(su));
1443 sockunion_free(sumem);
1444
1445 set_nonblocking(bmp_sock);
1446 set_cloexec(bmp_sock);
1447
1448 if (!sockunion2hostprefix(&su, &p)) {
1449 close(bmp_sock);
1450 return NULL;
1451 }
1452
1453 acl = NULL;
1454 switch (p.family) {
1455 case AF_INET:
1456 acl = access_list_lookup(AFI_IP, bt->acl_name);
1457 break;
1458 case AF_INET6:
1459 acl = access_list_lookup(AFI_IP6, bt->acl6_name);
1460 break;
1461 default:
1462 break;
1463 }
1464
1465 ret = FILTER_PERMIT;
1466 if (acl) {
1467 ret = access_list_apply(acl, &p);
1468 }
1469
1470 sockunion2str(&su, buf, SU_ADDRSTRLEN);
1471 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%u",
1472 su.sa.sa_family == AF_INET
1473 ? ntohs(su.sin.sin_port)
1474 : ntohs(su.sin6.sin6_port));
1475
1476 if (ret == FILTER_DENY) {
1477 bt->cnt_aclrefused++;
1478 zlog_info("bmp[%s] connection refused by access-list", buf);
1479 close(bmp_sock);
1480 return NULL;
1481 }
1482 bt->cnt_accept++;
1483
1484 if (setsockopt(bmp_sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
1485 flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt SO_KEEPALIVE: %s(%d)",
1486 bmp_sock, safe_strerror(errno), errno);
1487 if (setsockopt(bmp_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
1488 flog_err(EC_LIB_SOCKET, "bmp: %d can't setsockopt TCP_NODELAY: %s(%d)",
1489 bmp_sock, safe_strerror(errno), errno);
1490
1491 zlog_info("bmp[%s] connection established", buf);
1492
1493 /* Allocate new BMP structure and set up default values. */
1494 bmp = bmp_new(bt, bmp_sock);
1495 strlcpy(bmp->remote, buf, sizeof(bmp->remote));
1496
1497 bmp->state = BMP_PeerUp;
1498 bmp->pullwr = pullwr_new(bm->master, bmp_sock, bmp, bmp_wrfill,
1499 bmp_wrerr);
1500 thread_add_read(bm->master, bmp_read, bmp, bmp_sock, &bmp->t_read);
1501 bmp_send_initiation(bmp);
1502
1503 return bmp;
1504 }
1505
1506 /* Accept BMP connection. */
1507 static void bmp_accept(struct thread *thread)
1508 {
1509 union sockunion su;
1510 struct bmp_listener *bl = THREAD_ARG(thread);
1511 int bmp_sock;
1512
1513 /* We continue hearing BMP socket. */
1514 thread_add_read(bm->master, bmp_accept, bl, bl->sock, &bl->t_accept);
1515
1516 memset(&su, 0, sizeof(union sockunion));
1517
1518 /* We can handle IPv4 or IPv6 socket. */
1519 bmp_sock = sockunion_accept(bl->sock, &su);
1520 if (bmp_sock < 0) {
1521 zlog_info("bmp: accept_sock failed: %s", safe_strerror(errno));
1522 return;
1523 }
1524 bmp_open(bl->targets, bmp_sock);
1525 }
1526
1527 static void bmp_close(struct bmp *bmp)
1528 {
1529 struct bmp_queue_entry *bqe;
1530 struct bmp_mirrorq *bmq;
1531
1532 THREAD_OFF(bmp->t_read);
1533
1534 if (bmp->active)
1535 bmp_active_disconnected(bmp->active);
1536
1537 while ((bmq = bmp_pull_mirror(bmp)))
1538 if (!bmq->refcount)
1539 XFREE(MTYPE_BMP_MIRRORQ, bmq);
1540 while ((bqe = bmp_pull(bmp)))
1541 if (!bqe->refcount)
1542 XFREE(MTYPE_BMP_QUEUE, bqe);
1543
1544 THREAD_OFF(bmp->t_read);
1545 pullwr_del(bmp->pullwr);
1546 close(bmp->socket);
1547 }
1548
1549 static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp)
1550 {
1551 struct bmp_bgp dummy = { .bgp = bgp };
1552 return bmp_bgph_find(&bmp_bgph, &dummy);
1553 }
1554
1555 static struct bmp_bgp *bmp_bgp_get(struct bgp *bgp)
1556 {
1557 struct bmp_bgp *bmpbgp;
1558
1559 bmpbgp = bmp_bgp_find(bgp);
1560 if (bmpbgp)
1561 return bmpbgp;
1562
1563 bmpbgp = XCALLOC(MTYPE_BMP, sizeof(*bmpbgp));
1564 bmpbgp->bgp = bgp;
1565 bmpbgp->mirror_qsizelimit = ~0UL;
1566 bmp_mirrorq_init(&bmpbgp->mirrorq);
1567 bmp_bgph_add(&bmp_bgph, bmpbgp);
1568
1569 return bmpbgp;
1570 }
1571
1572 static void bmp_bgp_put(struct bmp_bgp *bmpbgp)
1573 {
1574 struct bmp_targets *bt;
1575 struct bmp_listener *bl;
1576
1577 bmp_bgph_del(&bmp_bgph, bmpbgp);
1578
1579 frr_each_safe (bmp_targets, &bmpbgp->targets, bt) {
1580 frr_each_safe (bmp_listeners, &bt->listeners, bl)
1581 bmp_listener_put(bl);
1582
1583 bmp_targets_put(bt);
1584 }
1585
1586 bmp_mirrorq_fini(&bmpbgp->mirrorq);
1587 XFREE(MTYPE_BMP, bmpbgp);
1588 }
1589
1590 static int bmp_bgp_del(struct bgp *bgp)
1591 {
1592 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
1593
1594 if (bmpbgp)
1595 bmp_bgp_put(bmpbgp);
1596 return 0;
1597 }
1598
1599 static struct bmp_bgp_peer *bmp_bgp_peer_find(uint64_t peerid)
1600 {
1601 struct bmp_bgp_peer dummy = { .peerid = peerid };
1602 return bmp_peerh_find(&bmp_peerh, &dummy);
1603 }
1604
1605 static struct bmp_bgp_peer *bmp_bgp_peer_get(struct peer *peer)
1606 {
1607 struct bmp_bgp_peer *bbpeer;
1608
1609 bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
1610 if (bbpeer)
1611 return bbpeer;
1612
1613 bbpeer = XCALLOC(MTYPE_BMP_PEER, sizeof(*bbpeer));
1614 bbpeer->peerid = peer->qobj_node.nid;
1615 bmp_peerh_add(&bmp_peerh, bbpeer);
1616
1617 return bbpeer;
1618 }
1619
1620 static struct bmp_targets *bmp_targets_find1(struct bgp *bgp, const char *name)
1621 {
1622 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
1623 struct bmp_targets dummy;
1624
1625 if (!bmpbgp)
1626 return NULL;
1627 dummy.name = (char *)name;
1628 return bmp_targets_find(&bmpbgp->targets, &dummy);
1629 }
1630
1631 static struct bmp_targets *bmp_targets_get(struct bgp *bgp, const char *name)
1632 {
1633 struct bmp_targets *bt;
1634
1635 bt = bmp_targets_find1(bgp, name);
1636 if (bt)
1637 return bt;
1638
1639 bt = XCALLOC(MTYPE_BMP_TARGETS, sizeof(*bt));
1640 bt->name = XSTRDUP(MTYPE_BMP_TARGETSNAME, name);
1641 bt->bgp = bgp;
1642 bt->bmpbgp = bmp_bgp_get(bgp);
1643 bmp_session_init(&bt->sessions);
1644 bmp_qhash_init(&bt->updhash);
1645 bmp_qlist_init(&bt->updlist);
1646 bmp_actives_init(&bt->actives);
1647 bmp_listeners_init(&bt->listeners);
1648
1649 QOBJ_REG(bt, bmp_targets);
1650 bmp_targets_add(&bt->bmpbgp->targets, bt);
1651 return bt;
1652 }
1653
1654 static void bmp_targets_put(struct bmp_targets *bt)
1655 {
1656 struct bmp *bmp;
1657 struct bmp_active *ba;
1658
1659 THREAD_OFF(bt->t_stats);
1660
1661 frr_each_safe (bmp_actives, &bt->actives, ba)
1662 bmp_active_put(ba);
1663
1664 frr_each_safe(bmp_session, &bt->sessions, bmp) {
1665 bmp_close(bmp);
1666 bmp_free(bmp);
1667 }
1668
1669 bmp_targets_del(&bt->bmpbgp->targets, bt);
1670 QOBJ_UNREG(bt);
1671
1672 bmp_listeners_fini(&bt->listeners);
1673 bmp_actives_fini(&bt->actives);
1674 bmp_qhash_fini(&bt->updhash);
1675 bmp_qlist_fini(&bt->updlist);
1676
1677 XFREE(MTYPE_BMP_ACLNAME, bt->acl_name);
1678 XFREE(MTYPE_BMP_ACLNAME, bt->acl6_name);
1679 bmp_session_fini(&bt->sessions);
1680
1681 XFREE(MTYPE_BMP_TARGETSNAME, bt->name);
1682 XFREE(MTYPE_BMP_TARGETS, bt);
1683 }
1684
1685 static struct bmp_listener *bmp_listener_find(struct bmp_targets *bt,
1686 const union sockunion *su,
1687 int port)
1688 {
1689 struct bmp_listener dummy;
1690 dummy.addr = *su;
1691 dummy.port = port;
1692 return bmp_listeners_find(&bt->listeners, &dummy);
1693 }
1694
1695 static struct bmp_listener *bmp_listener_get(struct bmp_targets *bt,
1696 const union sockunion *su,
1697 int port)
1698 {
1699 struct bmp_listener *bl = bmp_listener_find(bt, su, port);
1700
1701 if (bl)
1702 return bl;
1703
1704 bl = XCALLOC(MTYPE_BMP_LISTENER, sizeof(*bl));
1705 bl->targets = bt;
1706 bl->addr = *su;
1707 bl->port = port;
1708 bl->sock = -1;
1709
1710 bmp_listeners_add(&bt->listeners, bl);
1711 return bl;
1712 }
1713
1714 static void bmp_listener_start(struct bmp_listener *bl)
1715 {
1716 int sock, ret;
1717
1718 sock = socket(bl->addr.sa.sa_family, SOCK_STREAM, 0);
1719 if (sock < 0)
1720 return;
1721
1722 sockopt_reuseaddr(sock);
1723 sockopt_reuseport(sock);
1724 sockopt_v6only(bl->addr.sa.sa_family, sock);
1725 set_cloexec(sock);
1726
1727 ret = sockunion_bind(sock, &bl->addr, bl->port, &bl->addr);
1728 if (ret < 0)
1729 goto out_sock;
1730
1731 ret = listen(sock, 3);
1732 if (ret < 0)
1733 goto out_sock;
1734
1735 bl->sock = sock;
1736 thread_add_read(bm->master, bmp_accept, bl, sock, &bl->t_accept);
1737 return;
1738 out_sock:
1739 close(sock);
1740 }
1741
1742 static void bmp_listener_stop(struct bmp_listener *bl)
1743 {
1744 THREAD_OFF(bl->t_accept);
1745
1746 if (bl->sock != -1)
1747 close(bl->sock);
1748 bl->sock = -1;
1749 }
1750
1751 static struct bmp_active *bmp_active_find(struct bmp_targets *bt,
1752 const char *hostname, int port)
1753 {
1754 struct bmp_active dummy;
1755 dummy.hostname = (char *)hostname;
1756 dummy.port = port;
1757 return bmp_actives_find(&bt->actives, &dummy);
1758 }
1759
1760 static struct bmp_active *bmp_active_get(struct bmp_targets *bt,
1761 const char *hostname, int port)
1762 {
1763 struct bmp_active *ba;
1764
1765 ba = bmp_active_find(bt, hostname, port);
1766 if (ba)
1767 return ba;
1768
1769 ba = XCALLOC(MTYPE_BMP_ACTIVE, sizeof(*ba));
1770 ba->targets = bt;
1771 ba->hostname = XSTRDUP(MTYPE_TMP, hostname);
1772 ba->port = port;
1773 ba->minretry = BMP_DFLT_MINRETRY;
1774 ba->maxretry = BMP_DFLT_MAXRETRY;
1775 ba->socket = -1;
1776
1777 bmp_actives_add(&bt->actives, ba);
1778 return ba;
1779 }
1780
1781 static void bmp_active_put(struct bmp_active *ba)
1782 {
1783 THREAD_OFF(ba->t_timer);
1784 THREAD_OFF(ba->t_read);
1785 THREAD_OFF(ba->t_write);
1786
1787 bmp_actives_del(&ba->targets->actives, ba);
1788
1789 if (ba->bmp) {
1790 ba->bmp->active = NULL;
1791 bmp_close(ba->bmp);
1792 bmp_free(ba->bmp);
1793 }
1794 if (ba->socket != -1)
1795 close(ba->socket);
1796
1797 XFREE(MTYPE_TMP, ba->ifsrc);
1798 XFREE(MTYPE_TMP, ba->hostname);
1799 XFREE(MTYPE_BMP_ACTIVE, ba);
1800 }
1801
1802 static void bmp_active_setup(struct bmp_active *ba);
1803
1804 static void bmp_active_connect(struct bmp_active *ba)
1805 {
1806 enum connect_result res;
1807 struct interface *ifp;
1808 vrf_id_t vrf_id = VRF_DEFAULT;
1809 int res_bind;
1810
1811 for (; ba->addrpos < ba->addrtotal; ba->addrpos++) {
1812 if (ba->ifsrc) {
1813 if (ba->targets && ba->targets->bgp)
1814 vrf_id = ba->targets->bgp->vrf_id;
1815
1816 /* find interface and related */
1817 /* address with same family */
1818 ifp = if_lookup_by_name(ba->ifsrc, vrf_id);
1819 if (!ifp) {
1820 zlog_warn("bmp[%s]: failed to find interface",
1821 ba->ifsrc);
1822 continue;
1823 }
1824
1825 if (bgp_update_address(ifp, &ba->addrs[ba->addrpos],
1826 &ba->addrsrc)){
1827 zlog_warn("bmp[%s]: failed to find matching address",
1828 ba->ifsrc);
1829 continue;
1830 }
1831 zlog_info("bmp[%s]: selected source address : %pSU",
1832 ba->ifsrc, &ba->addrsrc);
1833 }
1834
1835 ba->socket = sockunion_socket(&ba->addrs[ba->addrpos]);
1836 if (ba->socket < 0) {
1837 zlog_warn("bmp[%s]: failed to create socket",
1838 ba->hostname);
1839 continue;
1840 }
1841
1842 set_nonblocking(ba->socket);
1843
1844 if (!sockunion_is_null(&ba->addrsrc)) {
1845 res_bind = sockunion_bind(ba->socket, &ba->addrsrc, 0,
1846 &ba->addrsrc);
1847 if (res_bind < 0) {
1848 zlog_warn(
1849 "bmp[%s]: no bind currently to source address %pSU:%d",
1850 ba->hostname, &ba->addrsrc, ba->port);
1851 close(ba->socket);
1852 ba->socket = -1;
1853 sockunion_init(&ba->addrsrc);
1854 continue;
1855 }
1856 }
1857
1858
1859 res = sockunion_connect(ba->socket, &ba->addrs[ba->addrpos],
1860 htons(ba->port), 0);
1861 switch (res) {
1862 case connect_error:
1863 zlog_warn("bmp[%s]: failed to connect to %pSU:%d",
1864 ba->hostname, &ba->addrs[ba->addrpos],
1865 ba->port);
1866 close(ba->socket);
1867 ba->socket = -1;
1868 sockunion_init(&ba->addrsrc);
1869 continue;
1870 case connect_success:
1871 zlog_info("bmp[%s]: connected to %pSU:%d",
1872 ba->hostname, &ba->addrs[ba->addrpos],
1873 ba->port);
1874 break;
1875 case connect_in_progress:
1876 zlog_warn("bmp[%s]: connect in progress %pSU:%d",
1877 ba->hostname, &ba->addrs[ba->addrpos],
1878 ba->port);
1879 bmp_active_setup(ba);
1880 return;
1881 }
1882 }
1883
1884 /* exhausted all addresses */
1885 ba->curretry += ba->curretry / 2;
1886 bmp_active_setup(ba);
1887 }
1888
1889 static void bmp_active_resolved(struct resolver_query *resq, const char *errstr,
1890 int numaddrs, union sockunion *addr)
1891 {
1892 struct bmp_active *ba = container_of(resq, struct bmp_active, resq);
1893 unsigned i;
1894
1895 if (numaddrs <= 0) {
1896 zlog_warn("bmp[%s]: hostname resolution failed: %s",
1897 ba->hostname, errstr);
1898 ba->last_err = errstr;
1899 ba->curretry += ba->curretry / 2;
1900 ba->addrpos = 0;
1901 ba->addrtotal = 0;
1902 bmp_active_setup(ba);
1903 return;
1904 }
1905
1906 if (numaddrs > (int)array_size(ba->addrs))
1907 numaddrs = array_size(ba->addrs);
1908
1909 ba->addrpos = 0;
1910 ba->addrtotal = numaddrs;
1911 for (i = 0; i < ba->addrtotal; i++)
1912 memcpy(&ba->addrs[i], &addr[i], sizeof(ba->addrs[0]));
1913
1914 bmp_active_connect(ba);
1915 }
1916
1917 static void bmp_active_thread(struct thread *t)
1918 {
1919 struct bmp_active *ba = THREAD_ARG(t);
1920 socklen_t slen;
1921 int status, ret;
1922 vrf_id_t vrf_id;
1923
1924 /* all 3 end up here, though only timer or read+write are active
1925 * at a time */
1926 THREAD_OFF(ba->t_timer);
1927 THREAD_OFF(ba->t_read);
1928 THREAD_OFF(ba->t_write);
1929
1930 ba->last_err = NULL;
1931
1932 if (ba->socket == -1) {
1933 /* get vrf_id */
1934 if (!ba->targets || !ba->targets->bgp)
1935 vrf_id = VRF_DEFAULT;
1936 else
1937 vrf_id = ba->targets->bgp->vrf_id;
1938 resolver_resolve(&ba->resq, AF_UNSPEC, vrf_id, ba->hostname,
1939 bmp_active_resolved);
1940 return;
1941 }
1942
1943 slen = sizeof(status);
1944 ret = getsockopt(ba->socket, SOL_SOCKET, SO_ERROR, (void *)&status,
1945 &slen);
1946
1947 if (ret < 0 || status != 0) {
1948 ba->last_err = strerror(status);
1949 zlog_warn("bmp[%s]: failed to connect to %pSU:%d: %s",
1950 ba->hostname, &ba->addrs[ba->addrpos], ba->port,
1951 ba->last_err);
1952 goto out_next;
1953 }
1954
1955 zlog_warn("bmp[%s]: outbound connection to %pSU:%d", ba->hostname,
1956 &ba->addrs[ba->addrpos], ba->port);
1957
1958 ba->bmp = bmp_open(ba->targets, ba->socket);
1959 if (!ba->bmp)
1960 goto out_next;
1961
1962 ba->bmp->active = ba;
1963 ba->socket = -1;
1964 ba->curretry = ba->minretry;
1965 return;
1966
1967 out_next:
1968 close(ba->socket);
1969 ba->socket = -1;
1970 ba->addrpos++;
1971 bmp_active_connect(ba);
1972 }
1973
1974 static void bmp_active_disconnected(struct bmp_active *ba)
1975 {
1976 ba->bmp = NULL;
1977 bmp_active_setup(ba);
1978 }
1979
1980 static void bmp_active_setup(struct bmp_active *ba)
1981 {
1982 THREAD_OFF(ba->t_timer);
1983 THREAD_OFF(ba->t_read);
1984 THREAD_OFF(ba->t_write);
1985
1986 if (ba->bmp)
1987 return;
1988 if (ba->resq.callback)
1989 return;
1990
1991 if (ba->curretry > ba->maxretry)
1992 ba->curretry = ba->maxretry;
1993
1994 if (ba->socket == -1)
1995 thread_add_timer_msec(bm->master, bmp_active_thread, ba,
1996 ba->curretry, &ba->t_timer);
1997 else {
1998 thread_add_read(bm->master, bmp_active_thread, ba, ba->socket,
1999 &ba->t_read);
2000 thread_add_write(bm->master, bmp_active_thread, ba, ba->socket,
2001 &ba->t_write);
2002 }
2003 }
2004
2005 static struct cmd_node bmp_node = {
2006 .name = "bmp",
2007 .node = BMP_NODE,
2008 .parent_node = BGP_NODE,
2009 .prompt = "%s(config-bgp-bmp)# "
2010 };
2011
2012 static void bmp_targets_autocomplete(vector comps, struct cmd_token *token)
2013 {
2014 struct bgp *bgp;
2015 struct bmp_targets *target;
2016 struct listnode *node;
2017
2018 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
2019 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
2020
2021 if (!bmpbgp)
2022 continue;
2023
2024 frr_each_safe (bmp_targets, &bmpbgp->targets, target)
2025 vector_set(comps,
2026 XSTRDUP(MTYPE_COMPLETION, target->name));
2027 }
2028 }
2029
2030 static const struct cmd_variable_handler bmp_targets_var_handlers[] = {
2031 {.tokenname = "BMPTARGETS", .completions = bmp_targets_autocomplete},
2032 {.completions = NULL}};
2033
2034 #define BMP_STR "BGP Monitoring Protocol\n"
2035
2036 #ifndef VTYSH_EXTRACT_PL
2037 #include "bgpd/bgp_bmp_clippy.c"
2038 #endif
2039
2040 DEFPY_NOSH(bmp_targets_main,
2041 bmp_targets_cmd,
2042 "bmp targets BMPTARGETS",
2043 BMP_STR
2044 "Create BMP target group\n"
2045 "Name of the BMP target group\n")
2046 {
2047 VTY_DECLVAR_CONTEXT(bgp, bgp);
2048 struct bmp_targets *bt;
2049
2050 bt = bmp_targets_get(bgp, bmptargets);
2051
2052 VTY_PUSH_CONTEXT_SUB(BMP_NODE, bt);
2053 return CMD_SUCCESS;
2054 }
2055
2056 DEFPY(no_bmp_targets_main,
2057 no_bmp_targets_cmd,
2058 "no bmp targets BMPTARGETS",
2059 NO_STR
2060 BMP_STR
2061 "Delete BMP target group\n"
2062 "Name of the BMP target group\n")
2063 {
2064 VTY_DECLVAR_CONTEXT(bgp, bgp);
2065 struct bmp_targets *bt;
2066
2067 bt = bmp_targets_find1(bgp, bmptargets);
2068 if (!bt) {
2069 vty_out(vty, "%% BMP target group not found\n");
2070 return CMD_WARNING;
2071 }
2072 bmp_targets_put(bt);
2073 return CMD_SUCCESS;
2074 }
2075
2076 DEFPY(bmp_listener_main,
2077 bmp_listener_cmd,
2078 "bmp listener <X:X::X:X|A.B.C.D> port (1-65535)",
2079 BMP_STR
2080 "Listen for inbound BMP connections\n"
2081 "IPv6 address to listen on\n"
2082 "IPv4 address to listen on\n"
2083 "TCP Port number\n"
2084 "TCP Port number\n")
2085 {
2086 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2087 struct bmp_listener *bl;
2088
2089 bl = bmp_listener_get(bt, listener, port);
2090 if (bl->sock == -1)
2091 bmp_listener_start(bl);
2092
2093 return CMD_SUCCESS;
2094 }
2095
2096 DEFPY(no_bmp_listener_main,
2097 no_bmp_listener_cmd,
2098 "no bmp listener <X:X::X:X|A.B.C.D> port (1-65535)",
2099 NO_STR
2100 BMP_STR
2101 "Create BMP listener\n"
2102 "IPv6 address to listen on\n"
2103 "IPv4 address to listen on\n"
2104 "TCP Port number\n"
2105 "TCP Port number\n")
2106 {
2107 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2108 struct bmp_listener *bl;
2109
2110 bl = bmp_listener_find(bt, listener, port);
2111 if (!bl) {
2112 vty_out(vty, "%% BMP listener not found\n");
2113 return CMD_WARNING;
2114 }
2115 bmp_listener_stop(bl);
2116 bmp_listener_put(bl);
2117 return CMD_SUCCESS;
2118 }
2119
2120 DEFPY(bmp_connect,
2121 bmp_connect_cmd,
2122 "[no] bmp connect HOSTNAME port (1-65535) {min-retry (100-86400000)|max-retry (100-86400000)} [source-interface <WORD$srcif>]",
2123 NO_STR
2124 BMP_STR
2125 "Actively establish connection to monitoring station\n"
2126 "Monitoring station hostname or address\n"
2127 "TCP port\n"
2128 "TCP port\n"
2129 "Minimum connection retry interval\n"
2130 "Minimum connection retry interval (milliseconds)\n"
2131 "Maximum connection retry interval\n"
2132 "Maximum connection retry interval (milliseconds)\n"
2133 "Source interface to use\n"
2134 "Define an interface\n")
2135 {
2136 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2137 struct bmp_active *ba;
2138
2139 if (no) {
2140 ba = bmp_active_find(bt, hostname, port);
2141 if (!ba) {
2142 vty_out(vty, "%% No such active connection found\n");
2143 return CMD_WARNING;
2144 }
2145 /* connection deletion need same hostname port and interface */
2146 if (ba->ifsrc || srcif)
2147 if ((!ba->ifsrc) || (!srcif) ||
2148 !strcmp(ba->ifsrc, srcif)) {
2149 vty_out(vty,
2150 "%% No such active connection found\n");
2151 return CMD_WARNING;
2152 }
2153 bmp_active_put(ba);
2154 return CMD_SUCCESS;
2155 }
2156
2157 ba = bmp_active_get(bt, hostname, port);
2158 if (srcif)
2159 ba->ifsrc = XSTRDUP(MTYPE_TMP, srcif);
2160 if (min_retry_str)
2161 ba->minretry = min_retry;
2162 if (max_retry_str)
2163 ba->maxretry = max_retry;
2164 ba->curretry = ba->minretry;
2165 bmp_active_setup(ba);
2166
2167 return CMD_SUCCESS;
2168 }
2169
2170 DEFPY(bmp_acl,
2171 bmp_acl_cmd,
2172 "[no] <ip|ipv6>$af access-list ACCESSLIST_NAME$access_list",
2173 NO_STR
2174 IP_STR
2175 IPV6_STR
2176 "Access list to restrict BMP sessions\n"
2177 "Access list name\n")
2178 {
2179 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2180 char **what;
2181
2182 if (no)
2183 access_list = NULL;
2184 if (!strcmp(af, "ipv6"))
2185 what = &bt->acl6_name;
2186 else
2187 what = &bt->acl_name;
2188
2189 XFREE(MTYPE_BMP_ACLNAME, *what);
2190 if (access_list)
2191 *what = XSTRDUP(MTYPE_BMP_ACLNAME, access_list);
2192
2193 return CMD_SUCCESS;
2194 }
2195
2196 DEFPY(bmp_stats_cfg,
2197 bmp_stats_cmd,
2198 "[no] bmp stats [interval (100-86400000)]",
2199 NO_STR
2200 BMP_STR
2201 "Send BMP statistics messages\n"
2202 "Specify BMP stats interval\n"
2203 "Interval (milliseconds) to send BMP Stats in\n")
2204 {
2205 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2206
2207 THREAD_OFF(bt->t_stats);
2208 if (no)
2209 bt->stat_msec = 0;
2210 else if (interval_str)
2211 bt->stat_msec = interval;
2212 else
2213 bt->stat_msec = BMP_STAT_DEFAULT_TIMER;
2214
2215 if (bt->stat_msec)
2216 thread_add_timer_msec(bm->master, bmp_stats, bt, bt->stat_msec,
2217 &bt->t_stats);
2218 return CMD_SUCCESS;
2219 }
2220
2221 DEFPY(bmp_monitor_cfg,
2222 bmp_monitor_cmd,
2223 "[no] bmp monitor <ipv4|ipv6|l2vpn> <unicast|multicast|evpn|vpn> <pre-policy|post-policy>$policy",
2224 NO_STR
2225 BMP_STR
2226 "Send BMP route monitoring messages\n"
2227 BGP_AF_STR
2228 BGP_AF_STR
2229 BGP_AF_STR
2230 BGP_AF_STR
2231 BGP_AF_STR
2232 BGP_AF_STR
2233 BGP_AF_STR
2234 "Send state before policy and filter processing\n"
2235 "Send state with policy and filters applied\n")
2236 {
2237 int index = 0;
2238 uint8_t flag, prev;
2239 afi_t afi;
2240 safi_t safi;
2241
2242 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2243 struct bmp *bmp;
2244
2245 argv_find_and_parse_afi(argv, argc, &index, &afi);
2246 argv_find_and_parse_safi(argv, argc, &index, &safi);
2247
2248 if (policy[1] == 'r')
2249 flag = BMP_MON_PREPOLICY;
2250 else
2251 flag = BMP_MON_POSTPOLICY;
2252
2253 prev = bt->afimon[afi][safi];
2254 if (no)
2255 bt->afimon[afi][safi] &= ~flag;
2256 else
2257 bt->afimon[afi][safi] |= flag;
2258
2259 if (prev == bt->afimon[afi][safi])
2260 return CMD_SUCCESS;
2261
2262 frr_each (bmp_session, &bt->sessions, bmp) {
2263 if (bmp->syncafi == afi && bmp->syncsafi == safi) {
2264 bmp->syncafi = AFI_MAX;
2265 bmp->syncsafi = SAFI_MAX;
2266 }
2267
2268 if (!bt->afimon[afi][safi]) {
2269 bmp->afistate[afi][safi] = BMP_AFI_INACTIVE;
2270 continue;
2271 }
2272
2273 bmp->afistate[afi][safi] = BMP_AFI_NEEDSYNC;
2274 }
2275
2276 return CMD_SUCCESS;
2277 }
2278
2279 DEFPY(bmp_mirror_cfg,
2280 bmp_mirror_cmd,
2281 "[no] bmp mirror",
2282 NO_STR
2283 BMP_STR
2284 "Send BMP route mirroring messages\n")
2285 {
2286 VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt);
2287 struct bmp *bmp;
2288
2289 if (bt->mirror == !no)
2290 return CMD_SUCCESS;
2291
2292 bt->mirror = !no;
2293 if (bt->mirror)
2294 return CMD_SUCCESS;
2295
2296 frr_each (bmp_session, &bt->sessions, bmp) {
2297 struct bmp_mirrorq *bmq;
2298
2299 while ((bmq = bmp_pull_mirror(bmp)))
2300 if (!bmq->refcount)
2301 XFREE(MTYPE_BMP_MIRRORQ, bmq);
2302 }
2303 return CMD_SUCCESS;
2304 }
2305
2306 DEFPY(bmp_mirror_limit_cfg,
2307 bmp_mirror_limit_cmd,
2308 "bmp mirror buffer-limit (0-4294967294)",
2309 BMP_STR
2310 "Route Mirroring settings\n"
2311 "Configure maximum memory used for buffered mirroring messages\n"
2312 "Limit in bytes\n")
2313 {
2314 VTY_DECLVAR_CONTEXT(bgp, bgp);
2315 struct bmp_bgp *bmpbgp;
2316
2317 bmpbgp = bmp_bgp_get(bgp);
2318 bmpbgp->mirror_qsizelimit = buffer_limit;
2319
2320 return CMD_SUCCESS;
2321 }
2322
2323 DEFPY(no_bmp_mirror_limit_cfg,
2324 no_bmp_mirror_limit_cmd,
2325 "no bmp mirror buffer-limit [(0-4294967294)]",
2326 NO_STR
2327 BMP_STR
2328 "Route Mirroring settings\n"
2329 "Configure maximum memory used for buffered mirroring messages\n"
2330 "Limit in bytes\n")
2331 {
2332 VTY_DECLVAR_CONTEXT(bgp, bgp);
2333 struct bmp_bgp *bmpbgp;
2334
2335 bmpbgp = bmp_bgp_get(bgp);
2336 bmpbgp->mirror_qsizelimit = ~0UL;
2337
2338 return CMD_SUCCESS;
2339 }
2340
2341
2342 DEFPY(show_bmp,
2343 show_bmp_cmd,
2344 "show bmp",
2345 SHOW_STR
2346 BMP_STR)
2347 {
2348 struct bmp_bgp *bmpbgp;
2349 struct bmp_targets *bt;
2350 struct bmp_listener *bl;
2351 struct bmp_active *ba;
2352 struct bmp *bmp;
2353 struct ttable *tt;
2354 char uptime[BGP_UPTIME_LEN];
2355 char *out;
2356
2357 frr_each(bmp_bgph, &bmp_bgph, bmpbgp) {
2358 vty_out(vty, "BMP state for BGP %s:\n\n",
2359 bmpbgp->bgp->name_pretty);
2360 vty_out(vty, " Route Mirroring %9zu bytes (%zu messages) pending\n",
2361 bmpbgp->mirror_qsize,
2362 bmp_mirrorq_count(&bmpbgp->mirrorq));
2363 vty_out(vty, " %9zu bytes maximum buffer used\n",
2364 bmpbgp->mirror_qsizemax);
2365 if (bmpbgp->mirror_qsizelimit != ~0UL)
2366 vty_out(vty, " %9zu bytes buffer size limit\n",
2367 bmpbgp->mirror_qsizelimit);
2368 vty_out(vty, "\n");
2369
2370 frr_each(bmp_targets, &bmpbgp->targets, bt) {
2371 vty_out(vty, " Targets \"%s\":\n", bt->name);
2372 vty_out(vty, " Route Mirroring %sabled\n",
2373 bt->mirror ? "en" : "dis");
2374
2375 afi_t afi;
2376 safi_t safi;
2377
2378 FOREACH_AFI_SAFI (afi, safi) {
2379 const char *str = NULL;
2380
2381 switch (bt->afimon[afi][safi]) {
2382 case BMP_MON_PREPOLICY:
2383 str = "pre-policy";
2384 break;
2385 case BMP_MON_POSTPOLICY:
2386 str = "post-policy";
2387 break;
2388 case BMP_MON_PREPOLICY | BMP_MON_POSTPOLICY:
2389 str = "pre-policy and post-policy";
2390 break;
2391 }
2392 if (!str)
2393 continue;
2394 vty_out(vty, " Route Monitoring %s %s %s\n",
2395 afi2str(afi), safi2str(safi), str);
2396 }
2397
2398 vty_out(vty, " Listeners:\n");
2399 frr_each (bmp_listeners, &bt->listeners, bl)
2400 vty_out(vty, " %pSU:%d\n", &bl->addr,
2401 bl->port);
2402
2403 vty_out(vty, "\n Outbound connections:\n");
2404 tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
2405 ttable_add_row(tt, "remote|state||timer|local");
2406 ttable_rowseps(tt, 0, BOTTOM, true, '-');
2407 frr_each (bmp_actives, &bt->actives, ba) {
2408 const char *state_str = "?";
2409
2410 if (ba->bmp) {
2411 peer_uptime(ba->bmp->t_up.tv_sec,
2412 uptime, sizeof(uptime),
2413 false, NULL);
2414 ttable_add_row(tt,
2415 "%s:%d|Up|%s|%s|%pSU",
2416 ba->hostname, ba->port,
2417 ba->bmp->remote, uptime,
2418 &ba->addrsrc);
2419 continue;
2420 }
2421
2422 uptime[0] = '\0';
2423
2424 if (ba->t_timer) {
2425 long trem = thread_timer_remain_second(
2426 ba->t_timer);
2427
2428 peer_uptime(monotime(NULL) - trem,
2429 uptime, sizeof(uptime),
2430 false, NULL);
2431 state_str = "RetryWait";
2432 } else if (ba->t_read) {
2433 state_str = "Connecting";
2434 } else if (ba->resq.callback) {
2435 state_str = "Resolving";
2436 }
2437
2438 ttable_add_row(tt, "%s:%d|%s|%s|%s|%pSU",
2439 ba->hostname, ba->port,
2440 state_str,
2441 ba->last_err ? ba->last_err : "",
2442 uptime, &ba->addrsrc);
2443 continue;
2444 }
2445 out = ttable_dump(tt, "\n");
2446 vty_out(vty, "%s", out);
2447 XFREE(MTYPE_TMP, out);
2448 ttable_del(tt);
2449
2450 vty_out(vty, "\n %zu connected clients:\n",
2451 bmp_session_count(&bt->sessions));
2452 tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
2453 ttable_add_row(tt, "remote|uptime|MonSent|MirrSent|MirrLost|ByteSent|ByteQ|ByteQKernel");
2454 ttable_rowseps(tt, 0, BOTTOM, true, '-');
2455
2456 frr_each (bmp_session, &bt->sessions, bmp) {
2457 uint64_t total;
2458 size_t q, kq;
2459
2460 pullwr_stats(bmp->pullwr, &total, &q, &kq);
2461
2462 peer_uptime(bmp->t_up.tv_sec, uptime,
2463 sizeof(uptime), false, NULL);
2464
2465 ttable_add_row(tt, "%s|%s|%Lu|%Lu|%Lu|%Lu|%zu|%zu",
2466 bmp->remote, uptime,
2467 bmp->cnt_update,
2468 bmp->cnt_mirror,
2469 bmp->cnt_mirror_overruns,
2470 total, q, kq);
2471 }
2472 out = ttable_dump(tt, "\n");
2473 vty_out(vty, "%s", out);
2474 XFREE(MTYPE_TMP, out);
2475 ttable_del(tt);
2476 vty_out(vty, "\n");
2477 }
2478 }
2479
2480 return CMD_SUCCESS;
2481 }
2482
2483 static int bmp_config_write(struct bgp *bgp, struct vty *vty)
2484 {
2485 struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
2486 struct bmp_targets *bt;
2487 struct bmp_listener *bl;
2488 struct bmp_active *ba;
2489 afi_t afi;
2490 safi_t safi;
2491
2492 if (!bmpbgp)
2493 return 0;
2494
2495 if (bmpbgp->mirror_qsizelimit != ~0UL)
2496 vty_out(vty, " !\n bmp mirror buffer-limit %zu\n",
2497 bmpbgp->mirror_qsizelimit);
2498
2499 frr_each(bmp_targets, &bmpbgp->targets, bt) {
2500 vty_out(vty, " !\n bmp targets %s\n", bt->name);
2501
2502 if (bt->acl6_name)
2503 vty_out(vty, " ipv6 access-list %s\n", bt->acl6_name);
2504 if (bt->acl_name)
2505 vty_out(vty, " ip access-list %s\n", bt->acl_name);
2506
2507 if (bt->stat_msec)
2508 vty_out(vty, " bmp stats interval %d\n",
2509 bt->stat_msec);
2510
2511 if (bt->mirror)
2512 vty_out(vty, " bmp mirror\n");
2513
2514 FOREACH_AFI_SAFI (afi, safi) {
2515 const char *afi_str = (afi == AFI_IP) ? "ipv4" : "ipv6";
2516
2517 if (bt->afimon[afi][safi] & BMP_MON_PREPOLICY)
2518 vty_out(vty, " bmp monitor %s %s pre-policy\n",
2519 afi_str, safi2str(safi));
2520 if (bt->afimon[afi][safi] & BMP_MON_POSTPOLICY)
2521 vty_out(vty, " bmp monitor %s %s post-policy\n",
2522 afi_str, safi2str(safi));
2523 }
2524 frr_each (bmp_listeners, &bt->listeners, bl)
2525 vty_out(vty, " \n bmp listener %pSU port %d\n",
2526 &bl->addr, bl->port);
2527
2528 frr_each (bmp_actives, &bt->actives, ba) {
2529 vty_out(vty, " bmp connect %s port %u min-retry %u max-retry %u",
2530 ba->hostname, ba->port,
2531 ba->minretry, ba->maxretry);
2532
2533 if (ba->ifsrc)
2534 vty_out(vty, " source-interface %s\n", ba->ifsrc);
2535 else
2536 vty_out(vty, "\n");
2537 }
2538 vty_out(vty, " exit\n");
2539 }
2540
2541 return 0;
2542 }
2543
2544 static int bgp_bmp_init(struct thread_master *tm)
2545 {
2546 install_node(&bmp_node);
2547 install_default(BMP_NODE);
2548
2549 cmd_variable_handler_register(bmp_targets_var_handlers);
2550
2551 install_element(BGP_NODE, &bmp_targets_cmd);
2552 install_element(BGP_NODE, &no_bmp_targets_cmd);
2553
2554 install_element(BMP_NODE, &bmp_listener_cmd);
2555 install_element(BMP_NODE, &no_bmp_listener_cmd);
2556 install_element(BMP_NODE, &bmp_connect_cmd);
2557 install_element(BMP_NODE, &bmp_acl_cmd);
2558 install_element(BMP_NODE, &bmp_stats_cmd);
2559 install_element(BMP_NODE, &bmp_monitor_cmd);
2560 install_element(BMP_NODE, &bmp_mirror_cmd);
2561
2562 install_element(BGP_NODE, &bmp_mirror_limit_cmd);
2563 install_element(BGP_NODE, &no_bmp_mirror_limit_cmd);
2564
2565 install_element(VIEW_NODE, &show_bmp_cmd);
2566
2567 resolver_init(tm);
2568 return 0;
2569 }
2570
2571 static int bgp_bmp_module_init(void)
2572 {
2573 hook_register(bgp_packet_dump, bmp_mirror_packet);
2574 hook_register(bgp_packet_send, bmp_outgoing_packet);
2575 hook_register(peer_status_changed, bmp_peer_status_changed);
2576 hook_register(peer_backward_transition, bmp_peer_backward);
2577 hook_register(bgp_process, bmp_process);
2578 hook_register(bgp_inst_config_write, bmp_config_write);
2579 hook_register(bgp_inst_delete, bmp_bgp_del);
2580 hook_register(frr_late_init, bgp_bmp_init);
2581 return 0;
2582 }
2583
2584 FRR_MODULE_SETUP(.name = "bgpd_bmp", .version = FRR_VERSION,
2585 .description = "bgpd BMP module",
2586 .init = bgp_bmp_module_init,
2587 );